[
  {
    "path": ".bzrignore",
    "content": "debian/*.debhelper\ndebian/files\ndebian/*.log\ndebian/stargus\ndebian/*.substvars\n*.dll\n*.exe\nExecDos.zip\nscmconvert\nstarextract\nstargus\nStargus-*.exe.asc\nstargus_*.tar.gz\nstargus_*.tar.gz.asc\nstartool\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# Keep GitHub Actions up to date with GitHub's Dependabot... dependabot.yml\r\n# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot\r\n# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem\r\nversion: 2\r\nupdates:\r\n  - package-ecosystem: github-actions\r\n    directory: /\r\n    groups:\r\n      github-actions:\r\n        patterns:\r\n          - \"*\"  # Group all Actions updates into a single larger pull request\r\n    schedule:\r\n      interval: weekly\r\n"
  },
  {
    "path": ".github/workflows/cmake.yml",
    "content": "name: CMake\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\nenv:\n  BUILD_TYPE: Release\n\njobs:\n  build:\n    strategy:\n      matrix:\n        os: [ubuntu-latest, ubuntu-20.04, windows-2022]\n    runs-on: ${{ matrix.os }}\n\n    steps:\n    - uses: actions/checkout@v6\n\n    - uses: olegtarasov/get-tag@v2.1.4\n      id: tagName\n\n    - name: Install ubuntu dependencies\n      if: startsWith(matrix.os, 'ubuntu')\n      run:  |\n        sudo apt-get update\n        sudo apt-get install -yy libpng-dev libgtk2.0-dev zlib1g-dev libstorm-dev libmagick++-6.q16-dev libcppunit-dev wget imagemagick\n        wget https://github.com/Wargus/stratagus/archive/master.zip\n        unzip master.zip\n\n    - name: Install windows dependencies\n      if: startsWith(matrix.os, 'windows')\n      run:  |\n        if ($null -eq $env:GIT_TAG_NAME) { $env:RELEASE = 'master-builds' } else { $env:RELEASE = $env:GIT_TAG_NAME }\n        if ($null -eq $env:GIT_TAG_NAME) { $env:SRCTAG = 'master' } else { $env:SRCTAG = $env:GIT_TAG_NAME }\n        Invoke-WebRequest https://github.com/Wargus/win32-stratagus-dependencies/releases/download/$env:RELEASE/dependencies.zip -OutFile ${{github.workspace}}/dependencies.zip\n        Expand-Archive ${{github.workspace}}/dependencies.zip -DestinationPath ${{github.workspace}}/\n        mkdir build\n        Invoke-WebRequest https://github.com/Wargus/stratagus/releases/download/$env:RELEASE/compiled-binaries.zip -OutFile ${{github.workspace}}/compiled-binaries.zip\n        Expand-Archive compiled-binaries.zip -DestinationPath ${{github.workspace}}/build/\n        Invoke-WebRequest https://github.com/Wargus/stratagus/archive/$env:SRCTAG.zip -OutFile ${{github.workspace}}/stratagus-source.zip\n        Expand-Archive stratagus-source.zip -DestinationPath ${{github.workspace}}/\n        if ($null -ne $env:GIT_TAG_NAME) { move stratagus-$env:SRCTAG stratagus-master }\n\n    - name: Configure CMake on unix\n      if: startsWith(matrix.os, 'ubuntu')\n      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DSTRATAGUS=stratagus -DSTRATAGUS_INCLUDE_DIR=${{github.workspace}}/stratagus-master/gameheaders\n\n    - name: Configure CMake on Windows\n      if: startsWith(matrix.os, 'windows')\n      run: cmake -B ${{github.workspace}}/build -G \"Visual Studio 17 2022\" -A win32 -DCMAKE_PREFIX_PATH=\"${{github.workspace}}\\\\dependencies\" -DSTRATAGUS=stratagus -DSTRATAGUS_INCLUDE_DIR=\"${{github.workspace}}\\\\stratagus-master\\\\gameheaders\" -DENABLE_NSIS=ON\n\n    - name: Build\n      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}\n\n    - name: Store windows artifacts\n      uses: actions/upload-artifact@v5\n      if: startsWith(matrix.os, 'windows')\n      with:\n        name: Stargus\n        path: ${{github.workspace}}/build/Stargus-*.exe\n\n    - uses: softprops/action-gh-release@v2\n      name: Publish nightly\n      if: github.ref == 'refs/heads/master' && startsWith(matrix.os, 'windows')\n      with:\n        name: master-builds\n        body: 'Automatic builds from the master branch'\n        draft: false\n        prerelease: true\n        tag_name: master-builds\n        files: ${{github.workspace}}/build/stargus-*.exe\n\n    - uses: softprops/action-gh-release@v2\n      name: Publish release\n      if: startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows')\n      with:\n        name: ${{ steps.tagName.outputs.tag }}\n        body: 'Release'\n        draft: false\n        prerelease: false\n        files: ${{github.workspace}}/build/stargus-*.exe\n"
  },
  {
    "path": ".github/workflows/macos.yml",
    "content": "name: macOS\n\non:\n  workflow_dispatch:\n  push:\n    paths:\n      - '**'\n      - '!.github/**'\n      - '!**.yml'\n      - '.github/workflows/macos.yml'\n      - '!**.md'\n      - '!.vscode/**'\n      - '!doc/**'\n\n  pull_request:\n    paths:\n      - '**'\n      - '!.github/**'\n      - '!**.yml'\n      - '.github/workflows/macos.yml'\n      - '!**.md'\n      - '!.vscode/**'\n      - '!doc/**'\n\njobs:\n  macOS:\n    strategy:\n      matrix:\n        include:\n            - runner: macos-latest\n              suffix: arm64\n            - runner: macos-15-intel\n              suffix: x86\n              \n    runs-on: ${{ matrix.runner}}\n\n    steps:\n    - name: Checkout Stargus\n      uses: actions/checkout@v6\n      with:\n        repository: Wargus/stargus\n        submodules: recursive\n        path: stargus\n\n    - name: Checkout Stratagus\n      uses: actions/checkout@v6\n      with: \n        repository: Wargus/stratagus\n        submodules: recursive\n        path: stratagus\n\n    - name: Install dependencies\n      run: brew install dylibbundler imagemagick sdl2 sdl2_mixer sdl2_image lua ffmpeg meson\n\n    - name: cmake --version\n      run: cmake --version\n\n    - name: Build Stratagus\n      run: |\n        cmake stratagus -B stratagus/build \\\n        -DCMAKE_BUILD_TYPE=Release \\\n        -DCMAKE_FIND_FRAMEWORK=LAST \\\n        -DBUILD_VENDORED_LUA=ON \\\n        -DBUILD_VENDORED_SDL=OFF \\\n        -DBUILD_VENDORED_MEDIA_LIBS=OFF \\\n        -DBUILD_TESTING=1\n        cmake --build stratagus/build\n\n    - name: Build Stargus\n      run: |\n        meson setup stargus \\\n        --buildtype=release \\\n        -DSTRATAGUS_INCLUDE_DIR=../../stratagus/gameheaders \\\n        -DSTRATAGUS_BIN=../../stratagus/build/stratagus \\\n        stargus/build\n        ninja -C stargus/build\n\n    - name: Create app bundle\n      run: |\n        export STRATAGUS=stratagus/build/stratagus\n        stargus/mac/bundle.sh\n        \n        dylibbundler -of -cd -b -x stargus/mac/Stargus.app/Contents/MacOS/stratagus -d stargus/mac/Stargus.app/Contents/libs/\n        dylibbundler -of -cd -b -x stargus/mac/Stargus.app/Contents/MacOS/startool -d stargus/mac/Stargus.app/Contents/libs/\n        \n        codesign --force --deep --sign - stargus/mac/Stargus.app\n        \n    - name: Create .dmg\n      run: hdiutil create -volname \"Stargus\" -srcfolder \"stargus/mac/Stargus.app\" \"Stargus-${{ matrix.suffix }}\"\n    \n    - name: Upload artifact\n      uses: actions/upload-artifact@v5\n      with:\n        name: Stargus-macOS-${{ matrix.suffix }}\n        path: Stargus-${{ matrix.suffix }}.dmg\n        if-no-files-found: error\n"
  },
  {
    "path": ".gitignore",
    "content": "#Ignore Visual Studio project files\nbuild/\nbuild_linux/\n.vscode/*\n**/.DS_Store\ncampaigns\n*/clangd/**"
  },
  {
    "path": ".travis.yml",
    "content": "language: cpp\ncompiler:\n  - gcc\nos:\n  - linux\ndist: focal\naddons:\n  apt:\n    packages:\n      - libpng-dev\n      - libgtk2.0-dev\n      - zlib1g-dev\n      - libstorm-dev\n      - meson\n      - ninja-build\n      - libmagick++-6.q16-dev\n      - libcppunit-dev\n      - nlohmann-json3-dev\nbefore_script:\n  - curl -L https://github.com/Wargus/stratagus/archive/master.zip -O master.zip || true\n  - unzip master.zip\n  - meson build -DSTRATAGUS_BIN='stratagus' -DSTRATAGUS_INCLUDE_DIR=../stratagus-master/gameheaders\nscript: ninja -C build\nafter_success:\n  - \"if [ $TRAVIS_OS_NAME == osx ]; then \\\n        if [ $TRAVIS_REPO_SLUG == Wargus/stargus -a \\\n             $TRAVIS_BRANCH == master -a \\\n             $TRAVIS_PULL_REQUEST == 'false' ]; then \\\n           cd $TRAVIS_BUILD_DIR;\n           git clone https://${GH_TOKEN}@github.com/Wargus/stratagus.wiki.git;\n           export STRATAGUS=$(pwd)/stratagus.wiki/$TRAVIS_OS_NAME/stratagus;\n           mac/bundle.sh;\n           tar czvf Stargus.app.tar.gz mac/Stargus.app;\n           cp Stargus.app.tar.gz stratagus.wiki/$TRAVIS_OS_NAME/;\n           cd stratagus.wiki/;\n           git config --global user.email \\\"travis-ci@travis.org\\\";\n           git config --global user.name \\\"Travis CI\\\";\n           git add $TRAVIS_OS_NAME/Stargus.app.tar.gz;\n           git commit --amend -C HEAD;\n           git push -fq origin master;\n           cd ..;\n        fi;\n    fi\"\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "#       _________ __                 __\n#      /   _____//  |_____________ _/  |______     ____  __ __  ______\n#      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n#      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ |\n#     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n#             \\/                  \\/          \\//_____/            \\/\n#  ______________________                           ______________________\n#                        T H E   W A R   B E G I N S\n#         Stratagus - A free fantasy real time strategy game engine\n#\n#    CMakeLists.txt\n#    Copyright (C) 2011-2012  Pali Rohár <pali.rohar@gmail.com>\n#\n#    This program is free software: you can redistribute it and/or modify\n#    it under the terms of the GNU General Public License as published by\n#    the Free Software Foundation, either version 2 of the License, or\n#    (at your option) any later version.\n#\n#    This program is distributed in the hope that it will be useful,\n#    but WITHOUT ANY WARRANTY; without even the implied warranty of\n#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#    GNU General Public License for more details.\n#\n#    You should have received a copy of the GNU General Public License\n#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n#\n\n# Project setup\n\nproject(stargus)\ncmake_minimum_required(VERSION 3.10)\ncmake_policy(VERSION 3.10..3.20.2)\nset(STARGUS_VERSION 2.4.1)\nset(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\nset(CMAKE_CXX_STANDARD 17)\n\n# CMake setup\n\nif(WIN32 AND MSVC)\n  if(EXISTS ${WIN32_CMAKE_PREFIX_PATH})\n    list(APPEND CMAKE_PREFIX_PATH \"${WIN32_CMAKE_PREFIX_PATH}\")\n    message(\"Using prefix path ${CMAKE_PREFIX_PATH}\")\n  endif()\n  if (NOT CMAKE_PREFIX_PATH)\n    # use a default\n    set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../dependencies)\n  endif()\nendif()\n\n# Stargus sources\n\nset(scmconvert_SRCS\n\tStorm.cpp\n\tscm.cpp\n\tFileUtil.cpp\n)\n\nset(scmconvert_HDRS\n\tStorm.h\n\tFileUtil.h\n)\n\nfile(GLOB startool_SRCS\n\tsrc/*.cpp\n\tsrc/dat/*.cpp\n\tsrc/kaitai/*.cpp\n\tsrc/libgrp/*.cpp\n\tsrc/libgrp/Exceptions/*.cpp\n\tsrc/libgrp/GRPFrame/*.cpp\n\tsrc/libgrp/GRPImage/*.cpp\n\tsrc/tileset/*.cpp\n)\n\nfile(GLOB startool_HDRS\n\tsrc/*.h\n\tsrc/dat/*.h\n\tsrc/kaitai/*.h\n\tsrc/libgrp/*.h\n\tsrc/libgrp/Exceptions/*.h\n\tsrc/libgrp/GRPFrame/*.h\n\tsrc/libgrp/GRPImage/*.h\n\tsrc/tileset/*.h\n)\n\nfile(GLOB stargus_SRCS\n\tsrc/stargus.cpp\n)\n\nlist(REMOVE_ITEM startool_SRCS \"${stargus_SRCS}\")\n\nif(WIN32)\n\tset(stargus_SRCS\n\t\t${stargus_SRCS}\n\t\tstargus.rc\n\t)\nendif()\n\n# Find all libraries\n\nfind_package(Stratagus REQUIRED)\nfind_package(PNG REQUIRED)\nfind_package(ZLIB REQUIRED)\nfind_package(StormLib REQUIRED)\nfind_package(CascLib)\n\nif(WIN32)\n\tfind_package(MakeNSIS)\nendif()\n\n# Windows RC compiler definitions\n\nif(WIN32)\n\tenable_language(RC)\n\tinclude(CMakeDetermineRCCompiler)\n\n\tif(MINGW)\n\t\tset(CMAKE_RC_COMPILER_INIT windres)\n\t\tset(CMAKE_RC_COMPILE_OBJECT \"<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>\")\n\tendif()\nendif()\n\n# Options for compiling\n\nif(WIN32)\n\toption(ENABLE_NSIS \"Create Stratagus Window NSIS Installer\" OFF)\nendif()\n\noption(WITH_CASCLIB \"Compile startool with CascLib support\" ON)\n\n# General definitions and compilation settings\n\nadd_definitions(${PNG_DEFINITIONS})\nadd_definitions(-DSOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../\")\nadd_definitions(-DKS_STR_ENCODING_NONE)\nadd_definitions(-DUSE_STORMLIB -D__STORMLIB_SELF__)\n\ninclude_directories(${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ${STORMLIB_INCLUDE_DIR} src)\n\nset(scmconvert_LIBS ${scmconvert_LIBS} ${ZLIB_LIBRARIES} ${STORMLIB_LIBRARY} ${BZIP2_LIBRARIES})\nset(startool_LIBS ${scmconvert_LIBS} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${STORMLIB_LIBRARY} ${BZIP2_LIBRARIES})\n\n# Platform specific definitions and compilation settings\n\nadd_subdirectory(\"subprojects/nlohmann_json\")\ninclude_directories(\"subprojects/nlohmann_json/include\")\nset(startool_LIBS ${startool_LIBS} ${NLOHMANN_JSON_TARGET_NAME})\n\nif(WIN32 AND MSVC)\n\tadd_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE=1 -D_HAS_STD_BYTE=0)\n\tadd_subdirectory(\"subprojects/win-iconv\")\n\tinclude_directories(\"subprojects/win-iconv\")\n\tset(startool_LIBS ${startool_LIBS} iconv-static)\nendif()\n\ninclude(CheckCXXSourceCompiles)\n\nset(FS_SRC \"\n#include <filesystem>\nnamespace fs = std::filesystem;\nint main() {\n\tfs::path p = fs::path(\\\".\\\");\n\tif (fs::absolute(p).is_absolute()) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n\")\ncheck_cxx_source_compiles(\"${FS_SRC}\" HAS_17_FS)\n\nif(NOT HAS_17_FS) # Tr\n\tset(EXPERIMENTAL_FS_SRC \"\n\t#include <experimental/filesystem>\n\tnamespace fs = std::experimental::filesystem;\n\tint main() {\n\t\tfs::path p = fs::path(\\\".\\\");\n\t\tif (fs::absolute(p).is_absolute()) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n\t}\n\t\")\n\tcheck_cxx_source_compiles(\"${EXPERIMENTAL_FS_SRC}\" HAS_17_EXPERIMENTAL_FS)\n\tif(NOT HAS_17_EXPERIMENTAL_FS)\n\t\tset(CMAKE_REQUIRED_LIBRARIES stdc++fs)\n\t\tcheck_cxx_source_compiles(\"${EXPERIMENTAL_FS_SRC}\" HAS_EXP_17_FS_WITH_STDC)\n\t\tif(HAS_EXP_17_FS_WITH_STDC)\n\t\t\tset(stargus_LIBS ${stargus_LIBS} stdc++fs)\n\t\t\tset(startool_LIBS ${startool_LIBS} stdc++fs)\n\t\telse()\n\t\t\tset(CMAKE_REQUIRED_LIBRARIES c++fs)\n\t\t\tcheck_cxx_source_compiles(\"${EXPERIMENTAL_FS_SRC}\" HAS_EXP_17_FS_WITH_CLIB)\n\t\t\tif(HAS_EXP_17_FS_WITH_CLIB)\n\t\t\t\tset(stargus_LIBS ${stargus_LIBS} c++fs)\n\t\t\t\tset(startool_LIBS ${startool_LIBS} c++fs)\n\t\t\telse()\n\t\t\t\tmessage(FATAL_ERROR \"I don't know how to compile with C++17 filesystem support on your system\")\n\t\t\tendif()\n\t\tendif()\n\tendif()\nendif()\n\n########### startool ###############\n\nset(BINDIR \"bin\" CACHE PATH \"Where to install user binaries\")\n\n#add_executable(scmconvert ${scmconvert_SRCS} ${scmconvert_HDRS})\n#target_link_libraries(scmconvert ${scmconvert_LIBS})\n#set_target_properties(scmconvert PROPERTIES COMPILE_DEFINITIONS \"STAND_ALONE\")\n#install(TARGETS scmconvert DESTINATION ${BINDIR})\n\nadd_executable(startool ${startool_SRCS} ${startool_HDRS})\ntarget_link_libraries(startool ${startool_LIBS})\ninstall(TARGETS startool DESTINATION ${BINDIR})\n\n########### stargus launcher and installer ###############\n\nif(STRATAGUS_FOUND)\n  include_directories(${STRATAGUS_INCLUDE_DIR})\n\n  set(GAMEDIR \"games\" CACHE PATH \"Where to install games binaries\")\n  set(SHAREDIR \"share/games/stratagus/stargus\" CACHE PATH \"Where to install data files\")\n  set(DATAROOTDIR \"${CMAKE_INSTALL_PREFIX}/share\" CACHE PATH \"Sets the root of data directories to a non-default location\")\n  set(ICONDIR \"${DATAROOTDIR}/pixmaps\" CACHE PATH \"Sets the icon directory for desktop entry to a non-default location.\")\n  set(DESKTOPDIR \"${DATAROOTDIR}/applications\" CACHE PATH \"Sets the desktop file directory for desktop entry to a non-default location.\")\n  if(NOT IS_ABSOLUTE \"${GAMEDIR}\")\n    set(GAMEDIRABS \"${CMAKE_INSTALL_PREFIX}/${GAMEDIR}\")\n  else()\n    set(GAMEDIRABS \"${GAMEDIR}\")\n  endif()\n  if(NOT IS_ABSOLUTE \"${SHAREDIR}\")\n    set(DATA_PATH \"${CMAKE_INSTALL_PREFIX}/${SHAREDIR}\")\n  else()\n    set(DATA_PATH \"${SHAREDIR}\")\n  endif()\n\n  if (NOT WIN32)\n    add_definitions(-DDATA_PATH=\"${DATA_PATH}\")\n    add_definitions(-DSCRIPTS_PATH=\"${DATA_PATH}\")\n    add_definitions(-DSTRATAGUS_BIN=\"${STRATAGUS}\")\n    configure_file (\n      \"${PROJECT_SOURCE_DIR}/stargus.desktop.in\"\n      \"${PROJECT_BINARY_DIR}/stargus.desktop\"\n    )\n    add_custom_command(OUTPUT \"${PROJECT_BINARY_DIR}/stargus.png\"\n      COMMAND convert\n      ARGS \"${PROJECT_SOURCE_DIR}/stargus.ico\" \"${PROJECT_BINARY_DIR}/stargus.png\"\n      DEPENDS stargus.ico\n      COMMENT \"Generating stargus.png\" VERBATIM\n    )\n    add_custom_target(icon ALL DEPENDS stargus.png)\n    install(FILES\n      \"${PROJECT_BINARY_DIR}/stargus.png\"\n      \"${CMAKE_CURRENT_SOURCE_DIR}/dataset/palettes.json\"\n      \"${CMAKE_CURRENT_SOURCE_DIR}/dataset/units.json\"\n      DESTINATION ${ICONDIR}\n    )\n    add_custom_command(OUTPUT \"${PROJECT_BINARY_DIR}/stargus.xpm\"\n      COMMAND convert\n      ARGS \"${PROJECT_SOURCE_DIR}/stargus.ico\" -resize 32x32 \"${PROJECT_BINARY_DIR}/stargus.xpm\"\n      DEPENDS stargus.ico\n      COMMENT \"Generating stargus.xmp\" VERBATIM\n    )\n    add_custom_target(xpmicon ALL DEPENDS stargus.xpm)\n    install(FILES \"${PROJECT_BINARY_DIR}/stargus.xpm\" DESTINATION ${ICONDIR})\n    install(FILES \"${PROJECT_BINARY_DIR}/stargus.desktop\" DESTINATION ${DESKTOPDIR})\n    install(DIRECTORY campaigns contrib maps scripts shaders DESTINATION ${SHAREDIR})\n\tinstall(FILES mpqlist.txt DESTINATION ${SHAREDIR})\n  elseif (WIN32)\n    if(ENABLE_NSIS AND MAKENSIS_FOUND)\n\tfile(COPY ${CMAKE_CURRENT_SOURCE_DIR}/COPYING DESTINATION ${CMAKE_CURRENT_BINARY_DIR})\n\tfile(COPY ${CMAKE_CURRENT_SOURCE_DIR}/stargus.ico DESTINATION ${CMAKE_CURRENT_BINARY_DIR})\n\tfile(COPY ${CMAKE_CURRENT_SOURCE_DIR}/mpqlist.txt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})\n      add_custom_target(nsis ALL\n        COMMAND ${MAKENSIS} ${MAKENSIS_FLAGS} -DPORTABLE=1 -DCMAKE_CURRENT_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\" -DCMAKE_CURRENT_BINARY_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" ${CMAKE_CURRENT_SOURCE_DIR}/stargus.nsi\n        COMMAND ${MAKENSIS} ${MAKENSIS_FLAGS} -DCMAKE_CURRENT_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\" -DCMAKE_CURRENT_BINARY_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" ${CMAKE_CURRENT_SOURCE_DIR}/stargus.nsi\n        DEPENDS stargus.nsi stargus startool COPYING mpqlist.txt stargus.ico\n        COMMENT \"Generating stargus Windows NSIS Installers\" VERBATIM\n        SOURCES stargus.nsi)\n    endif()\n  endif()\n\n  add_executable(stargus WIN32 ${stargus_SRCS})\n  target_link_libraries(stargus ${stargus_LIBS})\n  set(GAMEDIR \"games\" CACHE PATH \"Where to install games binaries\")\n  install(TARGETS stargus DESTINATION ${GAMEDIR})\nendif()\n\n# uninstall target\nif(NOT TARGET uninstall)\n    configure_file(\n        \"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in\"\n        \"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake\"\n        IMMEDIATE @ONLY)\n\n    add_custom_target(uninstall\n        COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)\nendif()\n"
  },
  {
    "path": "COPYING",
    "content": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\t\t\t    Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\f\n\t\t    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\f\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\f\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\f\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS\n\f\n\t    How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year  name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General\nPublic License instead of this License.\n"
  },
  {
    "path": "Doxyfile",
    "content": "# Doxyfile 1.8.17\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the configuration\n# file that follow. The default is UTF-8 which is also the encoding used for all\n# text before the first occurrence of this tag. Doxygen uses libiconv (or the\n# iconv built into libc) for the transcoding. See\n# https://www.gnu.org/software/libiconv/ for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = \"stargus\"\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         =\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          =\n\n# With the PROJECT_LOGO tag one can specify a logo or an icon that is included\n# in the documentation. The maximum height of the logo should not exceed 55\n# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy\n# the logo to the output directory.\n\nPROJECT_LOGO           =\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = doc/doxygen\n\n# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII\n# characters to appear in the names of generated files. If set to NO, non-ASCII\n# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode\n# U+3044.\n# The default value is: NO.\n\nALLOW_UNICODE_NAMES    = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,\n# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),\n# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,\n# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),\n# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,\n# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,\n# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,\n# Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all generated output in the proper direction.\n# Possible values are: None, LTR, RTL and Context.\n# The default value is: None.\n\nOUTPUT_TEXT_DIRECTION  = None\n\n# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       = \"The $name class\" \\\n                         \"The $name widget\" \\\n                         \"The $name file\" \\\n                         is \\\n                         provides \\\n                         specifies \\\n                         contains \\\n                         represents \\\n                         a \\\n                         an \\\n                         the\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = YES\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        =\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    =\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = NO\n\n# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line\n# such as\n# /***************\n# as being the beginning of a Javadoc-style comment \"banner\". If set to NO, the\n# Javadoc-style will behave just like regular comments and it will not be\n# interpreted by doxygen.\n# The default value is: NO.\n\nJAVADOC_BANNER         = NO\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new\n# page for each member. If set to NO, the documentation of a member will be part\n# of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 4\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:\\n\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". You can put \\n's in the value part of an alias to insert\n# newlines (in the resulting output). You can put ^^ in the value part of an\n# alias to insert a newline as if a physical newline was in the original file.\n# When you need a literal { or } or , in the value part of an alias you have to\n# escape them by means of a backslash (\\), this can lead to conflicts with the\n# commands \\{ and \\} for these it is advised to use the version @{ and @} or use\n# a double escape (\\\\{ and \\\\})\n\nALIASES                =\n\n# This tag can be used to specify a number of word-keyword mappings (TCL only).\n# A mapping has the form \"name=value\". For example adding \"class=itcl::class\"\n# will allow you to use the command class in the itcl::class meaning.\n\nTCL_SUBST              =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice\n# sources only. Doxygen will then generate output that is more tailored for that\n# language. For instance, namespaces will be presented as modules, types will be\n# separated into more groups, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_SLICE  = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,\n# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,\n# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:\n# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser\n# tries to guess whether the code is fixed or free formatted code, this is the\n# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat\n# .inc files as Fortran files (default is PHP), and .f files as C (default is\n# Fortran), use: inc=Fortran f=C.\n#\n# Note: For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen.\n\nEXTENSION_MAPPING      =\n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See https://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up\n# to that level are automatically included in the table of contents, even if\n# they do not have an id attribute.\n# Note: This feature currently applies only to Markdown headings.\n# Minimum value: 0, maximum value: 99, default value: 5.\n# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.\n\nTOC_INCLUDE_HEADINGS   = 5\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by putting a % sign in front of the word or\n# globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = YES\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# If one adds a struct or class to a group and this option is enabled, then also\n# any nested class or struct is added to the same group. By default this option\n# is disabled and one has to add nested compounds explicitly via \\ingroup.\n# The default value is: NO.\n\nGROUP_NESTED_COMPOUNDS = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = NO\n\n# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = YES\n\n# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual\n# methods of a class will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIV_VIRTUAL   = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = YES\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO,\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# This flag is only useful for Objective-C code. If set to YES, local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO, only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO, these classes will be included in the various overviews. This option\n# has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# declarations. If set to NO, these declarations will be included in the\n# documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO, these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file\n# names in lower-case letters. If set to YES, upper-case letters are also\n# allowed. This is useful if you have classes or files whose names only differ\n# in case and if your file system supports case sensitive file names. Windows\n# (including Cygwin) ands Mac users are advised to set this option to NO.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = YES\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES, the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will\n# append additional text to a page's title, such as Class Reference. If set to\n# YES the compound reference will be hidden.\n# The default value is: NO.\n\nHIDE_COMPOUND_REFERENCE= NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each\n# grouped member an include statement to the documentation, telling the reader\n# which file to include in order to use the member.\n# The default value is: NO.\n\nSHOW_GROUPED_MEMB_INC  = NO\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order. Note that\n# this will also influence the order of the classes in the class list.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo\n# list. This list is created by putting \\todo commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test\n# list. This list is created by putting \\test commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES, the\n# list will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = YES\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = YES\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            =\n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. See also \\cite for info how to create references.\n\nCITE_BIB_FILES         =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some parameters\n# in a documented function, or documenting parameters that don't exist or using\n# markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO, doxygen will only warn about wrong or incomplete\n# parameter documentation, but not about the absence of documentation. If\n# EXTRACT_ALL is set to YES then this flag will automatically be disabled.\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when\n# a warning is encountered.\n# The default value is: NO.\n\nWARN_AS_ERROR          = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr).\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  = src\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see: https://www.gnu.org/software/libiconv/) for the list of\n# possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# read by doxygen.\n#\n# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,\n# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,\n# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,\n# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),\n# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen\n# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,\n# *.vhdl, *.ucf, *.qsf and *.ice.\n\nFILE_PATTERNS          = *.c \\\n                         *.cc \\\n                         *.cxx \\\n                         *.cpp \\\n                         *.c++ \\\n                         *.java \\\n                         *.ii \\\n                         *.ixx \\\n                         *.ipp \\\n                         *.i++ \\\n                         *.inl \\\n                         *.idl \\\n                         *.ddl \\\n                         *.odl \\\n                         *.h \\\n                         *.hh \\\n                         *.hxx \\\n                         *.hpp \\\n                         *.h++ \\\n                         *.cs \\\n                         *.d \\\n                         *.php \\\n                         *.php4 \\\n                         *.php5 \\\n                         *.phtml \\\n                         *.inc \\\n                         *.m \\\n                         *.markdown \\\n                         *.md \\\n                         *.mm \\\n                         *.dox \\\n                         *.doc \\\n                         *.txt \\\n                         *.py \\\n                         *.pyw \\\n                         *.f90 \\\n                         *.f95 \\\n                         *.f03 \\\n                         *.f08 \\\n                         *.f \\\n                         *.for \\\n                         *.tcl \\\n                         *.vhd \\\n                         *.vhdl \\\n                         *.ucf \\\n                         *.qsf \\\n                         *.ice\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       =\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        =\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           =\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       = *\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             =\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS =\n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE =\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# entity all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see https://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the\n# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the\n# cost of reduced performance. This can be particularly helpful with template\n# rich C++ code for which doxygen's built-in parser lacks the necessary type\n# information.\n# Note: The availability of this option depends on whether or not doxygen was\n# generated with the -Duse_libclang=ON option for CMake.\n# The default value is: NO.\n\nCLANG_ASSISTED_PARSING = NO\n\n# If clang assisted parsing is enabled you can provide the compiler with command\n# line options that you would normally use when invoking the compiler. Note that\n# the include paths will already be set by doxygen for the files and directories\n# specified with INPUT and INCLUDE_PATH.\n# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.\n\nCLANG_OPTIONS          =\n\n# If clang assisted parsing is enabled you can provide the clang parser with the\n# path to the compilation database (see:\n# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files\n# were built. This is equivalent to specifying the \"-p\" option to a clang tool,\n# such as clang-check. These options will then be passed to the parser.\n# Note: The availability of this option depends on whether or not doxygen was\n# generated with the -Duse_libclang=ON option for CMake.\n\nCLANG_DATABASE_PATH    =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in\n# which the alphabetical index list will be split.\n# Minimum value: 1, maximum value: 20, default value: 5.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            =\n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            =\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        =\n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# cascading style sheets that are included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefore more robust against future updates.\n# Doxygen will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list). For an example see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  =\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       =\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the style sheet and background images according to\n# this color. Hue is specified as an angle on a colorwheel, see\n# https://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use grayscales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to YES can help to show when doxygen was last run and thus if the\n# documentation is up to date.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = NO\n\n# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML\n# documentation will contain a main index with vertical navigation menus that\n# are dynamically created via JavaScript. If disabled, the navigation index will\n# consists of multiple levels of tabs that are statically embedded in every HTML\n# page. Disable this option to support browsers that do not have JavaScript,\n# like the Qt help browser.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_MENUS     = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see: https://developer.apple.com/xcode/), introduced with OSX\n# 10.5 (Leopard). To create a documentation set, doxygen will generate a\n# Makefile in the HTML output directory. Running make will produce the docset in\n# that directory and running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy\n# genXcode/_index.html for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = NO\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = org.doxygen.Publisher\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = Publisher\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on\n# Windows.\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               =\n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler (hhc.exe). If non-empty,\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           =\n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated\n# (YES) or that it should be included in the master .chm file (NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     =\n\n# The BINARY_TOC flag controls whether a binary table of contents is generated\n# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it\n# enables the Previous and Next buttons.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-\n# folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# The QHG_LOCATION tag can be used to specify the location of Qt's\n# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the\n# generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = NO\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine-tune the look of the index. As an example, the default style\n# sheet generated by doxygen has an example that shows how to put an image at\n# the root of the tree instead of the PROJECT_NAME. Since the tree basically has\n# the same information as the tab index, you could consider setting\n# DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 250\n\n# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANSPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# The FORMULA_MACROFILE can contain LaTeX \\newcommand and \\renewcommand commands\n# to create new LaTeX commands to be used in formulas as building blocks. See\n# the section \"Including formulas\" for details.\n\nFORMULA_MACROFILE      =\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# https://www.mathjax.org) which uses client side JavaScript for the rendering\n# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. See the MathJax site (see:\n# http://docs.mathjax.org/en/latest/output.html) for more details.\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility), NativeMML (i.e. MathML) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from https://www.mathjax.org before deployment.\n# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     =\n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       =\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = YES\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using JavaScript. There\n# are two flavors of web server based searching depending on the EXTERNAL_SEARCH\n# setting. When disabled, doxygen will generate a PHP script for searching and\n# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing\n# and searching needs to be provided by external tools. See the section\n# \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: https://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: https://xapian.org/). See the section \"External Indexing and\n# Searching\" for details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       =\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     =\n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when not enabling USE_PDFLATEX the default is latex when enabling\n# USE_PDFLATEX the default is pdflatex and when in the later case latex is\n# chosen this is overwritten by pdflatex. For specific output languages the\n# default can have been set differently, this depends on the implementation of\n# the output language.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         =\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# Note: This tag is used in the Makefile / make.bat.\n# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file\n# (.tex).\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to\n# generate index for LaTeX. In case there is no backslash (\\) as first character\n# it will be automatically added in the LaTeX code.\n# Note: This tag is used in the generated output file (.tex).\n# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.\n# The default value is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_MAKEINDEX_CMD    = makeindex\n\n# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. The package can be specified just\n# by its name or with the correct syntax as to be used with the LaTeX\n# \\usepackage command. To get the times font for instance you can specify :\n# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}\n# To use the option intlimits with the amsmath package you can specify:\n# EXTRA_PACKAGES=[intlimits]{amsmath}\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         =\n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the\n# generated LaTeX document. The header should contain everything until the first\n# chapter. If it is left blank doxygen will generate a standard header. See\n# section \"Doxygen usage\" for information on how to let doxygen write the\n# default header to a separate file.\n#\n# Note: Only use a user-defined header if you know what you are doing! The\n# following commands have a special meaning inside the header: $title,\n# $datetime, $date, $doxygenversion, $projectname, $projectnumber,\n# $projectbrief, $projectlogo. Doxygen will replace $title with the empty\n# string, for the replacement values of the other commands the user is referred\n# to HTML_HEADER.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the\n# generated LaTeX document. The footer should contain everything after the last\n# chapter. If it is left blank doxygen will generate a standard footer. See\n# LATEX_HEADER for more information on how to generate a default footer and what\n# special commands can be used inside the footer.\n#\n# Note: Only use a user-defined footer if you know what you are doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           =\n\n# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# LaTeX style sheets that are included after the standard style sheets created\n# by doxygen. Using this option one can overrule certain style aspects. Doxygen\n# will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list).\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_STYLESHEET =\n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate\n# the PDF file directly from the LaTeX files. Set this option to YES, to get a\n# higher quality PDF documentation.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help. This option is also used\n# when generating formulas in HTML.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source\n# code with syntax highlighting in the LaTeX output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# https://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_TIMESTAMP        = NO\n\n# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)\n# path from which the emoji images will be read. If a relative path is entered,\n# it will be relative to the LATEX_OUTPUT directory. If left blank the\n# LATEX_OUTPUT directory will be used.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EMOJI_DIRECTORY  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's\n# configuration file, i.e. a series of assignments. You only have to provide\n# replacements, missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's configuration file. A template extensions file can be\n# generated using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    =\n\n# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code\n# with syntax highlighting in the RTF output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_SOURCE_CODE        = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# The MAN_SUBDIR tag determines the name of the directory created within\n# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by\n# MAN_EXTENSION with the initial . removed.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_SUBDIR             =\n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include\n# namespace members in file scope as well, matching the HTML output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_NS_MEMB_FILE_SCOPE = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the\n# program listings (including syntax highlighting and cross-referencing\n# information) to the DOCBOOK output. Note that enabling this will significantly\n# increase the size of the DOCBOOK output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_PROGRAMLISTING = NO\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an\n# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures\n# the structure of the code including all documentation. Note that this feature\n# is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO, the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names\n# in the source code. If set to NO, only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES, the include files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             =\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      =\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all references to function-like macros that are alone on a line, have\n# an all uppercase name, and do not end with a semicolon. Such function macros\n# are typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have a unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES, all external class will be listed in\n# the class index. If set to NO, only the inherited external classes will be\n# listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed\n# in the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram\n# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to\n# NO turns the diagrams off. Note that this option also works with HAVE_DOT\n# disabled, but it is recommended to install and use dot, since it yields more\n# powerful graphs.\n# The default value is: YES.\n\nCLASS_DIAGRAMS         = YES\n\n# You can include diagrams made with dia in doxygen documentation. Doxygen will\n# then run dia to produce the diagram and insert it in the documentation. The\n# DIA_PATH tag allows you to specify the directory where the dia binary resides.\n# If left empty dia is assumed to be found in the default search path.\n\nDIA_PATH               =\n\n# If set to YES the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: YES.\n\nHAVE_DOT               = YES\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font in the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for\n# each documented class showing the direct and indirect inheritance relations.\n# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command. Disabling a call graph can be\n# accomplished by means of the command \\hidecallgraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = YES\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command. Disabling a caller graph can be\n# accomplished by means of the command \\hidecallergraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = YES\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot. For an explanation of the image formats see the section\n# output formats in the documentation of the dot tool (Graphviz (see:\n# http://www.graphviz.org/)).\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,\n# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,\n# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,\n# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and\n# png:gdiplus:gdiplus.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           =\n\n# The DIAFILE_DIRS tag can be used to specify one or more directories that\n# contain dia files that are included in the documentation (see the \\diafile\n# command).\n\nDIAFILE_DIRS           =\n\n# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the\n# path where java can find the plantuml.jar file. If left blank, it is assumed\n# PlantUML is not used or called during a preprocessing step. Doxygen will\n# generate a warning when it encounters a \\startuml command in this case and\n# will not generate output for the diagram.\n\nPLANTUML_JAR_PATH      =\n\n# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a\n# configuration file for plantuml.\n\nPLANTUML_CFG_FILE      =\n\n# When using plantuml, the specified paths are searched for files specified by\n# the !include statement in a plantuml block.\n\nPLANTUML_INCLUDE_PATH  =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot\n# files that are used to generate the various graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "README.md",
    "content": "[![Join the chat at https://gitter.im/Wargus](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Wargus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n[![Discord](https://img.shields.io/discord/780082494447288340?style=flat-square&logo=discord&label=discord)](https://discord.gg/dQGxaw3QfB)\n\n### Nightly builds are available:\n\n- Windows Installer: https://github.com/Wargus/stargus/releases/tag/master-builds\n- Ubuntu/Debian Packages: https://code.launchpad.net/~timfelgentreff/+archive/ubuntu/stratagus\n- OS X App Bundle: https://github.com/Wargus/stratagus/wiki/osx/Stargus.app.tar.gz\n\n## Installation Instructions\n\nDownload the installer for your platform. Upon first launch of Stargus, it will ask you for\nyour Starcraft installation to extract the data to work with Stargus.\n\n## Build Instructions\n\nNOTE: stratagus ( https://github.com/Wargus/stratagus ) is required.\nstargus and stratagus version must match\n\n```\nmeson build\nninja -C build\n./stargus\n```\n\nPlease take a look into meson_options.txt for possible build options. Special -DSTRATAGUS_INCLUDE_DIR and -DSTRATAGUS_BIN.\n\n![image](https://cloud.githubusercontent.com/assets/46235/11292960/499a7d3c-8f55-11e5-9356-62c190c57467.png)\n![image](https://cloud.githubusercontent.com/assets/46235/11292993/9198675c-8f55-11e5-9f74-2f23fb207498.png)\n![image](https://cloud.githubusercontent.com/assets/46235/11293018/cef6e970-8f55-11e5-8625-8bd13082b041.png)\n"
  },
  {
    "path": "cmake/modules/FindCascLib.cmake",
    "content": "# - Try to find the CascLib library\n# Once done this will define\n#\n#  CASCLIB_FOUND - system has CascLib\n#  CASCLIB_INCLUDE_DIR - the CASCLIB include directory\n#  CASCLIB_LIBRARY - The CASCLIB library\n\n# Copyright (c) 2015, cybermind <cybermindid@gmail.com>\n#\n# Redistribution and use is allowed according to the terms of the BSD license.\n# For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n\nif(CASCLIB_INCLUDE_DIR AND CASCLIB_LIBRARY AND (NOT UNIX OR BZIP2_FOUND))\n\tset(CASCLIB_FOUND true)\nelse()\n\tfind_path(CASCLIB_INCLUDE_DIR CascLib.h)\n\tfind_library(CASCLIB_LIBRARY NAMES casc)\n\tif (UNIX)\n\t\tfind_package(BZip2)\n\tendif()\n\n\tif(CASCLIB_INCLUDE_DIR AND CASCLIB_LIBRARY AND (NOT UNIX OR BZIP2_FOUND))\n\t\tset(CASCLIB_FOUND true)\n\t\tmessage(STATUS \"Found CascLib: ${CASCLIB_LIBRARY}\")\n\telseif(UNIX AND NOT BZIP2_FOUND)\n\t\tset(CASCLIB_FOUND false)\n\t\tmessage(STATUS \"Could not find BZip2 required for CascLib\")\n\telse()\n\t\tset(CASCLIB_FOUND false)\n\t\tmessage(STATUS \"Could not find CascLib\")\n\tendif()\n\n\tmark_as_advanced(CASCLIB_INCLUDE_DIR CASCLIB_LIBRARY)\nendif()\n"
  },
  {
    "path": "cmake/modules/FindGTK2.cmake",
    "content": "# - FindGTK2.cmake\n# This module can find the GTK2 widget libraries and several of its other\n# optional components like gtkmm, glade, and glademm.\n#\n# NOTE: If you intend to use version checking, CMake 2.6.2 or later is\n#       required.\n#\n# Specify one or more of the following components\n# as you call this find module. See example below.\n#\n#   gtk\n#   gtkmm\n#   glade\n#   glademm\n#\n# The following variables will be defined for your use\n#\n#   GTK2_FOUND - Were all of your specified components found?\n#   GTK2_INCLUDE_DIRS - All include directories\n#   GTK2_LIBRARIES - All libraries\n#\n#   GTK2_VERSION - The version of GTK2 found (x.y.z)\n#   GTK2_MAJOR_VERSION - The major version of GTK2\n#   GTK2_MINOR_VERSION - The minor version of GTK2\n#   GTK2_PATCH_VERSION - The patch version of GTK2\n#\n# Optional variables you can define prior to calling this module:\n#\n#   GTK2_DEBUG - Enables verbose debugging of the module\n#   GTK2_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced\n#   GTK2_ADDITIONAL_SUFFIXES - Allows defining additional directories to\n#                              search for include files\n#\n#=================\n# Example Usage:\n#\n#   Call find_package() once, here are some examples to pick from:\n#\n#   Require GTK 2.6 or later\n#       find_package(GTK2 2.6 REQUIRED gtk)\n#\n#   Require GTK 2.10 or later and Glade\n#       find_package(GTK2 2.10 REQUIRED gtk glade)\n#\n#   Search for GTK/GTKMM 2.8 or later\n#       find_package(GTK2 2.8 COMPONENTS gtk gtkmm)\n#\n#   if(GTK2_FOUND)\n#      include_directories(${GTK2_INCLUDE_DIRS})\n#      add_executable(mygui mygui.cc)\n#      target_link_libraries(mygui ${GTK2_LIBRARIES})\n#   endif()\n#\n\n#=============================================================================\n# Copyright 2009 Kitware, Inc.\n# Copyright 2008-2009 Philip Lowman <philip@yhbt.com>\n#\n# Distributed under the OSI-approved BSD License (the \"License\");\n# see accompanying file Copyright.txt for details.\n#\n# This software is distributed WITHOUT ANY WARRANTY; without even the\n# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the License for more information.\n#=============================================================================\n# (To distribute this file outside of CMake, substitute the full\n#  License text for the above reference.)\n\n# Version 1.3 (11/9/2010) (CMake 2.8.4)\n#   * 11429: Add support for detecting GTK2 built with Visual Studio 10.\n#            Thanks to Vincent Levesque for the patch.\n\n# Version 1.2 (8/30/2010) (CMake 2.8.3)\n#   * Merge patch for detecting gdk-pixbuf library (split off\n#     from core GTK in 2.21).  Thanks to Vincent Untz for the patch\n#     and Ricardo Cruz for the heads up.\n# Version 1.1 (8/19/2010) (CMake 2.8.3)\n#   * Add support for detecting GTK2 under macports (thanks to Gary Kramlich)\n# Version 1.0 (8/12/2010) (CMake 2.8.3)\n#   * Add support for detecting new pangommconfig.h header file\n#     (Thanks to Sune Vuorela & the Debian Project for the patch)\n#   * Add support for detecting fontconfig.h header\n#   * Call find_package(Freetype) since it's required\n#   * Add support for allowing users to add additional library directories\n#     via the GTK2_ADDITIONAL_SUFFIXES variable (kind of a future-kludge in\n#     case the GTK developers change versions on any of the directories in the\n#     future).\n# Version 0.8 (1/4/2010)\n#   * Get module working under MacOSX fink by adding /sw/include, /sw/lib\n#     to PATHS and the gobject library\n# Version 0.7 (3/22/09)\n#   * Checked into CMake CVS\n#   * Added versioning support\n#   * Module now defaults to searching for GTK if COMPONENTS not specified.\n#   * Added HKCU prior to HKLM registry key and GTKMM specific environment\n#      variable as per mailing list discussion.\n#   * Added lib64 to include search path and a few other search paths where GTK\n#      may be installed on Unix systems.\n#   * Switched to lowercase CMake commands\n#   * Prefaced internal variables with _GTK2 to prevent collision\n#   * Changed internal macros to functions\n#   * Enhanced documentation\n# Version 0.6 (1/8/08)\n#   Added GTK2_SKIP_MARK_AS_ADVANCED option\n# Version 0.5 (12/19/08)\n#   Second release to cmake mailing list\n\n#=============================================================\n# _GTK2_GET_VERSION\n# Internal function to parse the version number in gtkversion.h\n#   _OUT_major = Major version number\n#   _OUT_minor = Minor version number\n#   _OUT_micro = Micro version number\n#   _gtkversion_hdr = Header file to parse\n#=============================================================\nfunction(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr)\n    file(READ ${_gtkversion_hdr} _contents)\n    if(_contents)\n        string(REGEX REPLACE \".*#define GTK_MAJOR_VERSION[ \\t]+\\\\(([0-9]+)\\\\).*\" \"\\\\1\" ${_OUT_major} \"${_contents}\")\n        string(REGEX REPLACE \".*#define GTK_MINOR_VERSION[ \\t]+\\\\(([0-9]+)\\\\).*\" \"\\\\1\" ${_OUT_minor} \"${_contents}\")\n        string(REGEX REPLACE \".*#define GTK_MICRO_VERSION[ \\t]+\\\\(([0-9]+)\\\\).*\" \"\\\\1\" ${_OUT_micro} \"${_contents}\")\n        \n        if(NOT ${_OUT_major} MATCHES \"[0-9]+\")\n            message(FATAL_ERROR \"Version parsing failed for GTK2_MAJOR_VERSION!\")\n        endif()\n        if(NOT ${_OUT_minor} MATCHES \"[0-9]+\")\n            message(FATAL_ERROR \"Version parsing failed for GTK2_MINOR_VERSION!\")\n        endif()\n        if(NOT ${_OUT_micro} MATCHES \"[0-9]+\")\n            message(FATAL_ERROR \"Version parsing failed for GTK2_MICRO_VERSION!\")\n        endif()\n\n        set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE)\n        set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE)\n        set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE)\n    else()\n        message(FATAL_ERROR \"Include file ${_gtkversion_hdr} does not exist\")\n    endif()\nendfunction()\n\n#=============================================================\n# _GTK2_FIND_INCLUDE_DIR\n# Internal function to find the GTK include directories\n#   _var = variable to set\n#   _hdr = header file to look for\n#=============================================================\nfunction(_GTK2_FIND_INCLUDE_DIR _var _hdr)\n\n    if(GTK2_DEBUG)\n        message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] \"\n                       \"_GTK2_FIND_INCLUDE_DIR( ${_var} ${_hdr} )\")\n    endif()\n\n    set(_relatives\n        # If these ever change, things will break.\n        ${GTK2_ADDITIONAL_SUFFIXES}\n        glibmm-2.4\n        glib-2.0\n        atk-1.0\n        atkmm-1.6\n        cairo\n        cairomm-1.0\n        gdk-pixbuf-2.0\n        gdkmm-2.4\n        giomm-2.4\n        gtk-2.0\n        gtkmm-2.4\n        libglade-2.0\n        libglademm-2.4\n        pango-1.0\n        pangomm-1.4\n        sigc++-2.0\n    )\n\n    set(_suffixes)\n    foreach(_d ${_relatives})\n        list(APPEND _suffixes ${_d})\n        list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include\n    endforeach()\n\n    if(GTK2_DEBUG)\n        message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}]     \"\n                       \"include suffixes = ${_suffixes}\")\n    endif()\n\n    find_path(${_var} ${_hdr}\n        PATHS\n            /usr/local/lib64\n            /usr/local/lib\n            /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}\n            /usr/lib64\n            /usr/lib\n            /opt/gnome/include\n            /opt/gnome/lib\n            /opt/openwin/include\n            /usr/openwin/lib\n            /sw/include\n            /sw/lib\n            /opt/local/include\n            /opt/local/lib\n            $ENV{GTKMM_BASEPATH}/include\n            $ENV{GTKMM_BASEPATH}/lib\n            [HKEY_CURRENT_USER\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/include\n            [HKEY_CURRENT_USER\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/lib\n            [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/include\n            [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/lib\n        PATH_SUFFIXES\n            ${_suffixes}\n    )\n\n    if(${_var})\n        set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE)\n        if(NOT GTK2_SKIP_MARK_AS_ADVANCED)\n            mark_as_advanced(${_var})\n        endif()\n    endif()\n\nendfunction(_GTK2_FIND_INCLUDE_DIR)\n\n#=============================================================\n# _GTK2_FIND_LIBRARY\n# Internal function to find libraries packaged with GTK2\n#   _var = library variable to create\n#=============================================================\nfunction(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)\n\n    if(GTK2_DEBUG)\n        message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] \"\n                       \"_GTK2_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )\")\n    endif()\n\n    # Not GTK versions per se but the versions encoded into Windows\n    # import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example)\n    # Also the MSVC libraries use _ for . (this is handled below)\n    set(_versions 2.20 2.18 2.16 2.14 2.12\n                  2.10  2.8  2.6  2.4  2.2 2.0\n                  1.20 1.18 1.16 1.14 1.12\n                  1.10  1.8  1.6  1.4  1.2 1.0)\n\n    set(_library)\n    set(_library_d)\n\n    set(_library ${_lib})\n\n    if(_expand_vc AND MSVC)\n        # Add vc80/vc90/vc100 midfixes\n        if(MSVC80)\n            set(_library   ${_library}-vc80)\n        elseif(MSVC90)\n            set(_library   ${_library}-vc90)\n        elseif(MSVC10)\n            set(_library ${_library}-vc100)\n        endif()\n        set(_library_d ${_library}-d)\n    endif()\n\n    if(GTK2_DEBUG)\n        message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}]     \"\n                       \"After midfix addition = ${_library} and ${_library_d}\")\n    endif()\n\n    set(_lib_list)\n    set(_libd_list)\n    if(_append_version)\n        foreach(_ver ${_versions})\n            list(APPEND _lib_list  \"${_library}-${_ver}\")\n            list(APPEND _libd_list \"${_library_d}-${_ver}\")\n        endforeach()\n    else()\n        set(_lib_list ${_library})\n        set(_libd_list ${_library_d})\n    endif()\n    \n    if(GTK2_DEBUG)\n        message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}]     \"\n                       \"library list = ${_lib_list} and library debug list = ${_libd_list}\")\n    endif()\n\n    # For some silly reason the MSVC libraries use _ instead of .\n    # in the version fields\n    if(_expand_vc AND MSVC)\n        set(_no_dots_lib_list)\n        set(_no_dots_libd_list)\n        foreach(_l ${_lib_list})\n            string(REPLACE \".\" \"_\" _no_dots_library ${_l})\n            list(APPEND _no_dots_lib_list ${_no_dots_library})\n        endforeach()\n        # And for debug\n        set(_no_dots_libsd_list)\n        foreach(_l ${_libd_list})\n            string(REPLACE \".\" \"_\" _no_dots_libraryd ${_l})\n            list(APPEND _no_dots_libd_list ${_no_dots_libraryd})\n        endforeach()\n\n        # Copy list back to original names\n        set(_lib_list ${_no_dots_lib_list})\n        set(_libd_list ${_no_dots_libd_list})\n    endif()\n\n    if(GTK2_DEBUG)\n        message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}]     \"\n                       \"While searching for ${_var}, our proposed library list is ${_lib_list}\")\n    endif()\n\n    find_library(${_var} \n        NAMES ${_lib_list}\n        PATHS\n            /opt/gnome/lib\n            /opt/gnome/lib64\n            /usr/openwin/lib\n            /usr/openwin/lib64\n            /sw/lib\n            $ENV{GTKMM_BASEPATH}/lib\n            [HKEY_CURRENT_USER\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/lib\n            [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/lib\n        )\n\n    if(_expand_vc AND MSVC)\n        if(GTK2_DEBUG)\n            message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}]     \"\n                           \"While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}\")\n        endif()\n\n        find_library(${_var}_DEBUG\n            NAMES ${_libd_list}\n            PATHS\n            $ENV{GTKMM_BASEPATH}/lib\n            [HKEY_CURRENT_USER\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/lib\n            [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\gtkmm\\\\2.4;Path]/lib\n        )\n\n        if(${_var} AND ${_var}_DEBUG)\n            if(NOT GTK2_SKIP_MARK_AS_ADVANCED)\n                mark_as_advanced(${_var}_DEBUG)\n            endif()\n            set(GTK2_LIBRARIES ${GTK2_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG})\n            set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)\n        endif()\n    else()\n        if(NOT GTK2_SKIP_MARK_AS_ADVANCED)\n            mark_as_advanced(${_var})\n        endif()\n        set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}})\n        set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)\n        # Set debug to release\n        set(${_var}_DEBUG ${${_var}})\n        set(${_var}_DEBUG ${${_var}} PARENT_SCOPE)\n    endif()\nendfunction(_GTK2_FIND_LIBRARY)\n\n#=============================================================\n\n#\n# main()\n#\n\nset(GTK2_FOUND)\nset(GTK2_INCLUDE_DIRS)\nset(GTK2_LIBRARIES)\n\nif(NOT GTK2_FIND_COMPONENTS)\n    # Assume they only want GTK\n    set(GTK2_FIND_COMPONENTS gtk)\nendif()\n\n#\n# If specified, enforce version number\n#\nif(GTK2_FIND_VERSION)\n    cmake_minimum_required(VERSION 2.6.2)\n    set(GTK2_FAILED_VERSION_CHECK true)\n    if(GTK2_DEBUG)\n        message(STATUS \"[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] \"\n                       \"Searching for version ${GTK2_FIND_VERSION}\")\n    endif()\n    _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)\n    if(GTK2_GTK_INCLUDE_DIR)\n        _GTK2_GET_VERSION(GTK2_MAJOR_VERSION\n                          GTK2_MINOR_VERSION\n                          GTK2_PATCH_VERSION\n                          ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)\n        set(GTK2_VERSION\n            ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})\n        if(GTK2_FIND_VERSION_EXACT)\n            if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION)\n                set(GTK2_FAILED_VERSION_CHECK false)\n            endif()\n        else()\n            if(GTK2_VERSION VERSION_EQUAL   GTK2_FIND_VERSION OR\n               GTK2_VERSION VERSION_GREATER GTK2_FIND_VERSION)\n                set(GTK2_FAILED_VERSION_CHECK false)\n            endif()\n        endif()\n    else()\n        # If we can't find the GTK include dir, we can't do version checking\n        if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)\n            message(FATAL_ERROR \"Could not find GTK2 include directory\")\n        endif()\n        return()\n    endif()\n\n    if(GTK2_FAILED_VERSION_CHECK)\n        if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)\n            if(GTK2_FIND_VERSION_EXACT)\n                message(FATAL_ERROR \"GTK2 version check failed.  Version ${GTK2_VERSION} was found, version ${GTK2_FIND_VERSION} is needed exactly.\")\n            else()\n                message(FATAL_ERROR \"GTK2 version check failed.  Version ${GTK2_VERSION} was found, at least version ${GTK2_FIND_VERSION} is required\")\n            endif()\n        endif()    \n        \n        # If the version check fails, exit out of the module here\n        return()\n    endif()\nendif()\n\n#\n# Find all components\n#\n\nfind_package(Freetype)\nlist(APPEND GTK2_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS})\nlist(APPEND GTK2_LIBRARIES ${FREETYPE_LIBRARIES})\n\nforeach(_GTK2_component ${GTK2_FIND_COMPONENTS})\n    if(_GTK2_component STREQUAL \"gtk\")\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GLIB_LIBRARY glib false true)\n        \n        _GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GOBJECT_LIBRARY gobject false true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)\n\n        if(UNIX)\n            _GTK2_FIND_LIBRARY    (GTK2_GDK_LIBRARY gdk-x11 false true)\n            _GTK2_FIND_LIBRARY    (GTK2_GTK_LIBRARY gtk-x11 false true)\n        else()\n            _GTK2_FIND_LIBRARY    (GTK2_GDK_LIBRARY gdk-win32 false true)\n            _GTK2_FIND_LIBRARY    (GTK2_GTK_LIBRARY gtk-win32 false true)\n        endif()\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h)\n        _GTK2_FIND_LIBRARY    (GTK2_CAIRO_LIBRARY cairo false false)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_FONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h)\n        _GTK2_FIND_LIBRARY    (GTK2_PANGO_LIBRARY pango false true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h)\n        _GTK2_FIND_LIBRARY    (GTK2_ATK_LIBRARY atk false true)\n\n\n    elseif(_GTK2_component STREQUAL \"gtkmm\")\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GLIBMM_LIBRARY glibmm true true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GDKMM_LIBRARY gdkmm true true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GTKMM_LIBRARY gtkmm true true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)\n        _GTK2_FIND_LIBRARY    (GTK2_CAIROMM_LIBRARY cairomm true true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h)\n        _GTK2_FIND_LIBRARY    (GTK2_PANGOMM_LIBRARY pangomm true true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)\n        _GTK2_FIND_LIBRARY    (GTK2_SIGC++_LIBRARY sigc true true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GIOMM_LIBRARY giomm true true)\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h)\n        _GTK2_FIND_LIBRARY    (GTK2_ATKMM_LIBRARY atkmm true true)\n\n    elseif(_GTK2_component STREQUAL \"glade\")\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GLADE_LIBRARY glade false true)\n    \n    elseif(_GTK2_component STREQUAL \"glademm\")\n\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM_INCLUDE_DIR libglademm.h)\n        _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h)\n        _GTK2_FIND_LIBRARY    (GTK2_GLADEMM_LIBRARY glademm true true)\n\n    else()\n        message(FATAL_ERROR \"Unknown GTK2 component ${_component}\")\n    endif()\nendforeach()\n\n#\n# Solve for the GTK2 version if we haven't already\n#\nif(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR)\n    _GTK2_GET_VERSION(GTK2_MAJOR_VERSION\n                      GTK2_MINOR_VERSION\n                      GTK2_PATCH_VERSION\n                      ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)\n    set(GTK2_VERSION ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})\nendif()\n\n#\n# Try to enforce components\n#\n\nset(_GTK2_did_we_find_everything true)  # This gets set to GTK2_FOUND\n\n#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)\nfind_package(PackageHandleStandardArgs)\n\nforeach(_GTK2_component ${GTK2_FIND_COMPONENTS})\n    string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER)\n\n    if(_GTK2_component STREQUAL \"gtk\")\n        FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} \"Some or all of the gtk libraries were not found.\"\n            GTK2_GTK_LIBRARY\n            GTK2_GTK_INCLUDE_DIR\n\n            GTK2_GLIB_INCLUDE_DIR\n            GTK2_GLIBCONFIG_INCLUDE_DIR\n            GTK2_GLIB_LIBRARY\n\n            GTK2_GDK_INCLUDE_DIR\n            GTK2_GDKCONFIG_INCLUDE_DIR\n            GTK2_GDK_LIBRARY\n        )\n    elseif(_GTK2_component STREQUAL \"gtkmm\")\n        FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} \"Some or all of the gtkmm libraries were not found.\"\n            GTK2_GTKMM_LIBRARY\n            GTK2_GTKMM_INCLUDE_DIR\n            GTK2_GTKMMCONFIG_INCLUDE_DIR\n\n            GTK2_GLIBMM_INCLUDE_DIR\n            GTK2_GLIBMMCONFIG_INCLUDE_DIR\n            GTK2_GLIBMM_LIBRARY\n\n            GTK2_GDKMM_INCLUDE_DIR\n            GTK2_GDKMMCONFIG_INCLUDE_DIR\n            GTK2_GDKMM_LIBRARY\n        )\n    elseif(_GTK2_component STREQUAL \"glade\")\n        FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} \"The glade library was not found.\"\n            GTK2_GLADE_LIBRARY\n            GTK2_GLADE_INCLUDE_DIR\n        )\n    elseif(_GTK2_component STREQUAL \"glademm\")\n        FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} \"The glademm library was not found.\"\n            GTK2_GLADEMM_LIBRARY\n            GTK2_GLADEMM_INCLUDE_DIR\n            GTK2_GLADEMMCONFIG_INCLUDE_DIR\n        )\n    endif()\n\n    if(NOT GTK2_${_COMPONENT_UPPER}_FOUND)\n        set(_GTK2_did_we_find_everything false)\n    endif()\nendforeach()\n\nif(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED)\n    set(GTK2_FOUND true)\nelse()\n    # Unset our variables.\n    set(GTK2_FOUND false)\n    set(GTK2_VERSION)\n    set(GTK2_VERSION_MAJOR)\n    set(GTK2_VERSION_MINOR)\n    set(GTK2_VERSION_PATCH)\n    set(GTK2_INCLUDE_DIRS)\n    set(GTK2_LIBRARIES)\nendif()\n\nif(GTK2_INCLUDE_DIRS)\n   list(REMOVE_DUPLICATES GTK2_INCLUDE_DIRS)\nendif()\n\n"
  },
  {
    "path": "cmake/modules/FindMakeNSIS.cmake",
    "content": "# - Try to find the MakeNSIS\n# Once done this will define\n#\n#  MAKENSIS_FOUND - system has MakeNSIS\n#  MAKENSIS - the MakeNSIS program\n#  MAKENSIS_FLAGS - the MakeNSIS flags\n#  MAKENSIS_SUFFIX - the MakeNSIS output file suffix\n\n# Copyright (c) 2011, Pali Rohár <pali.rohar@gmail.com>\n#\n# Redistribution and use is allowed according to the terms of the BSD license.\n# For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n\nif(MAKENSIS)\n\tset(MAKENSIS_FOUND true)\nelse()\n\tfind_program(MAKENSIS NAMES makensis HINTS \"C:/Program Files/NSIS\" \"C:/Program Files (x86)/NSIS\" \"C:/Program Files/NSIS/Unicode\" \"C:/Program Files (x86)/NSIS/Unicode\")\n\tfind_package(SelfPackers)\n\n\tset(MAKENSIS_ADDITIONAL_FLAGS \"\" CACHE STRING \"Additional flags for makensis\")\n\n\tif(MAKENSIS)\n\t\tset(MAKENSIS_FOUND true)\n\t\tmessage(STATUS \"Found MakeNSIS: ${MAKENSIS}\")\n\telse()\n\t\tset(MAKENSIS_FOUND false)\n#\t\tmessage(FATAL_ERROR \"Could not find program MakeNSIS\") # TODO: This fail if REQUIRED is not used too!\n\t\tmessage(STATUS \"Could not find program MakeNSIS\")\n\tendif()\n\n\tif(NOT CMAKE_VERBOSE_MAKEFILE)\n\t\tset(MAKENSIS_FLAGS ${MAKENSIS_FLAGS} -V2 -DQUIET)\n\tendif()\n\n\tif(CMAKE_BUILD_TYPE STREQUAL \"Debug\")\n\t\tset(MAKENSIS_FLAGS ${MAKENSIS_FLAGS} -DDBG)\n\t\tset(MAKENSIS_SUFFIX ${MAKENSIS_SUFFIX}-debug)\n\tendif()\n\n\tif(CMAKE_SIZEOF_VOID_P STREQUAL 8)\n\t\tset(MAKENSIS_FLAGS ${MAKENSIS_FLAGS} -DX86_64)\n\t\tset(MAKENSIS_SUFFIX ${MAKENSIS_SUFFIX}-x86_64)\n\tendif()\n\n\tif(ENABLE_UPX AND SELF_PACKER_FOR_EXECUTABLE)\n\t\tset(MAKENSIS_FLAGS ${MAKENSIS_FLAGS} -DUPX=${SELF_PACKER_FOR_EXECUTABLE} -DUPX_FLAGS=${SELF_PACKER_FOR_EXECUTABLE_FLAGS})\n\tendif()\n\n\tset(MAKENSIS_FLAGS ${MAKENSIS_ADDITIONAL_FLAGS} ${MAKENSIS_FLAGS} -NOCD CACHE STRING \"\")\n\tset(MAKENSIS_SUFFIX ${MAKENSIS_SUFFIX}${CMAKE_EXECUTABLE_SUFFIX} CACHE STRING \"\")\n\n\tmark_as_advanced(MAKENSIS MAKENSIS_FLAGS MAKENSIS_SUFFIX)\nendif()\n"
  },
  {
    "path": "cmake/modules/FindStormLib.cmake",
    "content": "# - Try to find the StormLib library\n# Once done this will define\n#\n#  STORMLIB_FOUND - system has StormLib\n#  STORMLIB_INCLUDE_DIR - the STORMLIB include directory\n#  STORMLIB_LIBRARY - The STORMLIB library\n\n# Copyright (c) 2015, cybermind <cybermindid@gmail.com>\n#\n# Redistribution and use is allowed according to the terms of the BSD license.\n# For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n\nif(STORMLIB_INCLUDE_DIR AND STORMLIB_LIBRARY AND (NOT UNIX OR BZIP2_FOUND))\n\tset(STORMLIB_FOUND true)\nelse()\n\tfind_path(STORMLIB_INCLUDE_DIR StormLib.h)\n\tfind_library(STORMLIB_LIBRARY NAMES storm)\n\tif (UNIX)\n\t\tfind_package(BZip2)\n\tendif()\n\n\tif(STORMLIB_INCLUDE_DIR AND STORMLIB_LIBRARY AND (NOT UNIX OR BZIP2_FOUND))\n\t\tset(STORMLIB_FOUND true)\n\t\tmessage(STATUS \"Found StormLib: ${STORMLIB_LIBRARY}\")\n\telseif(UNIX AND NOT BZIP2_FOUND)\n\t\tset(STORMLIB_FOUND false)\n\t\tmessage(STATUS \"Could not find BZip2 required for StormLib\")\n\telse()\n\t\tset(STORMLIB_FOUND false)\n\t\tmessage(STATUS \"Could not find StormLib\")\n\tendif()\n\n\tmark_as_advanced(STORMLIB_INCLUDE_DIR STORMLIB_LIBRARY)\nendif()\n"
  },
  {
    "path": "cmake/modules/FindStratagus.cmake",
    "content": "# - Try to find the stratagus executable and game headers\n# Once done this will define\n#\n#  STRATAGUS_FOUND - system has stratagus\n#  STRATAGUS - the stratagus executable\n#  STRATAGUS_INCLUDE_DIR - the stratagus include directory\n\n# Copyright (c) 2011, Pali Rohár <pali.rohar@gmail.com>\n#\n# Redistribution and use is allowed according to the terms of the BSD license.\n# For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n\nif(STRATAGUS AND STRATAGUS_INCLUDE_DIR)\n\tset(STRATAGUS_FOUND true)\nelse()\n\tfind_program(STRATAGUS NAMES stratagus PATH_SUFFIXES games)\n\tfind_path(STRATAGUS_INCLUDE_DIR stratagus-game-launcher.h)\n\n\tif(STRATAGUS AND STRATAGUS_INCLUDE_DIR)\n\t\tset(STRATAGUS_FOUND true)\n\t\tmessage(STATUS \"Found stratagus: ${STRATAGUS}:${STRATAGUS_INCLUDE_DIR}\")\n\telse()\n\t\tset(STRATAGUS_FOUND false)\n\t\tmessage(WARNING \"Could not find stratagus, not building launcher\")\n\tendif()\n\n\tmark_as_advanced(STRATAGUS STRATAGUS_INCLUDE_DIR)\nendif()\n"
  },
  {
    "path": "cmake_uninstall.cmake.in",
    "content": "if(NOT EXISTS \"@CMAKE_BINARY_DIR@/install_manifest.txt\")\n  message(FATAL_ERROR \"Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt\")\nendif(NOT EXISTS \"@CMAKE_BINARY_DIR@/install_manifest.txt\")\n\nfile(READ \"@CMAKE_BINARY_DIR@/install_manifest.txt\" files)\nstring(REGEX REPLACE \"\\n\" \";\" files \"${files}\")\nforeach(file ${files})\n  message(STATUS \"Uninstalling $ENV{DESTDIR}${file}\")\n  if(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    exec_program(\n      \"@CMAKE_COMMAND@\" ARGS \"-E remove \\\"$ENV{DESTDIR}${file}\\\"\"\n      OUTPUT_VARIABLE rm_out\n      RETURN_VALUE rm_retval\n      )\n    if(NOT \"${rm_retval}\" STREQUAL 0)\n      message(FATAL_ERROR \"Problem when removing $ENV{DESTDIR}${file}\")\n    endif(NOT \"${rm_retval}\" STREQUAL 0)\n  else(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    message(STATUS \"File $ENV{DESTDIR}${file} does not exist.\")\n  endif(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\nendforeach(file)\n"
  },
  {
    "path": "dataset/dlgs_race.json",
    "content": "[\n    {\n        \"frame\": [0],\n        \"name\": \"menu.png\"\n    },\n    {\n        \"frame\": [1],\n        \"name\": \"menu_pressed.png\"\n    },\n    {\n        \"frame\": [2],\n        \"name\": \"minimap_disabled.png\"\n    },\n    {\n        \"frame\": [3],\n        \"name\": \"minimap.png\"\n    },\n    {\n        \"frame\": [4],\n        \"name\": \"minimap_pressed.png\"\n    },\n    {\n        \"frame\": [5],\n        \"name\": \"radiobutton_disabled.png\"\n    },\n    {\n        \"frame\": [6],\n        \"name\": \"radiobutton_off_selected.png\"\n    },\n    {\n        \"frame\": [7],\n        \"name\": \"radiobutton_off.png\"\n    },\n    {\n        \"frame\": [8],\n        \"name\": \"radiobutton_on_selected.png\"\n    },\n    {\n        \"frame\": [9],\n        \"name\": \"radiobutton_on.png\"\n    },\n    {\n        \"frame\": [10],\n        \"name\": \"checkbutton_disabled.png\"\n    },\n    {\n        \"frame\": [11],\n        \"name\": \"checkbutton_off.png\"\n    },\n    {\n        \"frame\": [12],\n        \"name\": \"checkbutton_off_selected.png\"\n    },\n    {\n        \"frame\": [13],\n        \"name\": \"checkbutton_on.png\"\n    },\n    {\n        \"frame\": [14],\n        \"name\": \"checkbutton_on_selcted.png\"\n    },\n    {\n        \"frame\": [15],\n        \"name\": \"scroll_up_disabled.png\"\n    },\n    {\n        \"frame\": [16],\n        \"name\": \"scroll_up.png\"\n    },\n    {\n        \"frame\": [17],\n        \"name\": \"scroll_up_pressed.png\"\n    },\n    {\n        \"frame\": [18],\n        \"name\": \"scroll_down_disabled.png\"\n    },\n    {\n        \"frame\": [19],\n        \"name\": \"scroll_down.png\"\n    },\n    {\n        \"frame\": [20],\n        \"name\": \"scroll_down_pressed.png\"\n    },\n    {\n        \"frame\": [21],\n        \"name\": \"scroll_left_disabled.png\"\n    },\n    {\n        \"frame\": [22],\n        \"name\": \"scoll_left.png\"\n    },\n    {\n        \"frame\": [23],\n        \"name\": \"scroll_left_pressed.png\"\n    },\n    {\n        \"frame\": [24],\n        \"name\": \"scroll_right_disabled.png\"\n    },\n    {\n        \"frame\": [25],\n        \"name\": \"scroll_right.png\"\n    },\n    {\n        \"frame\": [26],\n        \"name\": \"scroll_right_pressed.png\"\n    },\n    {\n        \"frame\": [27],\n        \"name\": \"radiobutton_on_off_transition.png\"\n    },\n    {\n        \"frame\": [28],\n        \"name\": \"scrollborder_horiz_top.png\"\n    },\n    {\n        \"frame\": [29],\n        \"name\": \"scrollborder_horiz_middle.png\"\n    },\n    {\n        \"frame\": [30],\n        \"name\": \"scrollborder_horiz_bottom.png\"\n    },\n    {\n        \"frame\": [31],\n        \"name\": \"scrollborder_vert_left.png\"\n    },\n    {\n        \"frame\": [32],\n        \"name\": \"scrollborder_vert_middle.png\"\n    },\n    {\n        \"frame\": [33],\n        \"name\": \"scrollborder_vert_right.png\"\n    },\n    {\n        \"frame\": [34],\n        \"name\": \"panel01.png\"\n    },\n    {\n        \"frame\": [35],\n        \"name\": \"panel02.png\"\n    },\n    {\n        \"frame\": [36],\n        \"name\": \"panel03.png\"\n    },\n    {\n        \"frame\": [37],\n        \"name\": \"panel04.png\"\n    },\n    {\n        \"frame\": [38],\n        \"name\": \"panel05.png\"\n    },\n    {\n        \"frame\": [39],\n        \"name\": \"panel06.png\"\n    },\n    {\n        \"frame\": [40],\n        \"name\": \"panel07.png\"\n    },\n    {\n        \"frame\": [41],\n        \"name\": \"panel08.png\"\n    },\n    {\n        \"frame\": [42],\n        \"name\": \"panel09.png\"\n    },\n    {\n        \"frame\": [43],\n        \"name\": \"panel10.png\"\n    },\n    {\n        \"frame\": [44],\n        \"name\": \"panel11.png\"\n    },\n    {\n        \"frame\": [45],\n        \"name\": \"panel12.png\"\n    },\n    {\n        \"frame\": [46],\n        \"name\": \"panel13.png\"\n    },\n    {\n        \"frame\": [47],\n        \"name\": \"panel14.png\"\n    },\n    {\n        \"frame\": [48],\n        \"name\": \"panel15.png\"\n    },\n    {\n        \"frame\": [49],\n        \"name\": \"trangle1.png\"\n    },\n    {\n        \"frame\": [50],\n        \"name\": \"trangle2.png\"\n    },\n    {\n        \"frame\": [51],\n        \"name\": \"trangle3.png\"\n    },\n    {\n        \"frame\": [52],\n        \"name\": \"input_left.png\"\n    },\n    {\n        \"frame\": [53],\n        \"name\": \"input_middle.png\"\n    },\n    {\n        \"frame\": [54],\n        \"name\": \"input_right.png\"\n    },\n    {\n        \"frame\": [55],\n        \"name\": \"input2_left\"\n    },\n    {\n        \"frame\": [56],\n        \"name\": \"input2_middle\"\n    },\n    {\n        \"frame\": [57],\n        \"name\": \"input2_right\"\n    },\n    {\n        \"frame\": [58],\n        \"name\": \"diplomacy_disabled.png\"\n    },\n    {\n        \"frame\": [59],\n        \"name\": \"displomacy.png\"\n    },\n    {\n        \"frame\": [60],\n        \"name\": \"diplomacy_pressed.png\"\n    },\n    {\n        \"frame\": [61],\n        \"name\": \"skull_disabled.png\"\n    },\n    {\n        \"frame\": [62],\n        \"name\": \"skill.png\"\n    },\n    {\n        \"frame\": [63],\n        \"name\": \"skull_selected.png\"\n    },\n    {\n        \"frame\": [64],\n        \"name\": \"bird.png\"\n    },\n    {\n        \"frame\": [65],\n        \"name\": \"bird_selected.png\"\n    },\n    {\n        \"frame\": [66],\n        \"name\": \"dline_left_disabled.png\"\n    },\n    {\n        \"frame\": [67],\n        \"name\": \"dline_middle_disabled.png\"\n    },\n    {\n        \"frame\": [68],\n        \"name\": \"dline_right_disabled.png\"\n    },\n    {\n        \"frame\": [69],\n        \"name\": \"dline_left.png\"\n    },\n    {\n        \"frame\": [70],\n        \"name\": \"dline_middle.png\"\n    },\n    {\n        \"frame\": [71],\n        \"name\": \"dline_right.png\"\n    },\n    {\n        \"frame\": [72],\n        \"name\": \"dline_cross_disabled.png\"\n    },\n    {\n        \"frame\": [73],\n        \"name\": \"dline_cross.png\"\n    },\n    {\n        \"frame\": [74],\n        \"name\": \"statuslight_grey.png\"\n    },\n    {\n        \"frame\": [75],\n        \"name\": \"statuslight_yellow.png\"\n    },\n    {\n        \"frame\": [76],\n        \"name\": \"statuslight_green.png\"\n    },\n    {\n        \"frame\": [77],\n        \"name\": \"statuslight_red.png\"\n    },\n    {\n        \"frame\": [78],\n        \"name\": \"left_button_left_disabled.png\"\n    },\n    {\n        \"frame\": [79],\n        \"name\": \"button_middle_disabled.png\"\n    },\n    {\n        \"frame\": [80],\n        \"name\": \"left_button_right_disabled.png\"\n    },\n    {\n        \"frame\": [81],\n        \"name\": \"left_button_left.png\"\n    },\n    {\n        \"frame\": [82],\n        \"name\": \"button_middle.png\"\n    },\n    {\n        \"frame\": [83],\n        \"name\": \"left_button_right.png\"\n    },\n    {\n        \"frame\": [84],\n        \"name\": \"left_button_left_pressed.png\"\n    },\n    {\n        \"frame\": [85],\n        \"name\": \"button_middle_pressed.png\"\n    },\n    {\n        \"frame\": [86],\n        \"name\": \"left_button_right_pressed.png\"\n    },\n    {\n        \"frame\": [87],\n        \"name\": \"right_button_left_disabled.png\"\n    },\n    {\n        \"frame\": [88],\n        \"name\": \"right_button_left.png\"\n    },\n    {\n        \"frame\": [89],\n        \"name\": \"right_button_left_pressed.png\"\n    },\n    {\n        \"frame\": [90],\n        \"name\": \"right_button_right_disabled.png\"\n    },\n    {\n        \"frame\": [91],\n        \"name\": \"right_button_right.png\"\n    },\n    {\n        \"frame\": [92],\n        \"name\": \"right_button_right_pressed.png\"\n    },\n    {\n        \"frame\": [93],\n        \"name\": \"radar_deactivated.png\"\n    },\n    {\n        \"frame\": [94],\n        \"name\": \"radar.png\"\n    },\n    {\n        \"frame\": [95],\n        \"name\": \"radar_pressed.png\"\n    },\n    {\n        \"frame\": [96],\n        \"name\": \"input2_left.png\"\n    },\n    {\n        \"frame\": [97],\n        \"name\": \"input2_middle.png\"\n    },\n    {\n        \"frame\": [98],\n        \"name\": \"input2_right.png\"\n    },\n    {\n        \"frame\": [99],\n        \"name\": \"empty1.png\"\n    },\n    {\n        \"frame\": [100],\n        \"name\": \"empty2.png\"\n    },\n    {\n        \"frame\": [101],\n        \"name\": \"empty3.png\"\n    },\n    {\n\t\t\"frame\": [88,82,82,82,82,82,82,82,82,82,82,82,83],\n\t\t\"name\": \"agg/button_small.png\"\n\t},\n\t{\n\t\t\"frame\": [87,79,79,79,79,79,79,79,79,79,79,79,80],\n\t\t\"name\": \"agg/button_small_disabled.png\"\n\t},\n\t{\n\t\t\"frame\": [89,85,85,85,85,85,85,85,85,85,85,85,86],\n\t\t\"name\": \"agg/button_small_pressed.png\"\n\t},\n    {\n\t\t\"frame\": [81,82,82,82,82,82,82,82,82,82,82,82,83],\n\t\t\"name\": \"agg/button_left_small.png\"\n\t},\n\t{\n\t\t\"frame\": [78,79,79,79,79,79,79,79,79,79,79,79,80],\n\t\t\"name\": \"agg/button_left_small_disabled.png\"\n\t},\n\t{\n\t\t\"frame\": [84,85,85,85,85,85,85,85,85,85,85,85,86],\n\t\t\"name\": \"agg/button_left_small_pressed.png\"\n\t},\n\t{\n\t\t\"frame\": [88,82,82,82,82,82,82,82,82,82,82,82,91],\n\t\t\"name\": \"agg/button_right_small.png\"\n\t},\n\t{\n\t\t\"frame\": [87,79,79,79,79,79,79,79,79,79,79,79,90],\n\t\t\"name\": \"agg/button_right_small_disabled.png\"\n\t},\n\t{\n\t\t\"frame\": [89,85,85,85,85,85,85,85,85,85,85,85,92],\n\t\t\"name\": \"agg/button_right_small_pressed.png\"\n\t},\n\t{\n\t\t\"frame\": [88,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83],\n\t\t\"name\": \"agg/button_large.png\"\n\t},\n\t{\n\t\t\"frame\": [87,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,80],\n\t\t\"name\": \"agg/button_large_disabled.png\"\n\t},\n\t{\n\t\t\"frame\": [89,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,86],\n\t\t\"name\": \"agg/button_large_pressed.png\"\n\t},\n    {\n\t\t\"frame\": [81,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83],\n\t\t\"name\": \"agg/button_left_large.png\"\n\t},\n\t{\n\t\t\"frame\": [78,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,80],\n\t\t\"name\": \"agg/button_left_large_disabled.png\"\n\t},\n\t{\n\t\t\"frame\": [84,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,86],\n\t\t\"name\": \"agg/button_left_large_pressed.png\"\n\t},\n\t{\n\t\t\"frame\": [88,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,91],\n\t\t\"name\": \"agg/button_right_large.png\"\n\t},\n\t{\n\t\t\"frame\": [87,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,90],\n\t\t\"name\": \"agg/button_right_large_disabled.png\"\n\t},\n\t{\n\t\t\"frame\": [89,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,92],\n\t\t\"name\": \"agg/button_right_large_pressed.png\"\n\t}\n]"
  },
  {
    "path": "dataset/palettes.json",
    "content": "{\n    \"PCX\":\n\t[\n\t    {\n\t        \"name\": \"tunit\",\n\t        \"arcfile\": \"game\\\\tunit.pcx\",\n\t        \"palette\": \"tunit.pal\"\n\t    },\n\t    {\n\t        \"name\": \"twire\",\n\t        \"arcfile\": \"game\\\\twire.pcx\",\n\t        \"palette\": \"twire.pal\"\n\t    },\n\n\t    {\n\t        \"name\": \"tfontgam\",\n\t        \"arcfile\": \"game\\\\tfontgam.pcx\",\n\t        \"palette\": \"fontgam.pal\",\n\t\t\t\"mapping\": {\n\t\t        \"length\": 8,\n\t\t        \"start\": 1,\n\t\t        \"index\": 0\n\t\t\t    }\n\t    },\n\t    {\n\t        \"name\": \"ticon-0\",\n\t        \"arcfile\": \"unit\\\\cmdbtns\\\\ticon.pcx\",\n\t        \"palette\": \"ticon-0.pal\",\n\t\t\t\"mapping\": {\n\t\t        \"length\": 16,\n\t\t        \"start\": 0,\n\t\t        \"index\": 0\n\t\t\t    }\n\t    },\n\t    {\n\t        \"name\": \"tselect-0\",\n\t        \"arcfile\": \"game\\\\tselect.pcx\",\n\t        \"palette\": \"tselect.pal\",\n\t\t\t\"mapping\": {\n\t\t        \"length\": 8,\n\t\t        \"start\": 1,\n\t\t        \"index\": 0\n\t\t\t    }\n\t    }\n\t],\n    \"PCX2D\":\n\t[\n\t    {\n\t        \"name\": \"ofire\",\n\t        \"arcfile\": \"tileset\\\\<?>\\\\ofire.pcx\",\n\t        \"palette\": \"ofire.pal2d\"\n\t    },\n\t    {\n\t        \"name\": \"gfire\",\n\t        \"arcfile\": \"tileset\\\\<?>\\\\gfire.pcx\",\n\t        \"palette\": \"gfire.pal2d\"\n\t    },\n\t    {\n\t        \"name\": \"bfire\",\n\t        \"arcfile\": \"tileset\\\\<?>\\\\bfire.pcx\",\n\t        \"palette\": \"bfire.pal2d\"\n\t    },\n\t    {\n\t        \"name\": \"bexpl\",\n\t        \"arcfile\": \"tileset\\\\<?>\\\\bexpl.pcx\",\n\t        \"palette\": \"bexpl.pal2d\"\n\t    }\n\n\t],\n    \"WPE\":\n\t[\n\t    {\n\t        \"name\": \"ashworld\",\n\t        \"arcfile\": \"tileset\\\\ashworld.wpe\",\n\t        \"palette\": \"ashworld.pal\"\n\t    },\n\t    {\n\t        \"name\": \"badlands\",\n\t        \"arcfile\": \"tileset\\\\badlands.wpe\",\n\t        \"palette\": \"badlands.pal\"\n\t    },\n\t    {\n\t        \"name\": \"install\",\n\t        \"arcfile\": \"tileset\\\\install.wpe\",\n\t        \"palette\": \"install.pal\"\n\t    },\n\t    {\n\t        \"name\": \"jungle\",\n\t        \"arcfile\": \"tileset\\\\jungle.wpe\",\n\t        \"palette\": \"jungle.pal\"\n\t    },\n\t    {\n\t        \"name\": \"platform\",\n\t        \"arcfile\": \"tileset\\\\platform.wpe\",\n\t        \"palette\": \"platform.pal\"\n\t    },\n\t    {\n\t        \"name\": \"desert\",\n\t        \"arcfile\": \"tileset\\\\desert.wpe\",\n\t        \"palette\": \"desert.pal\"\n\t    },\n\t    {\n\t        \"name\": \"ice\",\n\t        \"arcfile\": \"tileset\\\\ice.wpe\",\n\t        \"palette\": \"ice.pal\"\n\t    },\n\t    {\n\t        \"name\": \"twilight\",\n\t        \"arcfile\": \"tileset\\\\twilight.wpe\",\n\t        \"palette\": \"twilight.pal\"\n\t    }\n\t]\n}\n\n"
  },
  {
    "path": "dataset/units.json",
    "content": "[\n    {\n        \"id\": 0,\n        \"name\": \"unit-terran-marine\"\n    },\n    {\n        \"id\": 1,\n        \"name\": \"unit-terran-ghost\"\n    },\n    {\n        \"id\": 2,\n        \"name\": \"unit-terran-vulture\"\n    },\n    {\n        \"id\": 3,\n        \"name\": \"unit-terran-goliath\"\n    },\n    {\n        \"id\": 4,\n        \"name\": \"unit-terran-goliath-turret\"\n    },\n    {\n        \"id\": 5,\n        \"name\": \"unit-terran-siege-tank-tank-mode\"\n    },\n    {\n        \"id\": 6,\n        \"name\": \"unit-terran-siege-tank-tank-mode-turret\"\n    },\n    {\n        \"id\": 7,\n        \"name\": \"unit-terran-scv\"\n    },\n    {\n        \"id\": 8,\n        \"name\": \"unit-terran-wraith\"\n    },\n    {\n        \"id\": 9,\n        \"name\": \"unit-terran-science-vessel\"\n    },\n    {\n        \"id\": 10,\n        \"name\": \"unit-hero-gui-montag\"\n    },\n    {\n        \"id\": 11,\n        \"name\": \"unit-terran-dropship\"\n    },\n    {\n        \"id\": 12,\n        \"name\": \"unit-terran-battlecruiser\"\n    },\n    {\n        \"id\": 13,\n        \"name\": \"unit-terran-vulture-spider-mine\"\n    },\n    {\n        \"id\": 14,\n        \"name\": \"unit-terran-nuclear-missile\"\n    },\n    {\n        \"id\": 15,\n        \"name\": \"unit-terran-civilian\"\n    },\n    {\n        \"id\": 16,\n        \"name\": \"unit-hero-sarah-kerrigan\"\n    },\n    {\n        \"id\": 17,\n        \"name\": \"unit-hero-alan-schezar\"\n    },\n    {\n        \"id\": 18,\n        \"name\": \"unit-hero-alan-schezar-turret\"\n    },\n    {\n        \"id\": 19,\n        \"name\": \"unit-hero-jim-raynor-vulture\"\n    },\n    {\n        \"id\": 20,\n        \"name\": \"unit-hero-jim-raynor-marine\"\n    },\n    {\n        \"id\": 21,\n        \"name\": \"unit-hero-tom-kazansky\"\n    },\n    {\n        \"id\": 22,\n        \"name\": \"unit-hero-magellan\"\n    },\n    {\n        \"id\": 23,\n        \"name\": \"unit-hero-edmund-duke-tank-mode\"\n    },\n    {\n        \"id\": 24,\n        \"name\": \"unit-hero-edmund-duke-tank-mode-turret\"\n    },\n    {\n        \"id\": 25,\n        \"name\": \"unit-hero-edmund-duke-siege-mode\"\n    },\n    {\n        \"id\": 26,\n        \"name\": \"unit-hero-edmund-duke-siege-mode-turret\"\n    },\n    {\n        \"id\": 27,\n        \"name\": \"unit-hero-arcturus-mengsk\"\n    },\n    {\n        \"id\": 28,\n        \"name\": \"unit-hero-hyperion\"\n    },\n    {\n        \"id\": 29,\n        \"name\": \"unit-hero-norad-ii\"\n    },\n    {\n        \"id\": 30,\n        \"name\": \"unit-terran-siege-tank-siege-mode\"\n    },\n    {\n        \"id\": 31,\n        \"name\": \"unit-terran-siege-tank-siege-mode-turret\"\n    },\n    {\n        \"id\": 32,\n        \"name\": \"unit-terran-firebat\"\n    },\n    {\n        \"id\": 33,\n        \"name\": \"unit-spell-scanner-sweep\"\n    },\n    {\n        \"id\": 34,\n        \"name\": \"unit-terran-medic\"\n    },\n    {\n        \"id\": 35,\n        \"name\": \"unit-zerg-larva\"\n    },\n    {\n        \"id\": 36,\n        \"name\": \"unit-zerg-egg\"\n    },\n    {\n        \"id\": 37,\n        \"name\": \"unit-zerg-zergling\"\n    },\n    {\n        \"id\": 38,\n        \"name\": \"unit-zerg-hydralisk\"\n    },\n    {\n        \"id\": 39,\n        \"name\": \"unit-zerg-ultralisk\"\n    },\n    {\n        \"id\": 40,\n        \"name\": \"unit-zerg-broodling\"\n    },\n    {\n        \"id\": 41,\n        \"name\": \"unit-zerg-drone\"\n    },\n    {\n        \"id\": 42,\n        \"name\": \"unit-zerg-overlord\"\n    },\n    {\n        \"id\": 43,\n        \"name\": \"unit-zerg-mutalisk\"\n    },\n    {\n        \"id\": 44,\n        \"name\": \"unit-zerg-guardian\"\n    },\n    {\n        \"id\": 45,\n        \"name\": \"unit-zerg-queen\"\n    },\n    {\n        \"id\": 46,\n        \"name\": \"unit-zerg-defiler\"\n    },\n    {\n        \"id\": 47,\n        \"name\": \"unit-zerg-scourge\"\n    },\n    {\n        \"id\": 48,\n        \"name\": \"unit-hero-torrasque\"\n    },\n    {\n        \"id\": 49,\n        \"name\": \"unit-hero-matriarch\"\n    },\n    {\n        \"id\": 50,\n        \"name\": \"unit-zerg-infested-terran\"\n    },\n    {\n        \"id\": 51,\n        \"name\": \"unit-hero-infested-kerrigan\"\n    },\n    {\n        \"id\": 52,\n        \"name\": \"unit-hero-unclean-one\"\n    },\n    {\n        \"id\": 53,\n        \"name\": \"unit-hero-hunter-killer\"\n    },\n    {\n        \"id\": 54,\n        \"name\": \"unit-hero-devouring-one\"\n    },\n    {\n        \"id\": 55,\n        \"name\": \"unit-hero-kukulza-mutalisk\"\n    },\n    {\n        \"id\": 56,\n        \"name\": \"unit-hero-kukulza-guardian\"\n    },\n    {\n        \"id\": 57,\n        \"name\": \"unit-hero-yggdrasill\"\n    },\n    {\n        \"id\": 58,\n        \"name\": \"unit-terran-valkyrie\"\n    },\n    {\n        \"id\": 59,\n        \"name\": \"unit-zerg-cocoon\"\n    },\n    {\n        \"id\": 60,\n        \"name\": \"unit-protoss-corsair\"\n    },\n    {\n        \"id\": 61,\n        \"name\": \"unit-protoss-dark-templar\"\n    },\n    {\n        \"id\": 62,\n        \"name\": \"unit-zerg-devourer\"\n    },\n    {\n        \"id\": 63,\n        \"name\": \"unit-protoss-dark-archon\"\n    },\n    {\n        \"id\": 64,\n        \"name\": \"unit-protoss-probe\"\n    },\n    {\n        \"id\": 65,\n        \"name\": \"unit-protoss-zealot\"\n    },\n    {\n        \"id\": 66,\n        \"name\": \"unit-protoss-dragoon\"\n    },\n    {\n        \"id\": 67,\n        \"name\": \"unit-protoss-high-templar\"\n    },\n    {\n        \"id\": 68,\n        \"name\": \"unit-protoss-archon\"\n    },\n    {\n        \"id\": 69,\n        \"name\": \"unit-protoss-shuttle\"\n    },\n    {\n        \"id\": 70,\n        \"name\": \"unit-protoss-scout\"\n    },\n    {\n        \"id\": 71,\n        \"name\": \"unit-protoss-arbiter\"\n    },\n    {\n        \"id\": 72,\n        \"name\": \"unit-protoss-carrier\"\n    },\n    {\n        \"id\": 73,\n        \"name\": \"unit-protoss-interceptor\"\n    },\n    {\n        \"id\": 74,\n        \"name\": \"unit-hero-dark-templar\"\n    },\n    {\n        \"id\": 75,\n        \"name\": \"unit-hero-zeratul\"\n    },\n    {\n        \"id\": 76,\n        \"name\": \"unit-hero-tassadar-zeratul-archon\"\n    },\n    {\n        \"id\": 77,\n        \"name\": \"unit-hero-fenix-zealot\"\n    },\n    {\n        \"id\": 78,\n        \"name\": \"unit-hero-fenix-dragoon\"\n    },\n    {\n        \"id\": 79,\n        \"name\": \"unit-hero-tassadar\"\n    },\n    {\n        \"id\": 80,\n        \"name\": \"unit-hero-mojo\"\n    },\n    {\n        \"id\": 81,\n        \"name\": \"unit-hero-warbringer\"\n    },\n    {\n        \"id\": 82,\n        \"name\": \"unit-hero-gantrithor\"\n    },\n    {\n        \"id\": 83,\n        \"name\": \"unit-protoss-reaver\"\n    },\n    {\n        \"id\": 84,\n        \"name\": \"unit-protoss-observer\"\n    },\n    {\n        \"id\": 85,\n        \"name\": \"unit-protoss-scarab\"\n    },\n    {\n        \"id\": 86,\n        \"name\": \"unit-hero-danimoth\"\n    },\n    {\n        \"id\": 87,\n        \"name\": \"unit-hero-aldaris\"\n    },\n    {\n        \"id\": 88,\n        \"name\": \"unit-hero-artanis\"\n    },\n    {\n        \"id\": 89,\n        \"name\": \"unit-critter-rhynadon\"\n    },\n    {\n        \"id\": 90,\n        \"name\": \"unit-critter-bengalaas\"\n    },\n    {\n        \"id\": 91,\n        \"name\": \"unit-special-cargo-ship\"\n    },\n    {\n        \"id\": 92,\n        \"name\": \"unit-special-mercenary-gunship\"\n    },\n    {\n        \"id\": 93,\n        \"name\": \"unit-critter-scantid\"\n    },\n    {\n        \"id\": 94,\n        \"name\": \"unit-critter-kakaru\"\n    },\n    {\n        \"id\": 95,\n        \"name\": \"unit-critter-ragnasaur\"\n    },\n    {\n        \"id\": 96,\n        \"name\": \"unit-critter-ursadon\"\n    },\n    {\n        \"id\": 97,\n        \"name\": \"unit-zerg-lurker-egg\"\n    },\n    {\n        \"id\": 98,\n        \"name\": \"unit-hero-raszagal\"\n    },\n    {\n        \"id\": 99,\n        \"name\": \"unit-hero-samir-duran\"\n    },\n    {\n        \"id\": 100,\n        \"name\": \"unit-hero-alexei-stukov\"\n    },\n    {\n        \"id\": 101,\n        \"name\": \"unit-special-map-revealer\"\n    },\n    {\n        \"id\": 102,\n        \"name\": \"unit-hero-gerard-dugalle\"\n    },\n    {\n        \"id\": 103,\n        \"name\": \"unit-zerg-lurker\"\n    },\n    {\n        \"id\": 104,\n        \"name\": \"unit-hero-infested-duran\"\n    },\n    {\n        \"id\": 105,\n        \"name\": \"unit-spell-disruption-web\"\n    },\n    {\n        \"id\": 106,\n        \"name\": \"unit-terran-command-center\"\n    },\n    {\n        \"id\": 107,\n        \"name\": \"unit-terran-comsat-station\"\n    },\n    {\n        \"id\": 108,\n        \"name\": \"unit-terran-nuclear-silo\"\n    },\n    {\n        \"id\": 109,\n        \"name\": \"unit-terran-supply-depot\"\n    },\n    {\n        \"id\": 110,\n        \"name\": \"unit-terran-refinery\"\n    },\n    {\n        \"id\": 111,\n        \"name\": \"unit-terran-barracks\"\n    },\n    {\n        \"id\": 112,\n        \"name\": \"unit-terran-academy\"\n    },\n    {\n        \"id\": 113,\n        \"name\": \"unit-terran-factory\"\n    },\n    {\n        \"id\": 114,\n        \"name\": \"unit-terran-starport\"\n    },\n    {\n        \"id\": 115,\n        \"name\": \"unit-terran-control-tower\"\n    },\n    {\n        \"id\": 116,\n        \"name\": \"unit-terran-science-facility\"\n    },\n    {\n        \"id\": 117,\n        \"name\": \"unit-terran-covert-ops\"\n    },\n    {\n        \"id\": 118,\n        \"name\": \"unit-terran-physics-lab\"\n    },\n    {\n        \"id\": 119,\n        \"name\": \"unit-unused-terran1\"\n    },\n    {\n        \"id\": 120,\n        \"name\": \"unit-terran-machine-shop\"\n    },\n    {\n        \"id\": 121,\n        \"name\": \"unit-unused-terran2\"\n    },\n    {\n        \"id\": 122,\n        \"name\": \"unit-terran-engineering-bay\"\n    },\n    {\n        \"id\": 123,\n        \"name\": \"unit-terran-armory\"\n    },\n    {\n        \"id\": 124,\n        \"name\": \"unit-terran-missile-turret\"\n    },\n    {\n        \"id\": 125,\n        \"name\": \"unit-terran-bunker\"\n    },\n    {\n        \"id\": 126,\n        \"name\": \"unit-special-crashed-norad-ii\"\n    },\n    {\n        \"id\": 127,\n        \"name\": \"unit-special-ion-cannon\"\n    },\n    {\n        \"id\": 128,\n        \"name\": \"unit-powerup-uraj-crystal\"\n    },\n    {\n        \"id\": 129,\n        \"name\": \"unit-powerup-khalis-crystal\"\n    },\n    {\n        \"id\": 130,\n        \"name\": \"unit-zerg-infested-command-center\"\n    },\n    {\n        \"id\": 131,\n        \"name\": \"unit-zerg-hatchery\"\n    },\n    {\n        \"id\": 132,\n        \"name\": \"unit-zerg-lair\"\n    },\n    {\n        \"id\": 133,\n        \"name\": \"unit-zerg-hive\"\n    },\n    {\n        \"id\": 134,\n        \"name\": \"unit-zerg-nydus-canal\"\n    },\n    {\n        \"id\": 135,\n        \"name\": \"unit-zerg-hydralisk-den\"\n    },\n    {\n        \"id\": 136,\n        \"name\": \"unit-zerg-defiler-mound\"\n    },\n    {\n        \"id\": 137,\n        \"name\": \"unit-zerg-greater-spire\"\n    },\n    {\n        \"id\": 138,\n        \"name\": \"unit-zerg-queens-nest\"\n    },\n    {\n        \"id\": 139,\n        \"name\": \"unit-zerg-evolution-chamber\"\n    },\n    {\n        \"id\": 140,\n        \"name\": \"unit-zerg-ultralisk-cavern\"\n    },\n    {\n        \"id\": 141,\n        \"name\": \"unit-zerg-spire\"\n    },\n    {\n        \"id\": 142,\n        \"name\": \"unit-zerg-spawning-pool\"\n    },\n    {\n        \"id\": 143,\n        \"name\": \"unit-zerg-creep-colony\"\n    },\n    {\n        \"id\": 144,\n        \"name\": \"unit-zerg-spore-colony\"\n    },\n    {\n        \"id\": 145,\n        \"name\": \"unit-unused-zerg1\"\n    },\n    {\n        \"id\": 146,\n        \"name\": \"unit-zerg-sunken-colony\"\n    },\n    {\n        \"id\": 147,\n        \"name\": \"unit-special-overmind-with-shell\"\n    },\n    {\n        \"id\": 148,\n        \"name\": \"unit-special-overmind\"\n    },\n    {\n        \"id\": 149,\n        \"name\": \"unit-zerg-extractor\"\n    },\n    {\n        \"id\": 150,\n        \"name\": \"unit-special-mature-chrysalis\"\n    },\n    {\n        \"id\": 151,\n        \"name\": \"unit-special-cerebrate\"\n    },\n    {\n        \"id\": 152,\n        \"name\": \"unit-special-cerebrate-daggoth\"\n    },\n    {\n        \"id\": 153,\n        \"name\": \"unit-unused-zerg2\"\n    },\n    {\n        \"id\": 154,\n        \"name\": \"unit-protoss-nexus\"\n    },\n    {\n        \"id\": 155,\n        \"name\": \"unit-protoss-robotics-facility\"\n    },\n    {\n        \"id\": 156,\n        \"name\": \"unit-protoss-pylon\"\n    },\n    {\n        \"id\": 157,\n        \"name\": \"unit-protoss-assimilator\"\n    },\n    {\n        \"id\": 158,\n        \"name\": \"unit-unused-protoss1\"\n    },\n    {\n        \"id\": 159,\n        \"name\": \"unit-protoss-observatory\"\n    },\n    {\n        \"id\": 160,\n        \"name\": \"unit-protoss-gateway\"\n    },\n    {\n        \"id\": 161,\n        \"name\": \"unit-unused-protoss2\"\n    },\n    {\n        \"id\": 162,\n        \"name\": \"unit-protoss-photon-cannon\"\n    },\n    {\n        \"id\": 163,\n        \"name\": \"unit-protoss-citadel-of-adun\"\n    },\n    {\n        \"id\": 164,\n        \"name\": \"unit-protoss-cybernetics-core\"\n    },\n    {\n        \"id\": 165,\n        \"name\": \"unit-protoss-templar-archives\"\n    },\n    {\n        \"id\": 166,\n        \"name\": \"unit-protoss-forge\"\n    },\n    {\n        \"id\": 167,\n        \"name\": \"unit-protoss-stargate\"\n    },\n    {\n        \"id\": 168,\n        \"name\": \"unit-special-stasis-cell-prison\"\n    },\n    {\n        \"id\": 169,\n        \"name\": \"unit-protoss-fleet-beacon\"\n    },\n    {\n        \"id\": 170,\n        \"name\": \"unit-protoss-arbiter-tribunal\"\n    },\n    {\n        \"id\": 171,\n        \"name\": \"unit-protoss-robotics-support-bay\"\n    },\n    {\n        \"id\": 172,\n        \"name\": \"unit-protoss-shield-battery\"\n    },\n    {\n        \"id\": 173,\n        \"name\": \"unit-special-khaydarin-crystal-form\"\n    },\n    {\n        \"id\": 174,\n        \"name\": \"unit-special-protoss-temple\"\n    },\n    {\n        \"id\": 175,\n        \"name\": \"unit-special-xelnaga-temple\"\n    },\n    {\n        \"id\": 176,\n        \"name\": \"unit-resource-mineral-field\"\n    },\n    {\n        \"id\": 177,\n        \"name\": \"unit-resource-mineral-field-type-2\"\n    },\n    {\n        \"id\": 178,\n        \"name\": \"unit-resource-mineral-field-type-3\"\n    },\n    {\n        \"id\": 179,\n        \"name\": \"unit-unused-cave\"\n    },\n    {\n        \"id\": 180,\n        \"name\": \"unit-unused-cave-in\"\n    },\n    {\n        \"id\": 181,\n        \"name\": \"unit-unused-cantina\"\n    },\n    {\n        \"id\": 182,\n        \"name\": \"unit-unused-mining-platform\"\n    },\n    {\n        \"id\": 183,\n        \"name\": \"unit-unused-independant-command-center\"\n    },\n    {\n        \"id\": 184,\n        \"name\": \"unit-special-independant-starport\"\n    },\n    {\n        \"id\": 185,\n        \"name\": \"unit-unused-independant-jump-gate\"\n    },\n    {\n        \"id\": 186,\n        \"name\": \"unit-unused-ruins\"\n    },\n    {\n        \"id\": 187,\n        \"name\": \"unit-unused-khaydarin-crystal-formation\"\n    },\n    {\n        \"id\": 188,\n        \"name\": \"unit-resource-vespene-geyser\"\n    },\n    {\n        \"id\": 189,\n        \"name\": \"unit-special-warp-gate\"\n    },\n    {\n        \"id\": 190,\n        \"name\": \"unit-special-psi-disrupter\"\n    },\n    {\n        \"id\": 191,\n        \"name\": \"unit-unused-zerg-marker\"\n    },\n    {\n        \"id\": 192,\n        \"name\": \"unit-unused-terran-marker\"\n    },\n    {\n        \"id\": 193,\n        \"name\": \"unit-unused-protoss-marker\"\n    },\n    {\n        \"id\": 194,\n        \"name\": \"unit-special-zerg-beacon\"\n    },\n    {\n        \"id\": 195,\n        \"name\": \"unit-special-terran-beacon\"\n    },\n    {\n        \"id\": 196,\n        \"name\": \"unit-special-protoss-beacon\"\n    },\n    {\n        \"id\": 197,\n        \"name\": \"unit-special-zerg-flag-beacon\"\n    },\n    {\n        \"id\": 198,\n        \"name\": \"unit-special-terran-flag-beacon\"\n    },\n    {\n        \"id\": 199,\n        \"name\": \"unit-special-protoss-flag-beacon\"\n    },\n    {\n        \"id\": 200,\n        \"name\": \"unit-special-power-generator\"\n    },\n    {\n        \"id\": 201,\n        \"name\": \"unit-special-overmind-cocoon\"\n    },\n    {\n        \"id\": 202,\n        \"name\": \"unit-spell-dark-swarm\"\n    },\n    {\n        \"id\": 203,\n        \"name\": \"unit-special-floor-missile-trap\"\n    },\n    {\n        \"id\": 204,\n        \"name\": \"unit-special-floor-hatch\"\n    },\n    {\n        \"id\": 205,\n        \"name\": \"unit-special-upper-level-door\"\n    },\n    {\n        \"id\": 206,\n        \"name\": \"unit-special-right-upper-level-door\"\n    },\n    {\n        \"id\": 207,\n        \"name\": \"unit-special-pit-door\"\n    },\n    {\n        \"id\": 208,\n        \"name\": \"unit-special-right-pit-door\"\n    },\n    {\n        \"id\": 209,\n        \"name\": \"unit-special-floor-gun-trap\"\n    },\n    {\n        \"id\": 210,\n        \"name\": \"unit-special-wall-missile-trap\"\n    },\n    {\n        \"id\": 211,\n        \"name\": \"unit-special-wall-flame-trap\"\n    },\n    {\n        \"id\": 212,\n        \"name\": \"unit-special-right-wall-missile-trap\"\n    },\n    {\n        \"id\": 213,\n        \"name\": \"unit-special-right-wall-flame-trap\"\n    },\n    {\n        \"id\": 214,\n        \"name\": \"unit-special-start-location\"\n    },\n    {\n        \"id\": 215,\n        \"name\": \"unit-powerup-flag\"\n    },\n    {\n        \"id\": 216,\n        \"name\": \"unit-powerup-young-chrysalis\"\n    },\n    {\n        \"id\": 217,\n        \"name\": \"unit-powerup-psi-emitter\"\n    },\n    {\n        \"id\": 218,\n        \"name\": \"unit-powerup-data-disk\"\n    },\n    {\n        \"id\": 219,\n        \"name\": \"unit-powerup-khaydarin-crystal\"\n    },\n    {\n        \"id\": 220,\n        \"name\": \"unit-powerup-mineral-cluster-type-1\"\n    },\n    {\n        \"id\": 221,\n        \"name\": \"unit-powerup-mineral-cluster-type-2\"\n    },\n    {\n        \"id\": 222,\n        \"name\": \"unit-powerup-protoss-gas-orb-type-1\"\n    },\n    {\n        \"id\": 223,\n        \"name\": \"unit-powerup-protoss-gas-orb-type-2\"\n    },\n    {\n        \"id\": 224,\n        \"name\": \"unit-powerup-zerg-gas-sac-type-1\"\n    },\n    {\n        \"id\": 225,\n        \"name\": \"unit-powerup-zerg-gas-sac-type-2\"\n    },\n    {\n        \"id\": 226,\n        \"name\": \"unit-powerup-terran-gas-tank-type-1\"\n    },\n    {\n        \"id\": 227,\n        \"name\": \"unit-powerup-terran-gas-tank-type-2\"\n    }\n]\n"
  },
  {
    "path": "debian/changelog",
    "content": "stargus (2.4.1-1) unstable; urgency=low\n\n  * Support Stratagus 2.4.1\n  * Correct error message if lua checksums mismatch\n\n -- Tim Felgentreff <tim.felgentreff@gmail.com>  Tue, 8 Nov 2016 9:33:12 +0100\n\nstargus (2.4.0-1) unstable; urgency=low\n\n  * Spawn larva in Zerg hatchery\n  * Initial work on Zerg creep\n  * Run with latest Stratagus\n  * Support Battle.net Installer for extraction\n\n -- Tim Felgentreff <tim.felgentreff@gmail.com>  Wed, 2 Dec 2015 9:33:12 +0100\n\nstargus (2.2.7-1) unstable; urgency=low\n\n  * Fixed bug #950442 - Fix script when map is loaded\n  * Fixed bug #931215 - Do not extract file which missing on french CD\n\n -- Pali Rohár <pali.rohar@gmail.com>  Tue, 21 Aug 2012 16:33:12 +0200\n\nstargus (2.2.6-1) unstable; urgency=low\n\n  * Fixed bug #768325 - NSIS: run startool with correct datadir path\n  * Fixed bug #909435 - Rewritten build system to CMake\n  * Fixed bug #910269 - Fixed compilation on OpenBSD 5.0\n  * Fixed bug #914555 - Fixed MPQ code\n  * Rewritten code for supporting 64bit architectures too\n  * Use Huffmann decoding from StormLib library\n  * Rewritten debian files to debhelper 7\n\n -- Pali Rohár <pali.rohar@gmail.com>  Sat, 25 Feb 2012 13:35:25 +0100\n\nstargus (2.2.5.5-1) unstable; urgency=low\n\n  * Fixed for new Stratagus\n  * Compile startool always 32bit\n  * Added icon\n  * Rewrited debian scripts\n  * Rewrited Makefile\n  * Added launcher starcraft.c\n  * Rewrited Windows NSIS Installer\n  * Fixed Windows resource file\n  * Added more resolutions and OpenGL settings in option menu\n  * Ported to Maemo\n\n -- Pali Rohár <pali.rohar@gmail.com>  Mon, 22 Nov 2010 23:16:16 +0100\n\nstargus (2.1pre2) unstable; urgency=low\n\n  * Upstream release\n\n -- M. Gerhardy <tlh2000@users.sf.net>  Sat, 23 May 2009 10:51:08 +0200\n"
  },
  {
    "path": "debian/compat",
    "content": "7\n"
  },
  {
    "path": "debian/control",
    "content": "Source: stargus\nSection: games\nPriority: optional\nMaintainer: Pali Rohár <pali.rohar@gmail.com>\nBuild-Depends: debhelper (>= 7), cmake (>= 2.6), pkg-config, imagemagick,\n po-debconf, sharutils, zlib1g-dev, libbz2-dev, libx11-dev,\n libpng12-dev (>= 1.2.5) | libpng-dev (>= 1.2.5), libhildon1-dev | libgtk2.0-dev, stratagus-dev\nStandards-Version: 3.9.2\nHomepage: https://github.com/Wargus/stargus\n\nPackage: stargus\nArchitecture: any\nDepends: ${stratagus:Depends}, ${misc:Depends}, ${shlibs:Depends}\nProvides: stratagus-data\nDescription: Starcraft data game set for the Stratagus engine\n Stargus can be used to play Starcraft from Blizzard Entertainment.\n .\n You need the original Starcraft CD to extract the game data files.\n .\n Stargus is developed together for Windows, Linux and Mac OS X.\n"
  },
  {
    "path": "debian/copyright",
    "content": "This work was packaged for Debian by:\n\n    Pali Rohár <pali.rohar@gmail.com> on Sat, 25 Feb 2012 13:38:30 +0100\n\nIt was downloaded from:\n\n    https://github.com/Wargus/stargus\n\nUpstream Author(s):\n\n    Jimmy Salmon <jsalmon3@users.sourceforge.net>\n    Russel Smith <mr-russ@users.sourceforge.net>\n    Nehal Mistry <nehalmistry@users.sourceforge.net>\n    Pali Rohár <pali.rohar@gmail.com>\n    Tim Felgentreff <timfelgentreff@gmail.com>\n\nCopyright:\n\n    (c) 2002-2022 by The Stratagus Project and Pali Rohár\n\nLicense:\n\n    This package is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This package is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this package; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nThe Debian packaging is:\n\n    Copyright (C) 2010-2012 Pali Rohár <pali.rohar@gmail.com>\n    Copyright (C) 2015-2016 Tim Felgentreff <timfelgentreff@gmail.com>\n\nand is licensed under the GPL version 2,\nsee \"/usr/share/common-licenses/GPL-2\".\n"
  },
  {
    "path": "debian/docs",
    "content": "README.md\ndoc/changelog\ndoc/todo\n"
  },
  {
    "path": "debian/manpages",
    "content": "doc/scmconvert.6\ndoc/stargus.6\ndoc/startool.6\n"
  },
  {
    "path": "debian/menu",
    "content": "?package(stargus):needs=\"x11\" section=\"Games/Strategy\" title=\"Stargus - Starcraft\" command=\"/usr/games/stargus\" icon=\"/usr/share/pixmaps/stargus.xpm\"\n"
  },
  {
    "path": "debian/po/POTFILES.in",
    "content": "[type: gettext/rfc822deb] templates\n"
  },
  {
    "path": "debian/po/templates.pot",
    "content": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"Report-Msgid-Bugs-To: stargus@packages.debian.org\\n\"\n\"POT-Creation-Date: 2012-02-25 13:44+0100\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n\"Language: \\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=CHARSET\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\n#. Type: boolean\n#. Description\n#: ../templates:1001\nmsgid \"Extract Starcraft data files now?\"\nmsgstr \"\"\n\n#. Type: boolean\n#. Description\n#: ../templates:1001\nmsgid \"Stargus needs data files from original Starcraft CD.\"\nmsgstr \"\"\n\n#. Type: string\n#. Description\n#: ../templates:2001\nmsgid \"Starcraft CD mount point:\"\nmsgstr \"\"\n\n#. Type: string\n#. Description\n#: ../templates:2001\nmsgid \"Enter path to your Starcraft CD mount point\"\nmsgstr \"\"\n\n#. Type: error\n#. Description\n#: ../templates:3001\nmsgid \"Data files not found\"\nmsgstr \"\"\n\n#. Type: error\n#. Description\n#: ../templates:3001\nmsgid \"\"\n\"Starcraft CD was not found in specified path. Specify another path which \"\n\"contains correct Starcraft data files.\"\nmsgstr \"\"\n"
  },
  {
    "path": "debian/postrm",
    "content": "#!/bin/sh\n\nset -e\n\nif [ \"$1\" = \"remove\" ] || [ \"$1\" = \"purge\" ]; then\n\trm -rf /usr/share/games/stratagus/stargus\nfi\n\n#DEBHELPER#\n\nexit 0\n"
  },
  {
    "path": "debian/rules",
    "content": "#!/usr/bin/make -f\n#       _________ __                 __\n#      /   _____//  |_____________ _/  |______     ____  __ __  ______\n#      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n#      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ |\n#     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n#             \\/                  \\/          \\//_____/            \\/\n#  ______________________                           ______________________\n#                        T H E   W A R   B E G I N S\n#         Stratagus - A free fantasy real time strategy game engine\n#\n#    debian/rules\n#    Copyright (C) 2010-2012  Pali Rohár <pali.rohar@gmail.com>\n#\n#    This program is free software: you can redistribute it and/or modify\n#    it under the terms of the GNU General Public License as published by\n#    the Free Software Foundation, either version 2 of the License, or\n#    (at your option) any later version.\n#\n#    This program is distributed in the hope that it will be useful,\n#    but WITHOUT ANY WARRANTY; without even the implied warranty of\n#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#    GNU General Public License for more details.\n#\n#    You should have received a copy of the GNU General Public License\n#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n#\n\nVERSION := $(shell dpkg-parsechangelog | sed -ne \"s/^Version: \\(.*\\)/\\1/p\" | sed \"s/-[^-]*$$//\" )\n\n%:\n\tdh $@\n\noverride_dh_auto_configure:\n\tdh_auto_configure -- -DCMAKE_INCLUDE_PATH=\"/usr/lib/$(shell dpkg-architecture -qDEB_BUILD_MULTIARCH)/\"\n\noverride_dh_install:\n\tdh_install\n\tconvert stargus.png -resize 32x32 debian/stargus/usr/share/pixmaps/stargus.xpm\n\noverride_dh_shlibdeps:\n\tdh_shlibdeps\n\techo \"stratagus:Depends=stratagus (>= $(VERSION)~0)\" >> debian/stargus.substvars\n"
  },
  {
    "path": "debian/source/format",
    "content": "3.0 (quilt)\n"
  },
  {
    "path": "doc/changelog",
    "content": "2.4.0\n - Spawn larva in Zerg hatchery\n - Initial work on Zerg creep\n - Run with latest Stratagus\n - Support Battle.net Installer for extraction\n\n2.2.7:\n - Fixed bug #950442 - Fix script when map is loaded\n - Fixed bug #931215 - Do not extract file which missing on french CD\n\n2.2.6:\n - Fixed bug #768325 - NSIS: run startool with correct datadir path\n - Fixed bug #909435 - Rewritten build system to CMake\n - Fixed bug #910269 - Fixed compilation on OpenBSD 5.0\n - Fixed bug #914555 - Fixed MPQ code\n - Rewritten code for supporting 64bit architectures too\n - Use Huffmann decoding from StormLib library\n - Rewritten debian files to debhelper 7\n\n2.2.5.5:\n - Fixed for new Stratagus\n - Compile startool always 32bit\n - Added icon\n - Rewrited debian scripts\n - Rewrited Makefile\n - Added launcher starcraft.c\n - Rewrited Windows NSIS Installer\n - Fixed Windows resource file\n - Added more resolutions and OpenGL settings in option menu\n - Ported to Maemo\n"
  },
  {
    "path": "doc/iscript.txt",
    "content": "# ----------------------------------------------------------------------------- #\r\n# Decompiled iscript.bin - Starcraft animations file\r\n# ----------------------------------------------------------------------------- #\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 000 Scourge (zerg\\avenger.grp)\r\n.headerstart\r\nIsId           \t0\r\nType           \t12\r\nInit           \tScourgeInit\r\nDeath          \tScourgeDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \tScourgeAirAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \tScourgeAirAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \tScourgeAirAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tScourgeWalking\r\nWalkingToIdle  \tScourgeAirAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScourgeInit:\r\n\timgul          \t1 0 42\t# ScourgeShad (zerg\\avenger.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twaitrand       \t1 5\r\nScourgeAirAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsetvertpos     \t0\r\n\twait           \t3\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t3\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tsetvertpos     \t1\r\n\twait           \t3\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tsetvertpos     \t2\r\n\twait           \t3\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tsetvertpos     \t1\r\n\twait           \t3\r\n\tgoto           \tScourgeAirAttkToIdle\r\n\r\nScourgeDeath:\r\n\tplaysnd        \t776\t# Zerg\\AVENGER\\ZAvDth00.WAV\r\n\timgol          \t3 0 0\t# ScourgeDeath (zerg\\zavDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nScourgeAirAttkInit:\r\n\tplaysnd        \t778\t# Zerg\\AVENGER\\ZAvHit00.WAV\r\n\tsprol          \t132 0 0\t# ScourgeExplosion (zerg\\zavExplo.grp)\r\n\twait           \t1\r\n\tattackwith     \t2\r\n\tgoto           \tlong00\r\n\r\nScourgeWalking:\r\n\tsetvertpos     \t0\r\nScourgeLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tgoto           \tScourgeLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 003 ScourgeDeath (zerg\\zavDeath.grp)\r\n.headerstart\r\nIsId           \t2\r\nType           \t0\r\nInit           \tScourgeDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScourgeDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\timgol          \t59 0 0\t# ZergAirDeathSmall (thingy\\zAirDthS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 004 ScourgeExplosion (zerg\\zavExplo.grp)\r\n.headerstart\r\nIsId           \t3\r\nType           \t1\r\nInit           \tScourgeExplosionInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScourgeExplosionInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 005 Broodling (zerg\\brood.grp)\r\n.headerstart\r\nIsId           \t4\r\nType           \t12\r\nInit           \tBroodlingInit\r\nDeath          \tBroodlingDeath\r\nGndAttkInit    \tBroodlingGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tBroodlingGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tBroodlingGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tBroodlingWalking\r\nWalkingToIdle  \tBroodlingGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBroodlingInit:\r\n\timgul          \t6 0 0\t# BroodlingShad (zerg\\zbrShad.grp)\r\nBroodlingGndAttkToIdle:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twaitrand       \t25 30\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twaitrand       \t25 30\r\n\tgoto           \tBroodlingGndAttkToIdle\r\n\r\nBroodlingDeath:\r\n\tplaysnd        \t785\t# Zerg\\BROODLING\\ZBrDth00.WAV\r\n\tlowsprul       \t134 0 0\t# BroodlingDeath (zerg\\zbrDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nBroodlingGndAttkInit:\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tattackmelee    \t1 786\t# Zerg\\BROODLING\\ZBrAtt00.WAV\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tBroodlingGndAttkToIdle\r\n\r\nBroodlingWalking:\r\n\tcall           \tBroodlingLocal00\r\n\tcall           \tBroodlingLocal00\r\n\twaitrand       \t3 6\r\n\tcall           \tBroodlingLocal00\r\n\twaitrand       \t3 6\r\n\tcall           \tBroodlingLocal00\r\n\tcall           \tBroodlingLocal00\r\n\tcall           \tBroodlingLocal00\r\n\twaitrand       \t3 6\r\n\tgoto           \tBroodlingWalking\r\n\r\nBroodlingLocal00:\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\treturn         \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 007 BroodlingDeath (zerg\\zbrDeath.grp)\r\n.headerstart\r\nIsId           \t5\r\nType           \t0\r\nInit           \tBroodlingRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBroodlingRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tplayfram       \t4\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 008 InfestedTerran (zerg\\bugguy.grp)\r\n.headerstart\r\nIsId           \t6\r\nType           \t26\r\nInit           \tInfestedTerranInit\r\nDeath          \tInfestedTerranDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tInfestedTerranWalking\r\nWalkingToIdle  \tInfestedTerranWalkingToIdle\r\nSpecialState1  \tInfestedTerranSpecialState1\r\nSpecialState2  \tInfestedTerranSpecialState2\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tInfestedTerranBurrow\r\nUnBurrow       \tInfestedTerranUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInfestedTerranInit:\r\n\timgul          \t9 0 0\t# InfestedTerranShad (zerg\\zbgShad.grp)\r\nInfestedTerranWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nInfestedTerranDeath:\r\n\tplaysnd        \t67\t# Bullet\\ZBGHit00.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xef\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xf0\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xf1\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xf2\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xf3\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xf4\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xf5\t# frame set 14\r\n\twait           \t1\r\n\tlowsprul       \t236 0 0\t# MarineDeath (terran\\tmaDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nInfestedTerranWalking:\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tInfestedTerranWalking\r\n\r\nInfestedTerranSpecialState1:\r\n\tattackwith     \t1\r\n\tsprol          \t136 0 0\t# InfestedTerranExplosion (thingy\\zbgExplo.grp)\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nInfestedTerranSpecialState2:\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\tgoto           \tlong00\r\n\r\nInfestedTerranBurrow:\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nInfestedTerranUnBurrow:\r\n\twaitrand       \t1 5\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 010 InfestedTerranExplosion (thingy\\zbgExplo.grp)\r\n.headerstart\r\nIsId           \t7\r\nType           \t1\r\nInit           \tInfestedTerranExplosionInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInfestedTerranExplosionInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 011 GuardianCocoon (zerg\\cocoon.grp)\r\n.headerstart\r\nIsId           \t8\r\nType           \t14\r\nInit           \tGuardianCocoonInit\r\nDeath          \tGuardianCocoonDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tGuardianCocoonSpecialState1\r\nSpecialState2  \tGuardianCocoonSpecialState2\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGuardianCocoonInit:\r\n\timgul          \t12 0 42\t# GuardianCocoonShad (zerg\\cocoon.grp)\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twaitrand       \t10 15\r\nGuardianCocoonLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tgoto           \tGuardianCocoonLocal00\r\n\r\nGuardianCocoonDeath:\r\n\tplaysnd        \t942\t# Zerg\\Mutalid\\ZMuDth00.WAV\r\n\timgol          \t41 0 0\t# MutaliskDeath (zerg\\zmuDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nGuardianCocoonSpecialState1:\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nGuardianCocoonSpecialState2:\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 013 Defiler (zerg\\defiler.grp)\r\n.headerstart\r\nIsId           \t9\r\nType           \t26\r\nInit           \tDefilerInit\r\nDeath          \tDefilerDeath\r\nGndAttkInit    \tDefilerGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDefilerGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tDefilerCastSpell\r\nGndAttkToIdle  \tDefilerGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tDefilerWalking\r\nWalkingToIdle  \tDefilerGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tDefilerSpecialState2\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tDefilerBurrow\r\nUnBurrow       \tDefilerUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDefilerInit:\r\n\timgul          \t14 0 3\t# DefilerShad (zerg\\defiler.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twaitrand       \t1 4\r\nDefilerGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t3\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t3\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t3\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t3\r\n\tgoto           \tDefilerGndAttkToIdle\r\n\r\nDefilerDeath:\r\n\tplaysnd        \t815\t# Zerg\\DEFILER\\ZDeDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t2\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t2\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t2\r\n\tlowsprul       \t139 0 0\t# DefilerDeath (zerg\\zdeDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nDefilerGndAttkInit:\r\n\tplaysnd        \t110\t# Bullet\\zdeAtt00.wav\r\n\timgoluselo     \t518 0 0\t# Unknown518 (thingy\\eplMuzz.grp)\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tgoto           \tDefilerGndAttkToIdle\r\n\r\nDefilerCastSpell:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tcastspell      \t\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tsigorder       \t2\r\n\tgoto           \tDefilerGndAttkToIdle\r\n\r\nDefilerWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tgoto           \tDefilerWalking\r\n\r\nDefilerSpecialState2:\r\n\tplayfram       \t0x110\t# frame set 16\r\n\tgoto           \tlong00\r\n\r\nDefilerBurrow:\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nDefilerUnBurrow:\r\n\twaitrand       \t1 5\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tDefilerGndAttkToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 016 DefilerDeath (zerg\\zdeDeath.grp)\r\n.headerstart\r\nIsId           \t10\r\nType           \t0\r\nInit           \tDefilerRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDefilerRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tplayfram       \t4\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 017 Drone (zerg\\drone.grp)\r\n.headerstart\r\nIsId           \t11\r\nType           \t26\r\nInit           \tDroneInit\r\nDeath          \tDroneDeath\r\nGndAttkInit    \tDroneGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDroneGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE].\r\nWalking        \tDroneWalking\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tDroneSpecialState2\r\nAlmostBuilt    \tDroneAlmostBuilt\r\nBuilt          \t[NONE]\r\nLanding        \tDroneWalking\r\nLiftOff        \tDroneLiftOff\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tDroneBurrow\r\nUnBurrow       \tDroneUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDroneInit:\r\n\timgul          \t18 0 7\t# DroneShad (zerg\\drone.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nDroneDeath:\r\n\tplaysnd        \t833\t# Zerg\\DRONE\\ZDrDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t2\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t2\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t2\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t2\r\n\tplayfram       \t0x121\t# frame set 17\r\n\twait           \t2\r\n\tlowsprul       \t141 0 0\t# DroneDeath (zerg\\zdrDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nDroneGndAttkInit:\r\n\tsetvertpos     \t0\r\n\tplaysnd        \t64\t# Bullet\\SpoogHit.wav\r\n\tsproluselo     \t332 0\t# NeedleSpines (thingy\\spooge.grp)\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nDroneWalking:\r\n\tsetvertpos     \t0\r\nDroneLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tgoto           \tDroneLocal00\r\n\r\nDroneSpecialState2:\r\n\tplayfram       \t0x176\t# frame set 22\r\n\tgoto           \tlong00\r\n\r\nDroneAlmostBuilt:\r\n\tsetvertpos     \t0\r\n\twaitrand       \t5 8\r\n\tplaysnd        \t847\t# Zerg\\DRONE\\ZDrMin00.wav\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t2\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tgoto           \tDroneAlmostBuilt\r\n\r\nDroneLiftOff:\r\n\tsigorder       \t16\r\n\tgoto           \tlong00\r\n\r\nDroneBurrow:\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0x132\t# frame set 18\r\n\twait           \t1\r\n\tplayfram       \t0x143\t# frame set 19\r\n\twait           \t1\r\n\tplayfram       \t0x154\t# frame set 20\r\n\twait           \t1\r\n\tplayfram       \t0x165\t# frame set 21\r\n\twait           \t1\r\n\tplayfram       \t0x176\t# frame set 22\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nDroneUnBurrow:\r\n\twaitrand       \t1 5\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0x165\t# frame set 21\r\n\twait           \t1\r\n\tplayfram       \t0x154\t# frame set 20\r\n\twait           \t1\r\n\tplayfram       \t0x143\t# frame set 19\r\n\twait           \t1\r\n\tplayfram       \t0x132\t# frame set 18\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 020 DroneDeath (zerg\\zdrDeath.grp)\r\n.headerstart\r\nIsId           \t12\r\nType           \t0\r\nInit           \tDroneRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDroneRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tplayfram       \t4\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 021 ZergEgg (zerg\\egg.grp)\r\n.headerstart\r\nIsId           \t13\r\nType           \t13\r\nInit           \tEggInit\r\nDeath          \tEggDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tEggSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEggInit:\r\n\timgul          \t22 0 0\t# ZergEggShad (zerg\\zegShad.grp)\r\n\tplayfram       \t20\r\n\twait           \t2\r\n\tplayfram       \t21\r\n\twait           \t2\r\n\tplayfram       \t22\r\n\twait           \t2\r\n\tplayfram       \t23\r\n\twait           \t2\r\nEggLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tgoto           \tEggLocal00\r\n\r\nEggDeath:\r\n\tplaysnd        \t830\t# Zerg\\Egg\\ZEgDth00.WAV\r\n\tlowsprul       \t143 0 0\t# ZergEggDeath (zerg\\zegDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nEggSpecialState1:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twait           \t2\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 024 ZergEggDeath (zerg\\zegDeath.grp)\r\n.headerstart\r\nIsId           \t14\r\nType           \t0\r\nInit           \tEggRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEggRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t25\r\n\tplayfram       \t10\r\n\twait           \t25\r\n\tplayfram       \t11\r\n\twait           \t25\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 025 Guardian (zerg\\guardian.grp)\r\n.headerstart\r\nIsId           \t15\r\nType           \t12\r\nInit           \tGuardianInit\r\nDeath          \tGuardianDeath\r\nGndAttkInit    \tGuardianGndAttkInit\r\nAirAttkInit    \tGuardianGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tGuardianGndAttkInit\r\nAirAttkRpt     \tGuardianGndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tGuardianGndAttkToIdle\r\nAirAttkToIdle  \tGuardianGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tGuardianWalking\r\nWalkingToIdle  \tGuardianGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGuardianInit:\r\n\timgul          \t26 0 42\t# GuardianShad (zerg\\guardian.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twaitrand       \t1 4\r\nGuardianGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tgoto           \tGuardianGndAttkToIdle\r\n\r\nGuardianDeath:\r\n\tplaysnd        \t852\t# Zerg\\Guardian\\ZGuDth00.WAV\r\n\timgol          \t28 0 0\t# GuardianDeath (zerg\\zguDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nGuardianGndAttkInit:\r\n\tplaysnd        \t71\t# Bullet\\ZGuFir00.wav\r\n\timgoluselo     \t518 0 0\t# Unknown518 (thingy\\eplMuzz.grp)\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tgoto           \tGuardianGndAttkToIdle\r\n\r\nGuardianWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tgoto           \tGuardianWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 027 GuardianBirth (zerg\\cocoon.grp)\r\n.headerstart\r\nIsId           \t16\r\nType           \t13\r\nInit           \tGuardianBirthInit\r\nDeath          \tGuardianCocoonDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tGuardianBirthSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGuardianBirthInit:\r\n\timgul          \t12 0 42\t# GuardianCocoonShad (zerg\\cocoon.grp)\r\n\tgoto           \tGuardianCocoonLocal00\r\n\r\nGuardianBirthSpecialState1:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twait           \t2\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tplayfram       \t20\r\n\twait           \t2\r\n\tplayfram       \t21\r\n\twait           \t2\r\n\tplayfram       \t22\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 028 GuardianDeath (zerg\\zguDeath.grp)\r\n.headerstart\r\nIsId           \t17\r\nType           \t0\r\nInit           \tGuardianDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGuardianDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\timgol          \t58 0 0\t# ZergAirDeathLarge (thingy\\zAirDthL.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 029 Hydralisk (zerg\\hydra.grp)\r\n.headerstart\r\nIsId           \t18\r\nType           \t26\r\nInit           \tHydraliskInit\r\nDeath          \tHydraliskDeath\r\nGndAttkInit    \tHydraliskGndAttkInit\r\nAirAttkInit    \tHydraliskGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tHydraliskGndAttkRpt\r\nAirAttkRpt     \tHydraliskGndAttkRpt\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tHydraliskGndAttkToIdle\r\nAirAttkToIdle  \tHydraliskGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tHydraliskWalking\r\nWalkingToIdle  \tHydraliskWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tHydraliskSpecialState2\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tHydraliskBurrow\r\nUnBurrow       \tHydraliskUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHydraliskInit:\r\n\timgul          \t30 0 0\t# HydraliskShad (zerg\\zhyShad.grp)\r\nHydraliskWalkingToIdle:\r\n\tplayfram       \t0x55\t# frame set 5\r\nHydraliskLocal02:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t25 HydraliskLocal00\r\n\trandcondjmp    \t128 HydraliskLocal01\r\n\tgoto           \tHydraliskLocal02\r\n\r\nHydraliskLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t25\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tHydraliskWalkingToIdle\r\n\r\nHydraliskLocal01:\r\n\trandcondjmp    \t128 HydraliskLocal03\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tgoto           \tHydraliskWalkingToIdle\r\n\r\nHydraliskLocal03:\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tgoto           \tHydraliskWalkingToIdle\r\n\r\nHydraliskDeath:\r\n\tplaysnd        \t867\t# Zerg\\Hydra\\ZHyDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xcd\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xce\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xcf\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd0\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd1\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd2\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd3\t# frame set 12\r\n\twait           \t2\r\n\tlowsprul       \t147 0 0\t# HydraliskDeath (zerg\\zhyDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nHydraliskGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\nHydraliskGndAttkRpt:\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tplaysnd        \t64\t# Bullet\\SpoogHit.wav\r\n\tsproluselo     \t332 0\t# NeedleSpines (thingy\\spooge.grp)\r\n\tattack         \t\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nHydraliskGndAttkToIdle:\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tHydraliskWalkingToIdle\r\n\r\nHydraliskWalking:\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tgoto           \tHydraliskWalking\r\n\r\nHydraliskSpecialState2:\r\n\tplayfram       \t0x118\t# frame set 16\r\n\tgoto           \tlong00\r\n\r\nHydraliskBurrow:\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xd4\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xe5\t# frame set 13\r\n\twait           \t1\r\n\tplayfram       \t0xf6\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0x107\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0x118\t# frame set 16\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nHydraliskUnBurrow:\r\n\twaitrand       \t1 5\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0x107\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0xf6\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xe5\t# frame set 13\r\n\twait           \t1\r\n\tplayfram       \t0xd4\t# frame set 12\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tHydraliskWalkingToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 032 HydraliskDeath (zerg\\zhyDeath.grp)\r\n.headerstart\r\nIsId           \t19\r\nType           \t0\r\nInit           \tHydraliskRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHydraliskRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 033 InfestedKerrigan (zerg\\uikerr.grp)\r\n.headerstart\r\nIsId           \t20\r\nType           \t26\r\nInit           \tInfestedKerriganInit\r\nDeath          \tInfestedKerriganDeath\r\nGndAttkInit    \tInfestedKerriganGndAttkInit\r\nAirAttkInit    \tInfestedKerriganGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tInfestedKerriganGndAttkRpt\r\nAirAttkRpt     \tInfestedKerriganGndAttkRpt\r\nCastSpell      \tInfestedKerriganCastSpell\r\nGndAttkToIdle  \tInfestedKerriganGndAttkToIdle\r\nAirAttkToIdle  \tInfestedKerriganGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tInfestedKerriganWalking\r\nWalkingToIdle  \tInfestedKerriganWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tInfestedKerriganBurrow\r\nUnBurrow       \tInfestedKerriganUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInfestedKerriganInit:\r\n\timgul          \t34 0 0\t# InfestedKerriganShad (zerg\\uikShad.grp)\r\nInfestedKerriganWalkingToIdle:\r\n\tplayfram       \t0x88\t# frame set 8\r\nInfestedKerriganLocal01:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t128 InfestedKerriganLocal00\r\n\tgoto           \tInfestedKerriganLocal01\r\n\r\nInfestedKerriganLocal00:\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tturnrand       \t3\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tgoto           \tInfestedKerriganWalkingToIdle\r\n\r\nInfestedKerriganDeath:\r\n\tplaysnd        \t967\t# Zerg\\ZERGKERRI\\UKiDth00.wav\r\n\timgol          \t231 0 0\t# Unknown231 (terran\\ghost.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nInfestedKerriganGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\nInfestedKerriganGndAttkRpt:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t112\t# Bullet\\UKiFir00.wav\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tattackmelee    \t1 0\t# <NONE>\r\n\twait           \t3\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nInfestedKerriganGndAttkToIdle:\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tgoto           \tInfestedKerriganWalkingToIdle\r\n\r\nInfestedKerriganCastSpell:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nInfestedKerriganWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tgoto           \tInfestedKerriganWalking\r\n\r\nInfestedKerriganBurrow:\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nInfestedKerriganUnBurrow:\r\n\twaitrand       \t1 5\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 036 Larva (zerg\\larva.grp)\r\n.headerstart\r\nIsId           \t21\r\nType           \t12\r\nInit           \tLarvaInit\r\nDeath          \tLarvaDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tLarvaWalking\r\nWalkingToIdle  \tLarvaInit\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLarvaInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nLarvaDeath:\r\n\tplaysnd        \t849\t# Zerg\\Larva\\ZLaDth00.WAV\r\n\tlowsprul       \t150 0 0\t# LarvaDeath (zerg\\zlaDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nLarvaWalking:\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tgoto           \tLarvaWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 037 LarvaDeath (zerg\\zlaDeath.grp)\r\n.headerstart\r\nIsId           \t22\r\nType           \t0\r\nInit           \tLarvaRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLarvaRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t25\r\n\tplayfram       \t7\r\n\twait           \t25\r\n\tplayfram       \t8\r\n\twait           \t25\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 038 Mutalisk (zerg\\mutalid.grp)\r\n.headerstart\r\nIsId           \t23\r\nType           \t12\r\nInit           \tMutaliskInit\r\nDeath          \tMutaliskDeath\r\nGndAttkInit    \tMutaliskGndAttkInit\r\nAirAttkInit    \tMutaliskGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tMutaliskGndAttkInit\r\nAirAttkRpt     \tMutaliskGndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tMutaliskGndAttkToIdle\r\nAirAttkToIdle  \tMutaliskGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tMutaliskWalking\r\nWalkingToIdle  \tMutaliskGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMutaliskInit:\r\n\timgul          \t39 0 42\t# MutaliskShad (zerg\\mutalid.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twaitrand       \t1 4\r\nMutaliskGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tgoto           \tMutaliskGndAttkToIdle\r\n\r\nMutaliskDeath:\r\n\tplaysnd        \t942\t# Zerg\\Mutalid\\ZMuDth00.WAV\r\n\timgol          \t41 0 0\t# MutaliskDeath (zerg\\zmuDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nMutaliskGndAttkInit:\r\n\tplaysnd        \t113\t# Bullet\\zmuFir00.wav\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tgoto           \tMutaliskGndAttkToIdle\r\n\r\nMutaliskWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tgoto           \tMutaliskWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 041 MutaliskDeath (zerg\\zmuDeath.grp)\r\n.headerstart\r\nIsId           \t24\r\nType           \t0\r\nInit           \tMutaliskDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMutaliskDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\timgol          \t59 0 0\t# ZergAirDeathSmall (thingy\\zAirDthS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 042 Overlord (zerg\\overlord.grp)\r\n.headerstart\r\nIsId           \t25\r\nType           \t12\r\nInit           \tOverlordInit\r\nDeath          \tOverlordDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tOverlordWalking\r\nWalkingToIdle  \tOverlordWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOverlordInit:\r\n\timgul          \t43 0 42\t# OverlordShad (zerg\\overlord.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nOverlordDeath:\r\n\tplaysnd        \t910\t# Zerg\\OVERLORD\\ZOvDth00.WAV\r\n\timgol          \t45 0 0\t# OverlordDeath (zerg\\zovDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nOverlordWalking:\r\n\tsetvertpos     \t0\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\nOverlordLocal00:\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tgoto           \tOverlordLocal00\r\n\r\nOverlordWalkingToIdle:\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tgoto           \tlong02\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 045 OverlordDeath (zerg\\zovDeath.grp)\r\n.headerstart\r\nIsId           \t26\r\nType           \t0\r\nInit           \tOverlordDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOverlordDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\timgol          \t58 0 0\t# ZergAirDeathLarge (thingy\\zAirDthL.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 046 Queen (zerg\\queen.grp)\r\n.headerstart\r\nIsId           \t27\r\nType           \t12\r\nInit           \tQueenInit\r\nDeath          \tQueenDeath\r\nGndAttkInit    \tQueenGndAttkInit\r\nAirAttkInit    \tQueenGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tQueenGndAttkInit\r\nAirAttkRpt     \tQueenGndAttkInit\r\nCastSpell      \tQueenCastSpell\r\nGndAttkToIdle  \tQueenGndAttkToIdle\r\nAirAttkToIdle  \tQueenGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tQueenWalking\r\nWalkingToIdle  \tQueenGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nQueenInit:\r\n\timgul          \t47 0 42\t# QueenShad (zerg\\queen.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twaitrand       \t1 4\r\nQueenGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tgoto           \tQueenGndAttkToIdle\r\n\r\nQueenDeath:\r\n\tplaysndbtwn    \t925 927\t# Zerg\\Queen\\ZQuDth00.WAV, Zerg\\Queen\\ZQuDth02.WAV\r\n\tsprol          \t156 0 0\t# QueenBirth (zerg\\zquDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nQueenGndAttkInit:\r\n\tsetvertpos     \t0\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tplaysnd        \t90\t# Bullet\\ZQuFir00.wav\r\n\tattackwith     \t1\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tgotorepeatattk \t\r\n\tgoto           \tQueenGndAttkToIdle\r\n\r\nQueenCastSpell:\r\n\tsetvertpos     \t0\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tQueenGndAttkToIdle\r\n\r\nQueenWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tgoto           \tQueenWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 048 QueenBirth (zerg\\zquDeath.grp)\r\n.headerstart\r\nIsId           \t28\r\nType           \t0\r\nInit           \tQueenDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nQueenDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\timgol          \t58 0 0\t# ZergAirDeathLarge (thingy\\zAirDthL.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 050 Ultralisk (zerg\\ultra.grp)\r\n.headerstart\r\nIsId           \t29\r\nType           \t12\r\nInit           \tUltraliskInit\r\nDeath          \tUltraliskDeath\r\nGndAttkInit    \tUltraliskGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tUltraliskGndAttkRpt\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tUltraliskGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tUltraliskWalking\r\nWalkingToIdle  \tUltraliskGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUltraliskInit:\r\n\timgul          \t51 0 0\t# UltraliskShad (zerg\\zulShad.grp)\r\nUltraliskGndAttkToIdle:\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tgoto           \tlong00\r\n\r\nUltraliskDeath:\r\n\tplaysnd        \t878\t# Zerg\\Ultra\\ZUlDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x100\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x101\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x102\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x103\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x104\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x105\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x106\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x107\t# frame set 15\r\n\twait           \t2\r\n\tplayfram       \t0x108\t# frame set 15\r\n\twait           \t2\r\n\tlowsprul       \t158 0 0\t# UltraliskDeath (zerg\\zulDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nUltraliskGndAttkInit:\r\n\tplayfram       \t0xee\t# frame set 14\r\nUltraliskGndAttkRpt:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplaysndrand    \t3 891 892 893\t# Zerg\\Ultra\\zulAtt00.WAV, Zerg\\Ultra\\zulAtt01.WAV, Zerg\\Ultra\\zulAtt02.WAV\r\n\twait           \t2\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tattackmelee    \t2 894 895\t# Zerg\\Ultra\\zulHit00.WAV, Zerg\\Ultra\\zulHit01.WAV\r\n\twait           \t2\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t2\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tUltraliskGndAttkToIdle\r\n\r\nUltraliskWalking:\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t3\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t7\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t7\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t7\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tgoto           \tUltraliskWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 053 UltraliskDeath (zerg\\zulDeath.grp)\r\n.headerstart\r\nIsId           \t30\r\nType           \t0\r\nInit           \tUltraliskRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUltraliskRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tplayfram       \t4\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 054 Zergling (zerg\\zergling.grp)\r\n.headerstart\r\nIsId           \t31\r\nType           \t26\r\nInit           \tZerglingInit\r\nDeath          \tZerglingDeath\r\nGndAttkInit    \tZerglingGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tZerglingGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tZerglingGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tZerglingWalking\r\nWalkingToIdle  \tZerglingGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tZerglingSpecialState2\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tZerglingBurrow\r\nUnBurrow       \tZerglingUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZerglingInit:\r\n\timgul          \t55 0 0\t# ZerglingShad (zerg\\zzeShad.grp)\r\nZerglingGndAttkToIdle:\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tgoto           \tlong00\r\n\r\nZerglingDeath:\r\n\tplaysnd        \t896\t# Zerg\\Zergling\\ZZeDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0x121\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x122\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x123\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x124\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x125\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x126\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x127\t# frame set 17\r\n\twait           \t2\r\n\tlowsprul       \t160 0 0\t# ZerglingDeath (zerg\\zzeDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nZerglingGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tattackmelee    \t1 894\t# Zerg\\Ultra\\zulHit00.WAV\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tZerglingGndAttkToIdle\r\n\r\nZerglingWalking:\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t9\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t7\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tgoto           \tZerglingWalking\r\n\r\nZerglingSpecialState2:\r\n\tplayfram       \t0x110\t# frame set 16\r\n\tgoto           \tlong00\r\n\r\nZerglingBurrow:\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nZerglingUnBurrow:\r\n\twaitrand       \t1 5\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tZerglingGndAttkToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 057 ZerglingDeath (zerg\\zzeDeath.grp)\r\n.headerstart\r\nIsId           \t32\r\nType           \t0\r\nInit           \tZerglingRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZerglingRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tplayfram       \t4\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 059 ZergAirDeathSmall (thingy\\zAirDthS.grp)\r\n# 058 ZergAirDeathLarge (thingy\\zAirDthL.grp)\r\n.headerstart\r\nIsId           \t33\r\nType           \t1\r\nInit           \tZergAirDeathExplosionInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergAirDeathExplosionInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 060 ZergBuildingDeath (thingy\\zBldDthS.grp)\r\n.headerstart\r\nIsId           \t34\r\nType           \t1\r\nInit           \tZergBuildingExplosionInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergBuildingExplosionInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 919 LurkerBirth (zerg\\zLubirth.grp)\r\n# 056 ZerglingBirth (zerg\\zzebirth.grp)\r\n# 052 UltraliskBirth (zerg\\zulbirth.grp)\r\n# 049 QueenDeath (zerg\\zquBirth.grp)\r\n# 044 OverlordBirth (zerg\\zovBirth.grp)\r\n# 040 MutaliskBirth (zerg\\zmubirth.grp)\r\n# 031 HydraliskBirth (zerg\\zhybirth.grp)\r\n# 019 DroneBirth (zerg\\zdrbirth.grp)\r\n# 015 DefilerBirth (zerg\\zdebirth.grp)\r\n# 002 ScourgeBirth (zerg\\zavBirth.grp)\r\n.headerstart\r\nIsId           \t36\r\nType           \t13\r\nInit           \tZergBirthInit\r\nDeath          \tZergBirthDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tZergBirthSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergBirthInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nZergBirthDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\nZergBirthSpecialState1:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tlowsprul       \t319 0 0\t# ZergEggSpawn (zerg\\zegspawn.grp)\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 023 ZergEggSpawn (zerg\\zegspawn.grp)\r\n.headerstart\r\nIsId           \t37\r\nType           \t0\r\nInit           \tEggSpawnInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEggSpawnInit:\r\n\tplayfram       \t0\r\n\twait           \t5\r\n\tplayfram       \t1\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 061 Cerebrate (zerg\\UCereb.grp)\r\n.headerstart\r\nIsId           \t38\r\nType           \t20\r\nInit           \tCerebrateInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tCerebrateAlmostBuilt\r\nBuilt          \tCerebrateBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tCerebrateIsWorking\r\nWorkingToIdle  \tCerebrateIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCerebrateInit:\r\n\timgul          \t62 0 0\t# CerabrateShad (zerg\\zucShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nCerebrateDeath:\r\n\tplaysnd        \t774\t# Zerg\\Bldg\\ZBldgDth.WAV\r\n\timgol          \t60 0 0\t# ZergBuildingDeath (thingy\\zBldDthS.grp)\r\n\twait           \t3\r\n\tlowsprul       \t186 0 0\t# ZergBuildingRubbleLarge (thingy\\ZRubbleS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nCerebrateAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nCerebrateBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 3\r\nCerebrateIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tgoto           \tCerebrateIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 063 InfestedCommandCenter (terran\\control.grp)\r\n.headerstart\r\nIsId           \t39\r\nType           \t20\r\nInit           \tInfestedCommandCenterInit\r\nDeath          \tInfestedCommandCenterDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tInfestedCommandCenterSpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tInfestedCommandCenterBuilt\r\nLanding        \tInfestedCommandCenterLanding\r\nLiftOff        \tInfestedCommandCenterLiftOff\r\nIsWorking      \tInfestedCommandCenterIsWorking\r\nWorkingToIdle  \tInfestedCommandCenterBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInfestedCommandCenterInit:\r\n\timgul          \t277 0 0\t# CommandCenterShad (terran\\tccShad.grp)\r\n\timgol          \t101 0 0\t# InfestedCommandCenterOverlay (zerg\\Infest03.grp)\r\nInfestedCommandCenterBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nInfestedCommandCenterDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t334 0 0\t# TerranBuildingExplosionlarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tliftoffcondjmp \tlong01\r\n\tlowsprul       \t274 0 0\t# TerranBuildingRubblelarge (thingy\\RubbleL.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nInfestedCommandCenterSpecialState1:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nInfestedCommandCenterLanding:\r\n\tnobrkcodestart \t\r\n\twait           \t18\r\n\tplaysnd        \t472\t# Misc\\Land.WAV\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t5\r\n\twait           \t5\r\n\tplayfram       \t0\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nInfestedCommandCenterLiftOff:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t471\t# Misc\\LiftOff.WAV\r\n\tplayfram       \t5\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nInfestedCommandCenterIsWorking:\r\n\timgol          \t276 0 0\t# CommandCenterOverlay (terran\\controlT.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 064 SpawningPool (zerg\\chrysal.grp)\r\n.headerstart\r\nIsId           \t40\r\nType           \t20\r\nInit           \tSpawningPoolInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tSpawningPoolAlmostBuilt\r\nBuilt          \tSpawningPoolBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tSpawningPoolIsWorking\r\nWorkingToIdle  \tSpawningPoolIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSpawningPoolInit:\r\n\tplayfram       \t0\r\n\timgul          \t65 0 0\t# SpawningPoolShad (zerg\\zchShad.grp)\r\n\tgoto           \tlong00\r\n\r\nSpawningPoolAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tSpawningPoolBuilt\r\n\r\nSpawningPoolBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 3\r\nSpawningPoolIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tSpawningPoolIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 066 EvolutionChamber (zerg\\cerebrat.grp)\r\n.headerstart\r\nIsId           \t41\r\nType           \t20\r\nInit           \tEvolutionChamberInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tEvolutionChamberAlmostBuilt\r\nBuilt          \tEvolutionChamberBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tEvolutionChamberIsWorking\r\nWorkingToIdle  \tEvolutionChamberIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEvolutionChamberInit:\r\n\timgul          \t67 0 0\t# EvolutinoChamberShad (zerg\\zceShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nEvolutionChamberAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nEvolutionChamberBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 3\r\nEvolutionChamberIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t3\r\n\tplayfram       \t2\r\n\twait           \t3\r\n\tplayfram       \t0\r\n\twait           \t3\r\n\tgoto           \tEvolutionChamberIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 068 CreepColony (zerg\\fcolony.grp)\r\n.headerstart\r\nIsId           \t42\r\nType           \t20\r\nInit           \tCreepColonyInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tCreepColonyAlmostBuilt\r\nBuilt          \tCreepColonyBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCreepColonyInit:\r\n\timgul          \t69 0 0\t# CreepColonyShad (zerg\\zfcShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nCreepColonyAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nCreepColonyBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 3\r\nCreepColonyLocal00:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tgoto           \tCreepColonyLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 070 Hatchery (zerg\\hatchery.grp)\r\n.headerstart\r\nIsId           \t43\r\nType           \t20\r\nInit           \tHatcheryInit\r\nDeath          \tlong03\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tHatcheryAlmostBuilt\r\nBuilt          \tHatcheryBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tHatcheryIsWorking\r\nWorkingToIdle  \tHatcheryIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHatcheryInit:\r\n\timgul          \t71 0 0\t# HatcheryShad (zerg\\zhaShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nHatcheryAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nHatcheryBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nHatcheryIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tHatcheryIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 072 Hive (Zerg\\Hive.grp)\r\n.headerstart\r\nIsId           \t44\r\nType           \t20\r\nInit           \tHiveInit\r\nDeath          \tlong03\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tHiveAlmostBuilt\r\nBuilt          \tHiveBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tHiveIsWorking\r\nWorkingToIdle  \tHiveIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHiveInit:\r\n\timgul          \t73 0 0\t# HiveShad (zerg\\zhiShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nHiveAlmostBuilt:\r\n\timgol          \t109 0 0\t# ZergBuildingSpawnLarge (zerg\\zSpawn03.grp)\r\nHiveBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nHiveIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tHiveIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 074 Lair (zerg\\Lair.grp)\r\n.headerstart\r\nIsId           \t45\r\nType           \t20\r\nInit           \tLairInit\r\nDeath          \tlong03\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tLairAlmostBuilt\r\nBuilt          \tLairBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tLairIsWorking\r\nWorkingToIdle  \tLairIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLairInit:\r\n\timgul          \t75 0 0\t# LairShad (zerg\\zlrShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nLairAlmostBuilt:\r\n\timgol          \t109 0 0\t# ZergBuildingSpawnLarge (zerg\\zSpawn03.grp)\r\nLairBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nLairIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tLairIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 076 SunkenColony (zerg\\Lurker.grp)\r\n.headerstart\r\nIsId           \t46\r\nType           \t20\r\nInit           \tSunkenColonyInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \tSunkenColonyGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tSunkenColonyGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tSunkenColonyGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tSunkenColonyAlmostBuilt\r\nBuilt          \tSunkenColonyBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tSunkenColonyIsWorking\r\nWorkingToIdle  \tSunkenColonyIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSunkenColonyInit:\r\n\tplayfram       \t0\r\n\timgul          \t77 0 0\t# SunkenColonyShad (zerg\\zluShad.grp)\r\n\tgoto           \tlong00\r\n\r\nSunkenColonyGndAttkInit:\r\n\ttrgtarccondjmp \t74 42 SunkenColonyLocal00\r\n\ttrgtarccondjmp \t159 42 SunkenColonyLocal01\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t78\t# Bullet\\ZLuFir00.wav\r\n\tplayfram       \t24\r\n\twait           \t1\r\n\tplayfram       \t25\r\n\twait           \t1\r\n\tplayfram       \t26\r\n\twait           \t1\r\n\tplayfram       \t27\r\n\twait           \t1\r\n\tplayfram       \t28\r\n\twait           \t1\r\n\tplayfram       \t29\r\n\twait           \t1\r\n\tplayfram       \t30\r\n\twait           \t1\r\n\tplayfram       \t31\r\n\twait           \t1\r\n\tplayfram       \t32\r\n\twait           \t1\r\n\tplayfram       \t33\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\twait           \t6\r\n\tplayfram       \t32\r\n\twait           \t1\r\n\tplayfram       \t31\r\n\twait           \t1\r\n\tplayfram       \t30\r\n\twait           \t1\r\n\tplayfram       \t29\r\n\twait           \t1\r\n\tplayfram       \t28\r\n\twait           \t1\r\n\tplayfram       \t27\r\n\twait           \t1\r\n\tplayfram       \t26\r\n\twait           \t1\r\n\tplayfram       \t25\r\n\twait           \t1\r\n\tplayfram       \t24\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nSunkenColonyGndAttkToIdle:\r\n\tgoto           \tSunkenColonyIsWorking\r\n\r\nSunkenColonyLocal00:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t78\t# Bullet\\ZLuFir00.wav\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\twait           \t6\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tSunkenColonyIsWorking\r\n\r\nSunkenColonyLocal01:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t78\t# Bullet\\ZLuFir00.wav\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tplayfram       \t15\r\n\twait           \t1\r\n\tplayfram       \t16\r\n\twait           \t1\r\n\tplayfram       \t17\r\n\twait           \t1\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tplayfram       \t19\r\n\twait           \t1\r\n\tplayfram       \t20\r\n\twait           \t1\r\n\tplayfram       \t21\r\n\twait           \t1\r\n\tplayfram       \t22\r\n\twait           \t1\r\n\tplayfram       \t23\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\twait           \t6\r\n\tplayfram       \t23\r\n\twait           \t1\r\n\tplayfram       \t22\r\n\twait           \t1\r\n\tplayfram       \t21\r\n\twait           \t1\r\n\tplayfram       \t20\r\n\twait           \t1\r\n\tplayfram       \t19\r\n\twait           \t1\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tplayfram       \t17\r\n\twait           \t1\r\n\tplayfram       \t16\r\n\twait           \t1\r\n\tplayfram       \t15\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tSunkenColonyIsWorking\r\n\r\nSunkenColonyAlmostBuilt:\r\n\timgol          \t107 0 0\t# ZergBuildingSpawnSmall (zerg\\zSpawn01.grp)\r\nSunkenColonyBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 2\r\nSunkenColonyIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tgoto           \tSunkenColonyIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 078 MatureChysalis (neutral\\kerrChry.grp)\r\n.headerstart\r\nIsId           \t47\r\nType           \t20\r\nInit           \tMatureChrysalisInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tMatureChrysalisAlmostBuilt\r\nBuilt          \tMatureChrysalisBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tMatureChrysalisIsWorking\r\nWorkingToIdle  \tMatureChrysalisIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMatureChrysalisInit:\r\n\tplayfram       \t0\r\n\timgul          \t79 0 0\t# MatureChysalisShad (neutral\\nkoShad.grp)\r\n\tgoto           \tlong00\r\n\r\nMatureChrysalisAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tMatureChrysalisBuilt\r\n\r\nMatureChrysalisBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 3\r\nMatureChrysalisIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tMatureChrysalisIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 080 GreaterSpire (zerg\\MutaCham.grp)\r\n.headerstart\r\nIsId           \t48\r\nType           \t20\r\nInit           \tGreaterSpireInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tGreaterSpireAlmostBuilt\r\nBuilt          \tGreaterSpireBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tGreaterSpireIsWorking\r\nWorkingToIdle  \tGreaterSpireIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGreaterSpireInit:\r\n\timgul          \t81 0 0\t# GreaterSpireShad (zerg\\zmcShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nGreaterSpireAlmostBuilt:\r\n\timgol          \t107 0 0\t# ZergBuildingSpawnSmall (zerg\\zSpawn01.grp)\r\nGreaterSpireBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nGreaterSpireIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tgoto           \tGreaterSpireIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 082 DefilerMound (zerg\\Mutapit.grp)\r\n.headerstart\r\nIsId           \t49\r\nType           \t20\r\nInit           \tDefilerMoundInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tDefilerMoundAlmostBuilt\r\nBuilt          \tDefilerMoundBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tDefilerMoundIsWorking\r\nWorkingToIdle  \tDefilerMoundIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDefilerMoundInit:\r\n\timgul          \t83 0 0\t# DefilerMoundShad (zerg\\zmhShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nDefilerMoundAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nDefilerMoundBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nDefilerMoundIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tgoto           \tDefilerMoundIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 084 QueensNest (zerg\\nest.grp)\r\n.headerstart\r\nIsId           \t50\r\nType           \t20\r\nInit           \tQueenNestInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tQueenNestAlmostBuilt\r\nBuilt          \tQueenNestBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tQueenNestIsWorking\r\nWorkingToIdle  \tQueenNestIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nQueenNestInit:\r\n\timgul          \t85 0 0\t# QueensNestShad (zerg\\zneShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nQueenNestAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nQueenNestBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nQueenNestIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t4\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tQueenNestIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 086 NydusCanal (zerg\\NydusPit.grp)\r\n.headerstart\r\nIsId           \t51\r\nType           \t20\r\nInit           \tNydusCanalInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tNydusCanalAlmostBuilt\r\nBuilt          \tNydusCanalBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tNydusCanalIsWorking\r\nWorkingToIdle  \tNydusCanalIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNydusCanalInit:\r\n\tplayfram       \t0\r\n\timgul          \t87 0 0\t# NydusCanalShad (zerg\\znyShad.grp)\r\n\tgoto           \tlong00\r\n\r\nNydusCanalAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nNydusCanalBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nNydusCanalIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tNydusCanalIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 088 Overmindwshell (zerg\\Over1.grp)\r\n.headerstart\r\nIsId           \t52\r\nType           \t20\r\nInit           \tOvermind_withShell_Init\r\nDeath          \tOvermind_withShell_Death\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tOvermind_withShell_AlmostBuilt\r\nBuilt          \tOvermind_withShell_Built\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tOvermind_withShell_IsWorking\r\nWorkingToIdle  \tOvermind_withShell_IsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOvermind_withShell_Init:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nOvermind_withShell_Death:\r\n\tplaysnd        \t774\t# Zerg\\Bldg\\ZBldgDth.WAV\r\n\timgol          \t60 0 0\t# ZergBuildingDeath (thingy\\zBldDthS.grp)\r\n\twait           \t3\r\n\timgol          \t89 0 0\t# OvermindShad (zerg\\Over2.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nOvermind_withShell_AlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tOvermind_withShell_Built\r\n\r\nOvermind_withShell_Built:\r\n\twaitrand       \t1 3\r\nOvermind_withShell_IsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\twait           \t1\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tOvermind_withShell_IsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 089 OvermindShad (zerg\\Over2.grp)\r\n.headerstart\r\nIsId           \t53\r\nType           \t1\r\nInit           \tOvermindRemnantsInit\r\nDeath          \tlong03\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOvermindRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t63\r\n\tgoto           \tlong03\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 090 Overmindwoutshell (zerg\\Over2.grp)\r\n.headerstart\r\nIsId           \t54\r\nType           \t20\r\nInit           \tOvermind_withoutShell_Init\r\nDeath          \tlong03\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tOvermind_withoutShell_AlmostBuilt\r\nBuilt          \tOvermind_withoutShell_Built\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tOvermind_withoutShell_IsWorking\r\nWorkingToIdle  \tOvermind_withoutShell_IsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOvermind_withoutShell_Init:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nOvermind_withoutShell_AlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tOvermind_withoutShell_Built\r\n\r\nOvermind_withoutShell_Built:\r\n\twaitrand       \t1 3\r\nOvermind_withoutShell_IsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\twait           \t1\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tOvermind_withoutShell_IsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 091 UltraliskCavern (zerg\\RCluster.grp)\r\n.headerstart\r\nIsId           \t55\r\nType           \t20\r\nInit           \tUltraliskCavernInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tUltraliskCavernAlmostBuilt\r\nBuilt          \tUltraliskCavernBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tUltraliskCavernIsWorking\r\nWorkingToIdle  \tUltraliskCavernIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUltraliskCavernInit:\r\n\timgul          \t92 0 0\t# UltraliskCavernShad (zerg\\zrcShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nUltraliskCavernAlmostBuilt:\r\n\timgol          \t107 0 0\t# ZergBuildingSpawnSmall (zerg\\zSpawn01.grp)\r\nUltraliskCavernBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 2\r\nUltraliskCavernIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t4\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tUltraliskCavernIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 093 Extractor (zerg\\Extract.grp)\r\n.headerstart\r\nIsId           \t56\r\nType           \t20\r\nInit           \tExtractorInit\r\nDeath          \tExtractorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tExtractorAlmostBuilt\r\nBuilt          \tExtractorBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tExtractorIsWorking\r\nWorkingToIdle  \tExtractorIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nExtractorInit:\r\n\timgul          \t94 0 0\t# ExtractorShad (zerg\\zreShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nExtractorDeath:\r\n\tplaysnd        \t774\t# Zerg\\Bldg\\ZBldgDth.WAV\r\n\tsprol          \t185 0 0\t# ZergBuildingDeath (thingy\\zBldDthS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nExtractorAlmostBuilt:\r\n\timgol          \t109 0 0\t# ZergBuildingSpawnLarge (zerg\\zSpawn03.grp)\r\nExtractorBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 5\r\nExtractorIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tcreategasoverlays\t0\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tgoto           \tExtractorIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 095 HydraliskDen (zerg\\Snakey.grp)\r\n.headerstart\r\nIsId           \t57\r\nType           \t20\r\nInit           \tHydraliskDenInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tHydraliskDenAlmostBuilt\r\nBuilt          \tHydraliskDenBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tHydraliskDenIsWorking\r\nWorkingToIdle  \tHydraliskDenIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHydraliskDenInit:\r\n\timgul          \t96 0 0\t# HydraliskDenShad (zerg\\zsbShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nHydraliskDenAlmostBuilt:\r\n\timgol          \t107 0 0\t# ZergBuildingSpawnSmall (zerg\\zSpawn01.grp)\r\nHydraliskDenBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 2\r\nHydraliskDenIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t4\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tHydraliskDenIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 097 Spire (zerg\\spire.grp)\r\n.headerstart\r\nIsId           \t58\r\nType           \t20\r\nInit           \tSpireInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tSpireAlmostBuilt\r\nBuilt          \tSpireBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tSpireIsWorking\r\nWorkingToIdle  \tSpireIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSpireInit:\r\n\timgul          \t98 0 0\t# SpireShad (zerg\\zspShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nSpireAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\nSpireBuilt:\r\n\tplayfram       \t0\r\n\twaitrand       \t1 3\r\nSpireIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t4\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tSpireIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 099 SporeColony (zerg\\SColony.grp)\r\n.headerstart\r\nIsId           \t59\r\nType           \t20\r\nInit           \tSporeColonyInit\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \tlong04\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \tlong04\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \tSporeColonyAirAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tSporeColonyAlmostBuilt\r\nBuilt          \tSporeColonyBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tSporeColonyAirAttkToIdle\r\nWorkingToIdle  \tSporeColonyAirAttkToIdle\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSporeColonyInit:\r\n\timgul          \t100 0 0\t# SporeColonyShad (zerg\\zscShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nSporeColonyAlmostBuilt:\r\n\timgol          \t108 0 0\t# ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\n\tplayfram       \t0\r\nSporeColonyBuilt:\r\n\twaitrand       \t1 3\r\nSporeColonyAirAttkToIdle:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tSporeColonyAirAttkToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 101 InfestedCommandCenterOverlay (zerg\\Infest03.grp)\r\n.headerstart\r\nIsId           \t60\r\nType           \t1\r\nInit           \tInfestedCommandCenterOverlayInit\r\nDeath          \tInfestedCommandCenterOverlayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInfestedCommandCenterOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tgoto           \tInfestedCommandCenterOverlayInit\r\n\r\nInfestedCommandCenterOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 105 ZergBuildingMorph4 (zerg\\ZBuild.grp)\r\n.headerstart\r\nIsId           \t61\r\nType           \t15\r\nInit           \tZergConstruction_Small_Init\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tZergConstruction_Small_SpecialState1\r\nSpecialState2  \tZergConstruction_Small_SpecialState1\r\nAlmostBuilt    \tZergConstruction_Small_AlmostBuilt\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergConstruction_Small_Init:\r\n\timgul          \t106 0 0\t# ZergBuildingMorphShad (zerg\\ZBShad.grp)\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nZergConstruction_Small_SpecialState1:\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tZergConstruction_Small_SpecialState1\r\n\r\nZergConstruction_Small_AlmostBuilt:\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 104 ZergBuildingMorph3 (zerg\\ZBuild.grp)\r\n.headerstart\r\nIsId           \t62\r\nType           \t15\r\nInit           \tZergConstruction_Medium_Init\r\nDeath          \tCerebrateDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tZergConstruction_Medium_SpecialState1\r\nSpecialState2  \tZergConstruction_Medium_SpecialState1\r\nAlmostBuilt    \tZergConstruction_Medium_AlmostBuilt\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergConstruction_Medium_Init:\r\n\timgul          \t106 0 0\t# ZergBuildingMorphShad (zerg\\ZBShad.grp)\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nZergConstruction_Medium_Local00:\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tZergConstruction_Medium_Local00\r\n\r\nZergConstruction_Medium_SpecialState1:\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tgoto           \tZergConstruction_Medium_SpecialState1\r\n\r\nZergConstruction_Medium_AlmostBuilt:\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tplayfram       \t20\r\n\twait           \t2\r\n\tplayfram       \t21\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 103 ZergBuildingMorph2 (zerg\\ZBuild.grp)\r\n.headerstart\r\nIsId           \t63\r\nType           \t15\r\nInit           \tZergBuildingMorphInit\r\nDeath          \tlong03\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tZergBuildingMorphSpecialState1\r\nSpecialState2  \tZergBuildingMorphSpecialState2\r\nAlmostBuilt    \tZergBuildingMorphAlmostBuilt\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergBuildingMorphInit:\r\n\timgul          \t106 0 0\t# ZergBuildingMorphShad (zerg\\ZBShad.grp)\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nZergBuildingMorphLocal00:\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tZergBuildingMorphLocal00\r\n\r\nZergBuildingMorphSpecialState1:\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tgoto           \tZergBuildingMorphSpecialState1\r\n\r\nZergBuildingMorphSpecialState2:\r\n\tplayfram       \t22\r\n\twait           \t2\r\n\tplayfram       \t23\r\n\twait           \t2\r\n\tplayfram       \t24\r\n\twait           \t2\r\n\tplayfram       \t25\r\n\twait           \t2\r\n\tplayfram       \t26\r\n\twait           \t2\r\n\tplayfram       \t27\r\n\twait           \t2\r\n\tplayfram       \t26\r\n\twait           \t2\r\n\tplayfram       \t25\r\n\twait           \t2\r\n\tplayfram       \t24\r\n\twait           \t2\r\n\tplayfram       \t23\r\n\twait           \t2\r\n\tgoto           \tZergBuildingMorphSpecialState2\r\n\r\nZergBuildingMorphAlmostBuilt:\r\n\tplayfram       \t28\r\n\twait           \t2\r\n\tplayfram       \t29\r\n\twait           \t2\r\n\tplayfram       \t30\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 102 ZergBuildingMorph1 (zerg\\ZBuild.grp)\r\n.headerstart\r\nIsId           \t64\r\nType           \t15\r\nInit           \tZergConstruction_Large_Init\r\nDeath          \tZergConstruction_Large_Death\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tZergBuildingMorphSpecialState2\r\nSpecialState2  \tZergBuildingMorphSpecialState2\r\nAlmostBuilt    \tZergBuildingMorphAlmostBuilt\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergConstruction_Large_Init:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tZergBuildingMorphSpecialState2\r\n\r\nZergConstruction_Large_Death:\r\n\tplaysnd        \t774\t# Zerg\\Bldg\\ZBldgDth.WAV\r\n\tsprol          \t185 0 0\t# ZergBuildingDeath (thingy\\zBldDthS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 109 ZergBuildingSpawnLarge (zerg\\zSpawn03.grp)\r\n# 108 ZergBuildingSpawnMedium (zerg\\zSpawn02.grp)\r\n# 107 ZergBuildingSpawnSmall (zerg\\zSpawn01.grp)\r\n.headerstart\r\nIsId           \t65\r\nType           \t1\r\nInit           \tZergBuildingSpawnInit\r\nDeath          \tZergBuildingSpawnDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergBuildingSpawnInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tend            \t\r\n\r\nZergBuildingSpawnDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 218 Battlecruiser (terran\\BattleCr.grp)\r\n.headerstart\r\nIsId           \t66\r\nType           \t12\r\nInit           \tBattlecruiserInit\r\nDeath          \tBattlecruiserDeath\r\nGndAttkInit    \tBattlecruiserGndAttkInit\r\nAirAttkInit    \tBattlecruiserAirAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tBattlecruiserGndAttkInit\r\nAirAttkRpt     \tBattlecruiserAirAttkInit\r\nCastSpell      \tBattlecruiserCastSpell\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \tlong00\r\nUnused2        \t[NONE]\r\nWalking        \tBattlecruiserWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBattlecruiserInit:\r\n\timgul          \t219 0 42\t# BattlecruiserShad (terran\\BattleCr.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nBattlecruiserDeath:\r\n\tplaysnd        \t177\t# Terran\\BATTLE\\tbaDth00.wav\r\n\timgol          \t333 0 0\t# TerranBuildingExplosionmedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nBattlecruiserGndAttkInit:\r\n\timgol          \t446 0 0\t# BCLaserFireOverlay (thingy\\elbBat.grp)\r\n\tgoto           \tlong05\r\n\r\nBattlecruiserAirAttkInit:\r\n\timgol          \t446 0 0\t# BCLaserFireOverlay (thingy\\elbBat.grp)\r\n\tgoto           \tlong04\r\n\r\nBattlecruiserCastSpell:\r\n\timgolorig      \t543\t# Unknown543 (thingy\\eycBlast.grp)\r\n\tgoto           \tlong00\r\n\r\nBattlecruiserWalking:\r\n\timgol          \t220 0 0\t# BattlecruiserGlow (thingy\\tbaGlow.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 221 Civilian (neutral\\civilian.grp)\r\n.headerstart\r\nIsId           \t67\r\nType           \t12\r\nInit           \tCivilianInit\r\nDeath          \tCivilianDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tCivilianWalking\r\nWalkingToIdle  \tCivilianWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCivilianInit:\r\n\timgul          \t222 0 0\t# CivilianShad (neutral\\nciShad.grp)\r\nCivilianWalkingToIdle:\r\n\tplayfram       \t0x77\t# frame set 7\r\nCivilianLocal01:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t128 CivilianLocal00\r\n\tgoto           \tCivilianLocal01\r\n\r\nCivilianLocal00:\r\n\tturnrand       \t3\r\n\tgoto           \tCivilianWalkingToIdle\r\n\r\nCivilianDeath:\r\n\tplaysndbtwn    \t276 277\t# Terran\\MARINE\\TMaDth00.WAV, Terran\\MARINE\\TMaDth01.WAV\r\n\timgol          \t242 0 0\t# Unknown242 (terran\\marine.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nCivilianWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tgoto           \tCivilianWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 223 Dropship (terran\\dropship.grp)\r\n.headerstart\r\nIsId           \t68\r\nType           \t12\r\nInit           \tDropshipInit\r\nDeath          \tDropshipDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tDropshipWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDropshipInit:\r\n\timgul          \t224 0 42\t# DropshipShad (terran\\dropship.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nDropshipDeath:\r\n\tplaysnd        \t210\t# Terran\\DROPSHIP\\TDrDth00.wav\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nDropshipWalking:\r\n\timgol          \t225 0 0\t# DropshipGlow (thingy\\tdrGlow.grp)\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 226 Firebat (terran\\firebat.grp)\r\n.headerstart\r\nIsId           \t69\r\nType           \t12\r\nInit           \tFirebatInit\r\nDeath          \tFirebatDeath\r\nGndAttkInit    \tFirebatGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tFirebatGndAttkRpt\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tFirebatGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tFirebatWalking\r\nWalkingToIdle  \tFirebatWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFirebatInit:\r\n\timgul          \t227 0 0\t# FirebatShad (terran\\tfbShad.grp)\r\nFirebatWalkingToIdle:\r\n\tplayfram       \t0x22\t# frame set 2\r\nFirebatLocal02:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t25 FirebatLocal00\r\n\trandcondjmp    \t128 FirebatLocal01\r\n\tgoto           \tFirebatLocal02\r\n\r\nFirebatLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\trandcondjmp    \t192 FirebatLocal03\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tgoto           \tFirebatWalkingToIdle\r\n\r\nFirebatLocal01:\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tturnrand       \t3\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tgoto           \tFirebatWalkingToIdle\r\n\r\nFirebatLocal03:\r\n\twait           \t13\r\n\tgoto           \tFirebatWalkingToIdle\r\n\r\nFirebatDeath:\r\n\tplaysndbtwn    \t296 298\t# Terran\\Firebat\\TFBDth00.WAV, Terran\\Firebat\\TFBDth02.WAV\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nFirebatGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\nFirebatGndAttkRpt:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\timgol          \t421 0 0\t# FlameThrower (thingy\\flamer.grp)\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tattkshiftproj  \t24\r\n\twait           \t1\r\n\tattkshiftproj  \t52\r\n\twait           \t1\r\n\tattkshiftproj  \t80\r\n\twait           \t5\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tignorerest     \t\r\nFirebatGndAttkToIdle:\r\n\tgoto           \tFirebatWalkingToIdle\r\n\r\nFirebatWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tgoto           \tFirebatWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 228 Ghost (terran\\ghost.grp)\r\n.headerstart\r\nIsId           \t70\r\nType           \t13\r\nInit           \tGhostInit\r\nDeath          \tGhostDeath\r\nGndAttkInit    \tGhostGndAttkInit\r\nAirAttkInit    \tGhostGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tGhostGndAttkRpt\r\nAirAttkRpt     \tGhostGndAttkRpt\r\nCastSpell      \tGhostCastSpell\r\nGndAttkToIdle  \tGhostGndAttkToIdle\r\nAirAttkToIdle  \tGhostGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tGhostWalking\r\nWalkingToIdle  \tGhostWalkingToIdle\r\nSpecialState1  \tGhostSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGhostInit:\r\n\timgul          \t229 0 0\t# GhostShad (terran\\tghShad.grp)\r\nGhostWalkingToIdle:\r\n\tplayfram       \t0x33\t# frame set 3\r\nGhostLocal02:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t25 GhostLocal00\r\n\trandcondjmp    \t128 GhostLocal01\r\n\tgoto           \tGhostLocal02\r\n\r\nGhostLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\trandcondjmp    \t192 GhostLocal03\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tgoto           \tGhostLocal04\r\n\r\nGhostLocal01:\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tturnrand       \t3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tgoto           \tGhostWalkingToIdle\r\n\r\nGhostLocal03:\r\n\twait           \t13\r\nGhostLocal04:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tGhostWalkingToIdle\r\n\r\nGhostDeath:\r\n\tplaysnd        \t238\t# Terran\\GHOST\\TGhDth00.wav\r\nGhostDeathInit:\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xde\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xdf\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe0\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe1\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe2\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe3\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe4\t# frame set 13\r\n\twait           \t2\r\n\tlowsprul       \t230 0 0\t# GhostDeath (terran\\tghDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nGhostGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\nGhostGndAttkRpt:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t98\t# Bullet\\TGhFir00.wav\r\n\tattack         \t\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nGhostGndAttkToIdle:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tGhostWalkingToIdle\r\n\r\nGhostCastSpell:\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplaysnd        \t240\t# Terran\\GHOST\\TGhLkd00.wav\r\n\tcastspell      \t\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tsigorder       \t2\r\n\tgoto           \tGhostGndAttkToIdle\r\n\r\nGhostWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tgoto           \tGhostWalking\r\n\r\nGhostSpecialState1:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 230 GhostDeath (terran\\tghDeath.grp)\r\n.headerstart\r\nIsId           \t71\r\nType           \t0\r\nInit           \tGhostRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGhostRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 231 Unknown231 (terran\\ghost.grp)\r\n.headerstart\r\nIsId           \t72\r\nType           \t1\r\nInit           \tGhostDeathInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 232 NukeBeam (thingy\\NukeBeam.grp)\r\n.headerstart\r\nIsId           \t73\r\nType           \t12\r\nInit           \tNukeBeamInit\r\nDeath          \tNukeBeamDeath\r\nGndAttkInit    \tNukeBeamDeath\r\nAirAttkInit    \tNukeBeamDeath\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tNukeBeamDeath\r\nAirAttkRpt     \tNukeBeamDeath\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tNukeBeamDeath\r\nAirAttkToIdle  \tNukeBeamDeath\r\nUnused2        \t[NONE]\r\nWalking        \tNukeBeamDeath\r\nWalkingToIdle  \tNukeBeamDeath\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNukeBeamInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tgoto           \tNukeBeamInit\r\n\r\nNukeBeamDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 233 NukeTarget (thingy\\NukeTarg.grp)\r\n.headerstart\r\nIsId           \t74\r\nType           \t1\r\nInit           \tNukeTargetDotInit\r\nDeath          \tNukeTargetDotDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNukeTargetDotInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tgoto           \tNukeTargetDotInit\r\n\r\nNukeTargetDotDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 234 GoliathBase (terran\\goliath.grp)\r\n.headerstart\r\nIsId           \t75\r\nType           \t23\r\nInit           \tGoliath_Base_Init\r\nDeath          \tGoliath_Base_Death\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tGoliath_Base_Walking\r\nWalkingToIdle  \tGoliath_Base_WalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tGoliath_Base_StarEditInit\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGoliath_Base_StarEditInit:\r\n\timgol          \t235 0 0\t# GoliathTurret (terran\\goliathT.grp)\r\nGoliath_Base_Init:\r\n\timgul          \t236 0 0\t# GoliathShad (terran\\tgoShad.grp)\r\nGoliath_Base_WalkingToIdle:\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tgoto           \tlong00\r\n\r\nGoliath_Base_Death:\r\n\tplaysnd        \t8\t# Misc\\ExploMed.wav\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nGoliath_Base_Walking:\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t3\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t3\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t3\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tgoto           \tGoliath_Base_Walking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 235 GoliathTurret (terran\\goliathT.grp)\r\n.headerstart\r\nIsId           \t76\r\nType           \t12\r\nInit           \tGoliath_Turret_Init\r\nDeath          \tlong01\r\nGndAttkInit    \tGoliath_Turret_GndAttkInit\r\nAirAttkInit    \tGoliath_Turret_AirAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tGoliath_Turret_GndAttkInit\r\nAirAttkRpt     \tGoliath_Turret_AirAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tGoliath_Turret_Init\r\nAirAttkToIdle  \tGoliath_Turret_Init\r\nUnused2        \t[NONE]\r\nWalking        \tGoliath_Turret_Walking\r\nWalkingToIdle  \tGoliath_Turret_Init\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGoliath_Turret_Init:\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tgoto           \tlong00\r\n\r\nGoliath_Turret_GndAttkInit:\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tplaysnd        \t70\t# Bullet\\TGoFir00.wav\r\n\tattackwith     \t1\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tgotorepeatattk \t\r\n\tgoto           \tGoliath_Turret_Init\r\n\r\nGoliath_Turret_AirAttkInit:\r\n\twait           \t1\r\n\tattackwith     \t2\r\n\tgotorepeatattk \t\r\n\tgoto           \tGoliath_Turret_Init\r\n\r\nGoliath_Turret_Walking:\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tgoto           \tGoliath_Turret_Walking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 237 KerriganGhost (terran\\ughost.grp)\r\n.headerstart\r\nIsId           \t77\r\nType           \t13\r\nInit           \tSarahKerriganInit\r\nDeath          \tSarahKerriganDeath\r\nGndAttkInit    \tSarahKerriganGndAttkInit\r\nAirAttkInit    \tSarahKerriganGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tSarahKerriganGndAttkRpt\r\nAirAttkRpt     \tSarahKerriganGndAttkRpt\r\nCastSpell      \tSarahKerriganCastSpell\r\nGndAttkToIdle  \tSarahKerriganGndAttkToIdle\r\nAirAttkToIdle  \tSarahKerriganGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tSarahKerriganWalking\r\nWalkingToIdle  \tSarahKerriganWalkingToIdle\r\nSpecialState1  \tSarahKerriganSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSarahKerriganInit:\r\n\timgul          \t238 0 0\t# KerriganGhostShad (terran\\ughShad.grp)\r\nSarahKerriganWalkingToIdle:\r\n\tplayfram       \t0x33\t# frame set 3\r\nSarahKerriganLocal02:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t25 SarahKerriganLocal00\r\n\trandcondjmp    \t128 SarahKerriganLocal01\r\n\tgoto           \tSarahKerriganLocal02\r\n\r\nSarahKerriganLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\trandcondjmp    \t192 SarahKerriganLocal03\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tgoto           \tSarahKerriganLocal04\r\n\r\nSarahKerriganLocal01:\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tturnrand       \t3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tgoto           \tSarahKerriganWalkingToIdle\r\n\r\nSarahKerriganLocal03:\r\n\twait           \t13\r\nSarahKerriganLocal04:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tSarahKerriganWalkingToIdle\r\n\r\nSarahKerriganDeath:\r\n\tplaysnd        \t470\t# Terran\\KERRIGAN\\UKeDth00.wav\r\n\timgol          \t231 0 0\t# Unknown231 (terran\\ghost.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nSarahKerriganGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\nSarahKerriganGndAttkRpt:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t98\t# Bullet\\TGhFir00.wav\r\n\tattack         \t\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nSarahKerriganGndAttkToIdle:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tSarahKerriganWalkingToIdle\r\n\r\nSarahKerriganCastSpell:\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplaysnd        \t240\t# Terran\\GHOST\\TGhLkd00.wav\r\n\tcastspell      \t\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tsigorder       \t2\r\n\tgoto           \tSarahKerriganGndAttkToIdle\r\n\r\nSarahKerriganWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tgoto           \tSarahKerriganWalking\r\n\r\nSarahKerriganSpecialState1:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 239 Marine (terran\\marine.grp)\r\n.headerstart\r\nIsId           \t78\r\nType           \t12\r\nInit           \tMarineInit\r\nDeath          \tMarineDeath\r\nGndAttkInit    \tMarineGndAttkInit\r\nAirAttkInit    \tMarineGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tMarineGndAttkRpt\r\nAirAttkRpt     \tMarineGndAttkRpt\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tMarineGndAttkToIdle\r\nAirAttkToIdle  \tMarineGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tMarineWalking\r\nWalkingToIdle  \tMarineWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMarineInit:\r\n\timgul          \t240 0 0\t# MarineShad (terran\\tmaShad.grp)\r\nMarineWalkingToIdle:\r\n\tplayfram       \t0x44\t# frame set 4\r\nMarineLocal02:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t25 MarineLocal00\r\n\trandcondjmp    \t128 MarineLocal01\r\n\tgoto           \tMarineLocal02\r\n\r\nMarineLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\trandcondjmp    \t192 MarineLocal03\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\tturncwise      \t2\r\n\twait           \t3\r\n\twait           \t6\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tturnccwise     \t2\r\n\twait           \t3\r\n\tgoto           \tMarineLocal04\r\n\r\nMarineLocal01:\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tturnrand       \t3\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tgoto           \tMarineWalkingToIdle\r\n\r\nMarineLocal03:\r\n\twait           \t13\r\nMarineLocal04:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tMarineWalkingToIdle\r\n\r\nMarineDeath:\r\n\tplaysndbtwn    \t276 277\t# Terran\\MARINE\\TMaDth00.WAV, Terran\\MARINE\\TMaDth01.WAV\r\nMarineDeathInit:\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xde\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xdf\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe0\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe1\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe2\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe3\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe4\t# frame set 13\r\n\twait           \t2\r\n\tlowsprul       \t236 0 0\t# MarineDeath (terran\\tmaDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nMarineGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\nMarineGndAttkRpt:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t69\t# Bullet\\TMaFir00.wav\r\n\tattackwith     \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nMarineGndAttkToIdle:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tMarineWalkingToIdle\r\n\r\nMarineWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tgoto           \tMarineWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 241 MarineDeath (terran\\tmaDeath.grp)\r\n.headerstart\r\nIsId           \t79\r\nType           \t0\r\nInit           \tMarineRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMarineRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 242 Unknown242 (terran\\marine.grp)\r\n.headerstart\r\nIsId           \t80\r\nType           \t1\r\nInit           \tMarineDeathInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 246 Unknown246 (terran\\marine.grp)\r\n.headerstart\r\nIsId           \t81\r\nType           \t1\r\nInit           \tScannerSweepInit\r\nDeath          \tScannerSweepDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScannerSweepInit:\r\n\tsprol          \t380 0 0\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t6\r\n\tsprol          \t380 32 32\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t2\r\n\tsprol          \t380 48 5\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t5\r\n\tsprol          \t380 32 224\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t2\r\n\tsprol          \t380 251 208\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t2\r\n\tsprol          \t380 224 224\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t5\r\n\tsprol          \t380 208 254\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t3\r\n\tsprol          \t380 224 32\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t5\r\n\tsprol          \t380 3 48\t# Unknown546 (thingy\\eveCast.grp)\r\n\twait           \t63\r\n\twait           \t63\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nScannerSweepDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 243 Wraith (terran\\phoenix.grp)\r\n.headerstart\r\nIsId           \t82\r\nType           \t12\r\nInit           \tWraithInit\r\nDeath          \tWraithDeath\r\nGndAttkInit    \tlong05\r\nAirAttkInit    \tlong04\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong05\r\nAirAttkRpt     \tlong04\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong02\r\nAirAttkToIdle  \tlong02\r\nUnused2        \t[NONE]\r\nWalking        \tWraithWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWraithInit:\r\n\timgul          \t244 0 42\t# WraithShad (terran\\phoenix.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nWraithDeath:\r\n\tplaysnd        \t257\t# Terran\\PHOENIX\\TPhDth00.WAV\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nWraithWalking:\r\n\timgol          \t245 0 0\t# WraithGlow (thingy\\tphGlow.grp)\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 245 WraithGlow (thingy\\tphGlow.grp)\r\n.headerstart\r\nIsId           \t83\r\nType           \t12\r\nInit           \tWraithAfterburnersInit\r\nDeath          \tlong01\r\nGndAttkInit    \tlong01\r\nAirAttkInit    \tlong01\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong01\r\nAirAttkToIdle  \tlong01\r\nUnused2        \t[NONE]\r\nWalking        \tWraithAfterburnersInit\r\nWalkingToIdle  \tlong01\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWraithAfterburnersInit:\r\n\twait           \t1\r\n\tengframe       \t0\r\n\twait           \t1\r\n\tengframe       \t17\r\n\tgoto           \tWraithAfterburnersInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 247 SCV (terran\\SCV.grp)\r\n.headerstart\r\nIsId           \t84\r\nType           \t15\r\nInit           \tSCVInit\r\nDeath          \tSCVDeath\r\nGndAttkInit    \tSCVGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tSCVGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tSCVGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tSCVWalking\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tSCVAlmostBuilt\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSCVInit:\r\n\timgul          \t248 0 7\t# SCVShad (terran\\SCV.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nSCVDeath:\r\n\tplaysnd        \t369\t# Terran\\SCV\\TSCDth00.WAV\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nSCVGndAttkInit:\r\n\tsetvertpos     \t0\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tattackwith     \t1\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nSCVGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nSCVWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\timgol          \t249 0 0\t# SCVGlow (thingy\\tscGlow.grp)\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\nSCVAlmostBuilt:\r\n\tsetvertpos     \t0\r\n\twait           \t1\r\nSCVLocal00:\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tuseweapon      \t14\t# Fusion Cutter\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twaitrand       \t8 10\r\n\tgoto           \tSCVLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 256 Vulture (terran\\Vulture.grp)\r\n.headerstart\r\nIsId           \t86\r\nType           \t13\r\nInit           \tVultureInit\r\nDeath          \tVultureDeath\r\nGndAttkInit    \tlong05\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong05\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tVultureSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nVultureInit:\r\n\timgul          \t257 0 7\t# VultureShad (terran\\Vulture.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nVultureDeath:\r\n\tplaysnd        \t353\t# Terran\\VULTURE\\TVuDth00.WAV\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nVultureSpecialState1:\r\n\tattackwith     \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 258 SpiderMine (terran\\Spider.grp)\r\n.headerstart\r\nIsId           \t87\r\nType           \t26\r\nInit           \tSpiderMineInit\r\nDeath          \tSpiderMineDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tSpiderMineWalking\r\nWalkingToIdle  \tSpiderMineWalkingToIdle\r\nSpecialState1  \tSpiderMineSpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tSpiderMineBurrow\r\nUnBurrow       \tSpiderMineUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSpiderMineInit:\r\n\timgul          \t259 0 0\t# SpiderMineShad (terran\\tsmShad.grp)\r\nSpiderMineWalkingToIdle:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nSpiderMineDeath:\r\n\timgol          \t429 0 0\t# Spidermineexplosion (thingy\\tmnExplo.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nSpiderMineWalking:\r\n\tplaysnd        \t355\t# Terran\\VULTURE\\TVuMin00.WAV\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\tmove           \t16\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\tgoto           \tSpiderMineWalking\r\n\r\nSpiderMineSpecialState1:\r\n\tcastspell      \t\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nSpiderMineBurrow:\r\n\tnobrkcodestart \t\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplaysnd        \t354\t# Terran\\VULTURE\\TVuMin01.WAV\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nSpiderMineUnBurrow:\r\n\tnobrkcodestart \t\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplaysnd        \t354\t# Terran\\VULTURE\\TVuMin01.WAV\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\tsigorder       \t4\r\n\tnobrkcodeend   \t\r\n\tgoto           \tSpiderMineWalkingToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 260 ScienceVessel (terran\\wessel.grp)\r\n.headerstart\r\nIsId           \t88\r\nType           \t12\r\nInit           \tScienceVessel_Base_Init\r\nDeath          \tScienceVessel_Base_Death\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tScienceVessel_Base_CastSpell\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScienceVessel_Base_Init:\r\n\timgol          \t261 0 0\t# ScienceVesselTurret (terran\\wesselt.grp)\r\n\timgul          \t262 0 42\t# ScienceVesselShad (terran\\tveShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nScienceVessel_Base_Death:\r\n\tplaysnd        \t348\t# Terran\\VESSEL\\TVeDth00.WAV\r\n\timgol          \t333 0 0\t# TerranBuildingExplosionmedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nScienceVessel_Base_CastSpell:\r\n\timgol          \t539 0 0\t# Unknown539 (thingy\\tveGlowO.grp)\r\n\tnobrkcodestart \t\r\n\twait           \t3\r\n\tcastspell      \t\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tsigorder       \t2\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 261 ScienceVesselTurret (terran\\wesselt.grp)\r\n.headerstart\r\nIsId           \t89\r\nType           \t12\r\nInit           \tScienceVessel_Turret_Init\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tlong00\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScienceVessel_Turret_Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 250 SiegeTankTankBase (terran\\tank.grp)\r\n.headerstart\r\nIsId           \t90\r\nType           \t23\r\nInit           \tSiegeTank_Tank_BaseInit\r\nDeath          \tSiegeTank_Tank_BaseDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tSiegeTank_Tank_BaseWalking\r\nWalkingToIdle  \tSiegeTank_Tank_BaseWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tSiegeTank_Tank_BaseStarEditInit\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSiegeTank_Tank_BaseStarEditInit:\r\n\tsetfldirect    \t12\r\n\timgoluselo     \t251 2 0\t# SiegeTankTankTurret (terran\\tankt.grp)\r\nSiegeTank_Tank_BaseInit:\r\n\twait           \t1\r\n\timgul          \t252 0 0\t# SiegeTankTankShad (terran\\ttaShad.grp)\r\n\tsetfldirect    \t12\r\nSiegeTank_Tank_BaseWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nSiegeTank_Tank_BaseDeath:\r\n\tplaysnd        \t317\t# Terran\\TANK\\TTaDth00.WAV\r\n\timgol          \t333 0 0\t# TerranBuildingExplosionmedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nSiegeTank_Tank_BaseWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tgoto           \tSiegeTank_Tank_BaseWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 251 SiegeTankTankTurret (terran\\tankt.grp)\r\n.headerstart\r\nIsId           \t91\r\nType           \t13\r\nInit           \tSiegeTank_Tank_TurretInit\r\nDeath          \tlong01\r\nGndAttkInit    \tSiegeTank_Tank_TurretGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tSiegeTank_Tank_TurretGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSiegeTank_Tank_TurretInit:\r\n\twait           \t1\r\n\tsetfldirect    \t12\r\n\tgoto           \tlong00\r\n\r\nSiegeTank_Tank_TurretGndAttkInit:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t68\t# Bullet\\TTaFir00.wav\r\n\timgol          \t536 0 0\t# Unknown536 (thingy\\ettFlash.grp)\r\n\twait           \t2\r\n\tattackwith     \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 253 SiegeTankSiegeBase (terran\\stank.grp)\r\n.headerstart\r\nIsId           \t92\r\nType           \t23\r\nInit           \tSiegeTank_Siege_BaseInit\r\nDeath          \tSiegeTank_Siege_BaseDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tSiegeTank_Siege_BaseSpecialState2\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tSiegeTank_Siege_BaseStarEditInit\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSiegeTank_Siege_BaseStarEditInit:\r\n\timgoluselo     \t254 2 0\t# SiegeTankSiegeTurret (terran\\stankt.grp)\r\nSiegeTank_Siege_BaseInit:\r\n\timgul          \t255 0 0\t# SiegeTankSiegeShad (terran\\tstShad.grp)\r\n\twait           \t1\r\n\tsetflspeed     \t0\r\n\tplaysnd        \t319\t# Terran\\TANK\\TTaTra01.WAV\r\n\tplayfram       \t0\r\n\twait           \t5\r\n\tplayfram       \t1\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t5\r\n\twait           \t38\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nSiegeTank_Siege_BaseDeath:\r\n\tplaysnd        \t317\t# Terran\\TANK\\TTaDth00.WAV\r\n\timgol          \t333 0 0\t# TerranBuildingExplosionmedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nSiegeTank_Siege_BaseSpecialState2:\r\n\twait           \t38\r\n\tplaysnd        \t319\t# Terran\\TANK\\TTaTra01.WAV\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t1\r\n\twait           \t5\r\n\tplayfram       \t0\r\n\twait           \t5\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 254 SiegeTankSiegeTurret (terran\\stankt.grp)\r\n.headerstart\r\nIsId           \t93\r\nType           \t14\r\nInit           \tSiegeTank_Siege_TurretInit\r\nDeath          \tlong01\r\nGndAttkInit    \tSiegeTank_Siege_TurretGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tSiegeTank_Siege_TurretGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tlong00\r\nSpecialState2  \tSiegeTank_Siege_TurretSpecialState2\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSiegeTank_Siege_TurretInit:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\twait           \t38\r\n\tplaysnd        \t318\t# Terran\\TANK\\TTaTra00.WAV\r\n\twait           \t3\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t3\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t3\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t3\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t3\r\n\tsetfldirect    \t28\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nSiegeTank_Siege_TurretGndAttkInit:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t96\t# Bullet\\TTaFi200.wav\r\n\timgoluselo     \t537 2 0\t# Unknown537 (thingy\\esiFire.grp)\r\n\twait           \t2\r\n\tattackwith     \t1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tlong00\r\n\r\nSiegeTank_Siege_TurretSpecialState2:\r\n\tsetfldirect    \t12\r\n\tplaysnd        \t318\t# Terran\\TANK\\TTaTra00.WAV\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t3\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t3\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t3\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t3\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 263 Academy (terran\\Academy.grp)\r\n.headerstart\r\nIsId           \t94\r\nType           \t20\r\nInit           \tAcademyInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tAcademyAlmostBuilt\r\nBuilt          \tAcademyBuilt\r\nLanding        \tlong00\r\nLiftOff        \tlong00\r\nIsWorking      \tAcademyIsWorking\r\nWorkingToIdle  \tAcademyBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcademyInit:\r\n\tplayfram       \t0\r\n\timgul          \t265 0 0\t# AcademyShad (terran\\tacShad.grp)\r\n\tgoto           \tlong00\r\n\r\nAcademyDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t334 0 0\t# TerranBuildingExplosionlarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tliftoffcondjmp \tlong01\r\n\tlowsprul       \t273 0 0\t# TerranBuildingRubblesmall (thingy\\RubbleS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nAcademyAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nAcademyBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nAcademyIsWorking:\r\n\timgol          \t264 0 0\t# AcademyOverlay (terran\\AcademyT.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 264 AcademyOverlay (terran\\AcademyT.grp)\r\n.headerstart\r\nIsId           \t95\r\nType           \t24\r\nInit           \tAcademyOverlayInit\r\nDeath          \tAcademyOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tAcademyOverlayDeath\r\nLiftOff        \tAcademyOverlayDeath\r\nIsWorking      \tAcademyOverlayIsWorking\r\nWorkingToIdle  \tAcademyOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tAcademyOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcademyOverlayInit:\r\n\tplayfram       \t0\r\nAcademyOverlayIsWorking:\r\n\twait           \t2\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t2 5\r\n\ttmprmgraphicend\t\r\n\tgoto           \tAcademyOverlayIsWorking\r\n\r\nAcademyOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 266 Barracks (terran\\TBarrack.grp)\r\n.headerstart\r\nIsId           \t96\r\nType           \t24\r\nInit           \tBarracksInit\r\nDeath          \tInfestedCommandCenterDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tBarracksSpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tBarracksAlmostBuilt\r\nBuilt          \tBarracksBuilt\r\nLanding        \tBarracksLanding\r\nLiftOff        \tBarracksLiftOff\r\nIsWorking      \tBarracksIsWorking\r\nWorkingToIdle  \tBarracksBuilt\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tBarracksDisable\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBarracksInit:\r\n\tplayfram       \t0\r\n\timgul          \t267 0 0\t# BarracksShad (terran\\tbrShad.grp)\r\n\tgoto           \tlong00\r\n\r\nBarracksSpecialState1:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nBarracksAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nBarracksBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nBarracksLanding:\r\n\tnobrkcodestart \t\r\n\twait           \t15\r\n\tplaysnd        \t472\t# Misc\\Land.WAV\r\n\tplayfram       \t4\r\n\twait           \t8\r\n\tplayfram       \t3\r\n\twait           \t8\r\n\tplayfram       \t2\r\n\twait           \t8\r\n\tplayfram       \t5\r\n\twait           \t8\r\n\tplayfram       \t0\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nBarracksLiftOff:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t471\t# Misc\\LiftOff.WAV\r\n\tplayfram       \t5\r\n\twait           \t8\r\n\tplayfram       \t2\r\n\twait           \t8\r\n\tplayfram       \t3\r\n\twait           \t8\r\n\tplayfram       \t4\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nBarracksIsWorking:\r\n\tplayfram       \t7\r\n\twait           \t4\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t4\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tgoto           \tBarracksIsWorking\r\n\r\nBarracksDisable:\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 268 Armory (terran\\chemlab.grp)\r\n.headerstart\r\nIsId           \t97\r\nType           \t20\r\nInit           \tArmoryInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tArmoryAlmostBuilt\r\nBuilt          \tArmoryBuilt\r\nLanding        \tlong00\r\nLiftOff        \tlong00\r\nIsWorking      \tArmoryIsWorking\r\nWorkingToIdle  \tArmoryBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArmoryInit:\r\n\timgul          \t270 0 0\t# ArmoryShad (terran\\tclShad.grp)\r\nArmoryBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nArmoryAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nArmoryIsWorking:\r\n\timgol          \t269 0 0\t# ArmoryOverlay (terran\\chemlabT.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 269 ArmoryOverlay (terran\\chemlabT.grp)\r\n.headerstart\r\nIsId           \t98\r\nType           \t24\r\nInit           \tArmoryOverlayInit\r\nDeath          \tArmoryOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tArmoryOverlayDeath\r\nLiftOff        \tArmoryOverlayDeath\r\nIsWorking      \tArmoryOverlayInit\r\nWorkingToIdle  \tArmoryOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tArmoryOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArmoryOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t3\r\n\tplayfram       \t1\r\n\twait           \t3\r\n\tplayfram       \t2\r\n\twait           \t3\r\n\tgoto           \tArmoryOverlayInit\r\n\r\nArmoryOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 271 ComsatStation (terran\\ComSat.grp)\r\n.headerstart\r\nIsId           \t99\r\nType           \t20\r\nInit           \tComsatStationInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tComsatStationAlmostBuilt\r\nBuilt          \tComsatStationBuilt\r\nLanding        \tComsatStationLanding\r\nLiftOff        \tlong00\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tComsatStationWorkingToIdle\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nComsatStationInit:\r\n\tplayfram       \t0\r\n\timgul          \t274 0 0\t# ComsatStationShad (terran\\tcsShad.grp)\r\n\tgoto           \tlong00\r\n\r\nComsatStationAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nComsatStationBuilt:\r\n\timgol          \t273 0 0\t# ComsatStationOverlay (terran\\ComSatT.grp)\r\nComsatStationWorkingToIdle:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nComsatStationLanding:\r\n\timgol          \t272 0 0\t# ComsatStationAttachment (terran\\ComSatC.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 272 ComsatStationAttachment (terran\\ComSatC.grp)\r\n.headerstart\r\nIsId           \t100\r\nType           \t24\r\nInit           \tComsatConnectorInit\r\nDeath          \tComsatConnectorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tComsatConnectorDeath\r\nLiftOff        \tComsatConnectorLiftOff\r\nIsWorking      \tComsatConnectorIsWorking\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nComsatConnectorInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\nComsatConnectorIsWorking:\r\n\tplayfram       \t3\r\n\tgoto           \tlong00\r\n\r\nComsatConnectorLiftOff:\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\nComsatConnectorDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 273 ComsatStationOverlay (terran\\ComSatT.grp)\r\n.headerstart\r\nIsId           \t101\r\nType           \t24\r\nInit           \tComsatOverlayInit\r\nDeath          \tComsatOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tComsatOverlayLanding\r\nLiftOff        \tlong00\r\nIsWorking      \tComsatOverlayIsWorking\r\nWorkingToIdle  \tComsatOverlayIsWorking\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nComsatOverlayInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nComsatOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\nComsatOverlayLanding:\r\n\twait           \t13\r\nComsatOverlayIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tgoto           \tComsatOverlayIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 275 CommandCenter (terran\\control.grp)\r\n.headerstart\r\nIsId           \t102\r\nType           \t20\r\nInit           \tCommandCenterInit\r\nDeath          \tInfestedCommandCenterDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tCommandCenterSpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tCommandCenterAlmostBuilt\r\nBuilt          \tCommandCenterBuilt\r\nLanding        \tCommandCenterLanding\r\nLiftOff        \tCommandCenterLiftOff\r\nIsWorking      \tCommandCenterIsWorking\r\nWorkingToIdle  \tCommandCenterBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCommandCenterInit:\r\n\timgul          \t277 0 0\t# CommandCenterShad (terran\\tccShad.grp)\r\nCommandCenterBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nCommandCenterSpecialState1:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nCommandCenterAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nCommandCenterLanding:\r\n\tnobrkcodestart \t\r\n\twait           \t18\r\n\tplaysnd        \t472\t# Misc\\Land.WAV\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t5\r\n\twait           \t5\r\n\tplayfram       \t0\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nCommandCenterLiftOff:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t471\t# Misc\\LiftOff.WAV\r\n\tplayfram       \t5\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nCommandCenterIsWorking:\r\n\timgol          \t276 0 0\t# CommandCenterOverlay (terran\\controlT.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 276 CommandCenterOverlay (terran\\controlT.grp)\r\n.headerstart\r\nIsId           \t103\r\nType           \t24\r\nInit           \tCommandCenterOverlayInit\r\nDeath          \tCommandCenterOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tCommandCenterOverlayDeath\r\nWalkingToIdle  \tCommandCenterOverlayDeath\r\nSpecialState1  \tCommandCenterOverlayDeath\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tCommandCenterOverlayDeath\r\nLiftOff        \tCommandCenterOverlayDeath\r\nIsWorking      \tCommandCenterOverlayInit\r\nWorkingToIdle  \tCommandCenterOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tCommandCenterOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCommandCenterOverlayInit:\r\n\tplayfram       \t0\r\n\ttmprmgraphicend\t\r\n\twait           \t4\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t3\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t3\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t4\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t3\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t3\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t4\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t3\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\tgoto           \tCommandCenterOverlayInit\r\n\r\nCommandCenterOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 299 CrashedNoradII (neutral\\Cbattle.grp)\r\n.headerstart\r\nIsId           \t104\r\nType           \t20\r\nInit           \tCrashedBattlecruiserInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tCrashedBattlecruiserBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCrashedBattlecruiserInit:\r\n\timgul          \t300 0 0\t# CrashedNoradIIShad (neutral\\cbaShad.grp)\r\nCrashedBattlecruiserBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 278 SupplyDepot (terran\\Depot.grp)\r\n.headerstart\r\nIsId           \t105\r\nType           \t24\r\nInit           \tSupplyDepotInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tSupplyDepotAlmostBuilt\r\nBuilt          \tSupplyDepotBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tSupplyDepotWorkingToIdle\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tSupplyDepotDisable\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSupplyDepotInit:\r\n\timgul          \t280 0 0\t# SupplyDepotShad (terran\\tdeShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nSupplyDepotAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nSupplyDepotBuilt:\r\n\timgol          \t279 0 0\t# SupplyDepotOverlay (terran\\DepotT.grp)\r\nSupplyDepotWorkingToIdle:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nSupplyDepotDisable:\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 279 SupplyDepotOverlay (terran\\DepotT.grp)\r\n.headerstart\r\nIsId           \t106\r\nType           \t24\r\nInit           \tSupplyDepotOverlayInit\r\nDeath          \tSupplyDepotOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tSupplyDepotOverlayInit\r\nWorkingToIdle  \tSupplyDepotOverlayInit\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSupplyDepotOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tSupplyDepotOverlayInit\r\n\r\nSupplyDepotOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 281 ControlTower (terran\\DryDocks.grp)\r\n.headerstart\r\nIsId           \t107\r\nType           \t24\r\nInit           \tControlTowerInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tControlTowerAlmostBuilt\r\nBuilt          \tControlTowerBuilt\r\nLanding        \tControlTowerLanding\r\nLiftOff        \tlong00\r\nIsWorking      \tControlTowerIsWorking\r\nWorkingToIdle  \tControlTowerBuilt\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tControlTowerDisable\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nControlTowerInit:\r\n\timgul          \t284 0 0\t# ControlTowerShad (terran\\tddShad.grp)\r\nControlTowerBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nControlTowerAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nControlTowerLanding:\r\n\timgol          \t282 0 0\t# ControlTowerAttachment (terran\\DryDockC.grp)\r\n\tgoto           \tlong00\r\n\r\nControlTowerIsWorking:\r\n\timgol          \t283 0 0\t# ControlTowerOverlay (terran\\DryDockT.grp)\r\n\tgoto           \tlong00\r\n\r\nControlTowerDisable:\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 282 ControlTowerAttachment (terran\\DryDockC.grp)\r\n.headerstart\r\nIsId           \t108\r\nType           \t24\r\nInit           \tControlTowerConnectorInit\r\nDeath          \tControlTowerConnectorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tControlTowerConnectorDeath\r\nLiftOff        \tControlTowerConnectorLiftOff\r\nIsWorking      \tControlTowerConnectorIsWorking\r\nWorkingToIdle  \tControlTowerConnectorIsWorking\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nControlTowerConnectorInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nControlTowerConnectorIsWorking:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nControlTowerConnectorLiftOff:\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\nControlTowerConnectorDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 283 ControlTowerOverlay (terran\\DryDockT.grp)\r\n.headerstart\r\nIsId           \t109\r\nType           \t24\r\nInit           \tControlTowerOverlayInit\r\nDeath          \tControlTowerOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tControlTowerOverlayDeath\r\nLiftOff        \tControlTowerOverlayDeath\r\nIsWorking      \tControlTowerOverlayIsWorking\r\nWorkingToIdle  \tControlTowerOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tControlTowerOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nControlTowerOverlayInit:\r\n\tplayfram       \t0\r\nControlTowerOverlayIsWorking:\r\n\ttmprmgraphicend\t\r\n\twait           \t5\r\n\ttmprmgraphicstart\t\r\n\twait           \t5\r\n\tgoto           \tControlTowerOverlayIsWorking\r\n\r\nControlTowerOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 285 Factory (terran\\factory.grp)\r\n.headerstart\r\nIsId           \t111\r\nType           \t24\r\nInit           \tFactoryInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tFactorySpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tFactoryAlmostBuilt\r\nBuilt          \tFactoryBuilt\r\nLanding        \tFactoryLanding\r\nLiftOff        \tFactoryLiftOff\r\nIsWorking      \tFactoryIsWorking\r\nWorkingToIdle  \tFactoryBuilt\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tFactoryDisable\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFactoryInit:\r\n\tplayfram       \t0\r\n\timgul          \t287 0 0\t# FactoryShad (terran\\tfaShad.grp)\r\n\tgoto           \tlong00\r\n\r\nFactorySpecialState1:\r\n\tplayfram       \t5\r\n\tgoto           \tlong00\r\n\r\nFactoryAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nFactoryBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nFactoryLanding:\r\n\tnobrkcodestart \t\r\n\twait           \t15\r\n\tplaysnd        \t472\t# Misc\\Land.WAV\r\n\tplayfram       \t5\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t6\r\n\twait           \t5\r\n\tplayfram       \t0\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nFactoryLiftOff:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t471\t# Misc\\LiftOff.WAV\r\n\tplayfram       \t6\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t5\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nFactoryIsWorking:\r\n\timgol          \t286 0 0\t# FactoryOverlay (terran\\factoryT.grp)\r\n\tgoto           \tlong00\r\n\r\nFactoryDisable:\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 286 FactoryOverlay (terran\\factoryT.grp)\r\n.headerstart\r\nIsId           \t112\r\nType           \t24\r\nInit           \tFactoryOverlayInit\r\nDeath          \tFactoryOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tFactoryOverlayDeath\r\nWalkingToIdle  \tFactoryOverlayDeath\r\nSpecialState1  \tFactoryOverlayDeath\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tFactoryOverlayDeath\r\nLiftOff        \tFactoryOverlayDeath\r\nIsWorking      \tFactoryOverlayInit\r\nWorkingToIdle  \tFactoryOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tFactoryOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFactoryOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t5\r\n\tplayfram       \t1\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tgoto           \tFactoryOverlayInit\r\n\r\nFactoryOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 288 CovertOps (terran\\GeneLab.grp)\r\n.headerstart\r\nIsId           \t113\r\nType           \t20\r\nInit           \tCovertOpsInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tCovertOpsAlmostBuilt\r\nBuilt          \tCovertOpsBuilt\r\nLanding        \tCovertOpsLanding\r\nLiftOff        \tlong00\r\nIsWorking      \tCovertOpsIsWorking\r\nWorkingToIdle  \tCovertOpsBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCovertOpsInit:\r\n\timgul          \t291 0 0\t# CovertOpsShad (terran\\tglShad.grp)\r\nCovertOpsBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nCovertOpsAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nCovertOpsLanding:\r\n\timgol          \t289 0 0\t# CovertOpsAttachment (terran\\GeneLabC.grp)\r\n\tgoto           \tlong00\r\n\r\nCovertOpsIsWorking:\r\n\timgol          \t290 0 0\t# CovertOpsOverlay (terran\\GeneLabT.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 289 CovertOpsAttachment (terran\\GeneLabC.grp)\r\n.headerstart\r\nIsId           \t114\r\nType           \t24\r\nInit           \tCovertOpsConnectorInit\r\nDeath          \tCovertOpsConnectorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tCovertOpsConnectorDeath\r\nLiftOff        \tCovertOpsConnectorLiftOff\r\nIsWorking      \tCovertOpsConnectorIsWorking\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCovertOpsConnectorInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nCovertOpsConnectorIsWorking:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nCovertOpsConnectorLiftOff:\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\nCovertOpsConnectorDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 290 CovertOpsOverlay (terran\\GeneLabT.grp)\r\n.headerstart\r\nIsId           \t115\r\nType           \t24\r\nInit           \tCovertOpsOverlayInit\r\nDeath          \tCovertOpsOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tCovertOpsOverlayDeath\r\nLiftOff        \tCovertOpsOverlayDeath\r\nIsWorking      \tCovertOpsOverlayIsWorking\r\nWorkingToIdle  \tCovertOpsOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tCovertOpsOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCovertOpsOverlayInit:\r\n\tplayfram       \t0\r\nCovertOpsOverlayIsWorking:\r\n\ttmprmgraphicend\t\r\n\twait           \t5\r\n\ttmprmgraphicstart\t\r\n\twait           \t5\r\n\tgoto           \tCovertOpsOverlayIsWorking\r\n\r\nCovertOpsOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 292 IonCannon (neutral\\ion.grp)\r\n.headerstart\r\nIsId           \t116\r\nType           \t20\r\nInit           \tIonCannonInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tIonCannonInit\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nIonCannonInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 293 MachineShop (terran\\machines.grp)\r\n.headerstart\r\nIsId           \t117\r\nType           \t24\r\nInit           \tMachineShopInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tMachineShopAlmostBuilt\r\nBuilt          \tMachineShopBuilt\r\nLanding        \tMachineShopLanding\r\nLiftOff        \tlong00\r\nIsWorking      \tMachineShopIsWorking\r\nWorkingToIdle  \tMachineShopBuilt\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tMachineShopDisable\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMachineShopInit:\r\n\tplayfram       \t0\r\n\timgul          \t295 0 0\t# MachineShopShad (terran\\tmsShad.grp)\r\n\tgoto           \tlong00\r\n\r\nMachineShopAlmostBuilt:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nMachineShopBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nMachineShopLanding:\r\n\timgol          \t294 0 0\t# MachineShopAttachment (terran\\machineC.grp)\r\n\tgoto           \tlong00\r\n\r\nMachineShopIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tgoto           \tMachineShopIsWorking\r\n\r\nMachineShopDisable:\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 294 MachineShopAttachment (terran\\machineC.grp)\r\n.headerstart\r\nIsId           \t118\r\nType           \t24\r\nInit           \tMachineShopConnectorInit\r\nDeath          \tMachineShopConnectorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tMachineShopConnectorDeath\r\nLiftOff        \tMachineShopConnectorLiftOff\r\nIsWorking      \tMachineShopConnectorIsWorking\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMachineShopConnectorInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\nMachineShopConnectorIsWorking:\r\n\tplayfram       \t3\r\n\tgoto           \tlong00\r\n\r\nMachineShopConnectorLiftOff:\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\nMachineShopConnectorDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 296 MissleTurretBase (terran\\missile.grp)\r\n.headerstart\r\nIsId           \t119\r\nType           \t20\r\nInit           \tMissileTurret_Base_Init\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \tlong00\r\nAirAttkInit    \tlong00\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong00\r\nAirAttkRpt     \tlong00\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \tlong00\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tMissileTurret_Base_AlmostBuilt\r\nBuilt          \tMissileTurret_Base_Built\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tMissileTurret_Base_WorkingToIdle\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMissileTurret_Base_Init:\r\n\tplayfram       \t2\r\n\timgul          \t298 0 0\t# MissleTurretShad (terran\\tmiShad.grp)\r\n\tgoto           \tlong00\r\n\r\nMissileTurret_Base_AlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nMissileTurret_Base_Built:\r\n\timgol          \t297 0 0\t# MissleTurretTurret (terran\\missileT.grp)\r\nMissileTurret_Base_WorkingToIdle:\r\n\tplayfram       \t2\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 297 MissleTurretTurret (terran\\missileT.grp)\r\n.headerstart\r\nIsId           \t120\r\nType           \t24\r\nInit           \tMissileTurret_Turret_Init\r\nDeath          \tMissileTurret_Turret_Death\r\nGndAttkInit    \tMissileTurret_Turret_GndAttkInit\r\nAirAttkInit    \tMissileTurret_Turret_GndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tMissileTurret_Turret_GndAttkInit\r\nAirAttkRpt     \tMissileTurret_Turret_GndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tMissileTurret_Turret_GndAttkToIdle\r\nAirAttkToIdle  \tMissileTurret_Turret_GndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tlong00\r\nBuilt          \tMissileTurret_Turret_Built\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tMissileTurret_Turret_Built\r\nWorkingToIdle  \tMissileTurret_Turret_Built\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMissileTurret_Turret_Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\nMissileTurret_Turret_Built:\r\n\twait           \t1\r\n\tturn1cwise     \t\r\n\tgoto           \tMissileTurret_Turret_Built\r\n\r\nMissileTurret_Turret_Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\nMissileTurret_Turret_GndAttkInit:\r\n\twait           \t1\r\n\tattack         \t\r\n\tgotorepeatattk \t\r\n\tsigorder       \t1\r\n\twait           \t13\r\n\tignorerest     \t\r\nMissileTurret_Turret_GndAttkToIdle:\r\n\tgoto           \tMissileTurret_Turret_Built\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 301 PhysicsLab (terran\\physics.grp)\r\n.headerstart\r\nIsId           \t121\r\nType           \t20\r\nInit           \tPhysicsLabInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tPhysicsLabAlmostBuilt\r\nBuilt          \tPhysicsLabBuilt\r\nLanding        \tPhysicsLabLanding\r\nLiftOff        \tPhysicsLabBuilt\r\nIsWorking      \tPhysicsLabIsWorking\r\nWorkingToIdle  \tPhysicsLabBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPhysicsLabInit:\r\n\timgul          \t303 0 0\t# PhysicsLabShad (terran\\tplShad.grp)\r\nPhysicsLabBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nPhysicsLabAlmostBuilt:\r\n\tplayfram       \t6\r\n\tgoto           \tlong00\r\n\r\nPhysicsLabLanding:\r\n\timgol          \t302 0 0\t# PhysicsLabAttachment (terran\\physicsC.grp)\r\n\tgoto           \tlong00\r\n\r\nPhysicsLabIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t3\r\n\tplayfram       \t2\r\n\twait           \t3\r\n\tplayfram       \t3\r\n\twait           \t3\r\n\tplayfram       \t4\r\n\twait           \t3\r\n\tplayfram       \t0\r\n\twait           \t3\r\n\tgoto           \tPhysicsLabIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 302 PhysicsLabAttachment (terran\\physicsC.grp)\r\n.headerstart\r\nIsId           \t122\r\nType           \t24\r\nInit           \tPhysicsLabConnectorInit\r\nDeath          \tPhysicsLabConnectorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tPhysicsLabConnectorDeath\r\nLiftOff        \tPhysicsLabConnectorLiftOff\r\nIsWorking      \tPhysicsLabConnectorIsWorking\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPhysicsLabConnectorInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nPhysicsLabConnectorIsWorking:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nPhysicsLabConnectorLiftOff:\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\nPhysicsLabConnectorDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 304 Bunker (terran\\PillBox.grp)\r\n.headerstart\r\nIsId           \t123\r\nType           \t24\r\nInit           \tBunkerInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tBunkerAlmostBuilt\r\nBuilt          \tBunkerBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBunkerInit:\r\n\timgul          \t305 0 0\t# BunkerShad (terran\\tpbShad.grp)\r\nBunkerBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nBunkerAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 306 BunkerOverlay (terran\\PillBoxT.grp)\r\n.headerstart\r\nIsId           \t124\r\nType           \t0\r\nInit           \tBunkerOverlayInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBunkerOverlayInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\ttmprmgraphicstart\t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 307 Refinery (terran\\refinery.grp)\r\n.headerstart\r\nIsId           \t125\r\nType           \t20\r\nInit           \tRefineryInit\r\nDeath          \tRefineryDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tRefinerySpecialState1\r\nSpecialState2  \tRefinerySpecialState2\r\nAlmostBuilt    \tRefineryAlmostBuilt\r\nBuilt          \tRefineryBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tRefineryBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRefineryInit:\r\n\timgul          \t308 0 0\t# RefineryShad (terran\\treShad.grp)\r\n\tplayfram       \t1\r\nRefineryLocal00:\r\n\twait           \t5\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t0\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t1\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t0\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t1\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\tgoto           \tRefineryLocal00\r\n\r\nRefineryDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\tsprol          \t272 0 0\t# TerranBuildingExplosionlarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nRefinerySpecialState1:\r\n\tplayfram       \t2\r\n\tgoto           \tRefineryLocal00\r\n\r\nRefinerySpecialState2:\r\n\tplayfram       \t3\r\n\tgoto           \tRefineryLocal00\r\n\r\nRefineryAlmostBuilt:\r\n\tplayfram       \t4\r\n\tgoto           \tRefineryLocal00\r\n\r\nRefineryBuilt:\r\n\tplayfram       \t0\r\n\twait           \t5\r\nRefineryLocal01:\r\n\tcreategasoverlays\t0\r\n\twait           \t20\r\n\twaitrand       \t5 100\r\n\tgoto           \tRefineryLocal01\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 309 ScienceFacility (terran\\research.grp)\r\n.headerstart\r\nIsId           \t126\r\nType           \t20\r\nInit           \tScienceFacilityInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tScienceFacilitySpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tScienceFacilityAlmostBuilt\r\nBuilt          \tScienceFacilityBuilt\r\nLanding        \tScienceFacilityLanding\r\nLiftOff        \tScienceFacilityLiftOff\r\nIsWorking      \tScienceFacilityIsWorking\r\nWorkingToIdle  \tScienceFacilityBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScienceFacilityInit:\r\n\timgul          \t311 0 0\t# ScienceFacilityShad (terran\\trlShad.grp)\r\nScienceFacilityBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nScienceFacilitySpecialState1:\r\n\tplayfram       \t5\r\n\tgoto           \tlong00\r\n\r\nScienceFacilityAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nScienceFacilityLanding:\r\n\tnobrkcodestart \t\r\n\twait           \t18\r\n\tplaysnd        \t472\t# Misc\\Land.WAV\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t0\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nScienceFacilityLiftOff:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t471\t# Misc\\LiftOff.WAV\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t5\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nScienceFacilityIsWorking:\r\n\timgol          \t310 0 0\t# ScienceFacilityOverlay (terran\\ResearcT.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 310 ScienceFacilityOverlay (terran\\ResearcT.grp)\r\n.headerstart\r\nIsId           \t127\r\nType           \t24\r\nInit           \tScienceFacilityOverlayInit\r\nDeath          \tScienceFacilityOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tScienceFacilityOverlayDeath\r\nWalkingToIdle  \tScienceFacilityOverlayDeath\r\nSpecialState1  \tScienceFacilityOverlayDeath\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tScienceFacilityOverlayDeath\r\nLiftOff        \tScienceFacilityOverlayDeath\r\nIsWorking      \tScienceFacilityOverlayIsWorking\r\nWorkingToIdle  \tScienceFacilityOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tScienceFacilityOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScienceFacilityOverlayInit:\r\n\tplayfram       \t0\r\nScienceFacilityOverlayIsWorking:\r\n\ttmprmgraphicend\t\r\n\twait           \t5\r\n\ttmprmgraphicstart\t\r\n\twait           \t5\r\n\tgoto           \tScienceFacilityOverlayIsWorking\r\n\r\nScienceFacilityOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 312 NukeSilo (terran\\nukesilo.grp)\r\n.headerstart\r\nIsId           \t128\r\nType           \t24\r\nInit           \tNuclearSiloInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tNuclearSiloAlmostBuilt\r\nBuilt          \tNuclearSiloBuilt\r\nLanding        \tNuclearSiloLanding\r\nLiftOff        \tlong00\r\nIsWorking      \tNuclearSiloIsWorking\r\nWorkingToIdle  \tNuclearSiloBuilt\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tNuclearSiloDisable\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNuclearSiloInit:\r\n\timgul          \t315 0 0\t# NukeSiloShad (terran\\tnsShad.grp)\r\nNuclearSiloBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nNuclearSiloAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nNuclearSiloLanding:\r\n\timgol          \t313 0 0\t# NukeSiloAttachment (terran\\NukeSilC.grp)\r\n\tgoto           \tlong00\r\n\r\nNuclearSiloIsWorking:\r\n\timgol          \t314 0 0\t# NukeSiloOverlay (terran\\NukeSilT.grp)\r\n\tgoto           \tlong00\r\n\r\nNuclearSiloDisable:\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 313 NukeSiloAttachment (terran\\NukeSilC.grp)\r\n.headerstart\r\nIsId           \t129\r\nType           \t24\r\nInit           \tNuclearSiloConnectorInit\r\nDeath          \tNuclearSiloConnectorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tNuclearSiloConnectorDeath\r\nLiftOff        \tNuclearSiloConnectorLiftOff\r\nIsWorking      \tNuclearSiloConnectorIsWorking\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNuclearSiloConnectorInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nNuclearSiloConnectorIsWorking:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nNuclearSiloConnectorLiftOff:\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\nNuclearSiloConnectorDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 314 NukeSiloOverlay (terran\\NukeSilT.grp)\r\n.headerstart\r\nIsId           \t130\r\nType           \t24\r\nInit           \tNuclearSiloOverlayInit\r\nDeath          \tNuclearSiloOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tNuclearSiloOverlayDeath\r\nLiftOff        \tNuclearSiloOverlayDeath\r\nIsWorking      \tNuclearSiloOverlayIsWorking\r\nWorkingToIdle  \tNuclearSiloOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tNuclearSiloOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNuclearSiloOverlayInit:\r\n\tplayfram       \t0\r\nNuclearSiloOverlayIsWorking:\r\n\ttmprmgraphicend\t\r\n\twait           \t5\r\n\ttmprmgraphicstart\t\r\n\twait           \t5\r\n\tgoto           \tNuclearSiloOverlayIsWorking\r\n\r\nNuclearSiloOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 316 NuclearMissile (terran\\nukemiss.grp)\r\n.headerstart\r\nIsId           \t131\r\nType           \t21\r\nInit           \tNuclearMissileInit\r\nDeath          \tNuclearMissileDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tNuclearMissileWalking\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tNuclearMissileSpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tNuclearMissileWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNuclearMissileInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nNuclearMissileDeath:\r\n\timgol          \t428 0 0\t# Smallexplosion (thingy\\small.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nNuclearMissileWalking:\r\n\tcurdirectcondjmp\t128 32 NuclearMissileLocal00\r\nNuclearMissileLocal01:\r\n\tsprol          \t309 0 10\t# MissleTrail (thingy\\smoke.grp)\r\n\twait           \t3\r\n\tgoto           \tNuclearMissileLocal01\r\n\r\nNuclearMissileLocal00:\r\n\twait           \t3\r\n\tsprol          \t309 0 246\t# MissleTrail (thingy\\smoke.grp)\r\n\tgoto           \tNuclearMissileLocal00\r\n\r\nNuclearMissileSpecialState1:\r\n\tcastspell      \t\r\n\tsigorder       \t1\r\n\ttmprmgraphicstart\t\r\n\timgol          \t428 0 0\t# Smallexplosion (thingy\\small.grp)\r\n\tsprol          \t267 0 214\t# NuclearExplosion (thingy\\NukeHit.grp)\r\n\tgoto           \tlong00\r\n\r\nNuclearMissileWarpIn:\r\n\twait           \t125\r\n\twait           \t125\r\n\tsigorder       \t2\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 318 NuclearExplosion (thingy\\NukeHit.grp)\r\n.headerstart\r\nIsId           \t133\r\nType           \t1\r\nInit           \tNukeExplosionInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNukeExplosionInit:\r\n\tplaysnd        \t85\t# Bullet\\TNsHit00.wav\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplaysnd        \t13\t# Misc\\Explo4.wav\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplaysnd        \t13\t# Misc\\Explo4.wav\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplaysnd        \t13\t# Misc\\Explo4.wav\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twait           \t2\r\n\tplaysnd        \t13\t# Misc\\Explo4.wav\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tplayfram       \t20\r\n\twait           \t2\r\n\tplayfram       \t21\r\n\twait           \t2\r\n\tplayfram       \t22\r\n\twait           \t2\r\n\tplayfram       \t23\r\n\twait           \t2\r\n\tplayfram       \t24\r\n\twait           \t2\r\n\tplayfram       \t25\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 319 Starport (terran\\starport.grp)\r\n.headerstart\r\nIsId           \t134\r\nType           \t20\r\nInit           \tStarportInit\r\nDeath          \tInfestedCommandCenterDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tStarportSpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tStarportAlmostBuilt\r\nBuilt          \tStarportBuilt\r\nLanding        \tStarportLanding\r\nLiftOff        \tStarportLiftOff\r\nIsWorking      \tStarportIsWorking\r\nWorkingToIdle  \tStarportBuilt\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStarportInit:\r\n\timgul          \t321 0 0\t# StarportShad (terran\\tspShad.grp)\r\nStarportBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nStarportSpecialState1:\r\n\tplayfram       \t3\r\n\tgoto           \tlong00\r\n\r\nStarportAlmostBuilt:\r\n\tplayfram       \t5\r\n\tgoto           \tlong00\r\n\r\nStarportLanding:\r\n\tnobrkcodestart \t\r\n\twait           \t20\r\n\tplaysnd        \t472\t# Misc\\Land.WAV\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t1\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t0\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nStarportLiftOff:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t471\t# Misc\\LiftOff.WAV\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t1\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nStarportIsWorking:\r\n\timgol          \t320 0 0\t# StarportOverlay (terran\\StarpoT.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 320 StarportOverlay (terran\\StarpoT.grp)\r\n.headerstart\r\nIsId           \t135\r\nType           \t24\r\nInit           \tStarportOverlayInit\r\nDeath          \tStarportOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tStarportOverlayInit\r\nWalkingToIdle  \tStarportOverlayInit\r\nSpecialState1  \tStarportOverlayDeath\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \tStarportOverlayInit\r\nLiftOff        \tStarportOverlayInit\r\nIsWorking      \tStarportOverlayInit\r\nWorkingToIdle  \tStarportOverlayDeath\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tStarportOverlayDeath\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStarportOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tgoto           \tStarportOverlayInit\r\n\r\nStarportOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 322 EngineeringBay (terran\\weaponpl.grp)\r\n.headerstart\r\nIsId           \t136\r\nType           \t24\r\nInit           \tEngineeringBayInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tEngineeringBaySpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tEngineeringBayAlmostBuilt\r\nBuilt          \tEngineeringBayBuilt\r\nLanding        \tEngineeringBayLanding\r\nLiftOff        \tEngineeringBayLiftOff\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tEngineeringBayWorkingToIdle\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tEngineeringBayDisable\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEngineeringBayInit:\r\n\tplayfram       \t0\r\n\timgul          \t324 0 0\t# EngineeringBayShad (terran\\twpShad.grp)\r\n\tgoto           \tlong00\r\n\r\nEngineeringBaySpecialState1:\r\n\tplayfram       \t4\r\n\tgoto           \tlong00\r\n\r\nEngineeringBayAlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nEngineeringBayBuilt:\r\n\timgol          \t323 0 0\t# EngineeringBayOverlay (terran\\weaponpT.grp)\r\nEngineeringBayWorkingToIdle:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nEngineeringBayLanding:\r\n\tnobrkcodestart \t\r\n\twait           \t25\r\n\tplaysnd        \t472\t# Misc\\Land.WAV\r\n\tplayfram       \t4\r\n\twait           \t4\r\n\tplayfram       \t2\r\n\twait           \t4\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\tplayfram       \t5\r\n\twait           \t4\r\n\tplayfram       \t0\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nEngineeringBayLiftOff:\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t471\t# Misc\\LiftOff.WAV\r\n\tplayfram       \t5\r\n\twait           \t4\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\tplayfram       \t2\r\n\twait           \t4\r\n\tplayfram       \t4\r\n\tsigorder       \t16\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\nEngineeringBayDisable:\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 323 EngineeringBayOverlay (terran\\weaponpT.grp)\r\n.headerstart\r\nIsId           \t137\r\nType           \t24\r\nInit           \tEngineeringBayOverlayInit\r\nDeath          \tEngineeringBayOverlayDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tlong00\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \tEngineeringBayOverlayDeath\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \tlong00\r\nLiftOff        \tlong00\r\nIsWorking      \tEngineeringBayOverlayIsWorking\r\nWorkingToIdle  \tEngineeringBayOverlayInit\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tEngineeringBayOverlayInit\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEngineeringBayOverlayInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nEngineeringBayOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\nEngineeringBayOverlayIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t5\r\n\tplayfram       \t1\r\n\twait           \t5\r\n\tplayfram       \t2\r\n\twait           \t5\r\n\tplayfram       \t3\r\n\twait           \t5\r\n\tplayfram       \t4\r\n\twait           \t5\r\n\tplayfram       \t5\r\n\twait           \t5\r\n\tgoto           \tEngineeringBayOverlayIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 325 ConstructionSitelarge (terran\\TBldLrg.grp)\r\n.headerstart\r\nIsId           \t138\r\nType           \t14\r\nInit           \tTerranConstruction_Large_Init\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tTerranConstruction_Large_SpecialState1\r\nSpecialState2  \tTerranConstruction_Large_SpecialState2\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTerranConstruction_Large_Init:\r\n\tplayfram       \t0\r\n\timgul          \t326 0 0\t# ConstructionSitelargeShad (terran\\tb2Shad.grp)\r\n\tgoto           \tlong00\r\n\r\nTerranConstruction_Large_SpecialState1:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nTerranConstruction_Large_SpecialState2:\r\n\tplayfram       \t2\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 327 ConstructionSitemedium (terran\\tBldMed.grp)\r\n.headerstart\r\nIsId           \t139\r\nType           \t14\r\nInit           \tTerranConstruction_Medium_Init\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tTerranConstruction_Medium_SpecialState1\r\nSpecialState2  \tTerranConstruction_Medium_SpecialState2\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTerranConstruction_Medium_Init:\r\n\tplayfram       \t0\r\n\timgul          \t328 0 0\t# ConstructionSitemediumShad (terran\\tb3Shad.grp)\r\n\tgoto           \tlong00\r\n\r\nTerranConstruction_Medium_SpecialState1:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nTerranConstruction_Medium_SpecialState2:\r\n\tplayfram       \t2\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 330 ConstructionSitesmalladdon (terran\\TBldSml.grp)\r\n.headerstart\r\nIsId           \t140\r\nType           \t14\r\nInit           \tTerranConstruction_Small_Init\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tTerranConstruction_Small_SpecialState1\r\nSpecialState2  \tTerranConstruction_Small_SpecialState2\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTerranConstruction_Small_Init:\r\n\tplayfram       \t0\r\n\timgul          \t331 0 0\t# ConstructionSitesmallShad (terran\\tb1Shad.grp)\r\n\tgoto           \tlong00\r\n\r\nTerranConstruction_Small_SpecialState1:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nTerranConstruction_Small_SpecialState2:\r\n\tplayfram       \t2\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 329 ConstructionSitesmall (terran\\TBldSml.grp)\r\n.headerstart\r\nIsId           \t141\r\nType           \t14\r\nInit           \tTerranConstruction_Small_Init\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tlong00\r\nSpecialState2  \tlong00\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 332 TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n# 213 ProtossBuildingExplosionSmall (thingy\\tBangS.grp)\r\n.headerstart\r\nIsId           \t142\r\nType           \t0\r\nInit           \tExplosion_Small_Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nExplosion_Small_Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 333 TerranBuildingExplosionmedium (thingy\\tBangL.grp)\r\n# 214 ProtossBuildingExplosionMedium (thingy\\tBangL.grp)\r\n.headerstart\r\nIsId           \t143\r\nType           \t0\r\nInit           \tExplosion_Medium_Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nExplosion_Medium_Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 334 TerranBuildingExplosionlarge (thingy\\tBangX.grp)\r\n# 215 ProtossBuildingExplosionLarge (thingy\\tBangX.grp)\r\n.headerstart\r\nIsId           \t144\r\nType           \t0\r\nInit           \tExplosion_Large_Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nExplosion_Large_Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 336 TerranBuildingRubblelarge (thingy\\RubbleL.grp)\r\n# 335 TerranBuildingRubblesmall (thingy\\RubbleS.grp)\r\n# 217 ProtossBuildingRubbleLarge (thingy\\PRubbleL.grp)\r\n# 216 ProtossBuildingRubbleSmall (thingy\\PRubbleS.grp)\r\n# 111 ZergBuildingRubbleSmall (thingy\\ZRubbleL.grp)\r\n# 110 ZergBuildingRubbleLarge (thingy\\ZRubbleS.grp)\r\n.headerstart\r\nIsId           \t145\r\nType           \t1\r\nInit           \tBuildingRubbleHeaderInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBuildingRubbleHeaderInit:\r\n\tplayfram       \t0\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\tplayfram       \t1\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\tplayfram       \t2\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\tplayfram       \t3\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\twait           \t125\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 130 Arbiter (protoss\\arbiter.grp)\r\n.headerstart\r\nIsId           \t146\r\nType           \t21\r\nInit           \tArbiterInit\r\nDeath          \tArbiterDeath\r\nGndAttkInit    \tArbiterGndAttkInit\r\nAirAttkInit    \tArbiterGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tArbiterGndAttkRpt\r\nAirAttkRpt     \tArbiterGndAttkRpt\r\nCastSpell      \tArbiterCastSpell\r\nGndAttkToIdle  \tlong02\r\nAirAttkToIdle  \tlong02\r\nUnused2        \t[NONE]\r\nWalking        \tArbiterWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tArbiterWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArbiterInit:\r\n\timgul          \t131 0 42\t# ArbiterShad (protoss\\arbiter.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nArbiterDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t213 0 0\t# ProtossBuildingExplosionSmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nArbiterGndAttkInit:\r\n\tsetvertpos     \t0\r\nArbiterGndAttkRpt:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tattackwith     \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nArbiterCastSpell:\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplaysnd        \t548\t# Protoss\\ARBITER\\PAbCag00.WAV\r\n\tcastspell      \t\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tsigorder       \t2\r\n\tgoto           \tlong00\r\n\r\nArbiterWalking:\r\n\timgol          \t132 0 0\t# ArbiterGlow (thingy\\pabGlow.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\nArbiterWarpIn:\r\n\timgol          \t133 0 0\t# Unknown133 (protoss\\arbiter.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 134 ArchonEnergy (protoss\\archon.grp)\r\n.headerstart\r\nIsId           \t147\r\nType           \t13\r\nInit           \tArchonEnergyInit\r\nDeath          \tArchonEnergyDeath\r\nGndAttkInit    \tArchonEnergyGndAttkInit\r\nAirAttkInit    \tArchonEnergyGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tArchonEnergyGndAttkInit\r\nAirAttkRpt     \tArchonEnergyGndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tArchonEnergyGndAttkInit\r\nAirAttkToIdle  \tArchonEnergyGndAttkInit\r\nUnused2        \t[NONE]\r\nWalking        \tArchonEnergyGndAttkInit\r\nWalkingToIdle  \tArchonEnergyGndAttkInit\r\nSpecialState1  \tArchonEnergySpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArchonEnergyInit:\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tplayfram       \t20\r\n\twait           \t2\r\n\tplayfram       \t21\r\n\twait           \t2\r\n\tplayfram       \t22\r\n\twait           \t2\r\n\tplayfram       \t23\r\n\twait           \t2\r\n\tplayfram       \t24\r\n\twait           \t2\r\n\tplayfram       \t25\r\n\twait           \t2\r\n\tplayfram       \t26\r\n\twait           \t2\r\n\timgol          \t135 0 0\t# ArchonBeing (protoss\\archonT.grp)\r\n\timgol          \t136 0 0\t# ArchonTeamColors (protoss\\archonT2.grp)\r\n\tsigorder       \t4\r\n\tnobrkcodeend   \t\r\n\twait           \t2\r\nArchonEnergyGndAttkInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tgoto           \tArchonEnergyGndAttkInit\r\n\r\nArchonEnergyDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t214 0 0\t# ProtossBuildingExplosionMedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nArchonEnergySpecialState1:\r\n\tplaysnd        \t617\t# Protoss\\TEMPLAR\\PTeSum00.WAV\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\nArchonEnergyLocal00:\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tgoto           \tArchonEnergyLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 135 ArchonBeing (protoss\\archonT.grp)\r\n.headerstart\r\nIsId           \t148\r\nType           \t12\r\nInit           \tArchonBeingInit\r\nDeath          \tlong01\r\nGndAttkInit    \tArchonBeingGndAttkInit\r\nAirAttkInit    \tArchonBeingGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tArchonBeingGndAttkInit\r\nAirAttkRpt     \tArchonBeingGndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tArchonBeingGndAttkToIdle\r\nAirAttkToIdle  \tArchonBeingGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tArchonBeingGndAttkToIdle\r\nWalkingToIdle  \tArchonBeingGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArchonBeingInit:\r\n\tsetfldirect    \t15\r\nArchonBeingGndAttkToIdle:\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t4\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t4\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t4\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t4\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t4\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t4\r\n\tgoto           \tArchonBeingGndAttkToIdle\r\n\r\nArchonBeingGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\ttrgtrangecondjmp\t48 ArchonBeingLocal00\r\n\timgoluselo     \t549 0 0\t# Unknown549 (thingy\\emsBeam.grp)\r\nArchonBeingLocal00:\r\n\tplaysnd        \t58\t# Bullet\\PArFir00.wav\r\n\tattack         \t\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t3\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tArchonBeingGndAttkToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 136 ArchonTeamColors (protoss\\archonT2.grp)\r\n.headerstart\r\nIsId           \t149\r\nType           \t1\r\nInit           \tArchonSwirlInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArchonSwirlInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 5\r\n\ttmprmgraphicend\t\r\nArchonSwirlLocal00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tgoto           \tArchonSwirlLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 112 Carrier (protoss\\carrier.grp)\r\n.headerstart\r\nIsId           \t151\r\nType           \t21\r\nInit           \tCarrierInit\r\nDeath          \tCarrierDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tCarrierWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tCarrierWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCarrierInit:\r\n\timgulnextid    \t0 42\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nCarrierDeath:\r\n\tplaysndbtwn    \t595 596\t# Protoss\\Carrier\\PCaDth00.WAV, Protoss\\Carrier\\PCaDth01.WAV\r\n\timgol          \t214 0 0\t# ProtossBuildingExplosionMedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nCarrierWalking:\r\n\timgol          \t114 0 0\t# CarrierGlow (thingy\\pcaGlow.grp)\r\n\tgoto           \tlong00\r\n\r\nCarrierWarpIn:\r\n\timgol          \t115 0 0\t# Unknown115 (protoss\\carrier.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 129 DarkTemplarHero (protoss\\dtemplar.grp)\r\n.headerstart\r\nIsId           \t152\r\nType           \t12\r\nInit           \tDarkTemplar_Hero_Init\r\nDeath          \tDarkTemplar_Hero_Death\r\nGndAttkInit    \tDarkTemplar_Hero_GndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDarkTemplar_Hero_GndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tDarkTemplar_Hero_CastSpell\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tDarkTemplar_Hero_Walking\r\nWalkingToIdle  \tDarkTemplar_Hero_Init\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDarkTemplar_Hero_Init:\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\tgoto           \tlong00\r\n\r\nDarkTemplar_Hero_Death:\r\n\tplaysnd        \t741\t# Protoss\\DARKTEMPLAR\\PDTDth00.WAV\r\n\timgol          \t153 0 0\t# Unknown153 (protoss\\zealot.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nDarkTemplar_Hero_GndAttkInit:\r\n\tplaysnd        \t111\t# Bullet\\UZeFir00.wav\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tDarkTemplar_Hero_Init\r\n\r\nDarkTemplar_Hero_CastSpell:\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\tgotorepeatattk \t\r\n\tgoto           \tDarkTemplar_Hero_Init\r\n\r\nDarkTemplar_Hero_Walking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x121\t# frame set 17\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\tgoto           \tDarkTemplar_Hero_Walking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 122 Dragoon (protoss\\dragoon.grp)\r\n.headerstart\r\nIsId           \t153\r\nType           \t21\r\nInit           \tDragoonInit\r\nDeath          \tDragoonDeath\r\nGndAttkInit    \tDragoonGndAttkInit\r\nAirAttkInit    \tDragoonGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDragoonGndAttkRpt\r\nAirAttkRpt     \tDragoonGndAttkRpt\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tDragoonGndAttkToIdle\r\nAirAttkToIdle  \tDragoonGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tDragoonWalking\r\nWalkingToIdle  \tDragoonWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tDragoonWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDragoonInit:\r\n\timgul          \t123 0 0\t# DragoonShad (protoss\\pdrShad.grp)\r\nDragoonWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twaitrand       \t1 3\r\nDragoonLocal00:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tgoto           \tDragoonLocal00\r\n\r\nDragoonDeath:\r\n\tplaysnd        \t493\t# Protoss\\DRAGOON\\PDrDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0x198\t# frame set 24\r\n\twait           \t2\r\n\tplayfram       \t0x199\t# frame set 24\r\n\twait           \t2\r\n\tplayfram       \t0x19a\t# frame set 24\r\n\twait           \t2\r\n\tplayfram       \t0x19b\t# frame set 24\r\n\twait           \t2\r\n\tplayfram       \t0x19c\t# frame set 24\r\n\twait           \t2\r\n\tplayfram       \t0x19d\t# frame set 24\r\n\twait           \t2\r\n\tplayfram       \t0x19e\t# frame set 24\r\n\twait           \t2\r\n\tlowsprul       \t192 0 0\t# DragoonDeath (protoss\\pdrDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nDragoonGndAttkInit:\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t1\r\n\tplayfram       \t0x121\t# frame set 17\r\n\twait           \t1\r\n\tplayfram       \t0x132\t# frame set 18\r\n\twait           \t1\r\n\tplayfram       \t0x143\t# frame set 19\r\n\twait           \t1\r\n\tplayfram       \t0x154\t# frame set 20\r\n\twait           \t1\r\n\tplayfram       \t0x165\t# frame set 21\r\n\twait           \t1\r\nDragoonGndAttkRpt:\r\n\tplayfram       \t0x176\t# frame set 22\r\n\twait           \t1\r\n\tplayfram       \t0x187\t# frame set 23\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tplayfram       \t0x176\t# frame set 22\r\n\twait           \t1\r\n\tplayfram       \t0x165\t# frame set 21\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nDragoonGndAttkToIdle:\r\n\twait           \t1\r\n\tplayfram       \t0x154\t# frame set 20\r\n\twait           \t1\r\n\tplayfram       \t0x143\t# frame set 19\r\n\twait           \t1\r\n\tplayfram       \t0x132\t# frame set 18\r\n\twait           \t1\r\n\tplayfram       \t0x121\t# frame set 17\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\tgoto           \tDragoonWalkingToIdle\r\n\r\nDragoonWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t8\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\tgoto           \tDragoonWalking\r\n\r\nDragoonWarpIn:\r\n\timgol          \t125 0 0\t# Unknown125 (protoss\\dragoon.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 124 DragoonDeath (protoss\\pdrDeath.grp)\r\n.headerstart\r\nIsId           \t154\r\nType           \t0\r\nInit           \tDragoonRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDragoonRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tplayfram       \t4\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 116 Interceptor (protoss\\Intercep.grp)\r\n.headerstart\r\nIsId           \t155\r\nType           \t12\r\nInit           \tInterceptorInit\r\nDeath          \tInterceptorDeath\r\nGndAttkInit    \tInterceptorGndAttkInit\r\nAirAttkInit    \tInterceptorGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tInterceptorGndAttkInit\r\nAirAttkRpt     \tInterceptorGndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \tlong00\r\nUnused2        \t[NONE]\r\nWalking        \tInterceptorWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInterceptorInit:\r\n\timgul          \t117 0 42\t# InterceptorShad (protoss\\Intercep.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nInterceptorDeath:\r\n\tplaysnd        \t8\t# Misc\\ExploMed.wav\r\n\timgol          \t213 0 0\t# ProtossBuildingExplosionSmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nInterceptorGndAttkInit:\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nInterceptorWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 137 Probe (protoss\\probe.grp)\r\n.headerstart\r\nIsId           \t156\r\nType           \t21\r\nInit           \tProbeInit\r\nDeath          \tProbeDeath\r\nGndAttkInit    \tlong05\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong05\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tProbeWalking\r\nWalkingToIdle  \tlong00\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tProbeAlmostBuilt\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tProbeWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nProbeInit:\r\n\timgul          \t138 0 7\t# ProbeShad (protoss\\probe.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nProbeDeath:\r\n\tplaysnd        \t598\t# Protoss\\PROBE\\PPrDth00.WAV\r\n\timgol          \t213 0 0\t# ProtossBuildingExplosionSmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nProbeWalking:\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\nProbeAlmostBuilt:\r\n\tuseweapon      \t63\t# Particle Beam\r\n\twait           \t1\r\n\twaitrand       \t8 10\r\n\tgoto           \tProbeAlmostBuilt\r\n\r\nProbeWarpIn:\r\n\timgol          \t139 0 0\t# Unknown139 (protoss\\probe.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 118 Shuttle (protoss\\shuttle.grp)\r\n.headerstart\r\nIsId           \t157\r\nType           \t21\r\nInit           \tShuttleInit\r\nDeath          \tShuttleDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tShuttleWalking\r\nWalkingToIdle  \tShuttleWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tShuttleWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nShuttleInit:\r\n\timgul          \t119 0 42\t# ShuttleShad (protoss\\shuttle.grp)\r\nShuttleWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nShuttleDeath:\r\n\tplaysnd        \t514\t# Protoss\\SHUTTLE\\PShDth00.WAV\r\n\timgol          \t213 0 0\t# ProtossBuildingExplosionSmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nShuttleWalking:\r\n\timgol          \t120 0 0\t# ShuttleGlow (thingy\\pshGlow.grp)\r\n\tsetvertpos     \t0\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nShuttleWarpIn:\r\n\timgol          \t121 0 0\t# Unknown121 (protoss\\shuttle.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 126 HighTemplar (protoss\\templar.grp)\r\n.headerstart\r\nIsId           \t158\r\nType           \t21\r\nInit           \tHighTemplarInit\r\nDeath          \tHighTemplarDeath\r\nGndAttkInit    \tHighTemplarGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tHighTemplarGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tHighTemplarCastSpell\r\nGndAttkToIdle  \tHighTemplarGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tHighTemplarWalking\r\nWalkingToIdle  \tHighTemplarWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tHighTemplarWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHighTemplarInit:\r\n\timgul          \t127 0 0\t# HighTemplarShad (protoss\\pteShad.grp)\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twaitrand       \t1 2\r\nHighTemplarGndAttkToIdle:\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t2\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t2\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t2\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t2\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tgoto           \tHighTemplarGndAttkToIdle\r\n\r\nHighTemplarDeath:\r\n\tplaysnd        \t635\t# Protoss\\TEMPLAR\\PTeDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0x121\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x122\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x123\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x124\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x125\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x126\t# frame set 17\r\n\twait           \t2\r\n\tplayfram       \t0x127\t# frame set 17\r\n\twait           \t2\r\n\tend            \t\r\n\r\nHighTemplarGndAttkInit:\r\n\tplaysnd        \t101\t# Bullet\\LaserB.wav\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tgoto           \tlong00\r\n\r\nHighTemplarCastSpell:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tgoto           \tlong00\r\n\r\nHighTemplarWalking:\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tsetvertpos     \t0\r\nHighTemplarLocal00:\r\n\twait           \t3\r\n\tspruluselo     \t320 0 0\t# HighTemplarTrail (thingy\\pteglow.grp)\r\n\tgoto           \tHighTemplarLocal00\r\n\r\nHighTemplarWalkingToIdle:\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tgoto           \tHighTemplarGndAttkToIdle\r\n\r\nHighTemplarWarpIn:\r\n\timgol          \t128 0 0\t# Unknown128 (protoss\\templar.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 144 Reaver (protoss\\trilob.grp)\r\n.headerstart\r\nIsId           \t159\r\nType           \t21\r\nInit           \tReaverInit\r\nDeath          \tReaverDeath\r\nGndAttkInit    \tReaverGndAttkInit\r\nAirAttkInit    \tReaverGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tReaverGndAttkInit\r\nAirAttkRpt     \tReaverGndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tReaverGndAttkToIdle\r\nAirAttkToIdle  \tReaverGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tReaverWalking\r\nWalkingToIdle  \tReaverWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tReaverWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nReaverInit:\r\n\timgul          \t145 0 0\t# ReaverShad (protoss\\ptrShad.grp)\r\nReaverWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nReaverDeath:\r\n\tplaysnd        \t638\t# Protoss\\TRILOBYTE\\PTrDth00.WAV\r\n\timgol          \t214 0 0\t# ProtossBuildingExplosionMedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nReaverGndAttkInit:\r\n\twait           \t1\r\n\tplaysndbtwn    \t102 103\t# Bullet\\pTrFir00.wav, Bullet\\pTrFir01.wav\r\n\tattackwith     \t1\r\n\twait           \t1\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nReaverGndAttkToIdle:\r\n\tgoto           \tReaverWalkingToIdle\r\n\r\nReaverWalking:\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t0\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t1\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t1\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t2\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t3\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t1\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t6\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tReaverWalking\r\n\r\nReaverWarpIn:\r\n\timgol          \t146 0 0\t# Unknown146 (protoss\\trilob.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 147 Scarab (protoss\\sapper.grp)\r\n.headerstart\r\nIsId           \t160\r\nType           \t13\r\nInit           \tScarabInit\r\nDeath          \tScarabDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tScarabWalking\r\nWalkingToIdle  \tScarabInit\r\nSpecialState1  \tScarabSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScarabInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nScarabDeath:\r\n\timgol          \t444 0 0\t# ScarabExplosion (thingy\\psaExplo.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nScarabWalking:\r\n\tsetflspeed     \t2048\r\n\tmove           \t16\r\n\tsprol          \t373 0 0\t# ScarabTrail (thingy\\HKTrail.grp)\r\n\twait           \t1\r\n\tgoto           \tScarabWalking\r\n\r\nScarabSpecialState1:\r\n\tuseweapon      \t82\t# Scarab\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 140 Scout (protoss\\scout.grp)\r\n.headerstart\r\nIsId           \t161\r\nType           \t21\r\nInit           \tScoutInit\r\nDeath          \tScoutDeath\r\nGndAttkInit    \tScoutGndAttkInit\r\nAirAttkInit    \tScoutAirAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tScoutGndAttkInit\r\nAirAttkRpt     \tScoutAirAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tScoutGndAttkToIdle\r\nAirAttkToIdle  \tScoutGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tScoutWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tScoutWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScoutInit:\r\n\timgul          \t141 0 42\t# ScoutShad (protoss\\scout.grp)\r\nScoutGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nScoutDeath:\r\n\tplaysnd        \t533\t# Protoss\\Scout\\PScDth00.WAV\r\n\timgol          \t213 0 0\t# ProtossBuildingExplosionSmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nScoutGndAttkInit:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nScoutAirAttkInit:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tattackwith     \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nScoutWalking:\r\n\timgol          \t142 0 0\t# ScoutGlow (thingy\\pscGlow.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\nScoutWarpIn:\r\n\timgol          \t143 0 0\t# Unknown143 (protoss\\scout.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 142 ScoutGlow (thingy\\pscGlow.grp)\r\n.headerstart\r\nIsId           \t162\r\nType           \t12\r\nInit           \tScoutEnginesInit\r\nDeath          \tlong01\r\nGndAttkInit    \tlong01\r\nAirAttkInit    \tlong01\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong01\r\nAirAttkToIdle  \tlong01\r\nUnused2        \t[NONE]\r\nWalking        \tScoutEnginesInit\r\nWalkingToIdle  \tlong01\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScoutEnginesInit:\r\n\twait           \t1\r\n\tengframe       \t0\r\n\twait           \t1\r\n\tengframe       \t17\r\n\tgoto           \tScoutEnginesInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 151 Zealot (protoss\\zealot.grp)\r\n.headerstart\r\nIsId           \t163\r\nType           \t21\r\nInit           \tZealotInit\r\nDeath          \tZealotDeath\r\nGndAttkInit    \tZealotGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tZealotGndAttkRpt\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tZealotGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tZealotWalking\r\nWalkingToIdle  \tZealotWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tZealotWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZealotInit:\r\n\timgul          \t152 0 0\t# ZealotShad (protoss\\pzeShad.grp)\r\nZealotWalkingToIdle:\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tgoto           \tlong00\r\n\r\nZealotDeath:\r\n\tplaysnd        \t678\t# Protoss\\ZEALOT\\PZeDth00.WAV\r\nZealotDeathInit:\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xde\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xdf\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe0\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe1\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe2\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe3\t# frame set 13\r\n\twait           \t2\r\n\tend            \t\r\n\r\nZealotGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\nZealotGndAttkRpt:\r\n\tplaysndrand    \t2 662 663\t# Protoss\\ZEALOT\\pzeAtt00.WAV, Protoss\\ZEALOT\\pzeAtt01.WAV\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tattackmelee    \t1 664\t# Protoss\\ZEALOT\\pzeHit00.WAV\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tattackmelee    \t1 664\t# Protoss\\ZEALOT\\pzeHit00.WAV\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nZealotGndAttkToIdle:\r\n\tgoto           \tZealotWalkingToIdle\r\n\r\nZealotWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tgoto           \tZealotWalking\r\n\r\nZealotWarpIn:\r\n\timgol          \t154 0 0\t# Unknown154 (protoss\\zealot.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 153 Unknown153 (protoss\\zealot.grp)\r\n.headerstart\r\nIsId           \t164\r\nType           \t1\r\nInit           \tZealotDeathInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 148 Observer (protoss\\witness.grp)\r\n.headerstart\r\nIsId           \t165\r\nType           \t21\r\nInit           \tObserverInit\r\nDeath          \tObserverDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tObserverWalking\r\nWalkingToIdle  \tlong02\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tObserverWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nObserverInit:\r\n\timgul          \t149 0 42\t# ObserverShad (protoss\\witness.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nObserverDeath:\r\n\tplaysndbtwn    \t651 652\t# Protoss\\Witness\\PWiDth00.WAV, Protoss\\Witness\\PWiDth01.WAV\r\n\timgol          \t214 0 0\t# ProtossBuildingExplosionMedium (thingy\\tBangL.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nObserverWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\nObserverWarpIn:\r\n\timgol          \t150 0 0\t# Unknown150 (protoss\\witness.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 155 TemplarArchives (protoss\\archives.grp)\r\n.headerstart\r\nIsId           \t166\r\nType           \t27\r\nInit           \tTemplarArchivesInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tTemplarArchivesWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTemplarArchivesInit:\r\n\timgul          \t157 0 0\t# TemplarArchivesShad (protoss\\pacShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nTemplarArchivesDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t215 0 0\t# ProtossBuildingExplosionLarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tlowsprul       \t223 0 0\t# ProtossBuildingRubbleSmall (thingy\\PRubbleS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nTemplarArchivesWarpIn:\r\n\timgol          \t156 0 0\t# Unknown156 (protoss\\archives.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 158 Assimilator (protoss\\assim.grp)\r\n.headerstart\r\nIsId           \t167\r\nType           \t27\r\nInit           \tAssimilatorInit\r\nDeath          \tAssimilatorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tAssimilatorBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tAssimilatorBuilt\r\nWorkingToIdle  \tAssimilatorBuilt\r\nWarpIn         \tAssimilatorWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAssimilatorInit:\r\n\timgul          \t160 0 0\t# Unknown160 (protoss\\pasShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nAssimilatorDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\tsprol          \t222 0 0\t# ProtossBuildingExplosionLarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nAssimilatorWarpIn:\r\n\timgol          \t159 0 0\t# Unknown159 (protoss\\assim.grp)\r\nAssimilatorBuilt:\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t0\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t3\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t3\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t0\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\twaitrand       \t5 50\r\n\tgoto           \tAssimilatorBuilt\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 161 Observatory (protoss\\beacon.grp)\r\n.headerstart\r\nIsId           \t168\r\nType           \t27\r\nInit           \tObservatoryInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tObservatoryWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nObservatoryInit:\r\n\timgul          \t163 0 0\t# ObservatoryShad (protoss\\pbeShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nObservatoryWarpIn:\r\n\timgol          \t162 0 0\t# ObservatoryWarpFlash (protoss\\beacon.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n.headerstart\r\nIsId           \t169\r\nType           \t20\r\nInit           \tUnknown169Init\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tUnknown169Init\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tUnknown169Init\r\nWorkingToIdle  \tUnknown169Init\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown169Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x01\t# frame set 0\r\n\twait           \t2\r\n\tgoto           \tUnknown169Init\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 164 CitadelofAdun (protoss\\citadel.grp)\r\n.headerstart\r\nIsId           \t170\r\nType           \t27\r\nInit           \tCitadelOfAdunInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tCitadelOfAdunWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCitadelOfAdunInit:\r\n\timgul          \t166 0 0\t# CitadelofAdunShad (protoss\\pciShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nCitadelOfAdunWarpIn:\r\n\timgol          \t165 0 0\t# CitadelofAdunWarpFlash (protoss\\citadel.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 167 Forge (protoss\\forge.grp)\r\n.headerstart\r\nIsId           \t171\r\nType           \t27\r\nInit           \tForgeInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tForgeBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tForgeWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nForgeInit:\r\n\timgul          \t170 0 0\t# ForgeShad (protoss\\pfoShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nForgeBuilt:\r\n\timgol          \t168 0 0\t# ForgeOverlay (protoss\\forgeT.grp)\r\n\tgoto           \tlong00\r\n\r\nForgeWarpIn:\r\n\timgol          \t169 0 0\t# ForgeWarpFlash (protoss\\forge.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 168 ForgeOverlay (protoss\\forgeT.grp)\r\n.headerstart\r\nIsId           \t172\r\nType           \t27\r\nInit           \tForgeOverlayInit\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tForgeOverlayIsWorking\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nForgeOverlayInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nForgeOverlayIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t3\r\n\tplayfram       \t1\r\n\twait           \t3\r\n\tplayfram       \t2\r\n\twait           \t3\r\n\tgoto           \tForgeOverlayIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 171 Gateway (protoss\\gateway.grp)\r\n.headerstart\r\nIsId           \t173\r\nType           \t27\r\nInit           \tGatewayInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tGatewayWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGatewayInit:\r\n\timgul          \t173 0 0\t# GatewayShad (protoss\\pgaShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nGatewayWarpIn:\r\n\timgol          \t172 0 0\t# GatewayWarpFlash (protoss\\gateway.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 174 CyberneticsCore (protoss\\gencore.grp)\r\n.headerstart\r\nIsId           \t174\r\nType           \t27\r\nInit           \tCyberneticsCoreInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tCyberneticsCoreBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tCyberneticsCoreWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCyberneticsCoreInit:\r\n\timgul          \t177 0 0\t# CyberneticsCoreShad (protoss\\pgcShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nCyberneticsCoreBuilt:\r\n\timgol          \t176 0 0\t# CyberneticsCoreOverlay (protoss\\gencoreT.grp)\r\n\tgoto           \tlong00\r\n\r\nCyberneticsCoreWarpIn:\r\n\timgol          \t175 0 0\t# CyberneticsCoreWarpFlash (protoss\\gencore.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 176 CyberneticsCoreOverlay (protoss\\gencoreT.grp)\r\n.headerstart\r\nIsId           \t175\r\nType           \t27\r\nInit           \tCybrneticsCoreOverlayInit\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tCybrneticsCoreOverlayIsWorking\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCybrneticsCoreOverlayInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nCybrneticsCoreOverlayIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tgoto           \tCybrneticsCoreOverlayIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 178 KhaydarinCrystal (neutral\\Khyad01.grp)\r\n.headerstart\r\nIsId           \t176\r\nType           \t20\r\nInit           \tKhaydarinCrystalFormationInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tKhaydarinCrystalFormationInit\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nKhaydarinCrystalFormationInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 179 Nexus (protoss\\nexus.grp)\r\n.headerstart\r\nIsId           \t177\r\nType           \t21\r\nInit           \tNexusInit\r\nDeath          \tNexusDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tNexusBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tNexusWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNexusInit:\r\n\timgul          \t182 0 0\t# NexusShad (protoss\\pneShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nNexusDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t215 0 0\t# ProtossBuildingExplosionLarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tlowsprul       \t224 0 0\t# ProtossBuildingRubbleLarge (thingy\\PRubbleL.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nNexusBuilt:\r\n\timgol          \t181 0 0\t# NexusGlow (protoss\\pneGlow.grp)\r\n\tgoto           \tlong00\r\n\r\nNexusWarpIn:\r\n\timgol          \t180 0 0\t# NexusWarpFlash (protoss\\nexus.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 181 NexusGlow (protoss\\pneGlow.grp)\r\n.headerstart\r\nIsId           \t178\r\nType           \t24\r\nInit           \tNexusOverlayInit\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tNexusOverlayIsWorking\r\nWorkingToIdle  \tNexusOverlayInit\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong01\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNexusOverlayInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nNexusOverlayIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tgoto           \tNexusOverlayIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 183 PhotonCannon (protoss\\photon.grp)\r\n.headerstart\r\nIsId           \t179\r\nType           \t27\r\nInit           \tPhotonCannonInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \tPhotonCannonGndAttkInit\r\nAirAttkInit    \tPhotonCannonGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tPhotonCannonGndAttkRpt\r\nAirAttkRpt     \tPhotonCannonGndAttkRpt\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tPhotonCannonGndAttkToIdle\r\nAirAttkToIdle  \tPhotonCannonGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tPhotonCannonWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPhotonCannonInit:\r\n\timgul          \t184 0 0\t# PhotonCannonShad (protoss\\ppbShad.grp)\r\nPhotonCannonLocal00:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nPhotonCannonGndAttkInit:\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nPhotonCannonGndAttkRpt:\r\n\twait           \t1\r\n\tattack         \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nPhotonCannonGndAttkToIdle:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tgoto           \tPhotonCannonLocal00\r\n\r\nPhotonCannonWarpIn:\r\n\timgol          \t185 0 0\t# PhotonCannonWarpFlash (protoss\\photon.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 186 ArbiterTribunal (protoss\\prism.grp)\r\n.headerstart\r\nIsId           \t180\r\nType           \t27\r\nInit           \tArbiterTribunalInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tArbiterTribunalWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArbiterTribunalInit:\r\n\timgul          \t188 0 0\t# ArbiterTribunalShad (protoss\\pauShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nArbiterTribunalWarpIn:\r\n\timgol          \t187 0 0\t# ArbiterTribunalWarpFlash (protoss\\prism.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 189 Pylon (protoss\\pylon.grp)\r\n.headerstart\r\nIsId           \t181\r\nType           \t21\r\nInit           \tPylonInit\r\nDeath          \tPylonDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tPylonBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tPylonWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPylonInit:\r\n\timgul          \t191 0 0\t# PylonShad (protoss\\ppyShad.grp)\r\nPylonBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nPylonDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t215 0 0\t# ProtossBuildingExplosionLarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nPylonWarpIn:\r\n\timgol          \t190 0 0\t# PylonWarpFlash (protoss\\pylon.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 192 RoboticsFacility (protoss\\robotic.grp)\r\n.headerstart\r\nIsId           \t182\r\nType           \t27\r\nInit           \tRoboticsFacilityInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tRoboticsFacilityBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tRoboticsFacilityWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRoboticsFacilityInit:\r\n\timgul          \t194 0 0\t# RoboticsFacilityShad (protoss\\proShad.grp)\r\nRoboticsFacilityBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nRoboticsFacilityWarpIn:\r\n\timgol          \t193 0 0\t# RoboticsFacilityWarpFlash (protoss\\robotic.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 195 ShieldBattery (protoss\\sbattery.grp)\r\n.headerstart\r\nIsId           \t183\r\nType           \t27\r\nInit           \tShieldBatteryInit\r\nDeath          \tShieldBatteryDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tShieldBatteryBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tShieldBatteryWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tShieldBatteryBuilt\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nShieldBatteryInit:\r\n\timgul          \t198 0 0\t# ShieldBatteryShad (protoss\\pbaShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nShieldBatteryDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t215 0 0\t# ProtossBuildingExplosionLarge (thingy\\tBangX.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nShieldBatteryBuilt:\r\n\timgol          \t196 0 0\t# ShieldBatteryGlow (protoss\\pbaGlow.grp)\r\n\tgoto           \tlong00\r\n\r\nShieldBatteryWarpIn:\r\n\timgol          \t197 0 0\t# ShieldBatteryWarpFlash (protoss\\sbattery.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 196 ShieldBatteryGlow (protoss\\pbaGlow.grp)\r\n.headerstart\r\nIsId           \t184\r\nType           \t24\r\nInit           \tShieldBatteryOverlayInit\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tShieldBatteryOverlayIsWorking\r\nWorkingToIdle  \tShieldBatteryOverlayInit\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong01\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nShieldBatteryOverlayInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nShieldBatteryOverlayIsWorking:\r\n\tplaysnd        \t481\t# Protoss\\Bldg\\PbaAct00.wav\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tgoto           \tShieldBatteryOverlayIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 199 Stargate (protoss\\stargate.grp)\r\n.headerstart\r\nIsId           \t185\r\nType           \t27\r\nInit           \tStargateInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tStargateBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tStargateWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tStargateBuilt\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStargateInit:\r\n\timgul          \t202 0 0\t# StargateShad (protoss\\psgShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nStargateBuilt:\r\n\timgol          \t200 0 0\t# StargateGlow (protoss\\psgGlow.grp)\r\n\tgoto           \tlong00\r\n\r\nStargateWarpIn:\r\n\timgol          \t201 0 0\t# StargateWarpFlash (protoss\\stargate.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 200 StargateGlow (protoss\\psgGlow.grp)\r\n.headerstart\r\nIsId           \t186\r\nType           \t24\r\nInit           \tStargateOverlayInit\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tStargateOverlayIsWorking\r\nWorkingToIdle  \tStargateOverlayInit\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong01\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStargateOverlayInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nStargateOverlayIsWorking:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tgoto           \tStargateOverlayIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 203 StasisCellPrison (neutral\\stasis.grp)\r\n.headerstart\r\nIsId           \t187\r\nType           \t20\r\nInit           \tStasisCellInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tStasisCellInit\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStasisCellInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 204 RoboticsSupportBay (protoss\\stasis.grp)\r\n.headerstart\r\nIsId           \t188\r\nType           \t27\r\nInit           \tRoboticsSupportBayInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tRoboticsSupportBayWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRoboticsSupportBayInit:\r\n\timgul          \t206 0 0\t# RoboticsSupportBayShad (protoss\\pstShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nRoboticsSupportBayWarpIn:\r\n\timgol          \t205 0 0\t# RoboticsSupportBayWarpFlash (protoss\\stasis.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 207 ProtossTemple (neutral\\temple.grp)\r\n.headerstart\r\nIsId           \t189\r\nType           \t20\r\nInit           \tTempleInit\r\nDeath          \tNexusDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tTempleInit\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTempleInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 208 FleetBeacon (protoss\\warp.grp)\r\n.headerstart\r\nIsId           \t190\r\nType           \t27\r\nInit           \tFleetBeaconInit\r\nDeath          \tTemplarArchivesDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \tFleetBeaconWarpIn\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong00\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFleetBeaconInit:\r\n\timgul          \t212 0 0\t# FleetBeaconShad (protoss\\pwaShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nFleetBeaconWarpIn:\r\n\timgol          \t209 0 0\t# Unknown209 (protoss\\warp.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 211 FleetBeaconGlow (protoss\\pb1Glow.grp)\r\n.headerstart\r\nIsId           \t191\r\nType           \t13\r\nInit           \tWarpAnchorInit\r\nDeath          \tWarpAnchorDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tWarpAnchorSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWarpAnchorInit:\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\nWarpAnchorLocal00:\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tgoto           \tWarpAnchorLocal00\r\n\r\nWarpAnchorDeath:\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tend            \t\r\n\r\nWarpAnchorSpecialState1:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 209 Unknown209 (protoss\\warp.grp)\r\n# 205 RoboticsSupportBayWarpFlash (protoss\\stasis.grp)\r\n# 201 StargateWarpFlash (protoss\\stargate.grp)\r\n# 197 ShieldBatteryWarpFlash (protoss\\sbattery.grp)\r\n# 193 RoboticsFacilityWarpFlash (protoss\\robotic.grp)\r\n# 190 PylonWarpFlash (protoss\\pylon.grp)\r\n# 187 ArbiterTribunalWarpFlash (protoss\\prism.grp)\r\n# 185 PhotonCannonWarpFlash (protoss\\photon.grp)\r\n# 180 NexusWarpFlash (protoss\\nexus.grp)\r\n# 175 CyberneticsCoreWarpFlash (protoss\\gencore.grp)\r\n# 172 GatewayWarpFlash (protoss\\gateway.grp)\r\n# 169 ForgeWarpFlash (protoss\\forge.grp)\r\n# 165 CitadelofAdunWarpFlash (protoss\\citadel.grp)\r\n# 162 ObservatoryWarpFlash (protoss\\beacon.grp)\r\n# 159 Unknown159 (protoss\\assim.grp)\r\n# 156 Unknown156 (protoss\\archives.grp)\r\n# 154 Unknown154 (protoss\\zealot.grp)\r\n# 150 Unknown150 (protoss\\witness.grp)\r\n# 146 Unknown146 (protoss\\trilob.grp)\r\n# 143 Unknown143 (protoss\\scout.grp)\r\n# 139 Unknown139 (protoss\\probe.grp)\r\n# 133 Unknown133 (protoss\\arbiter.grp)\r\n# 128 Unknown128 (protoss\\templar.grp)\r\n# 125 Unknown125 (protoss\\dragoon.grp)\r\n# 121 Unknown121 (protoss\\shuttle.grp)\r\n# 115 Unknown115 (protoss\\carrier.grp)\r\n.headerstart\r\nIsId           \t192\r\nType           \t1\r\nInit           \tWarpFlashHeaderInit\r\nDeath          \tWarpFlashHeaderDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWarpFlashHeaderInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tfollowmaingraphic\t\r\n\tgoto           \tlong00\r\n\r\nWarpFlashHeaderDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 210 Protossbuildingswarptexture (protoss\\texture.grp)\r\n.headerstart\r\nIsId           \t193\r\nType           \t1\r\nInit           \tWarpTextureInit\r\nDeath          \tWarpTextureDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWarpTextureInit:\r\n\twarpoverlay    \t0\r\n\twait           \t1\r\n\twarpoverlay    \t1\r\n\twait           \t1\r\n\twarpoverlay    \t2\r\n\twait           \t1\r\n\twarpoverlay    \t3\r\n\twait           \t1\r\n\twarpoverlay    \t4\r\n\twait           \t1\r\n\twarpoverlay    \t5\r\n\twait           \t1\r\n\twarpoverlay    \t6\r\n\twait           \t1\r\n\twarpoverlay    \t7\r\n\twait           \t1\r\n\twarpoverlay    \t8\r\n\twait           \t1\r\n\twarpoverlay    \t9\r\n\twait           \t1\r\n\twarpoverlay    \t10\r\n\twait           \t1\r\n\twarpoverlay    \t11\r\n\twait           \t1\r\n\twarpoverlay    \t12\r\n\twait           \t1\r\n\twarpoverlay    \t13\r\n\twait           \t1\r\n\twarpoverlay    \t14\r\n\twait           \t1\r\n\twarpoverlay    \t15\r\n\twait           \t1\r\n\twarpoverlay    \t16\r\n\twait           \t1\r\n\twarpoverlay    \t17\r\n\twait           \t1\r\n\twarpoverlay    \t18\r\n\twait           \t1\r\n\twarpoverlay    \t19\r\n\tsigorder       \t1\r\n\twait           \t1\r\n\tgoto           \tlong00\r\n\r\nWarpTextureDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 338 RagnasaurAshworld (neutral\\Acritter.grp)\r\n.headerstart\r\nIsId           \t198\r\nType           \t12\r\nInit           \tRagnasaurInit\r\nDeath          \tRagnasaurDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tRagnasaurWalking\r\nWalkingToIdle  \tRagnasaurWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRagnasaurInit:\r\n\timgul          \t339 0 0\t# RagnasaurShad (neutral\\nacShad.grp)\r\nRagnasaurWalkingToIdle:\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tgoto           \tlong00\r\n\r\nRagnasaurDeath:\r\n\tplaysnd        \t53\t# Misc\\CRITTERS\\LCrDth00.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x9a\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x9b\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x9c\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x9d\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x9e\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x9f\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0xa0\t# frame set 9\r\n\twait           \t1\r\n\tend            \t\r\n\r\nRagnasaurWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tgoto           \tRagnasaurWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 340 RynadonBadlands (neutral\\Bcritter.grp)\r\n.headerstart\r\nIsId           \t199\r\nType           \t12\r\nInit           \tRhynadonInit\r\nDeath          \tRhynadonDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tRhynadonWalking\r\nWalkingToIdle  \tRhynadonWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRhynadonInit:\r\n\timgul          \t341 0 0\t# RynadonShad (neutral\\nbcShad.grp)\r\nRhynadonWalkingToIdle:\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tgoto           \tlong00\r\n\r\nRhynadonDeath:\r\n\tplaysnd        \t57\t# Misc\\CRITTERS\\BCrDth00.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xbc\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xbd\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xbe\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xbf\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xc0\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xc1\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xc2\t# frame set 11\r\n\twait           \t1\r\n\tend            \t\r\n\r\nRhynadonWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tgoto           \tRhynadonWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 342 BengalassJungle (neutral\\Jcritter.grp)\r\n.headerstart\r\nIsId           \t200\r\nType           \t12\r\nInit           \tBengalaasInit\r\nDeath          \tBengalaasDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tBengalaasWalking\r\nWalkingToIdle  \tBengalaasWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBengalaasInit:\r\n\timgul          \t343 0 0\t# BengalassShad (neutral\\njcShad.grp)\r\nBengalaasWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nBengalaasDeath:\r\n\tplaysnd        \t49\t# Misc\\CRITTERS\\JCrDth00.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xcd\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xce\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xcf\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xd0\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xd1\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xd2\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xd3\t# frame set 12\r\n\twait           \t1\r\n\tend            \t\r\n\r\nBengalaasWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tBengalaasWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 344 VespeneGeyser (neutral\\geyser.grp)\r\n.headerstart\r\nIsId           \t201\r\nType           \t20\r\nInit           \tVespeneGeyserInit\r\nDeath          \tVespeneGeyserDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tVespeneGeyserSpecialState1\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tVespeneGeyserBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tVespeneGeyserSpecialState1\r\nWorkingToIdle  \tVespeneGeyserSpecialState1\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nVespeneGeyserInit:\r\n\tplayframtile   \t0\r\n\timgul          \t346 0 0\t# VespeneGeyserShad (neutral\\geyShad.grp)\r\nVespeneGeyserBuilt:\r\n\twait           \t15\r\nVespeneGeyserSpecialState1:\r\n\tcreategasoverlays\t0\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t1\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t0\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t1\r\n\twaitrand       \t5 50\r\n\tcreategasoverlays\t2\r\n\twaitrand       \t5 50\r\n\tgoto           \tVespeneGeyserSpecialState1\r\n\r\nVespeneGeyserDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 345 Unknown345 (neutral\\geyser.grp)\r\n.headerstart\r\nIsId           \t202\r\nType           \t20\r\nInit           \tVespeneGeyser2Init\r\nDeath          \tVespeneGeyserDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tlong00\r\nSpecialState2  \tlong00\r\nAlmostBuilt    \tlong00\r\nBuilt          \tlong00\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nVespeneGeyser2Init:\r\n\tplayframtile   \t0\r\n\timgul          \t346 0 0\t# VespeneGeyserShad (neutral\\geyShad.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 346 VespeneGeyserShad (neutral\\geyShad.grp)\r\n.headerstart\r\nIsId           \t203\r\nType           \t1\r\nInit           \tVespeneGeyserShadowInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nVespeneGeyserShadowInit:\r\n\tplayframtile   \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 347 MineralDeposit1 (neutral\\min01.grp)\r\n.headerstart\r\nIsId           \t204\r\nType           \t20\r\nInit           \tMineralFieldType1Init\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tMineralFieldType1SpecialState1\r\nSpecialState2  \tMineralFieldType1SpecialState2\r\nAlmostBuilt    \tMineralFieldType1AlmostBuilt\r\nBuilt          \tMineralFieldType1Built\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \tMineralFieldType1Built\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMineralFieldType1Init:\r\n\timgul          \t348 0 0\t# MineralDeposit1Shad (neutral\\min01Sha.grp)\r\n\tgoto           \tMineralFieldType1Built\r\n\r\nMineralFieldType3Init:\r\n\timgul          \t352 0 0\t# MineralDeposit3Shad (neutral\\min03Sha.grp)\r\nMineralFieldType1Built:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nMineralFieldType1SpecialState1:\r\n\tplayfram       \t3\r\n\tgoto           \tlong00\r\n\r\nMineralFieldType1SpecialState2:\r\n\tplayfram       \t2\r\n\tgoto           \tlong00\r\n\r\nMineralFieldType1AlmostBuilt:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 349 MineralDeposit2 (neutral\\min02.grp)\r\n.headerstart\r\nIsId           \t205\r\nType           \t20\r\nInit           \tMineralFieldType2Init\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tMineralFieldType1SpecialState1\r\nSpecialState2  \tMineralFieldType1SpecialState2\r\nAlmostBuilt    \tMineralFieldType1AlmostBuilt\r\nBuilt          \tMineralFieldType1Built\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \tMineralFieldType1Built\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMineralFieldType2Init:\r\n\timgul          \t350 0 0\t# MineralDeposit2Shad (neutral\\min02Sha.grp)\r\n\tgoto           \tMineralFieldType1Built\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 351 MineralDeposit3 (neutral\\min03.grp)\r\n.headerstart\r\nIsId           \t206\r\nType           \t20\r\nInit           \tMineralFieldType3Init\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tMineralFieldType1SpecialState1\r\nSpecialState2  \tMineralFieldType1SpecialState2\r\nAlmostBuilt    \tMineralFieldType1AlmostBuilt\r\nBuilt          \tMineralFieldType1Built\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \tMineralFieldType1Built\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 353 Unusedscoutcopy (protoss\\scout.grp)\r\n.headerstart\r\nIsId           \t207\r\nType           \t20\r\nInit           \tUnknown207Init\r\nDeath          \tUnknown207Death\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tUnknown207Init\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown207Init:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nUnknown207Death:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 355 ZergBeaconOverlay (zerg\\zCirGlow.grp)\r\n.headerstart\r\nIsId           \t208\r\nType           \t1\r\nInit           \tZergBeaconOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergBeaconOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tZergBeaconOverlayInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 357 TerranBeaconOverlay (terran\\tCirGlow.grp)\r\n.headerstart\r\nIsId           \t209\r\nType           \t1\r\nInit           \tTerranBeaconOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTerranBeaconOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tTerranBeaconOverlayInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 359 ProtossBeaconOverlay (protoss\\pCirGlow.grp)\r\n.headerstart\r\nIsId           \t210\r\nType           \t1\r\nInit           \tProtossBeaconOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nProtossBeaconOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tProtossBeaconOverlayInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 354 ZergBeacon (zerg\\zmarker.grp)\r\n.headerstart\r\nIsId           \t211\r\nType           \t1\r\nInit           \tZergBeaconInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nZergBeaconInit:\r\n\tplayfram       \t0\r\n\timgol          \t355 0 0\t# ZergBeaconOverlay (zerg\\zCirGlow.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 358 ProtossBeacon (protoss\\pMarker.grp)\r\n.headerstart\r\nIsId           \t212\r\nType           \t1\r\nInit           \tProtossBeaconInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nProtossBeaconInit:\r\n\tplayfram       \t0\r\n\timgol          \t359 0 0\t# ProtossBeaconOverlay (protoss\\pCirGlow.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 356 TerranBeacon (terran\\tMarker.grp)\r\n.headerstart\r\nIsId           \t213\r\nType           \t1\r\nInit           \tTerranBeaconInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTerranBeaconInit:\r\n\tplayfram       \t0\r\n\timgol          \t357 0 0\t# TerranBeaconOverlay (terran\\tCirGlow.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n.headerstart\r\nIsId           \t214\r\nType           \t1\r\nInit           \tUnknwon214Init\r\nDeath          \tUnknwon214Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknwon214Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nUnknwon214Death:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 418 PsiEmitterShadCarried (neutral\\npsSha2.grp)\r\n# 417 PsiEmitterShadGround (neutral\\npsShad.grp)\r\n# 416 ChrysalisShadCarried (neutral\\nkeSha2.grp)\r\n# 415 ChrysalisShadGround (neutral\\nkeShad.grp)\r\n# 414 CrystalShadCarried (neutral\\nkhSha2.grp)\r\n# 413 CrystalShadGround (neutral\\nkhShad.grp)\r\n# 412 FlagShadCarried (neutral\\nflSha2.grp)\r\n# 411 FlagShadGround (neutral\\nflShad.grp)\r\n# 410 DataDiskShadCarried (neutral\\nddSha2.grp)\r\n# 409 DataDiskShadGround (neutral\\nddShad.grp)\r\n# 408 TerranGasTankShad (neutral\\ngcShad.grp)\r\n# 407 ZergGasSackShad (neutral\\ngsShad.grp)\r\n# 406 ProtossGasOrbShad (neutral\\ngoShad.grp)\r\n# 405 MineralChunkShad (neutral\\norShad.grp)\r\n.headerstart\r\nIsId           \t215\r\nType           \t1\r\nInit           \tPowerupsShadowHeaderInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPowerupsShadowHeaderInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 392 Flag (neutral\\Flag.grp)\r\n.headerstart\r\nIsId           \t216\r\nType           \t1\r\nInit           \tFlagInit\r\nDeath          \tFlagDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFlagInit:\r\n\tplayfram       \t0\r\n\tpwrupcondjmp   \tFlagLocal00\r\n\timgul          \t411 0 0\t# FlagShadGround (neutral\\nflShad.grp)\r\n\tgoto           \tFlagLocal01\r\n\r\nFlagLocal00:\r\n\twait           \t1\r\n\tswitchul       \t412\r\nFlagLocal01:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tFlagLocal01\r\n\r\nFlagDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 394 PsiEmmiter (neutral\\PsiEmit.grp)\r\n.headerstart\r\nIsId           \t217\r\nType           \t1\r\nInit           \tPsiEmitterInit\r\nDeath          \tPsiEmitterDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsiEmitterInit:\r\n\tpwrupcondjmp   \tPsiEmitterLocal00\r\n\timgul          \t417 0 0\t# PsiEmitterShadGround (neutral\\npsShad.grp)\r\n\tgoto           \tPsiEmitterLocal01\r\n\r\nPsiEmitterLocal00:\r\n\twait           \t1\r\n\tswitchul       \t418\r\n\tgoto           \tPsiEmitterLocal01\r\n\r\nPsiEmitterLocal01:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tgoto           \tPsiEmitterLocal01\r\n\r\nPsiEmitterDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 395 DataDisc (neutral\\DataDisk.grp)\r\n.headerstart\r\nIsId           \t218\r\nType           \t1\r\nInit           \tDataDiskInit\r\nDeath          \tDataDiskDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDataDiskInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tpwrupcondjmp   \tDataDiskLocal00\r\n\timgul          \t409 0 0\t# DataDiskShadGround (neutral\\nddShad.grp)\r\n\tgoto           \tlong00\r\n\r\nDataDiskLocal00:\r\n\twait           \t1\r\n\tswitchul       \t410\r\n\tgoto           \tlong00\r\n\r\nDataDiskDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 959 KhalisCrystal (neutral\\Khalis.grp)\r\n# 958 UrajCrystal (neutral\\Uraj.grp)\r\n# 396 KhadarinCrystal (neutral\\KhChunk.grp)\r\n.headerstart\r\nIsId           \t219\r\nType           \t1\r\nInit           \tCrystalsShadowsInit\r\nDeath          \tCrystalsShadowsDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCrystalsShadowsInit:\r\n\tplayfram       \t0\r\n\tpwrupcondjmp   \tCrystalsShadowsLocal00\r\n\timgul          \t413 0 0\t# CrystalShadGround (neutral\\nkhShad.grp)\r\n\tgoto           \tlong00\r\n\r\nCrystalsShadowsLocal00:\r\n\twait           \t1\r\n\tswitchul       \t414\r\n\tgoto           \tlong00\r\n\r\nCrystalsShadowsDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 393 Chrysalis (neutral\\KerrEgg.grp)\r\n.headerstart\r\nIsId           \t220\r\nType           \t1\r\nInit           \tYoungChrysalisInit\r\nDeath          \tYoungChrysalisDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nYoungChrysalisInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tpwrupcondjmp   \tYoungChrysalisLocal00\r\n\timgul          \t415 0 0\t# ChrysalisShadGround (neutral\\nkeShad.grp)\r\n\tgoto           \tlong00\r\n\r\nYoungChrysalisLocal00:\r\n\twait           \t1\r\n\tswitchul       \t416\r\n\tgoto           \tlong00\r\n\r\nYoungChrysalisDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 397 MineralChunk (neutral\\OreChunk.grp)\r\n.headerstart\r\nIsId           \t221\r\nType           \t1\r\nInit           \tOreChunkInit\r\nDeath          \tOreChunkDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOreChunkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tpwrupcondjmp   \tlong00\r\n\timgul          \t405 0 0\t# MineralChunkShad (neutral\\norShad.grp)\r\n\tgoto           \tlong00\r\n\r\nOreChunkDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 398 Unknown398 (neutral\\OreChunk.grp)\r\n.headerstart\r\nIsId           \t222\r\nType           \t1\r\nInit           \tOreChunkInit\r\nDeath          \tOreChunkDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 401 ZergGasSac (neutral\\GasSac.grp)\r\n.headerstart\r\nIsId           \t223\r\nType           \t1\r\nInit           \tGasSacInit\r\nDeath          \tGasSacDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGasSacInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tpwrupcondjmp   \tlong00\r\n\timgul          \t407 0 0\t# ZergGasSackShad (neutral\\ngsShad.grp)\r\n\tgoto           \tlong00\r\n\r\nGasSacDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 402 Unknown402 (neutral\\GasSac.grp)\r\n.headerstart\r\nIsId           \t224\r\nType           \t1\r\nInit           \tGasSac2Init\r\nDeath          \tGasSacDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGasSac2Init:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tpwrupcondjmp   \tlong00\r\n\timgul          \t407 0 0\t# ZergGasSackShad (neutral\\ngsShad.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 399 ProtossGasOrb (neutral\\GasOrb.grp)\r\n.headerstart\r\nIsId           \t225\r\nType           \t1\r\nInit           \tGasOrbInit\r\nDeath          \tGasOrbDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGasOrbInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tpwrupcondjmp   \tlong00\r\n\timgul          \t406 0 0\t# ProtossGasOrbShad (neutral\\ngoShad.grp)\r\n\tgoto           \tlong00\r\n\r\nGasOrbDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 400 Unknown400 (neutral\\GasOrb.grp)\r\n.headerstart\r\nIsId           \t226\r\nType           \t1\r\nInit           \tGasOrb2Init\r\nDeath          \tGasOrbDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGasOrb2Init:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tpwrupcondjmp   \tlong00\r\n\timgul          \t406 0 0\t# ProtossGasOrbShad (neutral\\ngoShad.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 403 TerranGasTank (neutral\\GasTank.grp)\r\n.headerstart\r\nIsId           \t227\r\nType           \t1\r\nInit           \tGasTankInit\r\nDeath          \tGasTankDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGasTankInit:\r\n\tplayfram       \t0\r\n\tpwrupcondjmp   \tlong00\r\n\timgul          \t408 0 0\t# TerranGasTankShad (neutral\\ngcShad.grp)\r\n\tgoto           \tlong00\r\n\r\nGasTankDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 404 Unknown404 (neutral\\GasTank.grp)\r\n.headerstart\r\nIsId           \t228\r\nType           \t1\r\nInit           \tGasTank2Init\r\nDeath          \tGasTankDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGasTank2Init:\r\n\tplayfram       \t1\r\n\tpwrupcondjmp   \tlong00\r\n\timgul          \t408 0 0\t# TerranGasTankShad (neutral\\ngcShad.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 549 Unknown549 (thingy\\emsBeam.grp)\r\n.headerstart\r\nIsId           \t229\r\nType           \t1\r\nInit           \tArchonOverlayInit\r\nDeath          \tArchonOverlayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArchonOverlayInit:\r\n\tnobrkcodestart \t\r\n\ttmprmgraphicstart\t\r\n\ttrgtrangecondjmp\t70 ArchonOverlayLocal00\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tgoto           \tArchonOverlayDeath\r\n\r\nArchonOverlayLocal00:\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\ttmprmgraphicend\t\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\nArchonOverlayDeath:\r\n\tnobrkcodeend   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 520 Unknown520 (bullet\\ephFire.grp)\r\n.headerstart\r\nIsId           \t230\r\nType           \t2\r\nInit           \tParticleBeamHitInit\r\nDeath          \tParticleBeamHitDeath\r\nGndAttkInit    \tParticleBeamHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nParticleBeamHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nParticleBeamHitDeath:\r\n\tplayfram       \t0\r\n\tplaysnd        \t614\t# Protoss\\PROBE\\PPrMin00.WAV\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 519 Unknown519 (bullet\\pspark.grp)\r\n.headerstart\r\nIsId           \t231\r\nType           \t2\r\nInit           \tDualPhotonBlasterHitInit\r\nDeath          \tDualPhotonBlasterHitDeath\r\nGndAttkInit    \tDualPhotonBlasterHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDualPhotonBlasterHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nDualPhotonBlasterHitDeath:\r\n\tplayfram       \t0\r\n\tplaysnd        \t66\t# Bullet\\BlastGn2.wav\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 521 Unknown521 (bullet\\hks.grp)\r\n.headerstart\r\nIsId           \t232\r\nType           \t2\r\nInit           \tAntiMatterMissileInit\r\nDeath          \tAntiMatterMissileDeath\r\nGndAttkInit    \tAntiMatterMissileGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAntiMatterMissileInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tplaysnd        \t80\t# Bullet\\HKMISSLE.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\nAntiMatterMissileGndAttkInit:\r\n\twait           \t2\r\n\tsprol          \t373 0 0\t# ScarabTrail (thingy\\HKTrail.grp)\r\n\tgoto           \tAntiMatterMissileGndAttkInit\r\n\r\nAntiMatterMissileDeath:\r\n\timgol          \t442 0 0\t# Unknown442 (thingy\\HKexplod.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 522 PhotonCannonsInterceptor (bullet\\blastcan.grp)\r\n.headerstart\r\nIsId           \t233\r\nType           \t2\r\nInit           \tPulseCannonInit\r\nDeath          \tPulseCannonDeath\r\nGndAttkInit    \tPulseCannonGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPulseCannonInit:\r\n\tplaysnd        \t65\t# Bullet\\BlastCan.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nPulseCannonGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tgoto           \tPulseCannonGndAttkInit\r\n\r\nPulseCannonDeath:\r\n\tplaysnd        \t9\t# Misc\\ExploSm.wav\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 523 PhaseDisruptor (bullet\\dragbull.grp)\r\n.headerstart\r\nIsId           \t234\r\nType           \t2\r\nInit           \tPhaseDisruptorInit\r\nDeath          \tPhaseDisruptorDeath\r\nGndAttkInit    \tPhaseDisruptorGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPhaseDisruptorInit:\r\n\tplaysnd        \t99\t# Bullet\\DragBull.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nPhaseDisruptorGndAttkInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tgoto           \tPhaseDisruptorGndAttkInit\r\n\r\nPhaseDisruptorDeath:\r\n\timgol          \t427 0 0\t# Unknown427 (thingy\\HKexplod.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 524 Unknown524 (bullet\\epbBul.grp)\r\n.headerstart\r\nIsId           \t235\r\nType           \t2\r\nInit           \tSTASTSPhotonCannonOverlayInit\r\nDeath          \tSTASTSPhotonCannonOverlayDeath\r\nGndAttkInit    \tSTASTSPhotonCannonOverlayGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSTASTSPhotonCannonOverlayInit:\r\n\tplaysnd        \t99\t# Bullet\\DragBull.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nSTASTSPhotonCannonOverlayGndAttkInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tgoto           \tSTASTSPhotonCannonOverlayGndAttkInit\r\n\r\nSTASTSPhotonCannonOverlayDeath:\r\n\timgol          \t427 0 0\t# Unknown427 (thingy\\HKexplod.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 525 PsiStorm (thingy\\psiStorm.grp)\r\n.headerstart\r\nIsId           \t236\r\nType           \t14\r\nInit           \tPsionicStormInit\r\nDeath          \tPsionicStormDeath\r\nGndAttkInit    \tPsionicStormDeath\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tPsionicStormSpecialState2\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsionicStormInit:\r\n\tplayfram       \t0\r\n\tplaysnd        \t620\t# Protoss\\TEMPLAR\\PTeSto00.WAV\r\n\ttmprmgraphicstart\t\r\n\twait           \t5\r\n\tsigorder       \t1\r\nPsionicStormDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\nPsionicStormSpecialState2:\r\n\ttmprmgraphicend\t\r\nPsionicStormLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tgoto           \tPsionicStormLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 526 FusionCutter (bullet\\scvspark.grp)\r\n.headerstart\r\nIsId           \t237\r\nType           \t2\r\nInit           \tFusionCutterHitInit\r\nDeath          \tFusionCutterHitDeath\r\nGndAttkInit    \tFusionCutterHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFusionCutterHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nFusionCutterHitDeath:\r\n\tplayfram       \t0\r\n\tplaysndbtwn    \t35 39\t# terran\\SCV\\EDrRep00.wav, terran\\SCV\\EDrRep04.wav\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 527 Unknown527 (bullet\\tspark.grp)\r\n.headerstart\r\nIsId           \t238\r\nType           \t2\r\nInit           \tGaussRifleHitInit\r\nDeath          \tGaussRifleHitDeath\r\nGndAttkInit    \tGaussRifleHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGaussRifleHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nGaussRifleHitDeath:\r\n\tplayfram       \t0\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tplayfram       \t27\r\n\twait           \t1\r\n\tplayfram       \t36\r\n\twait           \t1\r\n\tplayfram       \t45\r\n\twait           \t1\r\n\tplayfram       \t54\r\n\twait           \t1\r\n\tplayfram       \t63\r\n\twait           \t1\r\n\tplayfram       \t72\r\n\twait           \t1\r\n\tplayfram       \t81\r\n\twait           \t1\r\n\tplayfram       \t90\r\n\twait           \t1\r\n\tplayfram       \t99\r\n\twait           \t1\r\n\tplayfram       \t108\r\n\twait           \t1\r\n\tplayfram       \t117\r\n\twait           \t1\r\n\tplayfram       \t126\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 528 GeminiMissles (bullet\\gemini.grp)\r\n.headerstart\r\nIsId           \t239\r\nType           \t2\r\nInit           \tGeminiMissilesInit\r\nDeath          \tGeminiMissilesDeath\r\nGndAttkInit    \tGeminiMissilesGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGeminiMissilesInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tplaysndbtwn    \t82 83\t# Bullet\\TPhFi200.wav, Bullet\\TPhFi200.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nGeminiMissilesGndAttkInit:\r\n\tsprol          \t309 0 0\t# MissleTrail (thingy\\smoke.grp)\r\n\twait           \t2\r\n\tgoto           \tGeminiMissilesGndAttkInit\r\n\r\nGeminiMissilesDeath:\r\n\tplaysnd        \t9\t# Misc\\ExploSm.wav\r\n\timgol          \t530 0 0\t# Unknown530 (thingy\\ecaHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 529 Unknown529 (bullet\\missile.grp)\r\n.headerstart\r\nIsId           \t240\r\nType           \t2\r\nInit           \tLongboltMissileInit\r\nDeath          \tLongboltMissileDeath\r\nGndAttkInit    \tLongboltMissileGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLongboltMissileInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tplaysnd        \t80\t# Bullet\\HKMISSLE.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nLongboltMissileGndAttkInit:\r\n\tsprol          \t309 0 0\t# MissleTrail (thingy\\smoke.grp)\r\n\twait           \t3\r\n\tgoto           \tLongboltMissileGndAttkInit\r\n\r\nLongboltMissileDeath:\r\n\tplaysnd        \t9\t# Misc\\ExploSm.wav\r\n\timgol          \t530 0 0\t# Unknown530 (thingy\\ecaHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 531 Unknown531 (thingy\\ecaHit.grp)\r\n.headerstart\r\nIsId           \t241\r\nType           \t2\r\nInit           \tC10CanisterRifleHitInit\r\nDeath          \tC10CanisterRifleHitDeath\r\nGndAttkInit    \tC10CanisterRifleHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nC10CanisterRifleHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nC10CanisterRifleHitDeath:\r\n\tplayfram       \t0\r\n\tdomissiledmg   \t\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 532 Unknown532 (bullet\\grenade.grp)\r\n.headerstart\r\nIsId           \t242\r\nType           \t2\r\nInit           \tFragmentationGrenadeInit\r\nDeath          \tFragmentationGrenadeDeath\r\nGndAttkInit    \tFragmentationGrenadeGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFragmentationGrenadeInit:\r\n\tplayfram       \t0\r\n\tplaysnd        \t106\t# Bullet\\tvuFir00.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nFragmentationGrenadeGndAttkInit:\r\n\tsprol          \t310 0 0\t# Fragmentationgrenadesmoke (thingy\\GreSmoke.grp)\r\n\twait           \t1\r\nFragmentationGrenadeLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tFragmentationGrenadeLocal00\r\n\r\nFragmentationGrenadeDeath:\r\n\timgol          \t440 0 0\t# Fragmentationgrenadehit (thingy\\efgHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 535 Unknown535 (thingy\\elbfireW.grp)\r\n# 534 Unknown534 (thingy\\elbfire.grp)\r\n.headerstart\r\nIsId           \t243\r\nType           \t2\r\nInit           \tLasersInit\r\nDeath          \tLasersDeath\r\nGndAttkInit    \tlong00\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLasersInit:\r\n\ttmprmgraphicstart\t\r\n\ttrgtrangecondjmp\t40 LasersLocal00\r\n\ttmprmgraphicend\t\r\nLasersLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tplaysnd        \t74\t# Bullet\\TPhFi100.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\n\tgoto           \tlong00\r\n\r\nLasersDeath:\r\n\timgol          \t447 0 0\t# LaserHit (thingy\\elbHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 360 lockdownmissileunused-whitebeam (thingy\\eldFire.grp)\r\n.headerstart\r\nIsId           \t244\r\nType           \t1\r\nInit           \tUnknown244Init\r\nDeath          \tUnknown244Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown244Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nUnknown244Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 363 lockdownunitoverlaylarge (thingy\\eldLarge.grp)\r\n# 362 lockdownunitoverlaymedium (thingy\\eldMed.grp)\r\n# 361 lockdownunitoverlaysmall (thingy\\eldSmall.grp)\r\n.headerstart\r\nIsId           \t245\r\nType           \t1\r\nInit           \tLockdownHitInit\r\nDeath          \tLockdownHitDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLockdownHitInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\nLockdownHitLocal00:\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tgoto           \tLockdownHitLocal00\r\n\r\nLockdownHitDeath:\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 533 Unknown533 (thingy\\mushroom.grp)\r\n.headerstart\r\nIsId           \t246\r\nType           \t2\r\nInit           \tArcliteShockCannonHitInit\r\nDeath          \tArcliteShockCannonHitDeath\r\nGndAttkInit    \tArcliteShockCannonHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nArcliteShockCannonHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nArcliteShockCannonHitDeath:\r\n\tplayfram       \t0\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\twait           \t1\r\n\tdomissiledmg   \t\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 541 Unknown541 (bullet\\eycBull.grp)\r\n.headerstart\r\nIsId           \t247\r\nType           \t2\r\nInit           \tYamatoGunInit\r\nDeath          \tYamatoGunDeath\r\nGndAttkInit    \tYamatoGunGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nYamatoGunInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tplaysnd        \t179\t# Terran\\BATTLE\\tBaYam02.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nYamatoGunGndAttkInit:\r\n\twait           \t3\r\n\tsprul          \t351 0 0\t# Unknown542 (bullet\\eycBull.grp)\r\n\tgoto           \tYamatoGunGndAttkInit\r\n\r\nYamatoGunDeath:\r\n\timgol          \t544 0 0\t# Unknown544 (thingy\\eycHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 542 Unknown542 (bullet\\eycBull.grp)\r\n.headerstart\r\nIsId           \t248\r\nType           \t0\r\nInit           \tYamatoGunTrailInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nYamatoGunTrailInit:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 554 Unknown554 (bullet\\missile.grp)\r\n.headerstart\r\nIsId           \t249\r\nType           \t2\r\nInit           \tLockdownMissileInit\r\nDeath          \tLockdownMissileDeath\r\nGndAttkInit    \tLockdownMissileGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLockdownMissileInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nLockdownMissileGndAttkInit:\r\n\tsprol          \t309 0 0\t# MissleTrail (thingy\\smoke.grp)\r\n\twait           \t3\r\n\tgoto           \tLockdownMissileGndAttkInit\r\n\r\nLockdownMissileDeath:\r\n\timgol          \t556 0 0\t# Unknown556 (thingy\\empl.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 536 Unknown536 (thingy\\ettFlash.grp)\r\n.headerstart\r\nIsId           \t250\r\nType           \t1\r\nInit           \tSiegeTank_Tank_TurretOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSiegeTank_Tank_TurretOverlayInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 537 Unknown537 (thingy\\esiFire.grp)\r\n.headerstart\r\nIsId           \t251\r\nType           \t1\r\nInit           \tSiegeTank_Siege_TurretOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSiegeTank_Siege_TurretOverlayInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 540 Unknown540 (thingy\\tveGlowW.grp)\r\n# 539 Unknown539 (thingy\\tveGlowO.grp)\r\n# 538 Unknown538 (thingy\\tveGlowB.grp)\r\n.headerstart\r\nIsId           \t252\r\nType           \t1\r\nInit           \tScienceVesselOverlayInit\r\nDeath          \tScienceVesselOverlayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScienceVesselOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t1\r\nScienceVesselOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 546 Unknown546 (thingy\\eveCast.grp)\r\n# 545 Unknown545 (thingy\\halmind.grp)\r\n.headerstart\r\nIsId           \t253\r\nType           \t1\r\nInit           \tHallucinationHitInit\r\nDeath          \tHallucinationHitDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHallucinationHitInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\nHallucinationHitDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n.headerstart\r\nIsId           \t254\r\nType           \t0\r\nInit           \tUnknown254Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown254Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x01\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x02\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x03\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x04\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x05\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x06\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x07\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x08\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x09\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0a\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0b\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0c\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0d\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0e\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0f\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x10\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 505 Unknown505 (bullet\\PDripHit.grp)\r\n.headerstart\r\nIsId           \t255\r\nType           \t2\r\nInit           \tUnknown255Init\r\nDeath          \tUnknown255Death\r\nGndAttkInit    \tUnknown255Death\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown255Init:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nUnknown255Death:\r\n\tplayfram       \t0\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 504 Unknown504 (bullet\\zspark.grp)\r\n.headerstart\r\nIsId           \t256\r\nType           \t2\r\nInit           \tNeedleSpinesHitInit\r\nDeath          \tNeedleSpinesHitDeath\r\nGndAttkInit    \tNeedleSpinesHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNeedleSpinesHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nNeedleSpinesHitDeath:\r\n\tplayfram       \t0\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 507 Unknown507 (thingy\\ep2Fire.grp)\r\n.headerstart\r\nIsId           \t257\r\nType           \t2\r\nInit           \tVenomInit\r\nDeath          \tVenomDeath\r\nGndAttkInit    \tlong00\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nVenomInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nVenomDeath:\r\n\tdomissiledmg   \t\r\n\timgol          \t508 0 0\t# Unknown508 (thingy\\etgHit.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 506 Unknown506 (bullet\\Tentacle.grp)\r\n.headerstart\r\nIsId           \t258\r\nType           \t2\r\nInit           \tSubterraneanTentacleInit\r\nDeath          \tSubterraneanTentacleDeath\r\nGndAttkInit    \tSubterraneanTentacleDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSubterraneanTentacleInit:\r\n\tplaysnd        \t79\t# Bullet\\ZLuHit00.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nSubterraneanTentacleDeath:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\tdomissiledmg   \t\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 508 Unknown508 (thingy\\etgHit.grp)\r\n.headerstart\r\nIsId           \t259\r\nType           \t1\r\nInit           \tVenomHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nVenomHitInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 509 Unknown509 (thingy\\ep3Shot.grp)\r\n.headerstart\r\nIsId           \t260\r\nType           \t2\r\nInit           \tAcidSporeInit\r\nDeath          \tAcidSporeDeath\r\nGndAttkInit    \tAcidSporeGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcidSporeInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nAcidSporeGndAttkInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tgoto           \tAcidSporeGndAttkInit\r\n\r\nAcidSporeDeath:\r\n\tdomissiledmg   \t\r\n\tplaysnd        \t72\t# Bullet\\ZGuHit00.wav\r\n\timgol          \t510 0 0\t# Unknown510 (thingy\\ep3Burst.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 510 Unknown510 (thingy\\ep3Burst.grp)\r\n.headerstart\r\nIsId           \t261\r\nType           \t1\r\nInit           \tAcidSporeHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcidSporeHitInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 518 Unknown518 (thingy\\eplMuzz.grp)\r\n.headerstart\r\nIsId           \t262\r\nType           \t1\r\nInit           \tGuardianAttackOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGuardianAttackOverlayInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 511 Unknown511 (bullet\\spores.grp)\r\n.headerstart\r\nIsId           \t264\r\nType           \t13\r\nInit           \tGlaveWurmInit\r\nDeath          \tGlaveWurmDeath\r\nGndAttkInit    \tGlaveWurmGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tGlaveWurmSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGlaveWurmInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nGlaveWurmGndAttkInit:\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tsprol          \t367 0 0\t# Unknown513 (thingy\\SpoTrail.grp)\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tgoto           \tGlaveWurmGndAttkInit\r\n\r\nGlaveWurmDeath:\r\n\tplaysnd        \t93\t# Bullet\\ZQuHit02.wav\r\n\tsprol          \t365 0 0\t# Unknown512 (thingy\\SporeHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\nGlaveWurmSpecialState1:\r\n\tplaysndbtwn    \t91 92\t# Bullet\\ZQuHit00.wav, Bullet\\ZQuHit01.wav\r\n\tsprol          \t365 0 0\t# Unknown512 (thingy\\SporeHit.grp)\r\n\tdomissiledmg   \t\r\n\tgoto           \tGlaveWurmGndAttkInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 512 Unknown512 (thingy\\SporeHit.grp)\r\n.headerstart\r\nIsId           \t265\r\nType           \t1\r\nInit           \tGlaveWurmHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGlaveWurmHitInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 515 Unknown515 (bullet\\Spore2.grp)\r\n.headerstart\r\nIsId           \t266\r\nType           \t2\r\nInit           \tSeekerSporesInit\r\nDeath          \tSeekerSporesDeath\r\nGndAttkInit    \tSeekerSporesGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSeekerSporesInit:\r\n\tplayfram       \t0\r\n\tplaysnd        \t78\t# Bullet\\ZLuFir00.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nSeekerSporesGndAttkInit:\r\n\tsprol          \t368 0 0\t# Unknown514 (thingy\\gSmoke.grp)\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tsprol          \t368 0 0\t# Unknown514 (thingy\\gSmoke.grp)\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tsprol          \t368 0 0\t# Unknown514 (thingy\\gSmoke.grp)\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tsprol          \t368 0 0\t# Unknown514 (thingy\\gSmoke.grp)\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tsprol          \t368 0 0\t# Unknown514 (thingy\\gSmoke.grp)\r\n\tgoto           \tSeekerSporesGndAttkInit\r\n\r\nSeekerSporesDeath:\r\n\tplaysnd        \t79\t# Bullet\\ZLuHit00.wav\r\n\tsprol          \t365 0 0\t# Unknown512 (thingy\\SporeHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 516 Parasite (bullet\\parasite.grp)\r\n.headerstart\r\nIsId           \t267\r\nType           \t2\r\nInit           \tQueenSpellHolderInit\r\nDeath          \tQueenSpellHolderDeath\r\nGndAttkInit    \tQueenSpellHolderGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nQueenSpellHolderInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tsigorder       \t1\r\nQueenSpellHolderGndAttkInit:\r\n\tgoto           \tlong00\r\n\r\nQueenSpellHolderDeath:\r\n\tsprol          \t365 0 0\t# Unknown512 (thingy\\SporeHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 548 Unknown548 (thingy\\emsHit.grp)\r\n.headerstart\r\nIsId           \t268\r\nType           \t2\r\nInit           \tPsionicShockwaveHitInit\r\nDeath          \tPsionicShockwaveHitDeath\r\nGndAttkInit    \tPsionicShockwaveHitDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsionicShockwaveHitInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nPsionicShockwaveHitDeath:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 513 Unknown513 (thingy\\SpoTrail.grp)\r\n.headerstart\r\nIsId           \t269\r\nType           \t1\r\nInit           \tGlaveWurmTrailInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGlaveWurmTrailInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 514 Unknown514 (thingy\\gSmoke.grp)\r\n.headerstart\r\nIsId           \t270\r\nType           \t1\r\nInit           \tSeekerSporesOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSeekerSporesOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 419 Unknown419 (thingy\\plasma.grp)\r\n.headerstart\r\nIsId           \t271\r\nType           \t1\r\nInit           \tAcidSprayInit\r\nDeath          \tAcidSprayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcidSprayInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t3\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t3\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t3\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t3\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t3\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t3\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t3\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t3\r\nAcidSprayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 420 Unknown420 (thingy\\PlasDrip.grp)\r\n.headerstart\r\nIsId           \t272\r\nType           \t1\r\nInit           \tUnknown272Init\r\nDeath          \tUnknown272Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown272Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\nUnknown272Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 960 Unknown960 (thingy\\bsmoke.grp)\r\n# 422 MissleTrail (thingy\\smoke.grp)\r\n.headerstart\r\nIsId           \t273\r\nType           \t1\r\nInit           \tGeminiMissilesTrailInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGeminiMissilesTrailInit:\r\n\ttmprmgraphicstart\t\r\n\twait           \t2\r\n\ttmprmgraphicend\t\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 423 Unknown423 (thingy\\bDust.grp)\r\n.headerstart\r\nIsId           \t274\r\nType           \t1\r\nInit           \tBurowingDustInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBurowingDustInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 957 UrsadonShad (neutral\\ncicShad.grp)\r\n# 955 KakaruShad (neutral\\Scritter.grp)\r\n# 953 ScantidShad (neutral\\nckShad.grp)\r\n# 950 PowerGeneraterShad (neutral\\tgnShad.grp)\r\n# 948 PsiDisruptorShad (neutral\\tpdShad.grp)\r\n# 945 MedicShad (terran\\tmeShad.grp)\r\n# 940 ValkyrieShad (terran\\bomber.grp)\r\n# 938 XelNagaTempleShad (protoss\\pxtShad.grp)\r\n# 935 WarpGateShad (protoss\\pwgShad.grp)\r\n# 930 CorsairShad (protoss\\corsair.grp)\r\n# 924 OvermindCocoonShad (zerg\\ZovShad.grp)\r\n# 922 LurkerShad (zerg\\zZluShad.grp)\r\n# 916 DevourerShad (zerg\\devour.grp)\r\n# 903 DesertDoodad53 (thingy\\tileset\\desert\\SLDPlnt4.grp)\r\n# 901 DesertDoodad51 (thingy\\tileset\\desert\\SLDMchn1.grp)\r\n# 899 DesertDoodad49 (thingy\\tileset\\desert\\SLDLbox1.grp)\r\n# 896 DesertDoodad46 (thingy\\tileset\\desert\\SHDLbox1.grp)\r\n# 893 DesertDoodad43 (thingy\\tileset\\desert\\SLDBTENT.grp)\r\n# 891 DesertDoodad41 (thingy\\tileset\\desert\\SLDBSUKY.grp)\r\n# 888 DesertDoodad38 (thingy\\tileset\\desert\\SLDBGREN.grp)\r\n# 886 DesertDoodad36 (thingy\\tileset\\desert\\SLDBGAS.grp)\r\n# 884 DesertDoodad34 (thingy\\tileset\\desert\\SLDBAZ.grp)\r\n# 882 DesertDoodad32 (thingy\\tileset\\desert\\SJGPLNT2.grp)\r\n# 879 DesertDoodad29 (thingy\\tileset\\desert\\SJGBRED.grp)\r\n# 877 DesertDoodad27 (thingy\\tileset\\desert\\SJGBFACT.grp)\r\n# 875 DesertDoodad25 (thingy\\tileset\\desert\\SJGBCOMM.grp)\r\n# 873 DesertDoodad23 (thingy\\tileset\\desert\\SJGBTENT.grp)\r\n# 871 DesertDoodad21 (thingy\\tileset\\desert\\SJGBSGN.grp)\r\n# 869 DesertDoodad19 (thingy\\tileset\\desert\\SJGBGEN.grp)\r\n# 867 DesertDoodad17 (thingy\\tileset\\desert\\SJGBGAS.grp)\r\n# 865 DesertDoodad15 (thingy\\tileset\\desert\\SJGBROKE.grp)\r\n# 863 DesertDoodad13 (thingy\\tileset\\desert\\SHDPLNT3.grp)\r\n# 861 DesertDoodad11 (thingy\\tileset\\desert\\SHDBTENT.grp)\r\n# 859 DesertDoodad9 (thingy\\tileset\\desert\\SHDBMOSS.grp)\r\n# 857 DesertDoodad7 (thingy\\tileset\\desert\\SHDBMED.grp)\r\n# 855 DesertDoodad5 (thingy\\tileset\\desert\\SHDBGAS.grp)\r\n# 853 DesertDoodad3 (thingy\\tileset\\desert\\SHDBBRKE.grp)\r\n# 850 IceWorldDoodad80 (thingy\\tileset\\ice\\sRJBTre4.grp)\r\n# 848 IceWorldDoodad78 (thingy\\tileset\\ice\\sRJBTre3.grp)\r\n# 846 IceWorldDoodad76 (thingy\\tileset\\ice\\sRJBTre2.grp)\r\n# 844 IceWorldDoodad74 (thingy\\tileset\\ice\\sRJBTre1.grp)\r\n# 835 IceWorldDoodad65 (thingy\\tileset\\ice\\SHDRadr2.grp)\r\n# 830 IceWorldDoodad60 (thingy\\tileset\\ice\\SLDthing.grp)\r\n# 828 IceWorldDoodad58 (thingy\\tileset\\ice\\SHDPipes.grp)\r\n# 826 IceWorldDoodad56 (thingy\\tileset\\ice\\SLDRck02.grp)\r\n# 824 IceWorldDoodad54 (thingy\\tileset\\ice\\SLDRck01.grp)\r\n# 822 IceWorldDoodad52 (thingy\\tileset\\ice\\SLDRdr03.grp)\r\n# 820 IceWorldDoodad50 (thingy\\tileset\\ice\\SLDRdr02.grp)\r\n# 818 IceWorldDoodad48 (thingy\\tileset\\ice\\SLDRdr01.grp)\r\n# 816 IceWorldDoodad46 (thingy\\tileset\\ice\\SLDDish.grp)\r\n# 814 IceWorldDoodad44 (thingy\\tileset\\ice\\SLDDtre2.grp)\r\n# 812 IceWorldDoodad42 (thingy\\tileset\\ice\\SLDDtre1.grp)\r\n# 810 IceWorldDoodad40 (thingy\\tileset\\ice\\SLDComm.grp)\r\n# 808 IceWorldDoodad38 (thingy\\tileset\\ice\\SLDbld02.grp)\r\n# 806 IceWorldDoodad36 (thingy\\tileset\\ice\\SLDbld01.grp)\r\n# 804 IceWorldDoodad34 (thingy\\tileset\\ice\\SLDBTre4.grp)\r\n# 802 IceWorldDoodad32 (thingy\\tileset\\ice\\SLDBTre3.grp)\r\n# 800 IceWorldDoodad30 (thingy\\tileset\\ice\\SLDBTre2.grp)\r\n# 798 IceWorldDoodad28 (thingy\\tileset\\ice\\SLDBTre1.grp)\r\n# 796 IceWorldDoodad26 (thingy\\tileset\\ice\\SHDTwr02.grp)\r\n# 794 IceWorldDoodad24 (thingy\\tileset\\ice\\SHDTwr01.grp)\r\n# 792 IceWorldDoodad22 (thingy\\tileset\\ice\\SHDSpire.grp)\r\n# 786 IceWorldDoodad16 (thingy\\tileset\\ice\\SHDRck02.grp)\r\n# 784 IceWorldDoodad14 (thingy\\tileset\\ice\\SHDRck01.grp)\r\n# 782 IceWorldDoodad12 (thingy\\tileset\\ice\\SHDradrR.grp)\r\n# 780 IceWorldDoodad10 (thingy\\tileset\\ice\\SHDradrl.grp)\r\n# 778 IceWorldDoodad8 (thingy\\tileset\\ice\\SHDbld04.grp)\r\n# 776 IceWorldDoodad6 (thingy\\tileset\\ice\\SHDbld03.grp)\r\n# 774 IceWorldDoodad4 (thingy\\tileset\\ice\\SHDbld02.grp)\r\n# 772 IceWorldDoodad2 (thingy\\tileset\\ice\\SHDbld01.grp)\r\n# 711 BadlandsDoodad21 (thingy\\tileset\\Badlands\\LDTree4S.grp)\r\n# 709 BadlandsDoodad19 (thingy\\tileset\\Badlands\\LDTree3S.grp)\r\n# 707 BadlandsDoodad17 (thingy\\tileset\\Badlands\\LDTree2S.grp)\r\n# 705 BadlandsDoodad15 (thingy\\tileset\\Badlands\\LDTree1S.grp)\r\n# 698 BadlandsDoodad8 (thingy\\tileset\\Badlands\\HDRock4S.grp)\r\n# 696 BadlandsDoodad6 (thingy\\tileset\\Badlands\\HDRock3S.grp)\r\n# 694 BadlandsDoodad4 (thingy\\tileset\\Badlands\\HDRock2S.grp)\r\n# 692 BadlandsDoodad2 (thingy\\tileset\\Badlands\\HDRock1S.grp)\r\n# 676 SpacePlatformDoodad11 (thingy\\tileset\\Platform\\Glob3Sha.grp)\r\n# 674 SpacePlatformDoodad9 (thingy\\tileset\\Platform\\Glob2Sha.grp)\r\n# 672 SpacePlatformDoodad7 (thingy\\tileset\\Platform\\Glob1Sha.grp)\r\n# 670 SpacePlatformDoodad5 (thingy\\tileset\\Platform\\Dish3Sha.grp)\r\n# 668 SpacePlatformDoodad3 (thingy\\tileset\\Platform\\Dish2Sha.grp)\r\n# 666 SpacePlatformDoodad (thingy\\tileset\\Platform\\Dish1Sha.grp)\r\n# 639 JungleDoodad30 (thingy\\tileset\\Jungle\\tree4sha.grp)\r\n# 637 JungleDoodad28 (thingy\\tileset\\Jungle\\tree3sha.grp)\r\n# 635 JungleDoodad26 (thingy\\tileset\\Jungle\\tree2sha.grp)\r\n# 633 JungleDoodad24 (thingy\\tileset\\Jungle\\tree1sha.grp)\r\n# 631 JungleDoodad22 (thingy\\tileset\\Jungle\\LDtree4s.grp)\r\n# 629 JungleDoodad20 (thingy\\tileset\\Jungle\\LDtree3s.grp)\r\n# 627 JungleDoodad18 (thingy\\tileset\\Jungle\\LDtree2s.grp)\r\n# 625 JungleDoodad16 (thingy\\tileset\\Jungle\\LDtree1s.grp)\r\n# 623 JungleDoodad14 (thingy\\tileset\\Jungle\\JUbush5s.grp)\r\n# 621 JungleDoodad12 (thingy\\tileset\\Jungle\\JUbush3s.grp)\r\n# 619 JungleDoodad10 (thingy\\tileset\\Jungle\\JUbush1S.grp)\r\n# 617 JungleDoodad8 (thingy\\tileset\\Jungle\\HDRock4s.grp)\r\n# 615 JungleDoodad6 (thingy\\tileset\\Jungle\\HDRock3s.grp)\r\n# 613 JungleDoodad4 (thingy\\tileset\\Jungle\\HDRock2s.grp)\r\n# 611 JungleDoodad2 (thingy\\tileset\\Jungle\\HDRock1s.grp)\r\n# 598 AshWorldDoodadRock5Shad (thingy\\tileset\\AshWorld\\Rock5Sha.grp)\r\n# 596 AshWorldDoodadRock4Shad (thingy\\tileset\\AshWorld\\Rock4Sha.grp)\r\n# 594 AshWorldDoodadRock3Shad (thingy\\tileset\\AshWorld\\Rock3Sha.grp)\r\n# 592 AshWorldDoodadRock2Shad (thingy\\tileset\\AshWorld\\Rock2Sha.grp)\r\n# 590 AshWorldDoodadRock1Shad (thingy\\tileset\\AshWorld\\Rock1Sha.grp)\r\n# 352 MineralDeposit3Shad (neutral\\min03Sha.grp)\r\n# 350 MineralDeposit2Shad (neutral\\min02Sha.grp)\r\n# 348 MineralDeposit1Shad (neutral\\min01Sha.grp)\r\n# 343 BengalassShad (neutral\\njcShad.grp)\r\n# 341 RynadonShad (neutral\\nbcShad.grp)\r\n# 339 RagnasaurShad (neutral\\nacShad.grp)\r\n# 331 ConstructionSitesmallShad (terran\\tb1Shad.grp)\r\n# 328 ConstructionSitemediumShad (terran\\tb3Shad.grp)\r\n# 326 ConstructionSitelargeShad (terran\\tb2Shad.grp)\r\n# 324 EngineeringBayShad (terran\\twpShad.grp)\r\n# 321 StarportShad (terran\\tspShad.grp)\r\n# 317 NuclearMissileShad (terran\\nukemiss.grp)\r\n# 315 NukeSiloShad (terran\\tnsShad.grp)\r\n# 311 ScienceFacilityShad (terran\\trlShad.grp)\r\n# 308 RefineryShad (terran\\treShad.grp)\r\n# 305 BunkerShad (terran\\tpbShad.grp)\r\n# 303 PhysicsLabShad (terran\\tplShad.grp)\r\n# 300 CrashedNoradIIShad (neutral\\cbaShad.grp)\r\n# 298 MissleTurretShad (terran\\tmiShad.grp)\r\n# 295 MachineShopShad (terran\\tmsShad.grp)\r\n# 291 CovertOpsShad (terran\\tglShad.grp)\r\n# 287 FactoryShad (terran\\tfaShad.grp)\r\n# 284 ControlTowerShad (terran\\tddShad.grp)\r\n# 280 SupplyDepotShad (terran\\tdeShad.grp)\r\n# 277 CommandCenterShad (terran\\tccShad.grp)\r\n# 274 ComsatStationShad (terran\\tcsShad.grp)\r\n# 270 ArmoryShad (terran\\tclShad.grp)\r\n# 267 BarracksShad (terran\\tbrShad.grp)\r\n# 265 AcademyShad (terran\\tacShad.grp)\r\n# 262 ScienceVesselShad (terran\\tveShad.grp)\r\n# 259 SpiderMineShad (terran\\tsmShad.grp)\r\n# 257 VultureShad (terran\\Vulture.grp)\r\n# 255 SiegeTankSiegeShad (terran\\tstShad.grp)\r\n# 252 SiegeTankTankShad (terran\\ttaShad.grp)\r\n# 248 SCVShad (terran\\SCV.grp)\r\n# 244 WraithShad (terran\\phoenix.grp)\r\n# 240 MarineShad (terran\\tmaShad.grp)\r\n# 238 KerriganGhostShad (terran\\ughShad.grp)\r\n# 236 GoliathShad (terran\\tgoShad.grp)\r\n# 229 GhostShad (terran\\tghShad.grp)\r\n# 227 FirebatShad (terran\\tfbShad.grp)\r\n# 224 DropshipShad (terran\\dropship.grp)\r\n# 222 CivilianShad (neutral\\nciShad.grp)\r\n# 219 BattlecruiserShad (terran\\BattleCr.grp)\r\n# 212 FleetBeaconShad (protoss\\pwaShad.grp)\r\n# 206 RoboticsSupportBayShad (protoss\\pstShad.grp)\r\n# 202 StargateShad (protoss\\psgShad.grp)\r\n# 198 ShieldBatteryShad (protoss\\pbaShad.grp)\r\n# 194 RoboticsFacilityShad (protoss\\proShad.grp)\r\n# 191 PylonShad (protoss\\ppyShad.grp)\r\n# 188 ArbiterTribunalShad (protoss\\pauShad.grp)\r\n# 184 PhotonCannonShad (protoss\\ppbShad.grp)\r\n# 182 NexusShad (protoss\\pneShad.grp)\r\n# 177 CyberneticsCoreShad (protoss\\pgcShad.grp)\r\n# 173 GatewayShad (protoss\\pgaShad.grp)\r\n# 170 ForgeShad (protoss\\pfoShad.grp)\r\n# 166 CitadelofAdunShad (protoss\\pciShad.grp)\r\n# 163 ObservatoryShad (protoss\\pbeShad.grp)\r\n# 160 Unknown160 (protoss\\pasShad.grp)\r\n# 157 TemplarArchivesShad (protoss\\pacShad.grp)\r\n# 152 ZealotShad (protoss\\pzeShad.grp)\r\n# 149 ObserverShad (protoss\\witness.grp)\r\n# 145 ReaverShad (protoss\\ptrShad.grp)\r\n# 141 ScoutShad (protoss\\scout.grp)\r\n# 138 ProbeShad (protoss\\probe.grp)\r\n# 131 ArbiterShad (protoss\\arbiter.grp)\r\n# 127 HighTemplarShad (protoss\\pteShad.grp)\r\n# 123 DragoonShad (protoss\\pdrShad.grp)\r\n# 119 ShuttleShad (protoss\\shuttle.grp)\r\n# 117 InterceptorShad (protoss\\Intercep.grp)\r\n# 113 CarrierShad (protoss\\carrier.grp)\r\n# 106 ZergBuildingMorphShad (zerg\\ZBShad.grp)\r\n# 100 SporeColonyShad (zerg\\zscShad.grp)\r\n# 098 SpireShad (zerg\\zspShad.grp)\r\n# 096 HydraliskDenShad (zerg\\zsbShad.grp)\r\n# 094 ExtractorShad (zerg\\zreShad.grp)\r\n# 092 UltraliskCavernShad (zerg\\zrcShad.grp)\r\n# 087 NydusCanalShad (zerg\\znyShad.grp)\r\n# 085 QueensNestShad (zerg\\zneShad.grp)\r\n# 083 DefilerMoundShad (zerg\\zmhShad.grp)\r\n# 081 GreaterSpireShad (zerg\\zmcShad.grp)\r\n# 079 MatureChysalisShad (neutral\\nkoShad.grp)\r\n# 077 SunkenColonyShad (zerg\\zluShad.grp)\r\n# 075 LairShad (zerg\\zlrShad.grp)\r\n# 073 HiveShad (zerg\\zhiShad.grp)\r\n# 071 HatcheryShad (zerg\\zhaShad.grp)\r\n# 069 CreepColonyShad (zerg\\zfcShad.grp)\r\n# 067 EvolutinoChamberShad (zerg\\zceShad.grp)\r\n# 065 SpawningPoolShad (zerg\\zchShad.grp)\r\n# 062 CerabrateShad (zerg\\zucShad.grp)\r\n# 055 ZerglingShad (zerg\\zzeShad.grp)\r\n# 051 UltraliskShad (zerg\\zulShad.grp)\r\n# 047 QueenShad (zerg\\queen.grp)\r\n# 043 OverlordShad (zerg\\overlord.grp)\r\n# 039 MutaliskShad (zerg\\mutalid.grp)\r\n# 034 InfestedKerriganShad (zerg\\uikShad.grp)\r\n# 030 HydraliskShad (zerg\\zhyShad.grp)\r\n# 026 GuardianShad (zerg\\guardian.grp)\r\n# 022 ZergEggShad (zerg\\zegShad.grp)\r\n# 018 DroneShad (zerg\\drone.grp)\r\n# 014 DefilerShad (zerg\\defiler.grp)\r\n# 012 GuardianCocoonShad (zerg\\cocoon.grp)\r\n# 009 InfestedTerranShad (zerg\\zbgShad.grp)\r\n# 006 BroodlingShad (zerg\\zbrShad.grp)\r\n# 001 ScourgeShad (zerg\\avenger.grp)\r\n.headerstart\r\nIsId           \t275\r\nType           \t1\r\nInit           \tShadowHeaderInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nShadowHeaderInit:\r\n\twait           \t1\r\n\tfollowmaingraphic\t\r\n\tgoto           \tShadowHeaderInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 424 PlasmaShields (thingy\\pshield.grp)\r\n.headerstart\r\nIsId           \t276\r\nType           \t1\r\nInit           \tShieldOverlayInit\r\nDeath          \tShieldOverlayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nShieldOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t17\r\n\twait           \t1\r\n\tplayfram       \t34\r\n\twait           \t1\r\n\tplayfram       \t51\r\nShieldOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 425 Unknown425 (thingy\\explo2.grp)\r\n.headerstart\r\nIsId           \t277\r\nType           \t1\r\nInit           \tUnknown277Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown277Init:\r\n\tplaysnd        \t9\t# Misc\\ExploSm.wav\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 426 Unknown426 (thingy\\dbl_exp.grp)\r\n.headerstart\r\nIsId           \t278\r\nType           \t1\r\nInit           \tDoubleExplosionInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDoubleExplosionInit:\r\n\tplaysnd        \t9\t# Misc\\ExploSm.wav\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tplayfram       \t27\r\n\twait           \t1\r\n\tplayfram       \t36\r\n\twait           \t1\r\n\tplayfram       \t45\r\n\twait           \t1\r\n\tplayfram       \t54\r\n\twait           \t1\r\n\tplayfram       \t63\r\n\twait           \t1\r\n\tplayfram       \t72\r\n\twait           \t1\r\n\tplayfram       \t81\r\n\twait           \t1\r\n\tplayfram       \t90\r\n\twait           \t1\r\n\tplayfram       \t99\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 428 Smallexplosion (thingy\\small.grp)\r\n.headerstart\r\nIsId           \t279\r\nType           \t1\r\nInit           \tNuclearMissileDeathInit\r\nDeath          \tNuclearMissileDeathDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNuclearMissileDeathInit:\r\n\tplaysnd        \t9\t# Misc\\ExploSm.wav\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t1\r\nNuclearMissileDeathDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 429 Spidermineexplosion (thingy\\tmnExplo.grp)\r\n.headerstart\r\nIsId           \t280\r\nType           \t0\r\nInit           \tSpiderMineExplosionInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSpiderMineExplosionInit:\r\n\tplaysnd        \t10\t# Misc\\Explo1.wav\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 434 Unknown434 (thingy\\GeySmok5.grp)\r\n# 433 Unknown433 (thingy\\GeySmok4.grp)\r\n# 432 Unknown432 (thingy\\GeySmok3.grp)\r\n# 431 Unknown431 (thingy\\GeySmok2.grp)\r\n# 430 Unknown430 (thingy\\GeySmok1.grp)\r\n.headerstart\r\nIsId           \t281\r\nType           \t1\r\nInit           \tVespeneGeyserSmokesInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nVespeneGeyserSmokesInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 439 Unknown439 (thingy\\GeySmoS1.grp)\r\n# 438 Unknown438 (thingy\\GeySmoS1.grp)\r\n# 437 Unknown437 (thingy\\GeySmoS1.grp)\r\n# 436 Unknown436 (thingy\\GeySmoS1.grp)\r\n# 435 Unknown435 (thingy\\GeySmoS1.grp)\r\n.headerstart\r\nIsId           \t282\r\nType           \t1\r\nInit           \tUnknown282Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown282Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 440 Fragmentationgrenadehit (thingy\\efgHit.grp)\r\n.headerstart\r\nIsId           \t283\r\nType           \t1\r\nInit           \tFragmentationGrenadeHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFragmentationGrenadeHitInit:\r\n\tplaysndbtwn    \t107 109\t# Bullet\\tvuHit00.wav, Bullet\\tvuHit02.wav\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 441 Fragmentationgrenadesmoke (thingy\\GreSmoke.grp)\r\n.headerstart\r\nIsId           \t284\r\nType           \t1\r\nInit           \tGrenadeShotSmokeInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGrenadeShotSmokeInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 442 Unknown442 (thingy\\HKexplod.grp)\r\n# 427 Unknown427 (thingy\\HKexplod.grp)\r\n.headerstart\r\nIsId           \t285\r\nType           \t1\r\nInit           \tAntiMatterMissileHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAntiMatterMissileHitInit:\r\n\tplaysnd        \t8\t# Misc\\ExploMed.wav\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 443 ScarabTrail (thingy\\HKTrail.grp)\r\n.headerstart\r\nIsId           \t286\r\nType           \t1\r\nInit           \tAntiMatterMissileOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAntiMatterMissileOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 444 ScarabExplosion (thingy\\psaExplo.grp)\r\n.headerstart\r\nIsId           \t287\r\nType           \t1\r\nInit           \tScarabHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScarabHitInit:\r\n\tplaysnd        \t100\t# Bullet\\psaHit00.wav\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 445 Unknown445 (thingy\\blackx.grp)\r\n.headerstart\r\nIsId           \t288\r\nType           \t2\r\nInit           \tlong00\r\nDeath          \t[NONE]\r\nGndAttkInit    \tCursorMarkerGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCursorMarkerGndAttkInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\t__2d           \t\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 580 od224 (thingy\\od224.grp)\r\n# 579 od146 (thingy\\od146.grp)\r\n# 578 od122 (thingy\\od122.grp)\r\n# 577 od110 (thingy\\od110.grp)\r\n# 576 od094 (thingy\\od094.grp)\r\n# 575 od072 (thingy\\od072.grp)\r\n# 574 od062 (thingy\\od062.grp)\r\n# 573 od048 (thingy\\od048.grp)\r\n# 572 od032 (thingy\\od032.grp)\r\n# 571 od022 (thingy\\od022.grp)\r\n# 570 o224 (thingy\\o224.grp)\r\n# 569 o146 (thingy\\o146.grp)\r\n# 568 o122 (thingy\\o122.grp)\r\n# 567 o110 (thingy\\o110.grp)\r\n# 566 o094 (thingy\\o094.grp)\r\n# 565 o072 (thingy\\o072.grp)\r\n# 564 o062 (thingy\\o062.grp)\r\n# 563 o048 (thingy\\o048.grp)\r\n# 562 o032 (thingy\\o032.grp)\r\n# 561 o022 (thingy\\o022.grp)\r\n# 560 Unknown560 (thingy\\blackx.grp)\r\n.headerstart\r\nIsId           \t289\r\nType           \t1\r\nInit           \tlong00\r\nDeath          \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 120 ShuttleGlow (thingy\\pshGlow.grp)\r\n# 114 CarrierGlow (thingy\\pcaGlow.grp)\r\n.headerstart\r\nIsId           \t290\r\nType           \t12\r\nInit           \tCarrierEnginesInit\r\nDeath          \tlong01\r\nGndAttkInit    \tlong01\r\nAirAttkInit    \tlong01\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong01\r\nAirAttkRpt     \tlong01\r\nCastSpell      \tlong01\r\nGndAttkToIdle  \tlong01\r\nAirAttkToIdle  \tlong01\r\nUnused2        \t[NONE]\r\nWalking        \tCarrierEnginesInit\r\nWalkingToIdle  \tlong01\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCarrierEnginesInit:\r\n\twait           \t1\r\n\tfollowmaingraphic\t\r\n\tgoto           \tCarrierEnginesInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 943 ValkyrieAfterburners (thingy\\tbmAfter.grp)\r\n# 942 ValkyrieOverlay2 (thingy\\tbmGlow.grp)\r\n# 941 ValkyrieOverlay (thingy\\tbmGlow.grp)\r\n# 249 SCVGlow (thingy\\tscGlow.grp)\r\n# 225 DropshipGlow (thingy\\tdrGlow.grp)\r\n# 220 BattlecruiserGlow (thingy\\tbaGlow.grp)\r\n# 132 ArbiterGlow (thingy\\pabGlow.grp)\r\n.headerstart\r\nIsId           \t291\r\nType           \t15\r\nInit           \tEngines_GlowHeaderInit\r\nDeath          \tlong01\r\nGndAttkInit    \tlong01\r\nAirAttkInit    \tlong01\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong01\r\nAirAttkRpt     \tlong01\r\nCastSpell      \tlong01\r\nGndAttkToIdle  \tlong01\r\nAirAttkToIdle  \tlong01\r\nUnused2        \t[NONE]\r\nWalking        \tEngines_GlowHeaderInit\r\nWalkingToIdle  \tlong01\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEngines_GlowHeaderInit:\r\n\tengset         \t0\r\n\twait           \t1\r\n\tengset         \t1\r\n\twait           \t1\r\n\tgoto           \tEngines_GlowHeaderInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 503 Unknown503 (bullet\\circle14.grp)\r\n.headerstart\r\nIsId           \t292\r\nType           \t2\r\nInit           \tWhiteCircleInit\r\nDeath          \tWhiteCircleDeath\r\nGndAttkInit    \tWhiteCircleDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWhiteCircleInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nWhiteCircleDeath:\r\n\tplayfram       \t0\r\n\twait           \t5\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 446 BCLaserFireOverlay (thingy\\elbBat.grp)\r\n.headerstart\r\nIsId           \t293\r\nType           \t1\r\nInit           \tBattlecruiserAttackOverlayInit\r\nDeath          \tBattlecruiserAttackOverlayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBattlecruiserAttackOverlayInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\nBattlecruiserAttackOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 447 LaserHit (thingy\\elbHit.grp)\r\n.headerstart\r\nIsId           \t294\r\nType           \t1\r\nInit           \tLasersHitInit\r\nDeath          \tLasersHitDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLasersHitInit:\r\n\tplaysnd        \t77\t# Bullet\\LASRHIT3.wav\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\nLasersHitDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 448 Unknown448 (thingy\\elbMuzz.grp)\r\n.headerstart\r\nIsId           \t295\r\nType           \t1\r\nInit           \tUnknown295Init\r\nDeath          \tUnknown295Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown295Init:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\nUnknown295Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 387 Plague (thingy\\ebbCloud.grp)\r\n.headerstart\r\nIsId           \t296\r\nType           \t2\r\nInit           \tPlagueCloudInit\r\nDeath          \tPlagueCloudDeath\r\nGndAttkInit    \tPlagueCloudDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPlagueCloudInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nPlagueCloudDeath:\r\n\tplaysnd        \t816\t# Zerg\\DEFILER\\ZDeBlo00.WAV\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tdomissiledmg   \t\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 390 PlagueUnitOverlayLarge (thingy\\ebbHitL.grp)\r\n# 389 PlagueUnitOverlayMedium (thingy\\ebbHitM.grp)\r\n# 388 PlagueUnitOverlaySmall (thingy\\ebbHitS.grp)\r\n.headerstart\r\nIsId           \t297\r\nType           \t1\r\nInit           \tPlagueOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPlagueOverlayInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 3\r\n\ttmprmgraphicend\t\r\nPlagueOverlayLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twaitrand       \t2 3\r\n\tgoto           \tPlagueOverlayLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 517 Consume (thingy\\consume.grp)\r\n.headerstart\r\nIsId           \t298\r\nType           \t2\r\nInit           \tConsumeInit\r\nDeath          \tConsumeDeath\r\nGndAttkInit    \tConsumeDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nConsumeInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nConsumeDeath:\r\n\tplaysnd        \t813\t# Zerg\\DEFILER\\ZDeCon00.WAV\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\tdomissiledmg   \t\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 337 DarkSwarm (thingy\\Dswarm.grp)\r\n.headerstart\r\nIsId           \t299\r\nType           \t1\r\nInit           \tDarkSwarmInit\r\nDeath          \tDarkSwarmDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDarkSwarmInit:\r\n\tplaysnd        \t922\t# Zerg\\Queen\\ZQuSwm00.WAV\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\nDarkSwarmLocal00:\r\n\tplayfram       \t5\r\n\twait           \t3\r\n\tplayfram       \t6\r\n\twait           \t3\r\n\tplayfram       \t7\r\n\twait           \t3\r\n\tplayfram       \t8\r\n\twait           \t3\r\n\tplayfram       \t9\r\n\twait           \t3\r\n\tplayfram       \t8\r\n\twait           \t3\r\n\tplayfram       \t7\r\n\twait           \t3\r\n\tplayfram       \t6\r\n\twait           \t3\r\n\tgoto           \tDarkSwarmLocal00\r\n\r\nDarkSwarmDeath:\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 376 defencematrixbacklarge (thingy\\edmBackL.grp)\r\n# 375 defencematrixbackmedium (thingy\\edmBackM.grp)\r\n# 374 defencematrixbacksmall (thingy\\edmBackS.grp)\r\n# 373 defencematrixfrontlarge (thingy\\edmFronL.grp)\r\n# 372 defencematrixfrontmedium (thingy\\edmFronM.grp)\r\n# 371 defencematrixfrontsmall (thingy\\edmFronS.grp)\r\n.headerstart\r\nIsId           \t300\r\nType           \t1\r\nInit           \tDefensiveMatrixOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDefensiveMatrixOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tgoto           \tDefensiveMatrixOverlayInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 379 defencematrixhitlarge (thingy\\edmHitL.grp)\r\n# 378 defencematrixhitmedium (thingy\\edmHitM.grp)\r\n# 377 defencematrixhitsmall (thingy\\edmHitS.grp)\r\n.headerstart\r\nIsId           \t301\r\nType           \t1\r\nInit           \tDefensiveMatrixHitInit\r\nDeath          \tDefensiveMatrixHitDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDefensiveMatrixHitInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\nDefensiveMatrixHitDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 383 Ensnare (thingy\\Ensnare.grp)\r\n.headerstart\r\nIsId           \t302\r\nType           \t1\r\nInit           \tEnsnareInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEnsnareInit:\r\n\tplaysnd        \t924\t# Zerg\\Queen\\ZQuEns00.WAV\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 386 EnsnareUnitOverlayLarge (thingy\\ensGooL.grp)\r\n# 385 EnsnareUnitOverlayMedium (thingy\\ensGooM.grp)\r\n# 384 EnsnareUnitOverlaySmall (thingy\\ensGooS.grp)\r\n.headerstart\r\nIsId           \t303\r\nType           \t1\r\nInit           \tEnsnareOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEnsnareOverlayInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 3\r\n\ttmprmgraphicend\t\r\nEnsnareOverlayLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twaitrand       \t2 3\r\n\tgoto           \tEnsnareOverlayLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 382 Irradiatelarge (thingy\\eradLrg.grp)\r\n# 381 Irradiatemedium (thingy\\eradLrg.grp)\r\n# 380 Irradiatesmall (thingy\\eradLrg.grp)\r\n.headerstart\r\nIsId           \t304\r\nType           \t1\r\nInit           \tIrradiateInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nIrradiateInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tIrradiateInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 391 Recall (thingy\\recall.grp)\r\n.headerstart\r\nIsId           \t305\r\nType           \t1\r\nInit           \tRecallFieldInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRecallFieldInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 367 stasisfieldunitoverlaylarge (thingy\\esfLarge.grp)\r\n# 366 stasisfieldunitoverlaymedium (thingy\\esfSmall.grp)\r\n# 365 stasisfieldunitoverlaysmall (thingy\\esfSmall.grp)\r\n.headerstart\r\nIsId           \t306\r\nType           \t1\r\nInit           \tStasisFieldOverlayInit\r\nDeath          \tStasisFieldOverlayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStasisFieldOverlayInit:\r\n\tplayfram       \t0\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t3 8\r\n\ttmprmgraphicend\t\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\nStasisFieldOverlayLocal00:\r\n\twaitrand       \t1 3\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tgoto           \tStasisFieldOverlayLocal00\r\n\r\nStasisFieldOverlayDeath:\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 364 stasisfieldhit (thingy\\esfHit.grp)\r\n.headerstart\r\nIsId           \t307\r\nType           \t1\r\nInit           \tStasisFieldHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStasisFieldHitInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 370 shieldbatteryunitoverlaylarge (thingy\\sbaLarge.grp)\r\n.headerstart\r\nIsId           \t308\r\nType           \t1\r\nInit           \tRechargeShields_Large_Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRechargeShields_Large_Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 369 shieldbatteryunitoverlaymedium (thingy\\sbaSmall.grp)\r\n# 368 shieldbatteryunitoverlaysmall (thingy\\sbaSmall.grp)\r\n.headerstart\r\nIsId           \t309\r\nType           \t1\r\nInit           \tRechargeShields_Small_Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRechargeShields_Small_Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tgoto           \tRechargeShields_Small_Init\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 449 HighTemplarTrail (thingy\\pteglow.grp)\r\n.headerstart\r\nIsId           \t310\r\nType           \t1\r\nInit           \tHighTemplarGlowInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHighTemplarGlowInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 035 NeedleSpines (thingy\\spooge.grp)\r\n.headerstart\r\nIsId           \t311\r\nType           \t1\r\nInit           \tNeedleSpinesOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNeedleSpinesOverlayInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 421 FlameThrower (thingy\\flamer.grp)\r\n.headerstart\r\nIsId           \t312\r\nType           \t1\r\nInit           \tFlamethrowerInit\r\nDeath          \tFlamethrowerDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFlamethrowerInit:\r\n\tplaysndbtwn    \t314 315\t# Terran\\Firebat\\TFBFir00.WAV, Terran\\Firebat\\TFBFir01.WAV\r\n\tgoto           \tFlamethrowerLocal00\r\n\r\nFlamethrowerLocal00:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tgoto           \tFlamethrowerLocal01\r\n\r\nFlamethrowerLocal01:\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tgoto           \tFlamethrowerDeath\r\n\r\nFlamethrowerDeath:\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 530 Unknown530 (thingy\\ecaHit.grp)\r\n.headerstart\r\nIsId           \t313\r\nType           \t1\r\nInit           \tGeminiMissilesExplosionInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nGeminiMissilesExplosionInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 543 Unknown543 (thingy\\eycBlast.grp)\r\n.headerstart\r\nIsId           \t314\r\nType           \t1\r\nInit           \tYamatoGunOverlayInit\r\nDeath          \tYamatoGunOverlayDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nYamatoGunOverlayInit:\r\n\tplaysnd        \t178\t# Terran\\BATTLE\\tBaYam01.wav\r\n\tplayfram       \t4\r\n\tnobrkcodestart \t\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\tcastspell      \t\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tsigorder       \t2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\nYamatoGunOverlayDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 544 Unknown544 (thingy\\eycHit.grp)\r\n.headerstart\r\nIsId           \t315\r\nType           \t1\r\nInit           \tYamatoGunHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nYamatoGunHitInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 547 Unknown547 (thingy\\emsHit.grp)\r\n.headerstart\r\nIsId           \t316\r\nType           \t1\r\nInit           \tUnknown316Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown316Init:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\timguluselo     \t552 2 0\t# Unknown552 (thingy\\elect02a.grp)\r\n\timguluselo     \t550 2 1\t# Unknown550 (thingy\\elect02a.grp)\r\n\timgoluselo     \t553 2 2\t# Unknown553 (thingy\\elect02.grp)\r\n\timgoluselo     \t551 2 3\t# Unknown551 (thingy\\elect02.grp)\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 551 Unknown551 (thingy\\elect02.grp)\r\n# 550 Unknown550 (thingy\\elect02a.grp)\r\n.headerstart\r\nIsId           \t317\r\nType           \t1\r\nInit           \tPsionicStormPartVariant1Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsionicStormPartVariant1Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 553 Unknown553 (thingy\\elect02.grp)\r\n# 552 Unknown552 (thingy\\elect02a.grp)\r\n.headerstart\r\nIsId           \t318\r\nType           \t1\r\nInit           \tPsionicStormPartVariant2Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsionicStormPartVariant2Init:\r\n\tplayfram       \t0\r\n\tsetflipstate   \t1\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 555 Unknown555 (thingy\\emp.grp)\r\n.headerstart\r\nIsId           \t319\r\nType           \t0\r\nInit           \tEMPShockwaveHit_Part1_Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEMPShockwaveHit_Part1_Init:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 556 Unknown556 (thingy\\empl.grp)\r\n.headerstart\r\nIsId           \t320\r\nType           \t0\r\nInit           \tEMPShockwaveHit_Part2_Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nEMPShockwaveHit_Part2_Init:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\timgul          \t555 0 0\t# Unknown555 (thingy\\emp.grp)\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 559 Unknown559 (thingy\\ehaMed.grp)\r\n# 558 Unknown558 (thingy\\ehaMed.grp)\r\n# 557 Unknown557 (thingy\\ehaMed.grp)\r\n.headerstart\r\nIsId           \t321\r\nType           \t0\r\nInit           \tHallucinationDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHallucinationDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t3\r\n\tplayfram       \t1\r\n\twait           \t3\r\n\tplayfram       \t2\r\n\twait           \t3\r\n\tplayfram       \t3\r\n\twait           \t3\r\n\tplayfram       \t4\r\n\twait           \t3\r\n\tplayfram       \t5\r\n\twait           \t3\r\n\tplayfram       \t6\r\n\twait           \t3\r\n\tplayfram       \t7\r\n\twait           \t3\r\n\tplayfram       \t8\r\n\twait           \t3\r\n\tplayfram       \t9\r\n\twait           \t3\r\n\tplayfram       \t10\r\n\twait           \t3\r\n\tplayfram       \t11\r\n\twait           \t3\r\n\tplayfram       \t12\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 471 ProtossBuildingBurn6 (thingy\\oFireV.grp)\r\n# 470 ProtossBuildingBurn5 (thingy\\oFireF.grp)\r\n# 469 ProtossBuildingBurn4 (thingy\\oFireC.grp)\r\n# 468 ProtossBuildingBurn3 (thingy\\oFireV.grp)\r\n# 467 ProtossBuildingBurn2 (thingy\\oFireF.grp)\r\n# 466 ProtossBuildingBurn (thingy\\oFireC.grp)\r\n# 457 TerranBuildingBurn8 (thingy\\oFireV.grp)\r\n# 456 TerranBuildingBurn7 (thingy\\oFireV.grp)\r\n# 455 TerranBuildingBurn6 (thingy\\oFireV.grp)\r\n# 454 TerranBuildingBurn5 (thingy\\oFireV.grp)\r\n# 453 TerranBuildingBurn4 (thingy\\oFireV.grp)\r\n# 452 TerranBuildingBurn3 (thingy\\oFireV.grp)\r\n# 451 TerranBuildingBurn2 (thingy\\oFireF.grp)\r\n# 450 TerranBuildingBurn (thingy\\oFireC.grp)\r\n.headerstart\r\nIsId           \t322\r\nType           \t1\r\nInit           \tFlames_Small_Init\r\nDeath          \tFlames_Small_Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown323Init:\r\n\tsetflipstate   \t1\r\nFlames_Small_Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x01\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x02\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x03\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x04\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x05\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x06\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x07\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x08\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x09\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0a\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0b\t# frame set 0\r\n\twait           \t2\r\n\tgoto           \tFlames_Small_Init\r\n\r\nFlames_Small_Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n.headerstart\r\nIsId           \t323\r\nType           \t1\r\nInit           \tUnknown323Init\r\nDeath          \tFlames_Small_Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 461 ZergBuildingBlood4 (thingy\\bblood04.grp)\r\n# 460 ZergBuildingBlood3 (thingy\\bblood03.grp)\r\n# 459 ZergBuildingBlood2 (thingy\\bblood02.grp)\r\n# 458 ZergBuildingBlood (thingy\\bblood01.grp)\r\n.headerstart\r\nIsId           \t324\r\nType           \t1\r\nInit           \tBleeding_Small_Variant1Init\r\nDeath          \tBleeding_Small_Variant1Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBleeding_Small_Variant2Init:\r\n\tsetflipstate   \t1\r\nBleeding_Small_Variant1Init:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tBleeding_Small_Variant1Init\r\n\r\nBleeding_Small_Variant1Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 465 ZergBuildingBlood8 (thingy\\bblood04.grp)\r\n# 464 ZergBuildingBlood7 (thingy\\bblood03.grp)\r\n# 463 ZergBuildingBlood6 (thingy\\bblood02.grp)\r\n# 462 ZergBuildingBlood5 (thingy\\bblood01.grp)\r\n.headerstart\r\nIsId           \t325\r\nType           \t1\r\nInit           \tBleeding_Small_Variant2Init\r\nDeath          \tBleeding_Small_Variant1Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 493 ProtossBuildingBurn12 (thingy\\oFireV.grp)\r\n# 492 ProtossBuildingBurn11 (thingy\\oFireF.grp)\r\n# 491 ProtossBuildingBurn10 (thingy\\oFireC.grp)\r\n# 490 ProtossBuildingBurn9 (thingy\\oFireV.grp)\r\n# 489 ProtossBuildingBurn8 (thingy\\oFireF.grp)\r\n# 488 ProtossBuildingBurn7 (thingy\\oFireC.grp)\r\n# 479 TerranBuildingBurn16 (thingy\\oFireV.grp)\r\n# 478 TerranBuildingBurn15 (thingy\\oFireV.grp)\r\n# 477 TerranBuildingBurn14 (thingy\\oFireV.grp)\r\n# 476 TerranBuildingBurn13 (thingy\\oFireV.grp)\r\n# 475 TerranBuildingBurn12 (thingy\\oFireV.grp)\r\n# 474 TerranBuildingBurn11 (thingy\\oFireV.grp)\r\n# 473 TerranBuildingBurn10 (thingy\\oFireF.grp)\r\n# 472 TerranBuildingBurn9 (thingy\\oFireC.grp)\r\n.headerstart\r\nIsId           \t326\r\nType           \t1\r\nInit           \tFlames_Large_Init\r\nDeath          \tFlames_Large_Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown327Init:\r\n\tsetflipstate   \t1\r\nFlames_Large_Init:\r\n\tplayfram       \t0x0c\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0d\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0e\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x0f\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x10\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x12\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x13\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x14\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x15\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x16\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x17\t# frame set 1\r\n\twait           \t2\r\n\tgoto           \tFlames_Large_Init\r\n\r\nFlames_Large_Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n.headerstart\r\nIsId           \t327\r\nType           \t1\r\nInit           \tUnknown327Init\r\nDeath          \tFlames_Large_Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 483 ZergBuildingBlood12 (thingy\\bblood04.grp)\r\n# 482 ZergBuildingBlood11 (thingy\\bblood03.grp)\r\n# 481 ZergBuildingBlood10 (thingy\\bblood02.grp)\r\n# 480 ZergBuildingBlood9 (thingy\\bblood01.grp)\r\n.headerstart\r\nIsId           \t328\r\nType           \t1\r\nInit           \tBleeding_Large_Variant1Init\r\nDeath          \tBleeding_Large_Variant1Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nBleeding_Large_Variant2Init:\r\n\tsetflipstate   \t1\r\nBleeding_Large_Variant1Init:\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tgoto           \tBleeding_Large_Variant1Init\r\n\r\nBleeding_Large_Variant1Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 487 ZergBuildingBlood16 (thingy\\bblood04.grp)\r\n# 486 ZergBuildingBlood15 (thingy\\bblood03.grp)\r\n# 485 ZergBuildingBlood14 (thingy\\bblood02.grp)\r\n# 484 ZergBuildingBlood13 (thingy\\bblood01.grp)\r\n.headerstart\r\nIsId           \t329\r\nType           \t1\r\nInit           \tBleeding_Large_Variant2Init\r\nDeath          \tBleeding_Large_Variant1Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 498 Unknown498 (thingy\\dust05.grp)\r\n# 497 Unknown497 (thingy\\dust04.grp)\r\n# 495 Unknown495 (thingy\\dust02.grp)\r\n.headerstart\r\nIsId           \t330\r\nType           \t0\r\nInit           \tDustVariant1Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDustVariant1Init:\r\n\tplayfram       \t0\r\n\twait           \t3\r\n\tplayfram       \t1\r\n\twait           \t3\r\n\tplayfram       \t2\r\n\twait           \t3\r\n\tplayfram       \t3\r\n\twait           \t3\r\n\tplayfram       \t4\r\n\twait           \t3\r\n\tplayfram       \t5\r\n\twait           \t3\r\n\tplayfram       \t6\r\n\twait           \t3\r\n\tplayfram       \t7\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 502 Unknown502 (thingy\\dust09.grp)\r\n# 501 Unknown501 (thingy\\dust08.grp)\r\n# 500 Unknown500 (thingy\\dust07.grp)\r\n# 499 Unknown499 (thingy\\dust06.grp)\r\n# 496 Unknown496 (thingy\\dust03.grp)\r\n# 494 ProtossBuildingBurn13 (thingy\\dust01.grp)\r\n.headerstart\r\nIsId           \t331\r\nType           \t0\r\nInit           \tDustVariant2Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDustVariant2Init:\r\n\tplayfram       \t0\r\n\twait           \t3\r\n\tplayfram       \t1\r\n\twait           \t3\r\n\tplayfram       \t2\r\n\twait           \t3\r\n\tplayfram       \t3\r\n\twait           \t3\r\n\tplayfram       \t4\r\n\twait           \t3\r\n\tplayfram       \t5\r\n\twait           \t3\r\n\tplayfram       \t6\r\n\twait           \t3\r\n\tplayfram       \t7\r\n\twait           \t3\r\n\tplayfram       \t8\r\n\twait           \t3\r\n\tplayfram       \t9\r\n\twait           \t3\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 585 PsiField2 (thingy\\Juice02.grp)\r\n# 583 Unknown583 (thingy\\blackx.grp)\r\n# 581 Unknown581 (thingy\\blackx.grp)\r\n.headerstart\r\nIsId           \t332\r\nType           \t1\r\nInit           \tConfirmCircleInit\r\nDeath          \tConfirmCircleDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nConfirmCircleInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nConfirmCircleDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 584 PsiField1 (thingy\\Juice01.grp)\r\n.headerstart\r\nIsId           \t333\r\nType           \t1\r\nInit           \tPsiFieldType1Init\r\nDeath          \tPsiFieldType1Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsiFieldType1Init:\r\n\tplayfram       \t0\r\n\timgol          \t586 130 179\t# PsiField3 (thingy\\Juice01.grp)\r\n\timgol          \t585 126 77\t# PsiField2 (thingy\\Juice02.grp)\r\n\timgol          \t587 130 77\t# PsiField4 (thingy\\Juice02.grp)\r\n\tsetpos         \t126 179\r\n\tgoto           \tlong00\r\n\r\nPsiFieldType1Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 906 DesertDoodad56 (thingy\\tileset\\desert\\HDMachn2.grp)\r\n# 842 IceWorldDoodad72 (thingy\\tileset\\ice\\JGant1.grp)\r\n# 840 IceWorldDoodad70 (thingy\\tileset\\ice\\HDRadr02.grp)\r\n# 770 TwilightDoodad16 (thingy\\tileset\\twilight\\rstatue.grp)\r\n# 587 PsiField4 (thingy\\Juice02.grp)\r\n# 586 PsiField3 (thingy\\Juice01.grp)\r\n.headerstart\r\nIsId           \t334\r\nType           \t1\r\nInit           \tPsiFieldType2Init\r\nDeath          \tPsiFieldType2Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsiFieldType2Init:\r\n\tplayfram       \t0\r\n\tsetflipstate   \t1\r\n\tgoto           \tlong00\r\n\r\nPsiFieldType2Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 588 StartLocation (thingy\\StartLoc.grp)\r\n.headerstart\r\nIsId           \t335\r\nType           \t0\r\nInit           \tStartLocationInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nStartLocationInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 897 DesertDoodad47 (thingy\\tileset\\desert\\HDMachn2.grp)\r\n# 880 DesertDoodad30 (thingy\\tileset\\desert\\JGPLNT01.grp)\r\n# 841 IceWorldDoodad71 (thingy\\tileset\\ice\\JGant1.grp)\r\n# 831 IceWorldDoodad61 (thingy\\tileset\\ice\\LDsmrock.grp)\r\n# 790 IceWorldDoodad20 (thingy\\tileset\\ice\\HDSTre04.grp)\r\n# 789 IceWorldDoodad19 (thingy\\tileset\\ice\\HDSTre03.grp)\r\n# 788 IceWorldDoodad18 (thingy\\tileset\\ice\\HDSTre02.grp)\r\n# 787 IceWorldDoodad17 (thingy\\tileset\\ice\\HDSTre01.grp)\r\n# 769 TwilightDoodad15 (thingy\\tileset\\twilight\\rstatue.grp)\r\n# 768 TwilightDoodad14 (thingy\\tileset\\twilight\\JTree05.grp)\r\n# 767 TwilightDoodad13 (thingy\\tileset\\twilight\\JTree04.grp)\r\n# 766 TwilightDoodad12 (thingy\\tileset\\twilight\\JTree03.grp)\r\n# 765 TwilightDoodad11 (thingy\\tileset\\twilight\\JTree02.grp)\r\n# 764 TwilightDoodad10 (thingy\\tileset\\twilight\\JTree01.grp)\r\n# 762 TwilightDoodad8 (thingy\\tileset\\twilight\\Ldxel06.grp)\r\n# 761 TwilightDoodad7 (thingy\\tileset\\twilight\\Ldxel05.grp)\r\n# 760 TwilightDoodad6 (thingy\\tileset\\twilight\\Ldxel04.grp)\r\n# 759 TwilightDoodad5 (thingy\\tileset\\twilight\\Ldxel03.grp)\r\n# 755 TwilightDoodad (thingy\\tileset\\twilight\\Ldarch.grp)\r\n# 749 InstallationDoodad15 (thingy\\tileset\\install\\DICran4.grp)\r\n# 748 InstallationDoodad14 (thingy\\tileset\\install\\DICran3.grp)\r\n# 747 InstallationDoodad13 (thingy\\tileset\\install\\DICran2.grp)\r\n# 746 InstallationDoodad12 (thingy\\tileset\\install\\DICran1.grp)\r\n# 734 BadlandsDoodad44 (thingy\\tileset\\Badlands\\LCSignCC.grp)\r\n# 733 BadlandsDoodad43 (thingy\\tileset\\Badlands\\LCSignBB.grp)\r\n# 732 BadlandsDoodad42 (thingy\\tileset\\Badlands\\LCSignAA.grp)\r\n# 731 BadlandsDoodad41 (thingy\\tileset\\Badlands\\LCSign09.grp)\r\n# 730 BadlandsDoodad40 (thingy\\tileset\\Badlands\\LCSign08.grp)\r\n# 729 BadlandsDoodad39 (thingy\\tileset\\Badlands\\LCSign07.grp)\r\n# 728 BadlandsDoodad38 (thingy\\tileset\\Badlands\\LCSign06.grp)\r\n# 727 BadlandsDoodad37 (thingy\\tileset\\Badlands\\LCSign05.grp)\r\n# 726 BadlandsDoodad36 (thingy\\tileset\\Badlands\\LCSign04.grp)\r\n# 725 BadlandsDoodad35 (thingy\\tileset\\Badlands\\LCSign03.grp)\r\n# 724 BadlandsDoodad34 (thingy\\tileset\\Badlands\\LCSign02.grp)\r\n# 723 BadlandsDoodad33 (thingy\\tileset\\Badlands\\LCSign01.grp)\r\n# 722 BadlandsDoodad32 (thingy\\tileset\\Badlands\\LCShopAA.grp)\r\n# 721 BadlandsDoodad31 (thingy\\tileset\\Badlands\\LCShop09.grp)\r\n# 720 BadlandsDoodad30 (thingy\\tileset\\Badlands\\LCShop08.grp)\r\n# 719 BadlandsDoodad29 (thingy\\tileset\\Badlands\\LCShop07.grp)\r\n# 718 BadlandsDoodad28 (thingy\\tileset\\Badlands\\LCShop06.grp)\r\n# 717 BadlandsDoodad27 (thingy\\tileset\\Badlands\\LCShop05.grp)\r\n# 716 BadlandsDoodad26 (thingy\\tileset\\Badlands\\LCShop04.grp)\r\n# 715 BadlandsDoodad25 (thingy\\tileset\\Badlands\\LCShop03.grp)\r\n# 714 BadlandsDoodad24 (thingy\\tileset\\Badlands\\LCShop02.grp)\r\n# 713 BadlandsDoodad23 (thingy\\tileset\\Badlands\\LCShop01.grp)\r\n# 712 BadlandsDoodad22 (thingy\\tileset\\Badlands\\HGTree01.grp)\r\n# 703 BadlandsDoodad13 (thingy\\tileset\\Badlands\\HDVent01.grp)\r\n# 702 BadlandsDoodad12 (thingy\\tileset\\Badlands\\HDRock08.grp)\r\n# 701 BadlandsDoodad11 (thingy\\tileset\\Badlands\\HDRock07.grp)\r\n# 700 BadlandsDoodad10 (thingy\\tileset\\Badlands\\HDRock06.grp)\r\n# 699 BadlandsDoodad9 (thingy\\tileset\\Badlands\\HDRock05.grp)\r\n# 690 SpacePlatformDoodad25 (thingy\\tileset\\Platform\\refinery.grp)\r\n# 689 SpacePlatformDoodad24 (thingy\\tileset\\Platform\\SPThin01.grp)\r\n# 688 SpacePlatformDoodad23 (thingy\\tileset\\Platform\\LBSign08.grp)\r\n# 687 SpacePlatformDoodad22 (thingy\\tileset\\Platform\\LBSign07.grp)\r\n# 686 SpacePlatformDoodad21 (thingy\\tileset\\Platform\\LBSign06.grp)\r\n# 685 SpacePlatformDoodad20 (thingy\\tileset\\Platform\\LBSign05.grp)\r\n# 684 SpacePlatformDoodad19 (thingy\\tileset\\Platform\\LBSign04.grp)\r\n# 683 SpacePlatformDoodad18 (thingy\\tileset\\Platform\\LBSign03.grp)\r\n# 682 SpacePlatformDoodad17 (thingy\\tileset\\Platform\\LBSign02.grp)\r\n# 681 SpacePlatformDoodad16 (thingy\\tileset\\Platform\\LBSign01.grp)\r\n# 678 SpacePlatformDoodad13 (thingy\\tileset\\Platform\\Towr02.grp)\r\n# 677 SpacePlatformDoodad12 (thingy\\tileset\\Platform\\Towr01.grp)\r\n# 664 JungleDoodad55 (thingy\\tileset\\Jungle\\dd211.grp)\r\n# 663 JungleDoodad54 (thingy\\tileset\\Jungle\\dd210.grp)\r\n# 662 JungleDoodad53 (thingy\\tileset\\Jungle\\dd209.grp)\r\n# 661 JungleDoodad52 (thingy\\tileset\\Jungle\\dd207.grp)\r\n# 660 JungleDoodad51 (thingy\\tileset\\Jungle\\dd206.grp)\r\n# 659 JungleDoodad50 (thingy\\tileset\\Jungle\\dd205.grp)\r\n# 658 JungleDoodad49 (thingy\\tileset\\Jungle\\dd204.grp)\r\n# 657 JungleDoodad48 (thingy\\tileset\\Jungle\\dd203.grp)\r\n# 656 JungleDoodad47 (thingy\\tileset\\Jungle\\dd091.grp)\r\n# 655 JungleDoodad46 (thingy\\tileset\\Jungle\\dd081.grp)\r\n# 654 JungleDoodad45 (thingy\\tileset\\Jungle\\dd080.grp)\r\n# 653 JungleDoodad44 (thingy\\tileset\\Jungle\\dd079.grp)\r\n# 652 JungleDoodad43 (thingy\\tileset\\Jungle\\dd078.grp)\r\n# 651 JungleDoodad42 (thingy\\tileset\\Jungle\\dd077.grp)\r\n# 650 JungleDoodad41 (thingy\\tileset\\Jungle\\dd076.grp)\r\n# 649 JungleDoodad40 (thingy\\tileset\\Jungle\\dd075.grp)\r\n# 648 JungleDoodad39 (thingy\\tileset\\Jungle\\dd056.grp)\r\n# 647 JungleDoodad38 (thingy\\tileset\\Jungle\\dd055.grp)\r\n# 646 JungleDoodad37 (thingy\\tileset\\Jungle\\dd031.grp)\r\n# 645 JungleDoodad36 (thingy\\tileset\\Jungle\\dd030.grp)\r\n# 644 JungleDoodad35 (thingy\\tileset\\Jungle\\dd029.grp)\r\n# 643 JungleDoodad34 (thingy\\tileset\\Jungle\\dd028.grp)\r\n# 642 JungleDoodad33 (thingy\\tileset\\Jungle\\dd027.grp)\r\n# 641 JungleDoodad32 (thingy\\tileset\\Jungle\\dd026.grp)\r\n# 640 JungleDoodad31 (thingy\\tileset\\Jungle\\dd025.grp)\r\n# 609 AshWorldDoodad11 (thingy\\tileset\\AshWorld\\RORock03.grp)\r\n# 608 AshWorldDoodad10 (thingy\\tileset\\AshWorld\\RORock02.grp)\r\n# 607 AshWorldDoodad9 (thingy\\tileset\\AshWorld\\RORock01.grp)\r\n# 606 AshWorldDoodad8 (thingy\\tileset\\AshWorld\\HASRoc06.grp)\r\n# 605 AshWorldDoodad7 (thingy\\tileset\\AshWorld\\HASRoc05.grp)\r\n# 604 AshWorldDoodad6 (thingy\\tileset\\AshWorld\\HASRoc04.grp)\r\n# 603 AshWorldDoodad5 (thingy\\tileset\\AshWorld\\HASRoc03.grp)\r\n# 602 AshWorldDoodad4 (thingy\\tileset\\AshWorld\\HASRoc02.grp)\r\n# 601 AshWorldDoodad3 (thingy\\tileset\\AshWorld\\HASRoc01.grp)\r\n# 600 AshWorldDoodad2 (thingy\\tileset\\AshWorld\\LALRoc02.grp)\r\n# 599 AshWorldDoodad (thingy\\tileset\\AshWorld\\LALRoc01.grp)\r\n.headerstart\r\nIsId           \t336\r\nType           \t0\r\nInit           \tDoodadHeaderInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDoodadHeaderInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 902 DesertDoodad52 (thingy\\tileset\\desert\\LDPlnt04.grp)\r\n# 900 DesertDoodad50 (thingy\\tileset\\desert\\LDMachn1.grp)\r\n# 898 DesertDoodad48 (thingy\\tileset\\desert\\LDLbox01.grp)\r\n# 895 DesertDoodad45 (thingy\\tileset\\desert\\HDLbox01.grp)\r\n# 892 DesertDoodad42 (thingy\\tileset\\desert\\LDBTENT.grp)\r\n# 890 DesertDoodad40 (thingy\\tileset\\desert\\LDBSUKY.grp)\r\n# 887 DesertDoodad37 (thingy\\tileset\\desert\\LDBGREN.grp)\r\n# 885 DesertDoodad35 (thingy\\tileset\\desert\\LDBGAS.grp)\r\n# 883 DesertDoodad33 (thingy\\tileset\\desert\\LDBAZ.grp)\r\n# 881 DesertDoodad31 (thingy\\tileset\\desert\\JGPLNT02.grp)\r\n# 878 DesertDoodad28 (thingy\\tileset\\desert\\JGBRED.grp)\r\n# 876 DesertDoodad26 (thingy\\tileset\\desert\\JGBFACT.grp)\r\n# 874 DesertDoodad24 (thingy\\tileset\\desert\\JGBCOMM.grp)\r\n# 872 DesertDoodad22 (thingy\\tileset\\desert\\JGBTENT.grp)\r\n# 870 DesertDoodad20 (thingy\\tileset\\desert\\JGBSGN.grp)\r\n# 868 DesertDoodad18 (thingy\\tileset\\desert\\JGBGEN.grp)\r\n# 866 DesertDoodad16 (thingy\\tileset\\desert\\JGBGAS.grp)\r\n# 864 DesertDoodad14 (thingy\\tileset\\desert\\JGBROKE.grp)\r\n# 862 DesertDoodad12 (thingy\\tileset\\desert\\HDPLNT03.grp)\r\n# 860 DesertDoodad10 (thingy\\tileset\\desert\\HDBTENT.grp)\r\n# 858 DesertDoodad8 (thingy\\tileset\\desert\\HDBMOSS.grp)\r\n# 856 DesertDoodad6 (thingy\\tileset\\desert\\HDBMED.grp)\r\n# 854 DesertDoodad4 (thingy\\tileset\\desert\\HDBGAS.grp)\r\n# 852 DesertDoodad2 (thingy\\tileset\\desert\\HDBBROKE.grp)\r\n# 849 IceWorldDoodad79 (thingy\\tileset\\ice\\RJBTree4.grp)\r\n# 847 IceWorldDoodad77 (thingy\\tileset\\ice\\RJBTree3.grp)\r\n# 845 IceWorldDoodad75 (thingy\\tileset\\ice\\RJBTree2.grp)\r\n# 843 IceWorldDoodad73 (thingy\\tileset\\ice\\RJBTree1.grp)\r\n# 834 IceWorldDoodad64 (thingy\\tileset\\ice\\HDRadr02.grp)\r\n# 829 IceWorldDoodad59 (thingy\\tileset\\ice\\LDthing.grp)\r\n# 827 IceWorldDoodad57 (thingy\\tileset\\ice\\HDPipes.grp)\r\n# 825 IceWorldDoodad55 (thingy\\tileset\\ice\\LDRck02.grp)\r\n# 823 IceWorldDoodad53 (thingy\\tileset\\ice\\LDRck01.grp)\r\n# 821 IceWorldDoodad51 (thingy\\tileset\\ice\\LDRdr03.grp)\r\n# 819 IceWorldDoodad49 (thingy\\tileset\\ice\\LDRdr02.grp)\r\n# 817 IceWorldDoodad47 (thingy\\tileset\\ice\\LDRdr01.grp)\r\n# 815 IceWorldDoodad45 (thingy\\tileset\\ice\\LDDish.grp)\r\n# 813 IceWorldDoodad43 (thingy\\tileset\\ice\\LDDtre02.grp)\r\n# 811 IceWorldDoodad41 (thingy\\tileset\\ice\\LDDtre01.grp)\r\n# 809 IceWorldDoodad39 (thingy\\tileset\\ice\\LDComm.grp)\r\n# 807 IceWorldDoodad37 (thingy\\tileset\\ice\\LDbld02.grp)\r\n# 805 IceWorldDoodad35 (thingy\\tileset\\ice\\LDbld01.grp)\r\n# 803 IceWorldDoodad33 (thingy\\tileset\\ice\\LDBTre04.grp)\r\n# 801 IceWorldDoodad31 (thingy\\tileset\\ice\\LDBTre03.grp)\r\n# 799 IceWorldDoodad29 (thingy\\tileset\\ice\\LDBTre02.grp)\r\n# 797 IceWorldDoodad27 (thingy\\tileset\\ice\\LDBTre01.grp)\r\n# 795 IceWorldDoodad25 (thingy\\tileset\\ice\\HDTwr02.grp)\r\n# 793 IceWorldDoodad23 (thingy\\tileset\\ice\\HDTwr01.grp)\r\n# 791 IceWorldDoodad21 (thingy\\tileset\\ice\\HDSpire.grp)\r\n# 785 IceWorldDoodad15 (thingy\\tileset\\ice\\HDRock02.grp)\r\n# 783 IceWorldDoodad13 (thingy\\tileset\\ice\\HDRock01.grp)\r\n# 781 IceWorldDoodad11 (thingy\\tileset\\ice\\HDradarR.grp)\r\n# 779 IceWorldDoodad9 (thingy\\tileset\\ice\\HDradarl.grp)\r\n# 777 IceWorldDoodad7 (thingy\\tileset\\ice\\HDbld04.grp)\r\n# 775 IceWorldDoodad5 (thingy\\tileset\\ice\\HDbld03.grp)\r\n# 773 IceWorldDoodad3 (thingy\\tileset\\ice\\HDbld02.grp)\r\n# 771 IceWorldDoodad (thingy\\tileset\\ice\\HDbld01.grp)\r\n# 710 BadlandsDoodad20 (thingy\\tileset\\Badlands\\HDTree04.grp)\r\n# 708 BadlandsDoodad18 (thingy\\tileset\\Badlands\\HDTree03.grp)\r\n# 706 BadlandsDoodad16 (thingy\\tileset\\Badlands\\HDTree02.grp)\r\n# 704 BadlandsDoodad14 (thingy\\tileset\\Badlands\\HDTree01.grp)\r\n# 697 BadlandsDoodad7 (thingy\\tileset\\Badlands\\HDRock04.grp)\r\n# 695 BadlandsDoodad5 (thingy\\tileset\\Badlands\\HDRock03.grp)\r\n# 693 BadlandsDoodad3 (thingy\\tileset\\Badlands\\HDRock02.grp)\r\n# 691 BadlandsDoodad (thingy\\tileset\\Badlands\\HDRock01.grp)\r\n# 675 SpacePlatformDoodad10 (thingy\\tileset\\Platform\\Glob03.grp)\r\n# 673 SpacePlatformDoodad8 (thingy\\tileset\\Platform\\Glob02.grp)\r\n# 671 SpacePlatformDoodad6 (thingy\\tileset\\Platform\\Glob01.grp)\r\n# 669 SpacePlatformDoodad4 (thingy\\tileset\\Platform\\Dish03.grp)\r\n# 667 SpacePlatformDoodad2 (thingy\\tileset\\Platform\\Dish02.grp)\r\n# 665 JungleDoodad56 (thingy\\tileset\\Platform\\Dish01.grp)\r\n# 638 JungleDoodad29 (thingy\\tileset\\Jungle\\tree04.grp)\r\n# 636 JungleDoodad27 (thingy\\tileset\\Jungle\\tree03.grp)\r\n# 634 JungleDoodad25 (thingy\\tileset\\Jungle\\tree02.grp)\r\n# 632 JungleDoodad23 (thingy\\tileset\\Jungle\\tree01.grp)\r\n# 630 JungleDoodad21 (thingy\\tileset\\Jungle\\LDtree04.grp)\r\n# 628 JungleDoodad19 (thingy\\tileset\\Jungle\\LDtree03.grp)\r\n# 626 JungleDoodad17 (thingy\\tileset\\Jungle\\LDtree02.grp)\r\n# 624 JungleDoodad15 (thingy\\tileset\\Jungle\\LDtree01.grp)\r\n# 622 JungleDoodad13 (thingy\\tileset\\Jungle\\JUbush05.grp)\r\n# 620 JungleDoodad11 (thingy\\tileset\\Jungle\\JUbush03.grp)\r\n# 618 JungleDoodad9 (thingy\\tileset\\Jungle\\JUbush01.grp)\r\n# 616 JungleDoodad7 (thingy\\tileset\\Jungle\\HDRock04.grp)\r\n# 614 JungleDoodad5 (thingy\\tileset\\Jungle\\HDRock03.grp)\r\n# 612 JungleDoodad3 (thingy\\tileset\\Jungle\\HDRock02.grp)\r\n# 610 JungleDoodad (thingy\\tileset\\Jungle\\HDRock01.grp)\r\n# 597 AshWorldDoodadRock5 (thingy\\tileset\\AshWorld\\rock05.grp)\r\n# 595 AshWorldDoodadRock4 (thingy\\tileset\\AshWorld\\rock04.grp)\r\n# 593 AshWorldDoodadRock3 (thingy\\tileset\\AshWorld\\rock03.grp)\r\n# 591 AshWorldDoodadRock2 (thingy\\tileset\\AshWorld\\rock02.grp)\r\n# 589 AshWorldDoodadRock1 (thingy\\tileset\\AshWorld\\rock01.grp)\r\n.headerstart\r\nIsId           \t337\r\nType           \t0\r\nInit           \tDoodadHeader_secondary_Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDoodadHeader_secondary_Init:\r\n\tplayfram       \t0\r\n\timgulnextid    \t0 0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 679 SpacePlatformDoodad14 (thingy\\tileset\\Platform\\tree01.grp)\r\n.headerstart\r\nIsId           \t338\r\nType           \t0\r\nInit           \tSpacePlatformDoodadInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSpacePlatformDoodadInit:\r\n\tplayfram       \t0\r\nSpacePlatformDoodadLocal00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tgoto           \tSpacePlatformDoodadLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 680 SpacePlatformDoodad15 (thingy\\tileset\\Platform\\tree02.grp)\r\n.headerstart\r\nIsId           \t339\r\nType           \t0\r\nInit           \tSpacePlatformDoodad2Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSpacePlatformDoodad2Init:\r\n\tplayfram       \t0\r\nSpacePlatformDoodad2Local00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tgoto           \tSpacePlatformDoodad2Local00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 754 InstallationDoodad20 (thingy\\tileset\\install\\DIHatc1.grp)\r\n# 750 InstallationDoodad16 (thingy\\tileset\\install\\DIDoor1.grp)\r\n# 742 InstallationDoodad8 (thingy\\tileset\\install\\CRDoor1.grp)\r\n.headerstart\r\nIsId           \t340\r\nType           \t27\r\nInit           \tInstallationDoodadInit\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tInstallationDoodadAlmostBuilt\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tInstallationDoodadStarEditInit\r\nDisable        \tInstallationDoodadDisable\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tInstallationDoodadStarEditInit\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInstallationDoodadInit:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nInstallationDoodadAlmostBuilt:\r\n\tplayfram       \t9\r\n\tgoto           \tlong00\r\n\r\nInstallationDoodadStarEditInit:\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nInstallationDoodadDisable:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 751 InstallationDoodad17 (thingy\\tileset\\install\\DIDoor1.grp)\r\n# 743 InstallationDoodad9 (thingy\\tileset\\install\\CRDoor1.grp)\r\n.headerstart\r\nIsId           \t341\r\nType           \t27\r\nInit           \tInstallationDoodad2Init\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tInstallationDoodad2AlmostBuilt\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tInstallationDoodad2StarEditInit\r\nDisable        \tInstallationDoodad2Disable\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tInstallationDoodad2StarEditInit\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInstallationDoodad2Init:\r\n\tplayfram       \t0\r\n\tsetflipstate   \t1\r\n\tgoto           \tlong00\r\n\r\nInstallationDoodad2AlmostBuilt:\r\n\tplayfram       \t9\r\n\tsetflipstate   \t1\r\n\tgoto           \tlong00\r\n\r\nInstallationDoodad2StarEditInit:\r\n\tplayfram       \t9\r\n\tsetflipstate   \t1\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nInstallationDoodad2Disable:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 744 InstallationDoodad10 (thingy\\tileset\\install\\DCFan1.grp)\r\n.headerstart\r\nIsId           \t342\r\nType           \t0\r\nInit           \tInstallationRightWallFansInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInstallationRightWallFansInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tgoto           \tInstallationRightWallFansInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 745 InstallationDoodad11 (thingy\\tileset\\install\\DCFan1.grp)\r\n.headerstart\r\nIsId           \t343\r\nType           \t0\r\nInit           \tInstallationLeftWallFansInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInstallationLeftWallFansInit:\r\n\tplayfram       \t0\r\n\tsetflipstate   \t1\r\n\twait           \t2\r\nInstallationLeftWallFansLocal00:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tgoto           \tInstallationLeftWallFansLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 753 InstallationDoodad19 (thingy\\tileset\\install\\DIGear2.grp)\r\n# 752 InstallationDoodad18 (thingy\\tileset\\install\\DIGear1.grp)\r\n.headerstart\r\nIsId           \t344\r\nType           \t0\r\nInit           \tInstallationGearInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nInstallationGearInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tgoto           \tInstallationGearInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 736 InstallationDoodad2 (thingy\\tileset\\install\\CLPlate1.grp)\r\n.headerstart\r\nIsId           \t345\r\nType           \t27\r\nInit           \tFloorMissileTrapInit\r\nDeath          \tFloorMissileTrapDeath\r\nGndAttkInit    \tFloorMissileTrapGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tFloorMissileTrapGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tFloorMissileTrapSpecialState1\r\nSpecialState2  \tFloorMissileTrapSpecialState2\r\nAlmostBuilt    \tlong00\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tFloorMissileTrapStarEditInit\r\nDisable        \tFloorMissileTrapSpecialState2\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFloorMissileTrapInit:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nFloorMissileTrapDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nFloorMissileTrapGndAttkInit:\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tlong00\r\n\r\nFloorMissileTrapSpecialState1:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\timgol          \t737 0 0\t# InstallationDoodad3 (thingy\\tileset\\install\\CLPlat1T.grp)\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nFloorMissileTrapSpecialState2:\r\n\tsetspawnframe  \t20\r\n\twait           \t1\r\nFloorMissileTrapLocal01:\r\n\tcurdirectcondjmp\t160 10 FloorMissileTrapLocal00\r\n\twait           \t2\r\n\tgoto           \tFloorMissileTrapLocal01\r\n\r\nFloorMissileTrapLocal00:\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nFloorMissileTrapStarEditInit:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 737 InstallationDoodad3 (thingy\\tileset\\install\\CLPlat1T.grp)\r\n.headerstart\r\nIsId           \t346\r\nType           \t24\r\nInit           \tFloorMissileTrapTurretInit\r\nDeath          \tlong01\r\nGndAttkInit    \tlong00\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong00\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tFloorMissileTrapTurretSpecialState2\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tFloorMissileTrapTurretSpecialState2\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFloorMissileTrapTurretInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tsetfldirect    \t20\r\n\tgoto           \tlong00\r\n\r\nFloorMissileTrapTurretSpecialState2:\r\n\twait           \t1\r\nFloorMissileTrapTurretLocal01:\r\n\tcurdirectcondjmp\t160 10 FloorMissileTrapTurretLocal00\r\n\twait           \t2\r\n\tgoto           \tFloorMissileTrapTurretLocal01\r\n\r\nFloorMissileTrapTurretLocal00:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 735 InstallationDoodad (thingy\\tileset\\install\\CLPlate2.grp)\r\n.headerstart\r\nIsId           \t347\r\nType           \t27\r\nInit           \tFloorGunTrapInit\r\nDeath          \tFloorGunTrapDeath\r\nGndAttkInit    \tFloorGunTrapGndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tFloorGunTrapGndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tFloorGunTrapGndAttkToIdle\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tFloorGunTrapSpecialState1\r\nSpecialState2  \tFloorGunTrapSpecialState2\r\nAlmostBuilt    \tlong00\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tFloorGunTrapSpecialState1\r\nDisable        \tFloorGunTrapSpecialState2\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFloorGunTrapInit:\r\n\tplayfram       \t1\r\n\tgoto           \tlong00\r\n\r\nFloorGunTrapDeath:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nFloorGunTrapGndAttkInit:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplaysnd        \t70\t# Bullet\\TGoFir00.wav\r\n\tattackwith     \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tlong00\r\n\r\nFloorGunTrapSpecialState1:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tsigorder       \t1\r\nFloorGunTrapGndAttkToIdle:\r\n\tplayfram       \t10\r\n\tgoto           \tlong00\r\n\r\nFloorGunTrapSpecialState2:\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 738 InstallationDoodad4 (thingy\\tileset\\install\\DCGun1.grp)\r\n.headerstart\r\nIsId           \t348\r\nType           \t27\r\nInit           \tWallMissileTrapType1Init\r\nDeath          \tWallMissileTrapType1Death\r\nGndAttkInit    \tWallMissileTrapType1GndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tWallMissileTrapType1GndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tWallMissileTrapType1SpecialState1\r\nSpecialState2  \tWallMissileTrapType1SpecialState2\r\nAlmostBuilt    \tlong00\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tWallMissileTrapType1SpecialState1\r\nDisable        \tWallMissileTrapType1SpecialState2\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWallMissileTrapType1Init:\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tsetfldirect    \t12\r\n\tgoto           \tlong00\r\n\r\nWallMissileTrapType1Death:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nWallMissileTrapType1GndAttkInit:\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tlong00\r\n\r\nWallMissileTrapType1SpecialState1:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nWallMissileTrapType1SpecialState2:\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 739 InstallationDoodad5 (thingy\\tileset\\install\\DCGun1.grp)\r\n.headerstart\r\nIsId           \t349\r\nType           \t27\r\nInit           \tWallMissileTrapTypet2Init\r\nDeath          \tWallMissileTrapTypet2Death\r\nGndAttkInit    \tWallMissileTrapTypet2GndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tWallMissileTrapTypet2GndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tWallMissileTrapTypet2SpecialState1\r\nSpecialState2  \tWallMissileTrapTypet2SpecialState2\r\nAlmostBuilt    \tlong00\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tWallMissileTrapTypet2SpecialState1\r\nDisable        \tWallMissileTrapTypet2SpecialState2\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWallMissileTrapTypet2Init:\r\n\tplayfram       \t1\r\n\tsetflipstate   \t1\r\n\twait           \t1\r\n\tsetfldirect    \t20\r\n\tgoto           \tlong00\r\n\r\nWallMissileTrapTypet2Death:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nWallMissileTrapTypet2GndAttkInit:\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tlong00\r\n\r\nWallMissileTrapTypet2SpecialState1:\r\n\tplayfram       \t1\r\n\tsetflipstate   \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nWallMissileTrapTypet2SpecialState2:\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 740 InstallationDoodad6 (thingy\\tileset\\install\\DCGun2.grp)\r\n.headerstart\r\nIsId           \t350\r\nType           \t27\r\nInit           \tWallFlameTrapType1Init\r\nDeath          \tWallFlameTrapType1Death\r\nGndAttkInit    \tWallFlameTrapType1GndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tWallFlameTrapType1GndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tWallFlameTrapType1SpecialState1\r\nSpecialState2  \tWallFlameTrapType1SpecialState2\r\nAlmostBuilt    \tlong00\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tWallFlameTrapType1SpecialState1\r\nDisable        \tWallFlameTrapType1SpecialState2\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWallFlameTrapType1Init:\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tsetfldirect    \t12\r\n\tgoto           \tlong00\r\n\r\nWallFlameTrapType1Death:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nWallFlameTrapType1GndAttkInit:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\timgoluselo     \t421 0 0\t# FlameThrower (thingy\\flamer.grp)\r\n\tsetfldirect    \t12\r\n\tattkshiftproj  \t24\r\n\twait           \t2\r\n\tattkshiftproj  \t52\r\n\twait           \t1\r\n\tattkshiftproj  \t80\r\n\twait           \t10\r\n\tignorerest     \t\r\n\tgoto           \tlong00\r\n\r\nWallFlameTrapType1SpecialState1:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nWallFlameTrapType1SpecialState2:\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 741 InstallationDoodad7 (thingy\\tileset\\install\\DCGun2.grp)\r\n.headerstart\r\nIsId           \t351\r\nType           \t27\r\nInit           \tWallFlameTrapType2Init\r\nDeath          \tWallFlameTrapType2Death\r\nGndAttkInit    \tWallFlameTrapType2GndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tWallFlameTrapType2GndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tWallFlameTrapType2SpecialState1\r\nSpecialState2  \tWallFlameTrapType2SpecialState2\r\nAlmostBuilt    \tlong00\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \tWallFlameTrapType2SpecialState1\r\nDisable        \tWallFlameTrapType2SpecialState2\r\nBurrow         \t[NONE]\r\nUnBurrow       \t[NONE]\r\nEnable         \tlong00\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWallFlameTrapType2Init:\r\n\tplayfram       \t1\r\n\tsetflipstate   \t1\r\n\twait           \t1\r\n\tsetfldirect    \t20\r\n\tgoto           \tlong00\r\n\r\nWallFlameTrapType2Death:\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nWallFlameTrapType2GndAttkInit:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\timgoluselo     \t421 0 0\t# FlameThrower (thingy\\flamer.grp)\r\n\tsetfldirect    \t20\r\n\tattkshiftproj  \t24\r\n\twait           \t2\r\n\tattkshiftproj  \t52\r\n\twait           \t1\r\n\tattkshiftproj  \t80\r\n\twait           \t10\r\n\tignorerest     \t\r\n\tgoto           \tlong00\r\n\r\nWallFlameTrapType2SpecialState1:\r\n\tplayfram       \t1\r\n\tsetflipstate   \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\nWallFlameTrapType2SpecialState2:\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tsigorder       \t1\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 582 MapRevealer (neutral\\maprev.grp)\r\n.headerstart\r\nIsId           \t352\r\nType           \t1\r\nInit           \tMapRevealerInit\r\nDeath          \tMapRevealerDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMapRevealerInit:\r\n\tplayfram       \t0\r\nMapRevealerLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tgoto           \tMapRevealerLocal00\r\n\r\nMapRevealerDeath:\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 914 LurkerEgg (zerg\\Lurkegg.grp)\r\n.headerstart\r\nIsId           \t353\r\nType           \t14\r\nInit           \tLurkerEggInit\r\nDeath          \tLurkerEggDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tLurkerEggSpecialState1\r\nSpecialState2  \tLurkerEggSpecialState2\r\nAlmostBuilt    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLurkerEggInit:\r\n\timgul          \t22 0 0\t# ZergEggShad (zerg\\zegShad.grp)\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twaitrand       \t1 3\r\nLurkerEggLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tgoto           \tLurkerEggLocal00\r\n\r\nLurkerEggDeath:\r\n\tplaysnd        \t830\t# Zerg\\Egg\\ZEgDth00.WAV\r\n\tlowsprul       \t143 0 0\t# ZergEggDeath (zerg\\zegDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nLurkerEggSpecialState1:\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nLurkerEggSpecialState2:\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 921 Unknown921 (zerg\\Zlurker.grp)\r\n.headerstart\r\nIsId           \t354\r\nType           \t26\r\nInit           \tLurkerInit\r\nDeath          \tLurkerDeath\r\nGndAttkInit    \tLurkerGndAttkInit\r\nAirAttkInit    \tLurkerGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tLurkerGndAttkRpt\r\nAirAttkRpt     \tLurkerGndAttkRpt\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tLurkerGndAttkToIdle\r\nAirAttkToIdle  \tLurkerGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tLurkerWalking\r\nWalkingToIdle  \tLurkerWalkingToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \tLurkerSpecialState2\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \t[NONE]\r\nBurrow         \tLurkerBurrow\r\nUnBurrow       \tLurkerUnBurrow\r\nEnable         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLurkerInit:\r\n\timgul          \t922 0 0\t# LurkerShad (zerg\\zZluShad.grp)\r\nLurkerWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\nLurkerLocal01:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t128 LurkerLocal00\r\n\tgoto           \tLurkerLocal01\r\n\r\nLurkerLocal00:\r\n\trandcondjmp    \t128 LurkerLocal02\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tturnccwise     \t1\r\n\tgoto           \tLurkerWalkingToIdle\r\n\r\nLurkerLocal02:\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tturncwise      \t1\r\n\tgoto           \tLurkerWalkingToIdle\r\n\r\nLurkerDeath:\r\n\tplaysnd        \t1080\t# Zerg\\LURKER\\ZLuDth00.WAV\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0x1a9\t# frame set 25\r\n\twait           \t2\r\n\tplayfram       \t0x1ba\t# frame set 26\r\n\twait           \t2\r\n\tplayfram       \t0x1cb\t# frame set 27\r\n\twait           \t2\r\n\tplayfram       \t0x1dc\t# frame set 28\r\n\twait           \t2\r\n\tplayfram       \t0x1ed\t# frame set 29\r\n\twait           \t2\r\n\tlowsprul       \t484 0 0\t# Unknown920 (zerg\\zLurker.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nLurkerGndAttkInit:\r\n\tnobrkcodestart \t\r\nLurkerGndAttkRpt:\r\n\twait           \t1\r\n\tplaysnd        \t64\t# Bullet\\SpoogHit.wav\r\n\tattack         \t\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\nLurkerGndAttkToIdle:\r\n\tgoto           \tlong00\r\n\r\nLurkerWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tLurkerWalking\r\n\r\nLurkerSpecialState2:\r\n\tplayfram       \t0x198\t# frame set 24\r\n\tgoto           \tlong00\r\n\r\nLurkerBurrow:\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplaysnd        \t1093\t# Zerg\\LURKER\\ZLuBurrw.wav\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t1\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t1\r\n\tplayfram       \t0x121\t# frame set 17\r\n\twait           \t1\r\n\tplayfram       \t0x132\t# frame set 18\r\n\twait           \t1\r\n\tplayfram       \t0x143\t# frame set 19\r\n\twait           \t1\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0xee\t# frame set 14\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\twait           \t1\r\n\tplayfram       \t0x121\t# frame set 17\r\n\twait           \t1\r\n\tplayfram       \t0x132\t# frame set 18\r\n\twait           \t1\r\n\tplayfram       \t0x143\t# frame set 19\r\n\twait           \t1\r\n\timgol          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0x154\t# frame set 20\r\n\twait           \t1\r\n\tplayfram       \t0x165\t# frame set 21\r\n\twait           \t1\r\n\tplayfram       \t0x176\t# frame set 22\r\n\twait           \t1\r\n\tplayfram       \t0x187\t# frame set 23\r\n\twait           \t1\r\n\tplayfram       \t0x198\t# frame set 24\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tlong00\r\n\r\nLurkerUnBurrow:\r\n\twaitrand       \t1 5\r\n\timgul          \t423 0 0\t# Unknown423 (thingy\\bDust.grp)\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tsigorder       \t4\r\n\tgoto           \tLurkerWalkingToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 920 Unknown920 (zerg\\zLurker.grp)\r\n.headerstart\r\nIsId           \t356\r\nType           \t0\r\nInit           \tLurkerRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nLurkerRemnantsInit:\r\n\tplayfram       \t510\r\n\twait           \t50\r\n\tplayfram       \t527\r\n\twait           \t50\r\n\tplayfram       \t544\r\n\twait           \t50\r\n\tplayfram       \t561\r\n\twait           \t50\r\n\tplayfram       \t578\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 915 Devourer (zerg\\devour.grp)\r\n.headerstart\r\nIsId           \t357\r\nType           \t12\r\nInit           \tDevourerInit\r\nDeath          \tDevourerDeath\r\nGndAttkInit    \tDevourerGndAttkInit\r\nAirAttkInit    \tDevourerGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDevourerGndAttkInit\r\nAirAttkRpt     \tDevourerGndAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tDevourerGndAttkToIdle\r\nAirAttkToIdle  \tDevourerGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tDevourerWalking\r\nWalkingToIdle  \tDevourerGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDevourerInit:\r\n\timgul          \t916 0 42\t# DevourerShad (zerg\\devour.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twaitrand       \t1 4\r\nDevourerGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tgoto           \tDevourerGndAttkToIdle\r\n\r\nDevourerDeath:\r\n\tplaysnd        \t1097\t# Zerg\\Devourer\\ZDvDth00.WAV\r\n\tsprol          \t483 0 0\t# DevourerDeath (zerg\\zdvDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nDevourerGndAttkInit:\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tplaysnd        \t1094\t# Zerg\\Devourer\\firesuck.wav\r\n\twait           \t2\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tattackwith     \t2\r\n\tgotorepeatattk \t\r\n\tgoto           \tDevourerGndAttkToIdle\r\n\r\nDevourerWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tgoto           \tDevourerWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 917 DevourerBirth (thingy\\zDvbirth.grp)\r\n.headerstart\r\nIsId           \t358\r\nType           \t13\r\nInit           \tDevourerBirthInit\r\nDeath          \tDevourerBirthDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \tDevourerBirthSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDevourerBirthInit:\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\twaitrand       \t10 15\r\nDevourerBirthLocal00:\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tgoto           \tDevourerBirthLocal00\r\n\r\nDevourerBirthDeath:\r\n\twait           \t1\r\n\tend            \t\r\n\r\nDevourerBirthSpecialState1:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tsigorder       \t4\r\n\tnobrkcodeend   \t\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 918 DevourerDeath (zerg\\zdvDeath.grp)\r\n.headerstart\r\nIsId           \t359\r\nType           \t0\r\nInit           \tDevourerDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDevourerDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\timgol          \t58 0 0\t# ZergAirDeathLarge (thingy\\zAirDthL.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 944 Medic (terran\\medic.grp)\r\n.headerstart\r\nIsId           \t360\r\nType           \t13\r\nInit           \tMedicInit\r\nDeath          \tMedicDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tMedicCastSpell\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tMedicWalking\r\nWalkingToIdle  \tMedicWalkingToIdle\r\nSpecialState1  \tMedicSpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMedicInit:\r\n\timgul          \t945 0 0\t# MedicShad (terran\\tmeShad.grp)\r\nMedicLocal02:\r\n\tplayfram       \t0x00\t# frame set 0\r\nMedicLocal01:\r\n\twaitrand       \t63 75\r\n\trandcondjmp    \t128 MedicLocal00\r\n\tgoto           \tMedicLocal01\r\n\r\nMedicLocal00:\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tturnrand       \t3\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tgoto           \tMedicLocal02\r\n\r\nMedicDeath:\r\n\tplaysnd        \t1000\t# Terran\\Medic\\TMdDth00.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xde\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xdf\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe0\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe1\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe2\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe3\t# frame set 13\r\n\twait           \t2\r\n\tplayfram       \t0xe4\t# frame set 13\r\n\twait           \t4\r\n\tplayfram       \t0xe5\t# frame set 13\r\n\twait           \t4\r\n\tlowsprul       \t490 0 0\t# MedicDeath (terran\\tmeDeath.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nMedicCastSpell:\r\n\torderdone      \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t3\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\twait           \t3\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t3\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nMedicWalking:\r\n\torderdone      \t1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tMedicWalking\r\n\r\nMedicWalkingToIdle:\r\n\torderdone      \t1\r\n\tgoto           \tMedicLocal02\r\n\r\nMedicSpecialState1:\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\nMedicLocal03:\r\n\tsigorder       \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplaysnd        \t1018\t# Terran\\Medic\\TMedHeal.wav\r\n\tgoto           \tMedicLocal03\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 946 MedicDeath (terran\\tmeDeath.grp)\r\n.headerstart\r\nIsId           \t361\r\nType           \t0\r\nInit           \tMedicRemnantsInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMedicRemnantsInit:\r\n\tplayfram       \t0\r\n\twait           \t50\r\n\tplayfram       \t1\r\n\twait           \t50\r\n\tplayfram       \t2\r\n\twait           \t50\r\n\tplayfram       \t3\r\n\twait           \t50\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 939 Valkyrie (terran\\bomber.grp)\r\n.headerstart\r\nIsId           \t362\r\nType           \t12\r\nInit           \tValkyrieInit\r\nDeath          \tValkyrieDeath\r\nGndAttkInit    \tlong05\r\nAirAttkInit    \tValkyrieAirAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tlong05\r\nAirAttkRpt     \tValkyrieAirAttkInit\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \tlong02\r\nAirAttkToIdle  \tlong02\r\nUnused2        \t[NONE]\r\nWalking        \tValkyrieWalking\r\nWalkingToIdle  \tValkyrieWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nValkyrieInit:\r\n\timgul          \t940 0 42\t# ValkyrieShad (terran\\bomber.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nValkyrieDeath:\r\n\tplaysnd        \t1040\t# Terran\\FRIGATE\\TVkDth00.WAV\r\n\timgol          \t332 0 0\t# TerranBuildingExplosionsmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nValkyrieAirAttkInit:\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tattackwith     \t2\r\n\twait           \t10\r\n\tattackwith     \t2\r\n\twait           \t10\r\n\tattackwith     \t2\r\n\twait           \t10\r\n\tattackwith     \t2\r\n\twait           \t10\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong02\r\n\r\nValkyrieWalking:\r\n\timgol          \t941 0 0\t# ValkyrieOverlay (thingy\\tbmGlow.grp)\r\n\tsigorder       \t64\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\nValkyrieWalkingToIdle:\r\n\torderdone      \t64\r\n\tgoto           \tlong02\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 925 DarkArchonEnergy (protoss\\darchn.grp)\r\n.headerstart\r\nIsId           \t365\r\nType           \t13\r\nInit           \tDarkArchonEnergyInit\r\nDeath          \tDarkArchonEnergyDeath\r\nGndAttkInit    \tDarkArchonEnergyGndAttkInit\r\nAirAttkInit    \tDarkArchonEnergyGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDarkArchonEnergyGndAttkInit\r\nAirAttkRpt     \tDarkArchonEnergyGndAttkInit\r\nCastSpell      \tDarkArchonEnergyCastSpell\r\nGndAttkToIdle  \tDarkArchonEnergyGndAttkInit\r\nAirAttkToIdle  \tDarkArchonEnergyGndAttkInit\r\nUnused2        \t[NONE]\r\nWalking        \tDarkArchonEnergyGndAttkInit\r\nWalkingToIdle  \tDarkArchonEnergyGndAttkInit\r\nSpecialState1  \tDarkArchonEnergySpecialState1\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDarkArchonEnergyInit:\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tplayfram       \t20\r\n\twait           \t2\r\n\tplayfram       \t21\r\n\twait           \t2\r\n\tplayfram       \t22\r\n\twait           \t2\r\n\tplayfram       \t23\r\n\twait           \t2\r\n\tplayfram       \t24\r\n\twait           \t2\r\n\tplayfram       \t25\r\n\twait           \t2\r\n\tplayfram       \t26\r\n\twait           \t2\r\n\timgol          \t926 0 0\t# DarkArchonBeing (protoss\\darchnT.grp)\r\n\timgol          \t927 0 0\t# DarkArchonTeamColors (protoss\\darchnT2.grp)\r\n\tsigorder       \t4\r\n\tnobrkcodeend   \t\r\n\twait           \t2\r\nDarkArchonEnergyGndAttkInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tgoto           \tDarkArchonEnergyGndAttkInit\r\n\r\nDarkArchonEnergyDeath:\r\n\tplaysnd        \t7\t# Misc\\ExploLrg.wav\r\n\timgol          \t928 0 0\t# DarkArchonDeath (protoss\\PdaDeath.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nDarkArchonEnergyCastSpell:\r\n\tnobrkcodestart \t\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tDarkArchonEnergyGndAttkInit\r\n\r\nDarkArchonEnergySpecialState1:\r\n\tplaysnd        \t617\t# Protoss\\TEMPLAR\\PTeSum00.WAV\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\nDarkArchonEnergyLocal00:\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tgoto           \tDarkArchonEnergyLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 926 DarkArchonBeing (protoss\\darchnT.grp)\r\n.headerstart\r\nIsId           \t366\r\nType           \t12\r\nInit           \tDarkArchonBeingInit\r\nDeath          \tlong01\r\nGndAttkInit    \tDarkArchonBeingGndAttkInit\r\nAirAttkInit    \tDarkArchonBeingGndAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDarkArchonBeingGndAttkInit\r\nAirAttkRpt     \tDarkArchonBeingGndAttkInit\r\nCastSpell      \tDarkArchonBeingCastSpell\r\nGndAttkToIdle  \tDarkArchonBeingGndAttkToIdle\r\nAirAttkToIdle  \tDarkArchonBeingGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tDarkArchonBeingGndAttkToIdle\r\nWalkingToIdle  \tDarkArchonBeingGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDarkArchonBeingInit:\r\n\tsetfldirect    \t15\r\nDarkArchonBeingGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t4\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t4\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t4\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t4\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t4\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t4\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t4\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t4\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t4\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t4\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t4\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t4\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t4\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t4\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t4\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t4\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t4\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t4\r\n\tgoto           \tDarkArchonBeingGndAttkToIdle\r\n\r\nDarkArchonBeingGndAttkInit:\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\ttrgtrangecondjmp\t48 DarkArchonBeingLocal00\r\n\timgoluselo     \t549 0 0\t# Unknown549 (thingy\\emsBeam.grp)\r\nDarkArchonBeingLocal00:\r\n\tplaysnd        \t58\t# Bullet\\PArFir00.wav\r\n\tattack         \t\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tDarkArchonBeingGndAttkToIdle\r\n\r\nDarkArchonBeingCastSpell:\r\n\tnobrkcodestart \t\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tDarkArchonBeingGndAttkToIdle\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 927 DarkArchonTeamColors (protoss\\darchnT2.grp)\r\n.headerstart\r\nIsId           \t367\r\nType           \t1\r\nInit           \tDarkArchonSwirlInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDarkArchonSwirlInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 5\r\n\ttmprmgraphicend\t\r\nDarkArchonSwirlLocal00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tgoto           \tDarkArchonSwirlLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 928 DarkArchonDeath (protoss\\PdaDeath.grp)\r\n.headerstart\r\nIsId           \t368\r\nType           \t0\r\nInit           \tDarkArchonDeathInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDarkArchonDeathInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 929 Corsair (protoss\\corsair.grp)\r\n.headerstart\r\nIsId           \t369\r\nType           \t21\r\nInit           \tCorsairInit\r\nDeath          \tCorsairDeath\r\nGndAttkInit    \tCorsairGndAttkInit\r\nAirAttkInit    \tCorsairAirAttkInit\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tCorsairGndAttkInit\r\nAirAttkRpt     \tCorsairAirAttkInit\r\nCastSpell      \tCorsairCastSpell\r\nGndAttkToIdle  \tCorsairGndAttkToIdle\r\nAirAttkToIdle  \tCorsairGndAttkToIdle\r\nUnused2        \t[NONE]\r\nWalking        \tCorsairWalking\r\nWalkingToIdle  \tCorsairGndAttkToIdle\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \t[NONE]\r\nWorkingToIdle  \t[NONE]\r\nWarpIn         \tCorsairWarpIn\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCorsairInit:\r\n\timgul          \t930 0 42\t# CorsairShad (protoss\\corsair.grp)\r\nCorsairGndAttkToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong02\r\n\r\nCorsairDeath:\r\n\tplaysnd        \t533\t# Protoss\\Scout\\PScDth00.WAV\r\n\timgol          \t213 0 0\t# ProtossBuildingExplosionSmall (thingy\\tBangS.grp)\r\n\twait           \t3\r\n\tend            \t\r\n\r\nCorsairGndAttkInit:\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tCorsairGndAttkToIdle\r\n\r\nCorsairAirAttkInit:\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tattackwith     \t2\r\n\tplaysnd        \t1060\t# Protoss\\Corsair\\PCorlasr2.wav\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tgoto           \tCorsairGndAttkToIdle\r\n\r\nCorsairCastSpell:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tnobrkcodestart \t\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplaysnd        \t1059\t# Protoss\\Corsair\\PCorWeb1.wav\r\n\tcastspell      \t\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tsigorder       \t2\r\n\tgoto           \tCorsairGndAttkToIdle\r\n\r\nCorsairWalking:\r\n\timgol          \t931 0 0\t# CorsairOverlay (thingy\\pcsGlow.grp)\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tsetvertpos     \t0\r\n\tgoto           \tlong00\r\n\r\nCorsairWarpIn:\r\n\timgol          \t143 0 0\t# Unknown143 (protoss\\scout.grp)\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 931 CorsairOverlay (thingy\\pcsGlow.grp)\r\n.headerstart\r\nIsId           \t370\r\nType           \t12\r\nInit           \tCorsairEnginesInit\r\nDeath          \tlong01\r\nGndAttkInit    \tlong01\r\nAirAttkInit    \tlong01\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tlong01\r\nGndAttkToIdle  \tlong01\r\nAirAttkToIdle  \tlong01\r\nUnused2        \t[NONE]\r\nWalking        \tCorsairEnginesInit\r\nWalkingToIdle  \tlong01\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCorsairEnginesInit:\r\n\tengframe       \t0\r\n\twait           \t1\r\n\tengframe       \t17\r\n\twait           \t1\r\n\tgoto           \tCorsairEnginesInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 932 Unknown932 (thingy\\elbFireC.grp)\r\n.headerstart\r\nIsId           \t371\r\nType           \t1\r\nInit           \tUnknown371Init\r\nDeath          \tUnknown371Death\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown371Init:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\nUnknown371Death:\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 933 DarkTemplarBWUnit (protoss\\dtemplar.grp)\r\n.headerstart\r\nIsId           \t372\r\nType           \t12\r\nInit           \tDarkTemplar_Unit_Init\r\nDeath          \tDarkTemplar_Unit_Death\r\nGndAttkInit    \tDarkTemplar_Unit_GndAttkInit\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \tDarkTemplar_Unit_GndAttkInit\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \tDarkTemplar_Unit_CastSpell\r\nGndAttkToIdle  \tlong00\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tDarkTemplar_Unit_Walking\r\nWalkingToIdle  \tDarkTemplar_Unit_Init\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDarkTemplar_Unit_Init:\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\tgoto           \tlong00\r\n\r\nDarkTemplar_Unit_Death:\r\n\tplaysnd        \t741\t# Protoss\\DARKTEMPLAR\\PDTDth00.WAV\r\n\timgol          \t153 0 0\t# Unknown153 (protoss\\zealot.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nDarkTemplar_Unit_GndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tnobrkcodestart \t\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tattackmelee    \t1 111\t# Bullet\\UZeFir00.wav\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tnobrkcodeend   \t\r\n\tgotorepeatattk \t\r\n\tignorerest     \t\r\n\tgoto           \tDarkTemplar_Unit_Init\r\n\r\nDarkTemplar_Unit_CastSpell:\r\n\tcastspell      \t\r\n\tsigorder       \t2\r\n\tgotorepeatattk \t\r\n\tgoto           \tDarkTemplar_Unit_Init\r\n\r\nDarkTemplar_Unit_Walking:\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0xee\t# frame set 14\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0xff\t# frame set 15\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0x110\t# frame set 16\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0x121\t# frame set 17\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\tmove           \t5\r\n\twait           \t1\r\n\tplayfram       \t0xdd\t# frame set 13\r\n\tgoto           \tDarkTemplar_Unit_Walking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 964 NeutronFlare (thingy\\PcsSplsh.grp)\r\n.headerstart\r\nIsId           \t373\r\nType           \t2\r\nInit           \tNeutronFlareInit\r\nDeath          \tNeutronFlareDeath\r\nGndAttkInit    \tNeutronFlareDeath\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nNeutronFlareInit:\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nNeutronFlareDeath:\r\n\tplayfram       \t0\r\n\tplaysnd        \t95\t# Bullet\\SHOCKBMB.wav\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 951 DisruptionWeb (thingy\\Disrupt.grp)\r\n.headerstart\r\nIsId           \t374\r\nType           \t1\r\nInit           \tDisruptionWebInit\r\nDeath          \tDisruptionWebDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDisruptionWebInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\nDisruptionWebLocal00:\r\n\tplayfram       \t5\r\n\twait           \t3\r\n\tplayfram       \t6\r\n\twait           \t3\r\n\tplayfram       \t7\r\n\twait           \t3\r\n\tplayfram       \t8\r\n\twait           \t3\r\n\tplayfram       \t9\r\n\twait           \t3\r\n\tgoto           \tDisruptionWebLocal00\r\n\r\nDisruptionWebDeath:\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 952 Scantid (neutral\\Kcritter.grp)\r\n.headerstart\r\nIsId           \t375\r\nType           \t12\r\nInit           \tScantidInit\r\nDeath          \tScantidDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tScantidWalking\r\nWalkingToIdle  \tScantidWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nScantidInit:\r\n\timgul          \t953 0 0\t# ScantidShad (neutral\\nckShad.grp)\r\nScantidWalkingToIdle:\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tgoto           \tlong00\r\n\r\nScantidDeath:\r\n\tplaysnd        \t975\t# Misc\\CRITTERS\\ScDeath01.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xcd\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xce\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xcf\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd0\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd1\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd2\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd3\t# frame set 12\r\n\twait           \t2\r\n\tend            \t\r\n\r\nScantidWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\tgoto           \tScantidWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 954 Kakaru (neutral\\Scritter.grp)\r\n.headerstart\r\nIsId           \t376\r\nType           \t12\r\nInit           \tKakaruInit\r\nDeath          \tKakaruDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tKakaruWalking\r\nWalkingToIdle  \tKakaruWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nKakaruInit:\r\n\timgul          \t955 0 42\t# KakaruShad (neutral\\Scritter.grp)\r\nKakaruWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t2\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t2\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t2\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t2\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t2\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t2\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t2\r\n\tgoto           \tKakaruWalkingToIdle\r\n\r\nKakaruDeath:\r\n\tplaysnd        \t979\t# Misc\\CRITTERS\\TerDeath01.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0xcc\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xcd\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xce\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xcf\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd0\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd1\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd2\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd3\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd4\t# frame set 12\r\n\twait           \t2\r\n\tplayfram       \t0xd5\t# frame set 12\r\n\twait           \t2\r\n\tend            \t\r\n\r\nKakaruWalking:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\twait           \t1\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t1\r\n\tplayfram       \t0x99\t# frame set 9\r\n\twait           \t1\r\n\tplayfram       \t0xaa\t# frame set 10\r\n\twait           \t1\r\n\tplayfram       \t0xbb\t# frame set 11\r\n\twait           \t1\r\n\tgoto           \tKakaruWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 956 Ursadon (neutral\\Icritter.grp)\r\n.headerstart\r\nIsId           \t377\r\nType           \t12\r\nInit           \tUrsadonInit\r\nDeath          \tUrsadonDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \tUrsadonWalking\r\nWalkingToIdle  \tUrsadonWalkingToIdle\r\nSpecialState1  \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUrsadonInit:\r\n\timgul          \t957 0 0\t# UrsadonShad (neutral\\ncicShad.grp)\r\nUrsadonWalkingToIdle:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tgoto           \tlong00\r\n\r\nUrsadonDeath:\r\n\tplaysnd        \t971\t# Misc\\CRITTERS\\PBDeath01.wav\r\n\tsetfldirect    \t0\r\n\tplayfram       \t0x88\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x89\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x8a\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x8b\t# frame set 8\r\n\twait           \t2\r\n\tplayfram       \t0x8c\t# frame set 8\r\n\twait           \t50\r\n\tplayfram       \t0x8d\t# frame set 8\r\n\twait           \t50\r\n\tplayfram       \t0x8e\t# frame set 8\r\n\twait           \t50\r\n\tplayfram       \t0x8f\t# frame set 8\r\n\twait           \t50\r\n\tend            \t\r\n\r\nUrsadonWalking:\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x11\t# frame set 1\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x22\t# frame set 2\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x33\t# frame set 3\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x44\t# frame set 4\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x55\t# frame set 5\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x66\t# frame set 6\r\n\tmove           \t4\r\n\twait           \t1\r\n\tplayfram       \t0x77\t# frame set 7\r\n\tgoto           \tUrsadonWalking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 965 HaloRocket (bullet\\SMmissle.grp)\r\n.headerstart\r\nIsId           \t378\r\nType           \t2\r\nInit           \tHaloRocketInit\r\nDeath          \tHaloRocketDeath\r\nGndAttkInit    \tHaloRocketGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nHaloRocketInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\tplaysnd        \t1023\t# Bullet\\Tfrshoot.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nHaloRocketGndAttkInit:\r\n\tsprol          \t505 0 0\t# Unknown960 (thingy\\bsmoke.grp)\r\n\twait           \t2\r\n\tgoto           \tHaloRocketGndAttkInit\r\n\r\nHaloRocketDeath:\r\n\tplaysnd        \t1022\t# Bullet\\Tfrhit.wav\r\n\timgol          \t530 0 0\t# Unknown530 (thingy\\ecaHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 966 OpticFlareProjectile (bullet\\grenade.grp)\r\n.headerstart\r\nIsId           \t379\r\nType           \t2\r\nInit           \tOpticalFlareInit\r\nDeath          \tOpticalFlareDeath\r\nGndAttkInit    \tOpticalFlareGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOpticalFlareInit:\r\n\tplayfram       \t0\r\n\tplaysnd        \t1016\t# Terran\\Medic\\TMedflsh.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nOpticalFlareGndAttkInit:\r\n\tsprol          \t310 0 0\t# Fragmentationgrenadesmoke (thingy\\GreSmoke.grp)\r\n\twait           \t1\r\nOpticalFlareLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tgoto           \tOpticalFlareLocal00\r\n\r\nOpticalFlareDeath:\r\n\timgol          \t977 0 0\t# OpticFlareMedium (thingy\\TmeFlshM.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 961 SubterraneanSpinesOverlay (bullet\\Spike.grp)\r\n.headerstart\r\nIsId           \t380\r\nType           \t1\r\nInit           \tSubterraneanSpinesOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSubterraneanSpinesOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 962 AcidSporesProjectile (thingy\\ZDvPuke.grp)\r\n.headerstart\r\nIsId           \t381\r\nType           \t2\r\nInit           \tCorrosiveAcidInit\r\nDeath          \tCorrosiveAcidDeath\r\nGndAttkInit    \tCorrosiveAcidGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCorrosiveAcidInit:\r\n\ttmprmgraphicstart\t\r\n\ttrgtrangecondjmp\t40 CorrosiveAcidLocal00\r\n\ttmprmgraphicend\t\r\nCorrosiveAcidLocal00:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nCorrosiveAcidGndAttkInit:\r\n\tplayfram       \t0x00\t# frame set 0\r\n\twait           \t2\r\n\tplayfram       \t0x11\t# frame set 1\r\n\twait           \t2\r\n\tplayfram       \t0x22\t# frame set 2\r\n\twait           \t2\r\n\tplayfram       \t0x33\t# frame set 3\r\n\twait           \t2\r\n\tgoto           \tlong00\r\n\r\nCorrosiveAcidDeath:\r\n\tplaysnd        \t72\t# Bullet\\ZGuHit00.wav\r\n\timgol          \t963 0 0\t# AcidSporesHit (thingy\\ZDvHit.grp)\r\n\tdomissiledmg   \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 963 AcidSporesHit (thingy\\ZDvHit.grp)\r\n.headerstart\r\nIsId           \t382\r\nType           \t1\r\nInit           \tCorrosiveAcidHitInit\r\nDeath          \tCorrosiveAcidHitDeath\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nCorrosiveAcidHitInit:\r\n\tplayfram       \t0\r\n\tplaysnd        \t1095\t# Zerg\\Devourer\\goophit.wav\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\nCorrosiveAcidHitDeath:\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 994 AcidSporesOverlay1Large (thingy\\ZdvGooL.grp)\r\n# 990 AcidSporesOverlay1Medium (thingy\\ZdvGooM.grp)\r\n# 986 AcidSporesOverlay1Small (thingy\\ZdvGooS.grp)\r\n.headerstart\r\nIsId           \t383\r\nType           \t1\r\nInit           \tAcidSpores_1_OverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcidSpores_1_OverlayInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 3\r\n\ttmprmgraphicend\t\r\nAcidSpores_1_OverlayLocal00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t34\r\n\twait           \t2\r\n\tplayfram       \t51\r\n\twaitrand       \t2 3\r\n\tgoto           \tAcidSpores_1_OverlayLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 995 AcidSporesOverlay2Large (thingy\\ZdvGooL.grp)\r\n# 991 AcidSporesOverlay2Medium (thingy\\ZdvGooM.grp)\r\n# 987 AcidSporesOverlay2Small (thingy\\ZdvGooS.grp)\r\n.headerstart\r\nIsId           \t384\r\nType           \t1\r\nInit           \tAcidSpores_2_3_OverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcidSpores_2_3_OverlayInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 3\r\n\ttmprmgraphicend\t\r\nAcidSpores_2_3_OverlayLocal00:\r\n\tplayfram       \t68\r\n\twait           \t2\r\n\tplayfram       \t85\r\n\twait           \t2\r\n\tplayfram       \t102\r\n\twait           \t2\r\n\tplayfram       \t119\r\n\twaitrand       \t2 3\r\n\tgoto           \tAcidSpores_2_3_OverlayLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 996 AcidSporesOverlay3Large (thingy\\ZdvGooL.grp)\r\n# 992 AcidSporesOverlay3Medium (thingy\\ZdvGooM.grp)\r\n# 988 AcidSporesOverlay3Small (thingy\\ZdvGooS.grp)\r\n.headerstart\r\nIsId           \t385\r\nType           \t1\r\nInit           \tAcidSpores_4_5_OverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcidSpores_4_5_OverlayInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 3\r\n\ttmprmgraphicend\t\r\nAcidSpores_4_5_OverlayLocal00:\r\n\tplayfram       \t136\r\n\twait           \t2\r\n\tplayfram       \t153\r\n\twait           \t2\r\n\tplayfram       \t170\r\n\twait           \t2\r\n\tplayfram       \t187\r\n\twaitrand       \t2 3\r\n\tgoto           \tAcidSpores_4_5_OverlayLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 997 AcidSporesOverlay4Large (thingy\\ZdvGooL.grp)\r\n# 993 AcidSporesOverlay4Medium (thingy\\ZdvGooM.grp)\r\n# 989 AcidSporesOverlay4Small (thingy\\ZdvGooS.grp)\r\n.headerstart\r\nIsId           \t386\r\nType           \t1\r\nInit           \tAcidSpores_6_9_OverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nAcidSpores_6_9_OverlayInit:\r\n\ttmprmgraphicstart\t\r\n\twaitrand       \t1 3\r\n\ttmprmgraphicend\t\r\nAcidSpores_6_9_OverlayLocal00:\r\n\tplayfram       \t204\r\n\twait           \t2\r\n\tplayfram       \t221\r\n\twait           \t2\r\n\tplayfram       \t238\r\n\twait           \t2\r\n\tplayfram       \t255\r\n\twaitrand       \t2 3\r\n\tgoto           \tAcidSpores_6_9_OverlayLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 909 DesertDoodad59 (thingy\\tileset\\desert\\LDMachn1.grp)\r\n# 907 DesertDoodad57 (thingy\\tileset\\desert\\LDLbox01.grp)\r\n# 904 DesertDoodad54 (thingy\\tileset\\desert\\HDLbox01.grp)\r\n# 838 IceWorldDoodad68 (thingy\\tileset\\ice\\LDRck02.grp)\r\n# 836 IceWorldDoodad66 (thingy\\tileset\\ice\\LDRck01.grp)\r\n# 832 IceWorldDoodad62 (thingy\\tileset\\ice\\HDPipes.grp)\r\n.headerstart\r\nIsId           \t387\r\nType           \t0\r\nInit           \tIceDoodadInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nIceDoodadInit:\r\n\tplayfram       \t0\r\n\tsetflipstate   \t1\r\n\timgulnextid    \t0 0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 910 DesertDoodad60 (thingy\\tileset\\desert\\SLDMchn1.grp)\r\n# 908 DesertDoodad58 (thingy\\tileset\\desert\\SLDLbox1.grp)\r\n# 905 DesertDoodad55 (thingy\\tileset\\desert\\SHDLbox1.grp)\r\n# 839 IceWorldDoodad69 (thingy\\tileset\\ice\\SLDRck02.grp)\r\n# 837 IceWorldDoodad67 (thingy\\tileset\\ice\\SLDRck01.grp)\r\n# 833 IceWorldDoodad63 (thingy\\tileset\\ice\\SHDPipes.grp)\r\n.headerstart\r\nIsId           \t388\r\nType           \t1\r\nInit           \tDoodadShadowsHeader_BW_Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDoodadShadowsHeader_BW_Init:\r\n\twait           \t1\r\n\tfollowmaingraphic\t\r\n\tgoto           \tDoodadShadowsHeader_BW_Init\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 969 RestorationLarge (thingy\\tCureLrg.grp)\r\n# 968 RestorationMedium (thingy\\tCureMed.grp)\r\n# 967 RestorationSmall (thingy\\tCureSml.grp)\r\n.headerstart\r\nIsId           \t389\r\nType           \t1\r\nInit           \tRestorationHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nRestorationHitInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tplayfram       \t15\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tplayfram       \t15\r\n\twait           \t1\r\n\tgoto           \tlong01\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 975 MindControlLarge (thingy\\PDaMyoLg.grp)\r\n# 974 MindControlMedium (thingy\\PDaMyoMd.grp)\r\n# 973 MindControlSmall (thingy\\PDaMyoSm.grp)\r\n.headerstart\r\nIsId           \t390\r\nType           \t1\r\nInit           \tMindControlHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMindControlHitInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tplayfram       \t15\r\n\twait           \t1\r\n\tplayfram       \t16\r\n\twait           \t1\r\n\tplayfram       \t17\r\n\twait           \t1\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tgoto           \tlong01\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 978 OpticFlareLarge (thingy\\TmeFlshL.grp)\r\n# 977 OpticFlareMedium (thingy\\TmeFlshM.grp)\r\n# 976 OpticFlareSmall (thingy\\TmeFlshS.grp)\r\n.headerstart\r\nIsId           \t391\r\nType           \t1\r\nInit           \tOpticalFlareHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOpticalFlareHitInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tgoto           \tlong01\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 981 FeedbackLarge (thingy\\PDaPsyLg.grp)\r\n# 980 FeedbackMedium (thingy\\PDaPsyMd.grp)\r\n# 979 FeedbackSmall (thingy\\PDaPsySm.grp)\r\n.headerstart\r\nIsId           \t392\r\nType           \t1\r\nInit           \tFeedbackInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nFeedbackInit:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twait           \t1\r\n\tplayfram       \t11\r\n\twait           \t1\r\n\tplayfram       \t12\r\n\twait           \t1\r\n\tplayfram       \t13\r\n\twait           \t1\r\n\tplayfram       \t14\r\n\twait           \t1\r\n\tplayfram       \t15\r\n\twait           \t1\r\n\tplayfram       \t16\r\n\twait           \t1\r\n\tplayfram       \t17\r\n\twait           \t1\r\n\tplayfram       \t18\r\n\twait           \t1\r\n\tplayfram       \t19\r\n\twait           \t1\r\n\tplayfram       \t20\r\n\tgoto           \tlong01\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 984 MaelstromUnitOverlayLarge (thingy\\PDaParLg.grp)\r\n# 983 MaelstromUnitOverlayMedium (thingy\\PDaParMd.grp)\r\n# 982 MaelstromUnitOverlaySmall (thingy\\PDaParSm.grp)\r\n.headerstart\r\nIsId           \t393\r\nType           \t1\r\nInit           \tMaelstormOverlayInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMaelstormOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tplayfram       \t9\r\n\twait           \t2\r\n\tplayfram       \t10\r\n\twait           \t2\r\n\tplayfram       \t11\r\n\twait           \t2\r\n\tplayfram       \t12\r\n\twait           \t2\r\n\tplayfram       \t13\r\n\twait           \t2\r\n\tplayfram       \t14\r\n\twait           \t2\r\n\tplayfram       \t15\r\n\twait           \t2\r\n\tplayfram       \t16\r\n\twait           \t2\r\n\tplayfram       \t17\r\n\twait           \t2\r\n\tplayfram       \t18\r\n\twait           \t2\r\n\tplayfram       \t19\r\n\twait           \t2\r\n\tplayfram       \t20\r\n\twait           \t2\r\n\tplayfram       \t21\r\n\twait           \t2\r\n\tplayfram       \t22\r\n\twait           \t2\r\n\tplayfram       \t23\r\n\twait           \t2\r\n\tgoto           \tMaelstormOverlayInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 972 Unknown972 (thingy\\tmeHealL.grp)\r\n# 971 Unknown971 (thingy\\tmeHealM.grp)\r\n# 970 Unknown970 (thingy\\tmeHealM.grp)\r\n.headerstart\r\nIsId           \t394\r\nType           \t1\r\nInit           \tUnknown394Init\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nUnknown394Init:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tgoto           \tlong01\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 985 SubterraneanSpines (zerg\\zmarker.grp)\r\n.headerstart\r\nIsId           \t395\r\nType           \t2\r\nInit           \tSubterraneanSpinesInit\r\nDeath          \tSubterraneanSpinesDeath\r\nGndAttkInit    \tSubterraneanSpinesGndAttkInit\r\nAirAttkInit    \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nSubterraneanSpinesInit:\r\n\tplaysnd        \t1108\t# Bullet\\ZLrkFir1.wav\r\n\twait           \t1\r\n\tsigorder       \t1\r\n\twait           \t1\r\nSubterraneanSpinesGndAttkInit:\r\n\tgrdsprol       \t511 0 0\t# SubterraneanSpinesOverlay (bullet\\Spike.grp)\r\n\tdogrddamage    \t\r\n\twait           \t2\r\n\tgoto           \tSubterraneanSpinesGndAttkInit\r\n\r\nSubterraneanSpinesDeath:\r\n\tplaysnd        \t1110\t# Bullet\\ZLrkHit1.wav\r\n\timgol          \t530 0 0\t# Unknown530 (thingy\\ecaHit.grp)\r\n\tdogrddamage    \t\r\n\twait           \t1\r\n\tend            \t\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 851 DesertDoodad (thingy\\tileset\\desert\\HDBANT.grp)\r\n.headerstart\r\nIsId           \t396\r\nType           \t0\r\nInit           \tDesertDoodadInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDesertDoodadInit:\r\n\tplayfram       \t0\r\nDesertDoodadLocal00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tgoto           \tDesertDoodadLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 889 DesertDoodad39 (thingy\\tileset\\desert\\LDBNEON.grp)\r\n.headerstart\r\nIsId           \t397\r\nType           \t0\r\nInit           \tDesertDoodad2Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDesertDoodad2Init:\r\n\tplayfram       \t0\r\nDesertDoodad2Local00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tgoto           \tDesertDoodad2Local00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 913 UnusedScout (protoss\\scout.grp)\r\n# 894 DesertDoodad44 (thingy\\tileset\\desert\\Ldneon.grp)\r\n.headerstart\r\nIsId           \t398\r\nType           \t0\r\nInit           \tDesertDoodad3Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDesertDoodad3Init:\r\n\tplayfram       \t0\r\nDesertDoodad3Local00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tgoto           \tDesertDoodad3Local00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 911 DesertDoodad61 (thingy\\tileset\\desert\\Tgas.grp)\r\n.headerstart\r\nIsId           \t399\r\nType           \t0\r\nInit           \tDesertDoodadOverlayInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDesertDoodadOverlayInit:\r\n\tplayfram       \t0\r\nDesertDoodadOverlayLocal00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t3\r\n\twait           \t1\r\n\tplayfram       \t4\r\n\twait           \t1\r\n\tplayfram       \t5\r\n\twait           \t1\r\n\tplayfram       \t6\r\n\twait           \t1\r\n\tplayfram       \t7\r\n\twait           \t1\r\n\tplayfram       \t8\r\n\twait           \t1\r\n\tplayfram       \t9\r\n\twait           \t1\r\n\tplayfram       \t10\r\n\twaitrand       \t63 75\r\n\tgoto           \tDesertDoodadOverlayLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 912 DesertDoodad62 (thingy\\tileset\\desert\\sarlacc.grp)\r\n.headerstart\r\nIsId           \t400\r\nType           \t0\r\nInit           \tDesertDoodad4Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nDesertDoodad4Init:\r\n\tplayfram       \t0\r\nDesertDoodad4Local00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tgoto           \tDesertDoodad4Local00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 756 TwilightDoodad2 (thingy\\tileset\\twilight\\Lddrill.grp)\r\n.headerstart\r\nIsId           \t401\r\nType           \t0\r\nInit           \tTwilightDoodadInit\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTwilightDoodadInit:\r\n\tplayfram       \t0\r\nTwilightDoodadLocal00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tgoto           \tTwilightDoodadLocal00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 757 TwilightDoodad3 (thingy\\tileset\\twilight\\Ldxel01.grp)\r\n.headerstart\r\nIsId           \t402\r\nType           \t0\r\nInit           \tTwilightDoodad2Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTwilightDoodad2Init:\r\n\tplayfram       \t0\r\nTwilightDoodad2Local00:\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t2\r\n\twait           \t1\r\n\tplayfram       \t1\r\n\twait           \t1\r\n\tplayfram       \t0\r\n\twait           \t1\r\n\tgoto           \tTwilightDoodad2Local00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 758 TwilightDoodad4 (thingy\\tileset\\twilight\\Ldxel02.grp)\r\n.headerstart\r\nIsId           \t403\r\nType           \t0\r\nInit           \tTwilightDoodad3Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTwilightDoodad3Init:\r\n\tplayfram       \t0\r\nTwilightDoodad3Local00:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tgoto           \tTwilightDoodad3Local00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 763 TwilightDoodad9 (thingy\\tileset\\twilight\\Ldxeltur.grp)\r\n.headerstart\r\nIsId           \t404\r\nType           \t0\r\nInit           \tTwilightDoodad4Init\r\nDeath          \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nTwilightDoodad4Init:\r\n\tplayfram       \t0\r\nTwilightDoodad4Local00:\r\n\tplayfram       \t0\r\n\tsetflipstate   \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tsetflipstate   \t1\r\n\tsethorpos      \t253\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tgoto           \tTwilightDoodad4Local00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 923 OvermindCocoon (zerg\\XOvermnd.grp)\r\n.headerstart\r\nIsId           \t405\r\nType           \t20\r\nInit           \tOvermindCocoonInit\r\nDeath          \tlong03\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tOvermindCocoonAlmostBuilt\r\nBuilt          \tOvermindCocoonBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tOvermindCocoonIsWorking\r\nWorkingToIdle  \tOvermindCocoonIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nOvermindCocoonInit:\r\n\timgul          \t924 0 0\t# OvermindCocoonShad (zerg\\ZovShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nOvermindCocoonAlmostBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tOvermindCocoonBuilt\r\n\r\nOvermindCocoonBuilt:\r\n\twaitrand       \t1 3\r\nOvermindCocoonIsWorking:\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t4\r\n\twait           \t1\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t0\r\n\twait           \t4\r\n\tgoto           \tOvermindCocoonIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 934 WarpGate (protoss\\XwarpGat.grp)\r\n.headerstart\r\nIsId           \t406\r\nType           \t20\r\nInit           \tWarpGateInit\r\nDeath          \tNexusDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tWarpGateAlmostBuilt\r\nBuilt          \tWarpGateBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tWarpGateIsWorking\r\nWorkingToIdle  \tWarpGateIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWarpGateInit:\r\n\timgul          \t935 0 0\t# WarpGateShad (protoss\\pwgShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nWarpGateAlmostBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tWarpGateBuilt\r\n\r\nWarpGateBuilt:\r\n\timgol          \t936 0 0\t# WarpGateOverlay (protoss\\XwarpFir.grp)\r\n\tgoto           \tlong00\r\n\r\nWarpGateIsWorking:\r\n\tplayfram       \t0\r\n\tgoto           \tWarpGateIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 947 PsiDisruptor (neutral\\PsiDisr.grp)\r\n.headerstart\r\nIsId           \t407\r\nType           \t20\r\nInit           \tPsiDisrupterInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tPsiDisrupterBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPsiDisrupterInit:\r\n\timgul          \t948 0 0\t# PsiDisruptorShad (neutral\\tpdShad.grp)\r\nPsiDisrupterBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 949 PowerGenerater (neutral\\Generate.grp)\r\n.headerstart\r\nIsId           \t408\r\nType           \t20\r\nInit           \tPowerGeneratorInit\r\nDeath          \tAcademyDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \tPowerGeneratorBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tlong00\r\nWorkingToIdle  \tlong00\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nPowerGeneratorInit:\r\n\timgul          \t950 0 0\t# PowerGeneraterShad (neutral\\tgnShad.grp)\r\nPowerGeneratorBuilt:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tgoto           \tPowerGeneratorBuilt\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 936 WarpGateOverlay (protoss\\XwarpFir.grp)\r\n.headerstart\r\nIsId           \t409\r\nType           \t24\r\nInit           \tWarpGateOverlayInit\r\nDeath          \tlong01\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \t[NONE]\r\nBuilt          \t[NONE]\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tWarpGateOverlayInit\r\nWorkingToIdle  \tWarpGateOverlayInit\r\nWarpIn         \t[NONE]\r\nUnused3        \t[NONE]\r\nStarEditInit   \t[NONE]\r\nDisable        \tlong01\r\nBurrow         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nWarpGateOverlayInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tgoto           \tWarpGateOverlayInit\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 937 XelNagaTemple (protoss\\XelTempl.grp)\r\n.headerstart\r\nIsId           \t410\r\nType           \t20\r\nInit           \tXelNagaTempleInit\r\nDeath          \tNexusDeath\r\nGndAttkInit    \t[NONE]\r\nAirAttkInit    \t[NONE]\r\nUnused1        \t[NONE]\r\nGndAttkRpt     \t[NONE]\r\nAirAttkRpt     \t[NONE]\r\nCastSpell      \t[NONE]\r\nGndAttkToIdle  \t[NONE]\r\nAirAttkToIdle  \t[NONE]\r\nUnused2        \t[NONE]\r\nWalking        \t[NONE]\r\nWalkingToIdle  \t[NONE]\r\nSpecialState1  \t[NONE]\r\nSpecialState2  \t[NONE]\r\nAlmostBuilt    \tXelNagaTempleAlmostBuilt\r\nBuilt          \tXelNagaTempleBuilt\r\nLanding        \t[NONE]\r\nLiftOff        \t[NONE]\r\nIsWorking      \tXelNagaTempleIsWorking\r\nWorkingToIdle  \tXelNagaTempleIsWorking\r\nWarpIn         \t[NONE]\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nXelNagaTempleInit:\r\n\timgul          \t938 0 0\t# XelNagaTempleShad (protoss\\pxtShad.grp)\r\n\tplayfram       \t0\r\n\tgoto           \tlong00\r\n\r\nXelNagaTempleAlmostBuilt:\r\n\tplayfram       \t0\r\n\tgoto           \tXelNagaTempleBuilt\r\n\r\nXelNagaTempleBuilt:\r\n\tgoto           \tlong00\r\n\r\nXelNagaTempleIsWorking:\r\n\tplayfram       \t0\r\n\tgoto           \tXelNagaTempleIsWorking\r\n\r\n\r\n# ----------------------------------------------------------------------------- #\r\n# This header is used by images.dat entries:\r\n# 998 MaelstromHit (thingy\\MaelHit.grp)\r\n.headerstart\r\nIsId           \t411\r\nType           \t1\r\nInit           \tMaelstromHitInit\r\nDeath          \tlong01\r\n.headerend\r\n# ----------------------------------------------------------------------------- #\r\n\r\nMaelstromHitInit:\r\n\tplayfram       \t0\r\n\twait           \t2\r\n\tplayfram       \t1\r\n\twait           \t2\r\n\tplayfram       \t2\r\n\twait           \t2\r\n\tplayfram       \t3\r\n\twait           \t2\r\n\tplayfram       \t4\r\n\twait           \t2\r\n\tplayfram       \t5\r\n\twait           \t2\r\n\tplayfram       \t6\r\n\twait           \t2\r\n\tplayfram       \t7\r\n\twait           \t2\r\n\tplayfram       \t8\r\n\twait           \t2\r\n\tend            \t\r\n\r\n\r\n# ------------------------------------------------------------------------------ #\r\n# LONG JUMPS (these are usually shared routines between many animations)         #\r\n# ------------------------------------------------------------------------------ #\r\n\r\nlong00:\r\n\twait           \t125\r\n\tgoto           \tlong00\r\n\r\nlong01:\r\n\twait           \t1\r\n\tend            \t\r\n\r\nlong02:\r\n\tsetvertpos     \t1\r\n\twaitrand       \t8 10\r\n\tsetvertpos     \t2\r\n\twaitrand       \t8 10\r\n\tsetvertpos     \t1\r\n\twaitrand       \t8 10\r\n\tsetvertpos     \t0\r\n\twaitrand       \t8 10\r\n\tgoto           \tlong02\r\n\r\nlong03:\r\n\tplaysnd        \t774\t# Zerg\\Bldg\\ZBldgDth.WAV\r\n\timgol          \t60 0 0\t# ZergBuildingDeath (thingy\\zBldDthS.grp)\r\n\twait           \t3\r\n\tlowsprul       \t187 0 0\t# ZergBuildingRubbleSmall (thingy\\ZRubbleL.grp)\r\n\twait           \t1\r\n\tend            \t\r\n\r\nlong04:\r\n\twait           \t1\r\n\tattackwith     \t2\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\nlong05:\r\n\twait           \t1\r\n\tattackwith     \t1\r\n\tgotorepeatattk \t\r\n\tgoto           \tlong00\r\n\r\n"
  },
  {
    "path": "doc/sc_dat_architecture",
    "content": "<mxfile host=\"app.diagrams.net\" modified=\"2022-09-23T15:34:23.123Z\" agent=\"5.0 (X11)\" etag=\"_bK8kSuio-MwEEBV6wpp\" version=\"20.3.0\" type=\"github\">\n  <diagram id=\"pLGyL3gJlz5I7s2QdtuP\" name=\"DAT Architecture\">\n    <mxGraphModel dx=\"2539\" dy=\"1753\" grid=\"1\" gridSize=\"10\" guides=\"1\" tooltips=\"1\" connect=\"1\" arrows=\"1\" fold=\"1\" page=\"1\" pageScale=\"1\" pageWidth=\"1169\" pageHeight=\"827\" math=\"0\" shadow=\"0\">\n      <root>\n        <mxCell id=\"0\" />\n        <mxCell id=\"1\" parent=\"0\" />\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-11\" value=\"same index\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-1\" target=\"PzZqxms0mEW9Ky41_EIL-22\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"350\" y=\"-10\" />\n              <mxPoint x=\"350\" y=\"190\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-1\" value=\"units.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"-10\" width=\"170\" height=\"265\" as=\"geometry\">\n            <mxRectangle x=\"160\" y=\"80\" width=\"80\" height=\"30\" as=\"alternateBounds\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-3\" value=\"\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-2\" value=\"graphics\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-45\" value=\"ground_weapon\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"85\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-44\" value=\"air_weapon\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"115\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-27\" value=\"*_sound_*\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"145\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-38\" value=\"portrait\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"175\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-13\" value=\"ai_*\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"205\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-6\" value=\"armor_upgrade\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-1\" vertex=\"1\">\n          <mxGeometry y=\"235\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-8\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-6\" target=\"PzZqxms0mEW9Ky41_EIL-23\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"300\" y=\"345\" />\n              <mxPoint x=\"300\" y=\"220\" />\n            </Array>\n            <mxPoint x=\"270\" y=\"370\" as=\"sourcePoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-5\" value=\"weapons.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"270\" width=\"170\" height=\"210\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-4\" value=\"&lt;div&gt;record_size=42&lt;/div&gt;\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=10;\" parent=\"PzZqxms0mEW9Ky41_EIL-5\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-6\" value=\"label\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-5\" vertex=\"1\">\n          <mxGeometry y=\"60\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-7\" value=\"graphics\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-5\" vertex=\"1\">\n          <mxGeometry y=\"90\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-8\" value=\"error_message\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-5\" vertex=\"1\">\n          <mxGeometry y=\"120\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-11\" value=\"icon\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-5\" vertex=\"1\">\n          <mxGeometry y=\"150\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-2\" value=\"damage_upgrade\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-5\" vertex=\"1\">\n          <mxGeometry y=\"180\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-9\" value=\"flingy.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"507\" width=\"170\" height=\"85\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-5\" value=\"record_size=15\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"PzZqxms0mEW9Ky41_EIL-9\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-10\" value=\"sprite\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-9\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-13\" value=\"sprites.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"622\" width=\"170\" height=\"100\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-6\" value=\"&lt;div&gt;record_size_first_130=4&lt;/div&gt;&lt;div&gt;record_size_rest=7&lt;br&gt;&lt;/div&gt;\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"PzZqxms0mEW9Ky41_EIL-13\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"40\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-14\" value=\"image_file\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-13\" vertex=\"1\">\n          <mxGeometry y=\"70\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-17\" value=\"images.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"737\" width=\"170\" height=\"85\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-7\" value=\"record_size=38\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"PzZqxms0mEW9Ky41_EIL-17\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-18\" value=\"grp\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-17\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-21\" value=\"stats_txt.tbl\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"460\" y=\"120\" width=\"140\" height=\"235\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-31\" value=\"size=num_offsets\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"PzZqxms0mEW9Ky41_EIL-21\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"140\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-22\" value=\"units\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-21\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-23\" value=\"weapons\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-21\" vertex=\"1\">\n          <mxGeometry y=\"85\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-24\" value=\"error_messages\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-21\" vertex=\"1\">\n          <mxGeometry y=\"115\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-60\" value=\"upgrades\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-21\" vertex=\"1\">\n          <mxGeometry y=\"145\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-12\" value=\"orders\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-21\" vertex=\"1\">\n          <mxGeometry y=\"175\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-24\" value=\"techdata\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-21\" vertex=\"1\">\n          <mxGeometry y=\"205\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-35\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-2\" target=\"PzZqxms0mEW9Ky41_EIL-9\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"230\" y=\"487\" as=\"sourcePoint\" />\n            <mxPoint x=\"330\" y=\"487\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"-50\" y=\"60\" />\n              <mxPoint x=\"-50\" y=\"527\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-37\" value=\"index pointer\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];\" parent=\"PzZqxms0mEW9Ky41_EIL-35\" vertex=\"1\" connectable=\"0\">\n          <mxGeometry x=\"0.3263\" y=\"3\" relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"-13\" y=\"-83\" as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-38\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.014;entryY=0.176;entryDx=0;entryDy=0;entryPerimeter=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-10\" target=\"PzZqxms0mEW9Ky41_EIL-13\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"230\" y=\"592\" as=\"sourcePoint\" />\n            <mxPoint x=\"330\" y=\"592\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"10\" y=\"577\" />\n              <mxPoint x=\"10\" y=\"640\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-39\" value=\"index pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;\" parent=\"PzZqxms0mEW9Ky41_EIL-38\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-40\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-14\" target=\"PzZqxms0mEW9Ky41_EIL-17\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"230\" y=\"592\" as=\"sourcePoint\" />\n            <mxPoint x=\"330\" y=\"592\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"10\" y=\"707\" />\n              <mxPoint x=\"10\" y=\"758\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-41\" value=\"index pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;\" parent=\"PzZqxms0mEW9Ky41_EIL-40\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-42\" value=\"images.tbl\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"460\" y=\"757\" width=\"140\" height=\"85\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-33\" value=\"size=num_offsets\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"PzZqxms0mEW9Ky41_EIL-42\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"140\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-43\" value=\"images\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"PzZqxms0mEW9Ky41_EIL-42\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-50\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-17\" target=\"PzZqxms0mEW9Ky41_EIL-43\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"230\" y=\"397\" as=\"sourcePoint\" />\n            <mxPoint x=\"330\" y=\"397\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"PzZqxms0mEW9Ky41_EIL-51\" value=\"index-1 pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;\" parent=\"PzZqxms0mEW9Ky41_EIL-50\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-9\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;\" parent=\"1\" target=\"PzZqxms0mEW9Ky41_EIL-9\" edge=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-5\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"70\" y=\"407\" as=\"sourcePoint\" />\n            <mxPoint x=\"37.61999999999989\" y=\"476.96000000000004\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"10\" y=\"375\" />\n              <mxPoint x=\"10\" y=\"507\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-10\" value=\"index pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;\" parent=\"wQT6I2i7r7E7tcLqA3oX-9\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-12\" value=\"cmdicon.grp\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"460\" y=\"457\" width=\"140\" height=\"120\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-13\" value=\"weapon\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-12\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-27\" value=\"upgrades\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-12\" vertex=\"1\">\n          <mxGeometry y=\"60\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-29\" value=\"techdata\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-12\" vertex=\"1\">\n          <mxGeometry y=\"90\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-18\" value=\"sfxdata.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"857\" width=\"170\" height=\"85\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-19\" value=\"record_size=9\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"wQT6I2i7r7E7tcLqA3oX-18\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-20\" value=\"sound_file (0=none)\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-18\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-21\" value=\"sfxdata.tbl\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"460\" y=\"877\" width=\"140\" height=\"85\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-34\" value=\"size=num_offsets\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"wQT6I2i7r7E7tcLqA3oX-21\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"140\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-22\" value=\"sound_file\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-21\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-23\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;\" parent=\"1\" source=\"wQT6I2i7r7E7tcLqA3oX-18\" target=\"wQT6I2i7r7E7tcLqA3oX-22\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"250\" y=\"897\" as=\"sourcePoint\" />\n            <mxPoint x=\"410\" y=\"937\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-24\" value=\"index-1 pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;\" parent=\"wQT6I2i7r7E7tcLqA3oX-23\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-25\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;\" parent=\"1\" source=\"wQT6I2i7r7E7tcLqA3oX-27\" target=\"wQT6I2i7r7E7tcLqA3oX-18\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"-130\" y=\"277\" as=\"sourcePoint\" />\n            <mxPoint x=\"-60\" y=\"668.25\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"-100\" y=\"150\" />\n              <mxPoint x=\"-100\" y=\"878\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-26\" value=\"index pointer\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];\" parent=\"wQT6I2i7r7E7tcLqA3oX-25\" vertex=\"1\" connectable=\"0\">\n          <mxGeometry x=\"0.3263\" y=\"3\" relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"-13\" y=\"-83\" as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-28\" value=\"portdata.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"977\" width=\"170\" height=\"115\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-29\" value=\"record_size=6\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"wQT6I2i7r7E7tcLqA3oX-28\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-30\" value=\"video_idle\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-28\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"v2uTlcIfrsabdLEwdSDk-2\" value=\"video_talking\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-28\" vertex=\"1\">\n          <mxGeometry y=\"85\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-31\" value=\"portdata.tbl\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"460\" y=\"980\" width=\"140\" height=\"85\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-35\" value=\"size=num_offsets\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"wQT6I2i7r7E7tcLqA3oX-31\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"140\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-32\" value=\"portrait_name\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-31\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-35\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;\" parent=\"1\" target=\"wQT6I2i7r7E7tcLqA3oX-32\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"240\" y=\"1048\" as=\"sourcePoint\" />\n            <mxPoint x=\"479.99999999999955\" y=\"1048.25\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-36\" value=\"index-1 pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;\" parent=\"wQT6I2i7r7E7tcLqA3oX-35\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-39\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;\" parent=\"1\" source=\"wQT6I2i7r7E7tcLqA3oX-38\" target=\"wQT6I2i7r7E7tcLqA3oX-28\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"-10\" y=\"270\" as=\"sourcePoint\" />\n            <mxPoint x=\"-10\" y=\"908.2500000000002\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"-180\" y=\"180\" />\n              <mxPoint x=\"-180\" y=\"1006\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-40\" value=\"index pointer\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];\" parent=\"wQT6I2i7r7E7tcLqA3oX-39\" vertex=\"1\" connectable=\"0\">\n          <mxGeometry x=\"0.3263\" y=\"3\" relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"-13\" y=\"-83\" as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-49\" value=\"upgrades.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"1120\" width=\"170\" height=\"130\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-50\" value=\"&lt;div&gt;record_size=20&lt;/div&gt;&lt;div&gt;record_size_broodwar=21&lt;br&gt;&lt;/div&gt;\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=10;\" parent=\"wQT6I2i7r7E7tcLqA3oX-49\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"40\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-51\" value=\"label\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-49\" vertex=\"1\">\n          <mxGeometry y=\"70\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-52\" value=\"icon\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"wQT6I2i7r7E7tcLqA3oX-49\" vertex=\"1\">\n          <mxGeometry y=\"100\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-58\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;fontSize=10;fontColor=#000000;exitX=1;exitY=0.5;exitDx=0;exitDy=0;\" parent=\"1\" source=\"wQT6I2i7r7E7tcLqA3oX-51\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"250\" y=\"1190\" as=\"sourcePoint\" />\n            <mxPoint x=\"600\" y=\"350\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"660\" y=\"1210\" />\n              <mxPoint x=\"660\" y=\"350\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"wQT6I2i7r7E7tcLqA3oX-59\" value=\"index pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontSize=10;fontColor=#000000;\" parent=\"wQT6I2i7r7E7tcLqA3oX-58\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-5\" value=\"orders.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"1260\" width=\"170\" height=\"150\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-6\" value=\"record_size=22\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-5\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-9\" value=\"label\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-5\" vertex=\"1\">\n          <mxGeometry y=\"60\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-7\" value=\"targeting\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-5\" vertex=\"1\">\n          <mxGeometry y=\"90\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-8\" value=\"energy\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-5\" vertex=\"1\">\n          <mxGeometry y=\"120\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-10\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;fontSize=10;fontColor=#000000;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;\" parent=\"1\" source=\"Gw3u6BSb_nzoXdGkpCYS-5\" target=\"Gw3u6BSb_nzoXdGkpCYS-12\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"290\" y=\"1335.0000000000005\" as=\"sourcePoint\" />\n            <mxPoint x=\"650\" y=\"500\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"710\" y=\"1335\" />\n              <mxPoint x=\"710\" y=\"310\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-11\" value=\"index pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontSize=10;fontColor=#000000;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-10\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-14\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;entryX=-0.028;entryY=0.086;entryDx=0;entryDy=0;entryPerimeter=0;\" parent=\"1\" source=\"Gw3u6BSb_nzoXdGkpCYS-13\" target=\"Gw3u6BSb_nzoXdGkpCYS-5\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"-10\" y=\"209\" as=\"sourcePoint\" />\n            <mxPoint x=\"-10\" y=\"1069.7500000000005\" as=\"targetPoint\" />\n            <Array as=\"points\">\n              <mxPoint x=\"-260\" y=\"209\" />\n              <mxPoint x=\"-260\" y=\"1273\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-15\" value=\"index pointer\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];\" parent=\"Gw3u6BSb_nzoXdGkpCYS-14\" vertex=\"1\" connectable=\"0\">\n          <mxGeometry x=\"0.3263\" y=\"3\" relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"-13\" y=\"-83\" as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-16\" value=\"techdata.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"1450\" width=\"170\" height=\"130\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-17\" value=\"&lt;div&gt;record_size=18&lt;/div&gt;&lt;div&gt;record_size_Broodwar=19&lt;br&gt;&lt;/div&gt;\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-16\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"40\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-18\" value=\"label\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-16\" vertex=\"1\">\n          <mxGeometry y=\"70\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-19\" value=\"icon\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"Gw3u6BSb_nzoXdGkpCYS-16\" vertex=\"1\">\n          <mxGeometry y=\"100\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-23\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.006;entryY=0.118;entryDx=0;entryDy=0;entryPerimeter=0;fontSize=12;\" parent=\"1\" source=\"Gw3u6BSb_nzoXdGkpCYS-8\" target=\"Gw3u6BSb_nzoXdGkpCYS-16\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-25\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=12;\" parent=\"1\" source=\"Gw3u6BSb_nzoXdGkpCYS-18\" target=\"Gw3u6BSb_nzoXdGkpCYS-24\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"800\" y=\"1525\" />\n              <mxPoint x=\"800\" y=\"340\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-26\" value=\"???\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=12;\" parent=\"1\" source=\"wQT6I2i7r7E7tcLqA3oX-11\" target=\"wQT6I2i7r7E7tcLqA3oX-13\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-28\" value=\"???\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=12;\" parent=\"1\" source=\"wQT6I2i7r7E7tcLqA3oX-52\" target=\"Gw3u6BSb_nzoXdGkpCYS-27\" edge=\"1\">\n          <mxGeometry x=\"0.3399\" relative=\"1\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-30\" value=\"???\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=12;\" parent=\"1\" source=\"Gw3u6BSb_nzoXdGkpCYS-19\" target=\"Gw3u6BSb_nzoXdGkpCYS-29\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Gw3u6BSb_nzoXdGkpCYS-36\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.006;entryY=0.093;entryDx=0;entryDy=0;entryPerimeter=0;fontSize=12;\" parent=\"1\" source=\"Gw3u6BSb_nzoXdGkpCYS-7\" target=\"PzZqxms0mEW9Ky41_EIL-5\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"-310\" y=\"1365\" />\n              <mxPoint x=\"-310\" y=\"290\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"MkfsawVckRxDqZAfUpWJ-1\" value=\"mapdata.dat\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"70\" y=\"1600\" width=\"170\" height=\"90\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"MkfsawVckRxDqZAfUpWJ-2\" value=\"size=eos\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;\" parent=\"MkfsawVckRxDqZAfUpWJ-1\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"MkfsawVckRxDqZAfUpWJ-3\" value=\"mission_dir\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"MkfsawVckRxDqZAfUpWJ-1\" vertex=\"1\">\n          <mxGeometry y=\"60\" width=\"170\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"MkfsawVckRxDqZAfUpWJ-8\" value=\"mapdata.tbl\" style=\"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#e1d5e7;strokeColor=#9673a6;\" parent=\"1\" vertex=\"1\">\n          <mxGeometry x=\"470\" y=\"1605\" width=\"140\" height=\"85\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"MkfsawVckRxDqZAfUpWJ-9\" value=\"size=num_offsets\" style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" parent=\"MkfsawVckRxDqZAfUpWJ-8\" vertex=\"1\">\n          <mxGeometry y=\"30\" width=\"140\" height=\"25\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"MkfsawVckRxDqZAfUpWJ-10\" value=\"mission_dir\" style=\"text;strokeColor=#6c8ebf;fillColor=#dae8fc;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;\" parent=\"MkfsawVckRxDqZAfUpWJ-8\" vertex=\"1\">\n          <mxGeometry y=\"55\" width=\"140\" height=\"30\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"MkfsawVckRxDqZAfUpWJ-13\" value=\"index-1 pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;\" parent=\"1\" source=\"MkfsawVckRxDqZAfUpWJ-3\" target=\"MkfsawVckRxDqZAfUpWJ-10\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-3\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.159;entryDx=0;entryDy=0;entryPerimeter=0;\" parent=\"1\" source=\"Wp9U09x5frf1_o0Q8clL-2\" target=\"wQT6I2i7r7E7tcLqA3oX-49\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"-140\" y=\"465\" />\n              <mxPoint x=\"-140\" y=\"1141\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-4\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.048;entryDx=0;entryDy=0;entryPerimeter=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-44\" target=\"PzZqxms0mEW9Ky41_EIL-5\" edge=\"1\">\n          <mxGeometry x=\"0.2496\" relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"30\" y=\"120\" />\n              <mxPoint x=\"30\" y=\"280\" />\n            </Array>\n            <mxPoint as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-5\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.094;entryDx=0;entryDy=0;entryPerimeter=0;\" parent=\"1\" source=\"PzZqxms0mEW9Ky41_EIL-45\" target=\"PzZqxms0mEW9Ky41_EIL-5\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"-20\" y=\"90\" />\n              <mxPoint x=\"-20\" y=\"290\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-7\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.083;entryDx=0;entryDy=0;entryPerimeter=0;\" parent=\"1\" source=\"Wp9U09x5frf1_o0Q8clL-6\" target=\"wQT6I2i7r7E7tcLqA3oX-49\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"-230\" y=\"240\" />\n              <mxPoint x=\"-230\" y=\"1131\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"Wp9U09x5frf1_o0Q8clL-9\" value=\"index pointer\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;\" parent=\"1\" source=\"wQT6I2i7r7E7tcLqA3oX-8\" target=\"PzZqxms0mEW9Ky41_EIL-24\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"v2uTlcIfrsabdLEwdSDk-3\" value=\"\" style=\"endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.833;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryPerimeter=0;\" parent=\"1\" source=\"v2uTlcIfrsabdLEwdSDk-2\" target=\"wQT6I2i7r7E7tcLqA3oX-32\" edge=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"250\" y=\"1058\" as=\"sourcePoint\" />\n            <mxPoint x=\"470\" y=\"1060\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v2uTlcIfrsabdLEwdSDk-4\" value=\"index-1 pointer\" style=\"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;\" parent=\"v2uTlcIfrsabdLEwdSDk-3\" connectable=\"0\" vertex=\"1\">\n          <mxGeometry relative=\"1\" as=\"geometry\" />\n        </mxCell>\n      </root>\n    </mxGraphModel>\n  </diagram>\n</mxfile>\n"
  },
  {
    "path": "doc/scmconvert.6",
    "content": ".TH SCMCONVERT 6 \"Dec 2015\" \"Stargus v2.4.0\"\n.SH NAME\nscmconvert \\- Tool to convert Starcraft archives into stargus archives\n.SH SYNOPSIS\n.B scmconvert\n.I \"inputfile [outputdir]\"\n"
  },
  {
    "path": "doc/stargus.6",
    "content": ".TH STARGUS 6 \"Dec 2015\" \"Stargus v2.4.0\"\n.SH NAME\nstargus \\- Starcraft data game set for the Stratagus engine\n\n.SH \"SEE ALSO\"\n.PD 0\n.TP\n\\fIstratagus\\fP(6), \\fIstartool\\fP(6), \\fIscmconvert\\fP(6)\n"
  },
  {
    "path": "doc/startool.6",
    "content": ".TH STARTOOL 6 \"Dec 2015\" \"Stargus v2.4.0\"\n.SH NAME\nstartool \\- Tool to extract the game data from your Starcraft CD.\n.SH SYNOPSIS\n.B startool\n.I \"archive-directory [destination-directory] [mpqlist-file]\"\n"
  },
  {
    "path": "doc/todo",
    "content": "Very Simple And Boring TODO List For Stargus\n\nScripts:\n1. Spells\n2. Before-game menus\n3. Tilesets\n4. Burning building Animations\n5. Protoss Units\n6. Campaigns\n\nEngine:\n1. Larva\n2. Creep\n3. Protoss Shields\n4. Seige Mode\n5. Flying Buildings\n6. Burrow\n7. \"Small\" Protoss units\n8. Active overlay\n9. Scriptable Error messages\n10. Tileset Grids\n11. Terrain Heights\n12. Seperate air/ground attacks\n13. start/end attack animations\n14. Building Addons\n15. Bounce attack effect\n16. Sub-tile movement\n\nHave Fun!\n"
  },
  {
    "path": "logging.prop",
    "content": "log4j.rootLogger=WARN, A1, R\nlog4j.appender.A1=org.apache.log4j.ConsoleAppender\nlog4j.appender.A1.layout=org.apache.log4j.PatternLayout\n\nlog4j.appender.R=org.apache.log4j.RollingFileAppender\nlog4j.appender.R.layout=org.apache.log4j.PatternLayout\nlog4j.appender.R.layout.ConversionPattern=%d %20.20F:%-4L %-5p %c - %m%n\nlog4j.appender.R.File=stargus.log\n\n# Print the date in ISO 8601 format\nlog4j.appender.A1.layout.ConversionPattern=%d %20.20F:%-4L %-5p %c - %m%n\n\n# Print only messages of level WARN or above in the package com.foo.\n#log4j.logger.startool.main=TRACE\n#log4j.logger.startool.Font=TRACE\n#log4j.logger.startool.Chk=TRACE\n#log4j.logger.startool.tileset.CV5=TRACE\n#log4j.logger.startool.Pcx=TRACE\nlog4j.logger.startool.StringUtil=TRACE\n#log4j.logger.startool.dat.IScript=TRACE\n#log4j.logger.startool.DataHub=TRACE\n#log4j.logger.startool=TRACE\n\n\n"
  },
  {
    "path": "mac/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleGetInfoString</key>\n  <string>Stargus</string>\n  <key>CFBundleExecutable</key>\n  <string>stargus</string>\n  <key>CFBundleIdentifier</key>\n  <string>stargus.stratagus.com.github.www</string>\n  <key>CFBundleName</key>\n  <string>Stargus</string>\n  <key>CFBundleIconFile</key>\n  <string>stargus</string>\n  <key>CFBundleShortVersionString</key>\n  <string>3.3.0</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundlePackageType</key>\n  <string>APPL</string>\n  <key>IFMajorVersion</key>\n  <integer>2</integer>\n  <key>IFMinorVersion</key>\n  <integer>4</integer>\n</dict>\n</plist>\n"
  },
  {
    "path": "mac/bundle.sh",
    "content": "#!/bin/bash\n\nif [ -z \"$STRATAGUS\" ]; then\n    echo \"You must tell me where the stratagus binary is located by setting the STRATAGUS variable!\"\n    exit 1\nfi\n\nSTRATAGUS=\"$(cd \"$(dirname \"$STRATAGUS\")\" && pwd -P)/$(basename $STRATAGUS)\"\n\ncd \"`dirname \"$0\"`\"\n\n# Create app bundle structure\nrm -rf Stargus.app\nmkdir -p Stargus.app/Contents/Resources\nmkdir -p Stargus.app/Contents/MacOS\nmkdir -p Stargus.app/Contents/libs\n\n# Copy launchscript and info.plist\ncp Info.plist Stargus.app/Contents/\n\n# Generate icons\nmkdir stargus.iconset\nsips -z 16 16     ../stargus.png --out stargus.iconset/icon_16x16.png\nsips -z 32 32     ../stargus.png --out stargus.iconset/icon_16x16@2x.png\nsips -z 32 32     ../stargus.png --out stargus.iconset/icon_32x32.png\nsips -z 64 64     ../stargus.png --out stargus.iconset/icon_32x32@2x.png\nsips -z 128 128   ../stargus.png --out stargus.iconset/icon_128x128.png\nsips -z 256 256   ../stargus.png --out stargus.iconset/icon_128x128@2x.png\nsips -z 256 256   ../stargus.png --out stargus.iconset/icon_256x256.png\nsips -z 512 512   ../stargus.png --out stargus.iconset/icon_256x256@2x.png\nsips -z 512 512   ../stargus.png --out stargus.iconset/icon_512x512.png\nsips -z 1024 1024   ../stargus.png --out stargus.iconset/icon_512x512@2x.png\niconutil -c icns stargus.iconset\nrm -R stargus.iconset\nmv stargus.icns Stargus.app/Contents/Resources/\n\n# Bundle resources\ncp -R ../contrib ../scripts Stargus.app/Contents/MacOS/\ncp -R ../scripts ../scripts Stargus.app/Contents/MacOS/\ncp -R ../mpqlist.txt ../scripts Stargus.app/Contents/MacOS/\n\n# Bundle binaries and their dependencies\nrm -rf macdylibbundler\ngit clone https://github.com/auriamg/macdylibbundler\ncd macdylibbundler\nmake\ncd ..\n\ncp ../build/src/startool Stargus.app/Contents/MacOS/\ncp ../build/src/stargus Stargus.app/Contents/MacOS/\ncp \"$STRATAGUS\" Stargus.app/Contents/MacOS/stratagus\ncp \"$(dirname \"$STRATAGUS\")\"/../libs/* Stargus.app/Contents/libs/\n\nmacdylibbundler/dylibbundler -cd -of -b -x ./Stargus.app/Contents/MacOS/startool -d ./Stargus.app/Contents/libs/\nmacdylibbundler/dylibbundler -cd -of -b -x ./Stargus.app/Contents/MacOS/stargus -d ./Stargus.app/Contents/libs/\n"
  },
  {
    "path": "meson.build",
    "content": "project('stargus', 'cpp', 'c',\n        default_options : ['cpp_std=c++17'])\n\ncpp = meson.get_compiler('cpp')\n\n# https://mesonbuild.com/Configuration.html\npkgdatadir = join_paths(get_option('datadir'), 'stargus')\nconf = configuration_data()\nconf.set_quoted('PACKAGE_DATA_DIR', join_paths(get_option('prefix'), pkgdatadir))\nconf.set_quoted('PACKAGE_SOURCE_DIR', meson.current_source_dir())\nconfigure_file(\n  output: 'config.h',\n  configuration: conf\n)\nconfig_incdir = include_directories('.')\nadd_project_arguments('-DHAVE_CONFIG_H', language: 'cpp')\n\n# Install our json files\n# https://mesonbuild.com/Installing.html\ninstall_data(\n\t['dataset/palettes.json', 'dataset/units.json'],\n\tinstall_dir: get_option('datadir') / 'dataset'\n)\n\nnlohmann_json_dep = dependency('nlohmann_json', fallback : ['nlohmann_json', 'nlohmann_json_dep'])\ncasc_dep = cpp.find_library('casc', required : false)\nstorm_dep = cpp.find_library('storm', required : false)\nif not storm_dep.found()\n\tcmake = import('cmake')\n\tstorm_proj = cmake.subproject('StormLib')\n\tstorm_dep = storm_proj.dependency('storm')\nendif\nzlib_dep = dependency('zlib', fallback: ['zlib', 'zlib_dep'])\npng_dep = dependency('libpng', fallback: ['libpng', 'png_dep'])\nbzip2_dep = cpp.find_library('bz2', required: false)\nif not bzip2_dep.found()\n\tcmake = import('cmake')\n\tbzip2_proj = cmake.subproject('bzip2')\n\tbzip2_dep = bzip2_proj.dependency('bz2')\nendif\nimagemagickpp_dep = dependency('ImageMagick++', required : false)\n\nif build_machine.system() == 'windows'\n\tcmake = import('cmake')\n\twin_iconv_proj = cmake.subproject('win-iconv')\n\ticonv_lib = win_iconv_proj.dependency('iconv-static')\nelse\n\tif cpp.has_function('iconv_open')\n\t\ticonv_lib = []\n\telif cpp.has_header_symbol('iconv.h', 'iconv_open')\n\t\ticonv_lib = [cpp.find_library('iconv')]\n\tendif\nendif\n\nlog4cxx_dep = dependency('liblog4cxx', required : false)\nif log4cxx_dep.found()\n  add_project_arguments('-DHAVE_LOG4CXX', language: 'cpp')\nendif\n\nif casc_dep.found()\n\tadd_project_arguments('-DHAVE_CASC', language: 'cpp')\nendif\n\nif imagemagickpp_dep.found()\n\tadd_project_arguments('-DHAVE_IMAGEMAGICKPP', language: 'cpp')\nendif\n\ncppunit_dep = dependency('cppunit', required : false)\n\nsubdir('src')\nsubdir('tools')\nsubdir('tools/sauwetter')\nsubdir('tools/scdat2json')\nsubdir('tools/grptool')\n#subdir('tools/iscript2json')\n#subdir('tools/scpalette')\nsubdir('test/lua')\n\nif cppunit_dep.found()\n\tsubdir('test/module')\nendif\n\n#subdir('test/gamedata/dat')\n"
  },
  {
    "path": "meson_options.txt",
    "content": "option('STRATAGUS_INCLUDE_DIR', type : 'string', value : '/usr/include/', description : 'Full path to search for \"stratagus-game-launcher.h\"')\noption('STRATAGUS_BIN', type : 'string', value : 'stratagus', description : 'Full path to \"stratagus\" binary. In debug case the binary is \"stratagus-dbg\".')\n\n\n"
  },
  {
    "path": "mpqlist.txt",
    "content": "(1)Enslavers01.scm\r\n(1)Enslavers02a.scm\r\n(1)Enslavers02b.scm\r\n(1)Enslavers03a.scm\r\n(1)Enslavers03b.scm\r\n(1)Epilogue.scx\r\n(1)Episode01.scx\r\n(1)Episode02.scx\r\n(1)Episode03.scx\r\n(1)Episode04A.scx\r\n(1)Episode04B.scx\r\n(1)Episode05A.scx\r\n(1)Episode05B.scx\r\n(2)Astral Balance.scm\r\n(2)Baby Steps.scm\r\n(2)Binary Burghs.scx\r\n(2)Bottleneck.scm\r\n(2)Boxer.scm\r\n(2)Breaking Point.scx\r\n(2)Challenger.scm\r\n(2)Crystallis.scm\r\n(2)Discovery.scm\r\n(2)Double Jeopardy.scm\r\n(2)Fading Realm.scx\r\n(2)Fire Walker.scm\r\n(2)Full Circle.scm\r\n(2)Gauntlet.scm\r\n(2)Ice Floes.scx\r\n(2)Isolation.scx\r\n(2)Jacobs Ladder.scm\r\n(2)Midnight Lagoon.scx\r\n(2)Pro Bowl.scm\r\n(2)River Crossing.scm\r\n(2)River Styx.scm\r\n(2)Road War.scm\r\n(2)Showdown.scx\r\n(2)Solar Station.scm\r\n(2)Space Madness.scm\r\n(2)Switchback.scm\r\n(2)The Small Divide.scm\r\n(2)Twilight Struggle.scx\r\n(2)Twisted Fate.scx\r\n(2)Volcanis.scm\r\n(2)Wakka Wakka.scm\r\n(2)Zerg Soccer.scm\r\n(3)Defenders of the Galaxy.scm\r\n(3)Holy Ground.scm\r\n(3)Ice Mountain.scx\r\n(3)Meltdown.scm\r\n(3)Overlook.scm\r\n(3)Stepping Stones.scm\r\n(3)Three Kingdoms.scm\r\n(3)Trench wars.scx\r\n(3)Triad.scm\r\n(3)Triskelion.scx\r\n(3)Triumvirate.scm\r\n(4)Alpha Draconis.scm\r\n(4)Archipelago.scm\r\n(4)Arctic Station.scx\r\n(4)Ashrigo.scm\r\n(4)Blood Bath.scm\r\n(4)Bone Canyon.scm\r\n(4)Boxed In.scm\r\n(4)Bridge Too Near.scm\r\n(4)Brushfire.scm\r\n(4)Caldera.scm\r\n(4)Catwalk Alley.scm\r\n(4)Crescent Moon.scx\r\n(4)Cross the Line.scx\r\n(4)Crossroads.scm\r\n(4)Crusader.scm\r\n(4)Cyclone.scm\r\n(4)Dark Crystal.scm\r\n(4)Dark Star.scm\r\n(4)Desolation.scx\r\n(4)Dire Straits.scm\r\n(4)Dust Bowl.scx\r\n(4)Entanglement.scm\r\n(4)Eye of the Storm.scx\r\n(4)Forsaken Valley.scx\r\n(4)Frenzy.scm\r\n(4)Gladiator Pits.scm\r\n(4)Greener Pastures.scx\r\n(4)Heartwood.scm\r\n(4)Highland Denizens.scm\r\n(4)Hot Zone.scx\r\n(4)Inferno.scm\r\n(4)Jungle Siege.scm\r\n(4)Kakaru Keys.scx\r\n(4)King of the Hill.scm\r\n(4)Lake Shore.scm\r\n(4)Landslide.scm\r\n(4)Lost Civilization.scm\r\n(4)Lost Temple.scm\r\n(4)Mausoleum.scx\r\n(4)Molten Playground.scm\r\n(4)Nightfall.scx\r\n(4)Nightmare Station.scm\r\n(4)No Way Out.scm\r\n(4)NovaStation.scm\r\n(4)Old Faithful.scm\r\n(4)Opposing City States '98.scm\r\n(4)Orbital Gully.scm\r\n(4)Orbital Relay.scm\r\n(4)Path of Sorrow.scx\r\n(4)Power Lines.scm\r\n(4)Proving Grounds.scm\r\n(4)Ramparts.scm\r\n(4)Red Canyons.scm\r\n(4)Remote Outpost.scm\r\n(4)Rivalry.scm\r\n(4)River Lethe.scx\r\n(4)Road to Nowhere.scm\r\n(4)Ruins of the Ancients.scm\r\n(4)Sanctuary.scx\r\n(4)Scorched Earth.scx\r\n(4)Shadowlands.scx\r\n(4)Shroud Platform.scm\r\n(4)Snowbound.scx\r\n(4)Space Atoll.scm\r\n(4)Space Debris.scm\r\n(4)Spring Thaw.scx\r\n(4)Steal the Bacon.scm\r\n(4)Steal the Beacon.scm\r\n(4)Tarsonis Orbital.scm\r\n(4)The Gardens.scm\r\n(4)The Highway.scm\r\n(4)Warp Gates.scm\r\n(4)Wasteland.scx\r\n(4)Water's Edge.scm\r\n(4)Waypoint Junction.scm\r\n(4)Zergling Round-Up.scm\r\n(4)Zoo Keeper.scm\r\n(5)Diablo.scm\r\n(5)Ebon Lakes.scx\r\n(5)Island Hop.scm\r\n(5)Jeweled River.scm\r\n(5)Lake of Fire.scm\r\n(5)Predators.scm\r\n(5)Race of Death.scm\r\n(5)Rosewood.scm\r\n(5)Sandstorm.scx\r\n(5)Sherwood Forest.scm\r\n(5)Twilight Star.scx\r\n(5)Typhoon.scm\r\n(6)Acropolis.scm\r\n(6)Across the Cape.scm\r\n(6)Aftershock.scm\r\n(6)Avalanche.scx\r\n(6)Azure Plains.scx\r\n(6)Blast Furnace.scm\r\n(6)BunkerCommand.scm\r\n(6)Cauldron.scx\r\n(6)Chain Lightning.scm\r\n(6)Close Encounters.scx\r\n(6)Crash Sites.scx\r\n(6)Crazy Critters.scm\r\n(6)Divided Factions.scm\r\n(6)Flooded Plains.scx\r\n(6)Funeral Pyre.scm\r\n(6)Ghost Town.scm\r\n(6)Grand Canyon.scm\r\n(6)Ground Zero.scm\r\n(6)Hidden Shrine.scm\r\n(6)Hypothermia.scx\r\n(6)Legacy.scm\r\n(6)Medusa.scx\r\n(6)New Gettysburg.scm\r\n(6)Polaris Prime.scm\r\n(6)Razor Thicket.scm\r\n(6)River of Light.scm\r\n(6)Sapphire Isles.scx\r\n(6)Sirocco.scx\r\n(6)Tale of Two Cities.scm\r\n(6)Thin Ice.scx\r\n(6)Triple Team.scm\r\n(6)Valley of Re.scx\r\n(6)Winter Conquest.scx\r\n(7)Black Lotus.scx\r\n(7)Broken Steppes.scm\r\n(7)Continental Divide.scm\r\n(7)Nightshade.scx\r\n(7)River War.scm\r\n(8)Allied Fortress.scm\r\n(8)Aurora.scm\r\n(8)Backwoods.scm\r\n(8)Big Game Hunters.scm\r\n(8)Border Dispute.scm\r\n(8)Bridge to Bridge '98.scm\r\n(8)Char Magma.scm\r\n(8)Crystal Castles.scm\r\n(8)Dark Continent.scx\r\n(8)Double Diamond.scm\r\n(8)Elderlands.scm\r\n(8)Enigma.scm\r\n(8)Eruption.scm\r\n(8)Expedition.scm\r\n(8)Friends in Space.scm\r\n(8)Friends98.scm\r\n(8)Frozen Sea.scx\r\n(8)Garden of Aiur.scm\r\n(8)Green Valleys.scm\r\n(8)Hellfire.scm\r\n(8)Homeworld.scm\r\n(8)Jungle Rumble.scm\r\n(8)Killing Fields.scm\r\n(8)Labyrinth.scm\r\n(8)Octopus.scx\r\n(8)Orbital Death.scm\r\n(8)Plains of Snow '98.scm\r\n(8)Primeval Isles.scx\r\n(8)River Runs Through It.scm\r\n(8)StarCraft Fortress.scm\r\n(8)Station Unrest.scm\r\n(8)The Hunters.scm\r\n(8)Theatre of War.scm\r\n(8)Tribes.scm\r\n(8)Turbo.scm\r\n(8)Wheel of war.scm\r\n(attributes)\r\n(listfile)\r\n(signature)\r\n.ds_store\r\n95\\comctl32.dll\r\nabrtmenu.005\r\nabrtmenu.015\r\nabrtmenu.016\r\nabrtmenu.017\r\nabrtmenu.01b\r\nabrtmenu.01e\r\nabrtmenu.025\r\nabrtmenu.027\r\nabrtmenu.029\r\nabrtmenu.031\r\nabrtmenu.035\r\nabrtmenu.037\r\nabrtmenu.038\r\nabrtmenu.03b\r\nabrtmenu.045\r\nabrtmenu.047\r\nabrtmenu.049\r\nabrtmenu.04d\r\nabrtmenu.050\r\nabrtmenu.05d\r\nabrtmenu.069\r\nabrtmenu.bin\r\nAISCRIPT.BIN\r\nallyfltr.006\r\nallyfltr.016\r\nallyfltr.017\r\nallyfltr.018\r\nallyfltr.01c\r\nallyfltr.01f\r\nallyfltr.026\r\nallyfltr.028\r\nallyfltr.02a\r\nallyfltr.032\r\nallyfltr.036\r\nallyfltr.038\r\nallyfltr.039\r\nallyfltr.03c\r\nallyfltr.046\r\nallyfltr.048\r\nallyfltr.04a\r\nallyfltr.04e\r\nallyfltr.051\r\nallyfltr.05e\r\nallyfltr.06a\r\nallyfltr.bin\r\narr\\flingy.dat\r\narr\\flingy.tbl\r\narr\\images.dat\r\narr\\images.tbl\r\narr\\mapdata.dat\r\narr\\mapdata.tbl\r\narr\\orders.dat\r\narr\\orders.tbl\r\narr\\portdata.dat\r\narr\\portdata.tbl\r\narr\\sfxdata.dat\r\narr\\sfxdata.tbl\r\narr\\sprites.dat\r\narr\\sprites.tbl\r\narr\\techdata.dat\r\narr\\techdata.tbl\r\narr\\units.dat\r\narr\\units.tbl\r\narr\\upgrades.dat\r\narr\\upgrades.tbl\r\narr\\weapons.dat\r\narr\\weapons.tbl\r\nbattle.snp\r\nBliz.cnd\r\nBlizzard.cnd\r\nBlizzard_1.cnd\r\nblizzard_2.cnd\r\nBlizzardError.exe\r\nbnbeta.txt\r\nbncache.dat\r\nbnetunin.exe\r\nbnupdate.exe\r\nbroodunits.doc\r\nbwscript.bin\r\ncampaign\\expprotoss\\protoss01\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\combeep0.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\intonydus.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b00pad.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b01zer.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b02pad.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b03zer.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b04pad.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b05zer.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b06pad.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b07art.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b08pad.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b09ray.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1b10zer.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1m00zer.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1m10pze.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1m20zer.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1m30pte.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1m40zer.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\p1m41ray.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\pdrwht06.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\pdryes06.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\pshtra01.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\pshwht00.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\teleport.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\zavwht00.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\zavwht01.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\zavyes00.wav\r\ncampaign\\expprotoss\\protoss01\\staredit\\wav\\zavyes01.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\combeep0.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2b00art.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2b01zer.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m00art.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m10pdt.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m11zer.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m12pdt.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m20art.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m30art.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m40ray.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m41art.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m42ray.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m43fed.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m44art.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M45ART.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M45FED.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M45RAY.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M45ZER.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M46ART.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M46FED.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M46RAY.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\P2M46ZER.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\p2m47ray.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\PDTWht00.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\pdtwht01.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\PDTWht02.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\pdtwht03.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\PDTYes00.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\pdtyes01.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\PDTYes02.wav\r\ncampaign\\expprotoss\\protoss02\\staredit\\wav\\PDTYes03.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\ComBeep0.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\nullsound.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3b00ras.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3b01pad.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3b02ras.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3b03pad.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3b04ras.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3b05art.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3b06ras.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\P3M00ART.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m00zer.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m10art.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m11zer.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\P3M20ART.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m30zke.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m31zer.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m32zke.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m33pad.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m34zke.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m35zer.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m36zke.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\p3m37ras.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\P3M37ZER.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\pcoyes01.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\pshtra00.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\pshwht00.wav\r\ncampaign\\expprotoss\\protoss03\\staredit\\wav\\zovtra01.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\combeep0.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b00ras.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b01zke.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b02zer.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b03zke.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b04pad.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b05ras.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b06zke.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b07zer.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b08zke.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b09ras.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\P4B09ZER.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4b10art.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4m00art.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4m10zke.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4m11zer.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4m20zke.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4m21zer.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\p4m22zke.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\pshtra00.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\pshwht00.wav\r\ncampaign\\expprotoss\\protoss04\\staredit\\wav\\tcvwht02.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\combeep0.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\nullsound.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5b00art.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5b01stu.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5b02zer.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5b03art.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5b04zer.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5b05art.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5m00art.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\p5m01zer.wav\r\ncampaign\\expprotoss\\protoss05\\staredit\\wav\\tpwrdown.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\ComBeep0.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b00art.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b01zer.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b02zke.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b03art.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b04zer.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b05art.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b06zke.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6b07art.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6m00art.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\P6M00ZER.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\P6M00ZKE.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6m10art.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\P6M10ZER.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\P6M10ZKE.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\p6m20art.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\prescue.wav\r\ncampaign\\expprotoss\\protoss06\\staredit\\wav\\pshtra00.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\combeep0.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\nullsound.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7b00ras.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7b01zer.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7b02ras.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7b03art.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7b04ras.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7b05zer.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7b06art.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m00art.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m01zer.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m10pad.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m11pad.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m20zer.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m21pad.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m22art.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m23pad.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m24zke.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m25zer.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m26zke.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m27zer.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\p7m28zke.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\pshtra00.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\zovtra00.wav\r\ncampaign\\expprotoss\\protoss07\\staredit\\wav\\zovtra01.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\scenario.chk\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\combeep0.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b00art.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b01zer.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b02ras.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b03zer.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b04ras.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b05zer.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b06art.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8b07ras.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8m00ras.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8m10art.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8m20zer.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8m30art.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\p8m40zer.wav\r\ncampaign\\expprotoss\\protoss08\\staredit\\wav\\utmwht00.wav\r\ncampaign\\expterran\\terran01\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran01\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1b00tad.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1b01gal.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1b02tad.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1b03stu.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m00dur.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m01stu.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m02dur.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m03stu.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m04dur.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m05stu.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m10dur.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m11stu.wav\r\ncampaign\\expterran\\terran01\\staredit\\wav\\t1m20tma.wav\r\ncampaign\\expterran\\terran02\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran02\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b00tad.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b01gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b02dur.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b03gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b04dur.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b05stu.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b06gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2B06STU.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2b07stu.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m00stu.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2M01STU.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m01tme.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2M10TAD.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m10tme.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2M11DUK.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2M12STU.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2M13DUK.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2M14STU.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\T2M15DUK.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m21tgh.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m30tma.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m31gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m31tta.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m40gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m40tad.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m41gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m42gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m43gal.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m50tad.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m51duk.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m52stu.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m53duk.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m54stu.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\t2m55duk.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\tbardy00.wav\r\ncampaign\\expterran\\terran02\\staredit\\wav\\tdrtra01.wav\r\ncampaign\\expterran\\terran03\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran03\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\combeep1.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\inhelp1.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b00tad.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b01stu.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b02dur.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b03gal.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b04stu.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b05dur.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b06stu.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3b07gal.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m00gal.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m01tad.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m02dur.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m03gal.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m10dur.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m11tgh.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m12dur.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\t3m20dur.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\tdrtra01.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\tdrwht00.wav\r\ncampaign\\expterran\\terran03\\staredit\\wav\\trescue.wav\r\ncampaign\\expterran\\terran04\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran04\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran04\\staredit\\wav\\t4b00gal.wav\r\ncampaign\\expterran\\terran04\\staredit\\wav\\t4b01stu.wav\r\ncampaign\\expterran\\terran04\\staredit\\wav\\t4b02dur.wav\r\ncampaign\\expterran\\terran04\\staredit\\wav\\t4b03stu.wav\r\ncampaign\\expterran\\terran04\\staredit\\wav\\t4b04gal.wav\r\ncampaign\\expterran\\terran04\\staredit\\wav\\t4m00stu.wav\r\ncampaign\\expterran\\terran04\\staredit\\wav\\t4m10stu.wav\r\ncampaign\\expterran\\terran05a\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\nullsound.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\sittight.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5ab01ga.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5ab02st.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5ab03ga.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5b00tad.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m00tad.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m01men.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m02gal.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m03men.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m04gal.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m05men.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m06gal.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m07ray.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m08tad.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m09gal.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m10men.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m11ray.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\t5m12gal.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tadupd04.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tadupd05.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tcvrdy00.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tdrtra01.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tdryes01.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tghpss00.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tghpss01.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tghwht00.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tghyes02.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\trescue.wav\r\ncampaign\\expterran\\terran05a\\staredit\\wav\\tvewht00.wav\r\ncampaign\\expterran\\terran05b\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\nullsound.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\sittight.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5b00tad.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5bb01ga.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BB01GAL.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5bb02st.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM01ME.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM02GA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM03ME.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM04GA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM05ME.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM06GA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM07RA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM08TA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM09GA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM10ME.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM11RA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\T5BM12GA.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m00tad.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m01men.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m02gal.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m03men.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m04gal.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m05men.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m06gal.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m07ray.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m08tad.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m09gal.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m10men.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m11ray.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\t5m12gal.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\tbapss00.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\tbapss01.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\tbardy00.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\tbayes01.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\tbayes03.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\tdrtra01.wav\r\ncampaign\\expterran\\terran05b\\staredit\\wav\\tdryes00.wav\r\ncampaign\\expterran\\terran06\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran06\\staredit\\wav\\afteron.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\pshwht00.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6b00tad.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6b01gal.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6b02stu.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6b03gal.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6m00stu.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6m10stu.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6m11dur.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6m12stu.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6m13dur.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\t6m14stu.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\tcb08tad.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\tdrtra01.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\tdryes01.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\teleport.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\trescue.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\tvkrdy00.wav\r\ncampaign\\expterran\\terran06\\staredit\\wav\\warpgate.wav\r\ncampaign\\expterran\\terran07\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran07\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\combeep1.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\inhelp1.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\ppwrdown.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m20tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m30tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m40tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m50tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T3M60TAD.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m60tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m70tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m80uci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3m90tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t3ma0tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t4m40tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t4m50tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t4m60tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t4m70tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T4M90TAD.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b00tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b01gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b02dur.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b03gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b04tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b05gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b06dur.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b07gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7b08dur.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7B09TAD.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7B10GAL.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m00dur.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m01stu.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m02dur.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m03stu.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m04gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m05stu.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m06gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m07tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m08gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m09tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m10gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m20tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m21tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m22gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7M22TMA.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m30tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m40gal.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m50tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m51tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m52tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m53tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m60tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m61tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m62tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7M63TAD.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m63tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m64tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m65tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7M65TMA.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m66tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m67tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m68tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m69tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m70tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m71tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m72tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m73tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m74tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m75tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m76tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7M76TMA.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m77tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m78tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m79tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m80tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m81tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m82tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m83tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m84tci.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m85tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m86tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7M87TAD.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m87tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m88tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m89tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\T7M90TAD.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\t7m90tma.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tcvwht01.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tcvwht02.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tdrtra00.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tfbrdy00.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tfbwht00.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tmapss00.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tmayes01.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tmdrdy00.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\tphclo00.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\z5m00tad.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\zbgrdy00.wav\r\ncampaign\\expterran\\terran07\\staredit\\wav\\zulrdy00.wav\r\ncampaign\\expterran\\terran08\\staredit\\scenario.chk\r\ncampaign\\expterran\\terran08\\staredit\\wav\\combeep0.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\nullsound.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\roar.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8b00tad.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8b01gal.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8b02tad.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8b03gal.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m00tma.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\T8M10TGH.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m10tma.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m20tma.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m30tma.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m60tgh.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m70tgh.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m71dur.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m72gal.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m73zke.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m74gal.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m75zke.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m76gal.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\t8m77zke.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\trescue.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\uicwht00.wav\r\ncampaign\\expterran\\terran08\\staredit\\wav\\zovtra01.wav\r\ncampaign\\expzerg\\bonus\\staredit\\scenario.chk\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1b00zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1b01pte.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1b02zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m00pte.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m01zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m10zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m20zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m21tad.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m22zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m30tad.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m31zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m40zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m50zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m51tad.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\B1M51ZER.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m52zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m60zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m70zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m71tad.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m72zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m80zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m81tad.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m82zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m83dur.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m84zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m85dur.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m86zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m87dur.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m88zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m89dur.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m90zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m91dur.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m92zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\b1m93dur.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\gettin' jiggy wit' it.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\p1m31zer.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\parwht03.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\ptewht02.wav\r\ncampaign\\expzerg\\bonus\\staredit\\wav\\zbgwht01.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\burrowup.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\combeep1.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\trescue.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b00zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b01zdu.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b02zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b03ray.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b04zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b05ray.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b06zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b07fed.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b08zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b09ray.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b10zdu.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b11zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b12zdu.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1b13zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1m00zdu.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\z1m01zke.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\zadupd00.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\zavwht00.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\zdeyes01.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\zquyes02.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\zrescue.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\zulrdy00.wav\r\ncampaign\\expzerg\\zerg01\\staredit\\wav\\zulwht01.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\tdrtra00.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\tdrtra01.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\tdryes02.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\tghyes01.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\tmayes00.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\trescue.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b00zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b01ray.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b02zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b03men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b04zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b05men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b06zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b07men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b08zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b09men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b10zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b11men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b12zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b13men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b14zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2b15men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m00ray.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m10ray.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m20ray.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\Z2M21RAY.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m21zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m22men.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m30zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m40zke.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m50tci.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m51tci.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m52tad.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m53tma.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\z2m54tsc.wav\r\ncampaign\\expzerg\\zerg02\\staredit\\wav\\zulrdy00.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b00fed.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b01ray.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b02men.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b03ray.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b04zke.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b05fed.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b06zke.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b07ray.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b08zke.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b09ray.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b10fed.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b11ray.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b12zdu.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3b13zke.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m00zke.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m10zke.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m20fed.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m21ray.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m22fed.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m23ray.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m30fed.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m40fed.wav\r\ncampaign\\expzerg\\zerg03\\staredit\\wav\\z3m50fed.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4b00zke.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4b01men.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4b02zke.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4b03men.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4b04zke.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4m00zke.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4m10zke.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4m11men.wav\r\ncampaign\\expzerg\\zerg04a\\staredit\\wav\\z4m12zke.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4b00zke.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4b01men.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4b02zke.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4b03men.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4b04zke.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4m00zke.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4m10zke.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4m11men.wav\r\ncampaign\\expzerg\\zerg04b\\staredit\\wav\\z4m12zke.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4b00zke.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4b01men.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4b02zke.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4b03men.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4b04zke.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4m00zke.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4m10zke.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4m11men.wav\r\ncampaign\\expzerg\\zerg04c\\staredit\\wav\\z4m12zke.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4b00zke.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4b01men.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4b02zke.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4b03men.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4b04zke.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4m00zke.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4m10zke.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4m11men.wav\r\ncampaign\\expzerg\\zerg04d\\staredit\\wav\\z4m12zke.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4b00zke.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4b01men.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4b02zke.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4b03men.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4b04zke.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4m00zke.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4m10zke.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4m11men.wav\r\ncampaign\\expzerg\\zerg04e\\staredit\\wav\\z4m12zke.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4b00zke.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4b01men.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4b02zke.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4b03men.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4b04zke.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4m00zke.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4m10zke.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4m11men.wav\r\ncampaign\\expzerg\\zerg04f\\staredit\\wav\\z4m12zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\tcvwht01.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\tcvwht02.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b00zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b01zdu.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b02zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b03zdu.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b04zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05azd.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05bzd.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05czd.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05dzdu.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05ezdu.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05fzdu.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05gzdu.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b05hzdu.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5b06zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m00tma.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m01zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m10duk.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m11zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m12duk.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m20men.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m21zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m22men.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m23zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m30fed.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m31zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m32fed.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m33zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m34fed.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m35zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m40ray.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m41zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m42ray.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m43zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m44ray.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m45zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m46ray.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\z5m50zke.wav\r\ncampaign\\expzerg\\zerg05\\staredit\\wav\\zrescue.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\z6b00zdu.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\z6b01zke.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\z6b02zdu.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\z6b03zke.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\z6m00zdu.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\z6m01zke.wav\r\ncampaign\\expzerg\\zerg06\\staredit\\wav\\z6m02zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\ptesum00.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7b00zke.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7b01zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7b02zke.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7b03zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7b04zke.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7b05zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7b06zke.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7m00zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7m01zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7m02zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7m10zdu.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7m11zke.wav\r\ncampaign\\expzerg\\zerg07\\staredit\\wav\\z7m12zdu.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\nullsound.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\pshtra01.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\pshwht00.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b00zke.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b01zdu.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b02zke.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b03zdu.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b04zke.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b05zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b06zke.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b07zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b08ras.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b09zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b10ras.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8b11zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m00zdu.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m10zdu.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m20zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m21zke.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m22ras.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m23zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m24zke.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m25zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m26zke.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\z8m27zer.wav\r\ncampaign\\expzerg\\zerg08\\staredit\\wav\\zovtra01.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\combeep0.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\nullsound.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\pabfol02.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\pshtra01.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\pshyes00.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9b00zdu.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9b01zke.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9b02zdu.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9b03zke.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9b04zdu.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9b05zke.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m00zdu.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m10zer.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m11ras.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m12zke.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m13zer.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m14zke.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m15zer.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m16zke.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\z9m17zer.wav\r\ncampaign\\expzerg\\zerg09\\staredit\\wav\\zovtra01.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\scenario.chk\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab00zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab01men.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab02zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab03men.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab04zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab05men.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab06zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab07art.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab08zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab09men.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab10zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab11gal.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab12zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab13gal.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab14zke.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zab15gal.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zam00men.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zam10art.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zam20gal.wav\r\ncampaign\\expzerg\\zerg10\\staredit\\wav\\zam21zke.wav\r\ncampaign\\multisw\\(2)Byways\\staredit\\blizzard_2.cnd\r\ncampaign\\multisw\\(2)byways\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss01\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss01\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p0b00ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p0b01ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p0m00ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p0m01ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p0m02ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p0m03ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1b00pad.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1b01pad.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1b02pad.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1m00ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1m40ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1m60ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1m61ufe.wav\r\ncampaign\\protoss\\protoss01\\staredit\\wav\\p1m62ufe.wav\r\ncampaign\\protoss\\protoss02\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss02\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b00pad.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b01uta.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b02pad.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b03uta.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b04uta.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b05ufe.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b06pad.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b07uta.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b08uta.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b09pad.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b10uta.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2b11ufe.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2m00ufe.wav\r\ncampaign\\protoss\\protoss02\\staredit\\wav\\p2m01ufe.wav\r\ncampaign\\protoss\\protoss03\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss03\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss03\\staredit\\wav\\p3b00ufe.wav\r\ncampaign\\protoss\\protoss03\\staredit\\wav\\p3b01pad.wav\r\ncampaign\\protoss\\protoss03\\staredit\\wav\\p3b02pad.wav\r\ncampaign\\protoss\\protoss03\\staredit\\wav\\p3b03ufe.wav\r\ncampaign\\protoss\\protoss03\\staredit\\wav\\p3m00ufe.wav\r\ncampaign\\protoss\\protoss03\\staredit\\wav\\p3m01pad.wav\r\ncampaign\\protoss\\protoss03\\staredit\\wav\\p3m02pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss04\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4b00pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4b01pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4b02pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4b03pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m00uta.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m01pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m02uta.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m03ura.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m04pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m05ura.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m06pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m07uta.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m08uta.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m09pad.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m10uta.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m11ute.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\p4m20uta.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\zhyrdy00.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\zhyyes03.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\zqurdy00.wav\r\ncampaign\\protoss\\protoss04\\staredit\\wav\\zzerdy00.wav\r\ncampaign\\protoss\\protoss05\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss05\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b00pad.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b01uta.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b02pad.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b03uta.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b04uta.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b05pad.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b06uta.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b07uta.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5b08pad.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5m00udu.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5m01udu.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5m02ura.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5m03uta.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\p5m04udu.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\tdrTra00.wav\r\ncampaign\\protoss\\protoss05\\staredit\\wav\\tdrTra01.wav\r\ncampaign\\protoss\\protoss06\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss06\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6b00uta.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6b01ura.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6b02uta.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m00tad.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m00uta.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m01uze.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m02uze.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m03uta.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m04uze.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m20uma.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m30uma.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\p6m40uma.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\pshbld03.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\T4M40tad.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\T4M60tad.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\T4M70tad.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\T4M80tma.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\T4M81tfb.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\tdrTra00.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\tmapss00.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\TMaPss01.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\TMaPss02.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\zbgrdy00.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\ZZePss02.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\zzerdy00.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\zzeyes01.wav\r\ncampaign\\protoss\\protoss06\\staredit\\wav\\zzeyes03.wav\r\ncampaign\\protoss\\protoss07\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss07\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\P5M04udu.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b00ufd.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b01uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b02ufd.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b03uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b04ufd.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b05ufd.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b06uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b07ufd.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7b08uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7m00pad.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7m01uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7m20uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7m21pad.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7m22pad.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7m23uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\p7m24uta.wav\r\ncampaign\\protoss\\protoss07\\staredit\\wav\\pshbld03.wav\r\ncampaign\\protoss\\protoss08\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss08\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\combeep1.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8b00ufd.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8b01ufd.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8b02ura.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8b03ufd.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m00ufd.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m01pad.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m02uze.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m03pad.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m04uze.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m05pad.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m06uze.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m07uze.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\p8m08pad.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\pshBld00.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\pshBld01.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\pshBld02.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\pshbld03.wav\r\ncampaign\\protoss\\protoss08\\staredit\\wav\\pshBld04.wav\r\ncampaign\\protoss\\protoss09\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss09\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9b00uta.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9b01uze.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9b02uze.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9b03uta.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9b04ufd.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9b05uta.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9b06ura.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9m00pad.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9m01pad.wav\r\ncampaign\\protoss\\protoss09\\staredit\\wav\\p9m02ura.wav\r\ncampaign\\protoss\\protoss10\\staredit\\blizzard_2.cnd\r\ncampaign\\protoss\\protoss10\\staredit\\scenario.chk\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\combeep0.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\p9m00pad.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\p9m02ura.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\pab00ufd.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\pab01uta.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\pab02uta.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\pab03uze.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\PAB04ufd.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\pab05ura.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\pab06uta.wav\r\ncampaign\\protoss\\protoss10\\staredit\\wav\\pam00uta.wav\r\ncampaign\\protoss\\tutorial\\staredit\\scenario.chk\r\ncampaign\\protoss\\tutorial\\staredit\\wav\\p1b00pad.wav\r\ncampaign\\protoss\\tutorial\\staredit\\wav\\p1b01pad.wav\r\ncampaign\\protoss\\tutorial\\staredit\\wav\\p1b02pad.wav\r\ncampaign\\protoss\\tutorial\\staredit\\wav\\p1m00ufe.wav\r\ncampaign\\protoss\\tutorial\\staredit\\wav\\p1m20ufe.wav\r\ncampaign\\protoss\\tutorial\\staredit\\wav\\p1m40ufe.wav\r\ncampaign\\terran\\terran01\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran01\\staredit\\scenario.chk\r\ncampaign\\terran\\terran01\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\combeep1.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t0m20tad.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t1b00tad.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t1b01udu.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t1b02tad.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t1m00uma.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t1m01uci.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t1m20ura.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\t1m40ura.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\tadUpd04.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\tm60tgo.wav\r\ncampaign\\terran\\terran01\\staredit\\wav\\TSCTra00.wav\r\ncampaign\\terran\\terran02\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran02\\staredit\\scenario.chk\r\ncampaign\\terran\\terran02\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\combeep1.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2b00tad.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2b01ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2b02tad.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2b03udu.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2b04ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m00ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m20ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m30uci.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m40ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m60ftb.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m60tma.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m60ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m80udu.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m81ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m82udu.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\t2m83ura.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\tcb02tad.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\tdrtra01.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\tfbrdy00.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\tmawht02.wav\r\ncampaign\\terran\\terran02\\staredit\\wav\\tmawht03.wav\r\ncampaign\\terran\\terran03\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran03\\staredit\\scenario.chk\r\ncampaign\\terran\\terran03\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t0m40tvu.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3b00tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3b01udu.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3b02tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3b03ume.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3b04ume.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3b05tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3m00tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3m20tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3m21tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3m60tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3m70tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3m80tad.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\t3m90tma.wav\r\ncampaign\\terran\\terran03\\staredit\\wav\\tdryes04.wav\r\ncampaign\\terran\\terran04\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran04\\staredit\\scenario.chk\r\ncampaign\\terran\\terran04\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\combeep1.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\p6m00tad.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\ppwrdown.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4b00tad.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4b01ura.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4b02ume.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4b03ume.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4b04ura.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m00uci.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m00ura.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m01ume.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m02ume.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m20uci.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m20ura.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m30uma.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m40tad.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m50tad.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m60tad.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m70tad.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m80tma.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\t4m81tfb.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\tdrTra00.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\z5m00tad.wav\r\ncampaign\\terran\\terran04\\staredit\\wav\\Z5M00uda.wav\r\ncampaign\\terran\\terran05\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran05\\staredit\\scenario.chk\r\ncampaign\\terran\\terran05\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5b00ura.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5b01tad.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5b02ume.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5b03uke.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5b04ume.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m00uke.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m01ura.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m02uke.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m03ura.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m04uke.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m20uke.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m40uma.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m41uke.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m42tad.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m43uke.wav\r\ncampaign\\terran\\terran05\\staredit\\wav\\t5m44uma.wav\r\ncampaign\\terran\\terran06\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran06\\staredit\\scenario.chk\r\ncampaign\\terran\\terran06\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b00tad.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b01udu.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b02ura.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b03ume.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b04ura.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b05uke.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b06ume.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b07uke.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b08ume.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b09uke.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6b10ura.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m00ura.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m20udu.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m21ura.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m22ume.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m23udu.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m24ume.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m25udu.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m26ume.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m27udu.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m28ume.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m29ura.wav\r\ncampaign\\terran\\terran06\\staredit\\wav\\t6m30ume.wav\r\ncampaign\\terran\\terran07\\staredit\\scenario.chk\r\ncampaign\\terran\\terran07\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b00tad.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b01ura.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b02udu.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b03ura.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b04udu.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b05uke.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b06ume.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b07uke.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7b08ume.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m00udu.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m01ura.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m02udu.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m03ura.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m20tad.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m21ura.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m22uta.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m23ura.wav\r\ncampaign\\terran\\terran07\\staredit\\wav\\t7m24uta.wav\r\ncampaign\\terran\\terran08\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran08\\staredit\\scenario.chk\r\ncampaign\\terran\\terran08\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\ComBeep1.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b00tad.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b01ume.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b02uke.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b03ura.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b04uke.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b05ume.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b06ura.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b07ume.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b08ume.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8b09ume.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8m00uke.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8m01ume.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8m02uke.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8m20uke.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8m21ume.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8m40uke.wav\r\ncampaign\\terran\\terran08\\staredit\\wav\\t8m41ume.wav\r\ncampaign\\terran\\terran09\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran09\\staredit\\scenario.chk\r\ncampaign\\terran\\terran09\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9b00tad.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9b01ume.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9b02udu.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9b03ura.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9b04udu.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9b05ura.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9m00ura.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\t9m20udu.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\tam00udu.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\tam01uke.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\tam02ume.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\tam03uke.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\tam04ura.wav\r\ncampaign\\terran\\terran09\\staredit\\wav\\tam05ume.wav\r\ncampaign\\terran\\terran10\\staredit\\scenario.chk\r\ncampaign\\terran\\terran10\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tab00tad.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tab01ume.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tab02ume.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tab03uke.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tab04udu.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tab05ura.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tab06udu.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tam00udu.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tam01uke.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tam02ume.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tam03uke.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tam04ura.wav\r\ncampaign\\terran\\terran10\\staredit\\wav\\tam05ume.wav\r\ncampaign\\terran\\terran11\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran11\\staredit\\scenario.chk\r\ncampaign\\terran\\terran11\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbb00tad.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbb01ume.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbb02ura.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbb03ume.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbb04ura.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbb05uke.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbb06ura.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm00ura.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm01uke.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm02uke.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm03uke.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm04ura.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm20ume.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm21uma.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm40tad.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm41uke.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm42ume.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm43ura.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm44ume.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm45uke.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm46ura.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm47ume.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\tbm48uke.wav\r\ncampaign\\terran\\terran11\\staredit\\wav\\TBM99uke.wav\r\ncampaign\\terran\\terran12\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\terran12\\staredit\\scenario.chk\r\ncampaign\\terran\\terran12\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb00tad.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb01ura.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb02tad.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb03ume.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb04ura.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb05ume.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb06ura.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb07ume.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb08tad.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcb09ura.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcm00ura.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcm01ura.wav\r\ncampaign\\terran\\terran12\\staredit\\wav\\tcm20tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\blizzard_2.cnd\r\ncampaign\\terran\\tutorial\\staredit\\scenario.chk\r\ncampaign\\terran\\tutorial\\staredit\\wav\\combeep0.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0b00tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0b01tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0b02tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0b03tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0b04tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0b05tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0b60tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m00tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m01tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m02tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m03tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m04tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m05tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m06tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m07tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m20tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m21tad.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m30tma.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m31tma.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\t0m40tvu.wav\r\ncampaign\\terran\\tutorial\\staredit\\wav\\tscyes01.wav\r\ncampaign\\terranED\\terran01\\staredit\\blizzard_2.chk\r\ncampaign\\terraned\\terran01\\staredit\\scenario.chk\r\ncampaign\\terraned\\terran01\\staredit\\wav\\combeep0.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t0m30tma.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t0m31tma.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1b00tad.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1B00TCo.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1b01umc.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1m00tma.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M01TCo.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1m01umc.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M02ucc.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M03umc.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M05tad.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M20THe.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1m20ucc.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M21TCo.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1m21umc.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M22THe.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1m22ucc.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M40Tad.wav\r\ncampaign\\terraned\\terran01\\staredit\\wav\\t1m40tma.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T1M60Tma.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T2B00tad.wav\r\ncampaign\\terranED\\terran01\\staredit\\wav\\T9B00tad.wav\r\ncampaign\\terraned\\terran02\\staredit\\scenario.chk\r\ncampaign\\terraned\\terran02\\staredit\\wav\\combeep1.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\Laughing Marines.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3b00ucc.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3b01umc.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3b02ucc.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m00ucf.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\T3M01ucc.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\T3M02tma.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\T3M03tma.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\T3M04tma.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\T3M05tma.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\T3M06tma.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\T3M08tci.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m10ucc.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m20tma.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m30tma.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m40tma.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m50tma.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m60tma.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m70tma.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m80uci.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3m90tma.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t3ma0tci.wav\r\ncampaign\\terraned\\terran02\\staredit\\wav\\t4m70tad.wav\r\ncampaign\\terranED\\terran02\\staredit\\wav\\~OLDT1M00uma.wav\r\ncampaign\\terranED\\terran03\\staredit\\blizzard_2.chk\r\ncampaign\\terraned\\terran03\\staredit\\scenario.chk\r\ncampaign\\terraned\\terran03\\staredit\\wav\\combeep0.wav\r\ncampaign\\terraned\\terran03\\staredit\\wav\\t2b00tad.wav\r\ncampaign\\terranED\\terran03\\staredit\\wav\\T2M00ucg.wav\r\ncampaign\\terraned\\terran03\\staredit\\wav\\t3m20tvu.wav\r\ncampaign\\terraned\\terran03\\staredit\\wav\\t3m90tma.wav\r\ncampaign\\terranED\\terran03\\staredit\\wav\\T4B00TCo.wav\r\ncampaign\\terraned\\terran03\\staredit\\wav\\t4b00ucc.wav\r\ncampaign\\terraned\\terran03\\staredit\\wav\\t4b01tad.wav\r\ncampaign\\terraned\\terran03\\staredit\\wav\\t4b02umc.wav\r\ncampaign\\terraned\\terran03\\staredit\\wav\\t5m00ucc.wav\r\ncampaign\\terranED\\tutorial\\staredit\\blizzard_2.chk\r\ncampaign\\terraned\\tutorial\\staredit\\scenario.chk\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\combeep0.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0b00tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0b01tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0b02tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0b03tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0b04tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0b05tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0b60tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m00tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m01tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m02tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m03tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m04tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m05tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m06tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m07tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m21tad.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\t0m22tad.wav\r\ncampaign\\terranED\\tutorial\\staredit\\wav\\T0M30tma.wav\r\ncampaign\\terranED\\tutorial\\staredit\\wav\\T0M31tma.wav\r\ncampaign\\terraned\\tutorial\\staredit\\wav\\tscyes01.wav\r\ncampaign\\terranSW\\terran01\\staredit\\scenario.chk\r\ncampaign\\terranSW\\terran02\\staredit\\scenario.chk\r\ncampaign\\terranSW\\terran03\\staredit\\scenario.chk\r\ncampaign\\terranSW\\terran04\\staredit\\scenario.chk\r\ncampaign\\terranSW\\terran05\\staredit\\scenario.chk\r\ncampaign\\terranSW\\tutorial\\staredit\\scenario.chk\r\ncampaign\\zerg\\tutorial\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg01\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg01\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m01uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m02uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m03uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m04uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m05uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m06uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m07uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m08uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z0m09uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z1b00zad.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z1b01zad.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z1b02zad.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z1b03zad.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z1m00uza.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\z1m20uda.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\zpwrdown.wav\r\ncampaign\\zerg\\zerg01\\staredit\\wav\\zpwrup.wav\r\ncampaign\\zerg\\zerg02\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg02\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\ComBeep1.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z1m20uda.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z2b00zad.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z2b01zad.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z2b02uza.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z2b03uda.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z2m00uda.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z2m20uza.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\z2m21uda.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\ZPwrDown.wav\r\ncampaign\\zerg\\zerg02\\staredit\\wav\\ZPwrUp.wav\r\ncampaign\\zerg\\zerg03\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg03\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\z3b00zad.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\z3b01uza.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\z3b02udu.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\z3b03uda.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\z3m00udu.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\z3m01uda.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\z3m02uza.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\zpwrdown.wav\r\ncampaign\\zerg\\zerg03\\staredit\\wav\\zpwrup.wav\r\ncampaign\\zerg\\zerg04\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg04\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4b00uza.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4b01zad.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4b02zad.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m00ura.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m20uza.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m40zad.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m41uki.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m42zad.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m43ura.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m60ura.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m61uki.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m62ura.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m63uki.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m64uki.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m65ura.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m66uki.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\z4m67ura.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\ZPwrDown.wav\r\ncampaign\\zerg\\zerg04\\staredit\\wav\\ZPwrUp.wav\r\ncampaign\\zerg\\zerg05\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg05\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\combeep1.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\p6m00tad.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\ppwrdown.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\t4m00uci.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\t4m20uci.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\t4m70tad.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\tbm21uma.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5b00uki.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5b01uki.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5b02uza.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5b03uki.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5b04zad.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5b05uza.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m00tad.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m00uda.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m20uci.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m20uki.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m30uci.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m40uma.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m50uma.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m51uma.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\z5m60uda.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\zpwrdown.wav\r\ncampaign\\zerg\\zerg05\\staredit\\wav\\ZPwrUp.wav\r\ncampaign\\zerg\\zerg06\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg06\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\combeep1.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6b00uki.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6b01uki.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6b02uta.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6b03uki.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6b04uta.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6b05uki.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6m00uza.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6m01uki.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6m02uza.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6m20uki.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6m40uta.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6m60uki.wav\r\ncampaign\\zerg\\zerg06\\staredit\\wav\\z6m61uta.wav\r\ncampaign\\zerg\\zerg07\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg07\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg07\\staredit\\wav\\ComBeep0.wav\r\ncampaign\\zerg\\zerg07\\staredit\\wav\\z7b00uki.wav\r\ncampaign\\zerg\\zerg07\\staredit\\wav\\z7b01uda.wav\r\ncampaign\\zerg\\zerg07\\staredit\\wav\\z7b02uki.wav\r\ncampaign\\zerg\\zerg07\\staredit\\wav\\z7b03uda.wav\r\ncampaign\\zerg\\zerg07\\staredit\\wav\\z7b04uki.wav\r\ncampaign\\zerg\\zerg07\\staredit\\wav\\z7b05uda.wav\r\ncampaign\\zerg\\zerg08\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg08\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8b00zad.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8b01zad.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8b02zad.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8b03uda.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8m00uda.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8m20uda.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8m40uki.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8m41uze.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8m42uki.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\z8m60uki.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\ZergEndCommunication.wav\r\ncampaign\\zerg\\zerg08\\staredit\\wav\\ZergStartCommunication.wav\r\ncampaign\\zerg\\zerg09\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg09\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\z9b00zad.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\z9b01zad.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\z9b02zad.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\z9m00uda.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\z9m01uda.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\zdrerr00.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\zdrmin00.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\ZergEndCommunication.wav\r\ncampaign\\zerg\\zerg09\\staredit\\wav\\ZergStartCommunication.wav\r\ncampaign\\zerg\\zerg10\\staredit\\blizzard_2.cnd\r\ncampaign\\zerg\\zerg10\\staredit\\scenario.chk\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\combeep0.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\zab00zad.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\zab01zad.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\zab02zad.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\zam00uda.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\zam20zad.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\ZAM21zad.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\ZergEndCommunication.wav\r\ncampaign\\zerg\\zerg10\\staredit\\wav\\ZergStartCommunication.wav\r\ncaps.dat\r\ncmdicons.grp\r\ncommand.txt\r\ncrdt_exp.002\r\ncrdt_exp.005\r\ncrdt_exp.008\r\ncrdt_exp.00b\r\ncrdt_exp.txt\r\nctrlpan\\golddrop.cel\r\nctrlpan\\p8bulbs.cel\r\nCtrlPan\\P8But2.cel\r\nctrlpan\\panel8.cel\r\nctrlpan\\panel8bu.cel\r\nctrlpan\\smaltext.cel\r\nctrlpan\\spelicon.cel\r\nctrlpan\\talkbutt.cel\r\nctrlpan\\talkpanl.cel\r\ncursor\\arrhot.pcx\r\ncursor\\arrow.grp\r\ncursor\\arrow.smk\r\ncursor\\drag.grp\r\ncursor\\drag.pcx\r\ncursor\\drag.smk\r\ncursor\\illegal.grp\r\ncursor\\illegal.pcx\r\ncursor\\illegal.smk\r\ncursor\\magg.grp\r\ncursor\\magg.pcx\r\ncursor\\magg.smk\r\ncursor\\magr.grp\r\ncursor\\magr.pcx\r\ncursor\\magr.smk\r\ncursor\\magy.grp\r\ncursor\\magy.pcx\r\ncursor\\magy.smk\r\ncursor\\scrolld.grp\r\ncursor\\scrolld.pcx\r\ncursor\\scrolld.smk\r\ncursor\\scrolldl.grp\r\ncursor\\scrolldl.pcx\r\ncursor\\scrolldl.smk\r\ncursor\\scrolldr.grp\r\ncursor\\scrolldr.pcx\r\ncursor\\scrolldr.smk\r\ncursor\\scrolll.grp\r\ncursor\\scrolll.pcx\r\ncursor\\scrolll.smk\r\ncursor\\scrollr.grp\r\ncursor\\scrollr.pcx\r\ncursor\\scrollr.smk\r\ncursor\\scrollu.grp\r\ncursor\\scrollu.pcx\r\ncursor\\scrollu.smk\r\ncursor\\scrollul.grp\r\ncursor\\scrollul.pcx\r\ncursor\\scrollul.smk\r\ncursor\\scrollur.grp\r\ncursor\\scrollur.pcx\r\ncursor\\scrollur.smk\r\ncursor\\targg.grp\r\ncursor\\targg.pcx\r\ncursor\\targg.smk\r\ncursor\\targn.grp\r\ncursor\\targn.pcx\r\ncursor\\targn.smk\r\ncursor\\targr.grp\r\ncursor\\targr.pcx\r\ncursor\\targr.smk\r\ncursor\\targy.grp\r\ncursor\\targy.pcx\r\ncursor\\targy.smk\r\ncursor\\time.grp\r\ncursor\\time.pcx\r\ncursor\\time.smk\r\ndata\\bigtgold.cel\r\ndata\\char.cel\r\ndata\\charbut.cel\r\ndata\\diabsmal.cel\r\nData\\hf_logo3.cel\r\ndata\\inv\\inv.cel\r\ndata\\inv\\inv_rog.cel\r\ndata\\inv\\inv_sor.cel\r\ndata\\inv\\objcurs.cel\r\nData\\Inv\\Objcurs2.cel\r\ndata\\medtexts.cel\r\ndata\\optbar.cel\r\ndata\\option.cel\r\nData\\PentSpin.cel\r\ndata\\pentspn2.cel\r\ndata\\quest.cel\r\nData\\SpelIcon.cel\r\ndata\\spellbk.cel\r\ndata\\spellbkb.cel\r\ndata\\spelli2.cel\r\ndata\\square.cel\r\ndata\\textbox.cel\r\ndata\\textbox2.cel\r\ndata\\textslid.cel\r\ndelete.lst\r\ndf.battle.net (carbon)\r\ndf.bnupdate (carbon)\r\ndf.standard (carbon)\r\ndf.starcraft (carbon)\r\ndf.storm (carbon)\r\ndiabbeta.exe\r\ndiablo.exe\r\ndiablo.ini\r\ndiablo.lnk\r\ndiablo_s.exe\r\ndiabloui.dll\r\ndiabunin.exe\r\ndisrupt.000\r\ndisrupt.grp\r\nDlg.056\r\nDlg.05b\r\nDlg.060\r\nDlg.grp\r\ndlgs\\protoss.grp\r\ndlgs\\terran.grp\r\ndlgs\\tile.grp\r\ndlgs\\zerg.grp\r\neditlocal.dll\r\neditor\\mask.flc\r\neditor\\mask.fsp\r\neditor\\mask.grp\r\neditor\\trigrgn.flc\r\neditor\\trigrgn.fsp\r\neditor\\trigrgn.grp\r\nfiles\\battle.snp\r\nfiles\\bnupdate.exe\r\nfiles\\broodat.mpq\r\nfiles\\broodunits.doc\r\nfiles\\editlocal.dll\r\nfiles\\font\\font10.fnt\r\nfiles\\font\\font12.fnt\r\nfiles\\font\\font14.fnt\r\nfiles\\font\\font16.fnt\r\nfiles\\font\\font16x.fnt\r\nfiles\\font\\font32.fnt\r\nfiles\\font\\font50.fnt\r\nfiles\\font\\font8.fnt\r\nfiles\\license.txt\r\nfiles\\local.dll\r\nfiles\\msv2all.vxp\r\nfiles\\mvoice.vxp\r\nfiles\\readme.cnt\r\nfiles\\readme.hlp\r\nfiles\\readme.txt\r\nfiles\\report bugs.url\r\nfiles\\Riched20.dll\r\nfiles\\seditdeu.loc\r\nfiles\\seditenu.loc\r\nfiles\\seditesp.loc\r\nfiles\\seditfra.loc\r\nfiles\\seditita.loc\r\nfiles\\seditptg.loc\r\nfiles\\smackw32.dll\r\nfiles\\standard.snp\r\nfiles\\starcraft - brood war electronic registration.url\r\nfiles\\starcraft electronic registration.url\r\nfiles\\starcraft shareware(ed) electronic registration.url\r\nfiles\\starcraft.exe\r\nfiles\\stardat.mpq\r\nfiles\\stardated.mpq\r\nfiles\\staredit.cnt\r\nfiles\\staredit.exe\r\nfiles\\staredit.hlp\r\nfiles\\storm.dll\r\nfiles\\vadagc.vxp\r\nfiles\\vct32150.dll\r\nfiles\\vfonts.vxp\r\nflingy.dat\r\nfont\\font.ccd\r\nfont\\font.clh\r\nfont\\font.gid\r\nfont\\font10.fnt\r\nfont\\font12.fnt\r\nfont\\font14.fnt\r\nfont\\font16.fnt\r\nfont\\font16x.fnt\r\nfont\\font32.fnt\r\nfont\\font50.fnt\r\nfont\\font8.fnt\r\nfree for all(1).002\r\nfree for all(1).003\r\nfree for all(1).007\r\nfree for all(1).008\r\nfree for all(1).00c\r\nfree for all(1).00d\r\nfree for all(1).00e\r\nfree for all(1).00f\r\nfree for all(1).011\r\nfree for all(1).012\r\nfree for all(1).016\r\nfree for all(1).017\r\nfree for all(1).01f\r\nfree for all(1).021\r\nfree for all(1).027\r\nfree for all(1).030\r\nfree for all(1).033\r\nfree for all(1).040\r\nfree for all(1).041\r\nfree for all(1).045\r\nfree for all(1).052\r\nfree for all(1).057\r\nfree for all(1).059\r\nfree for all(1).072\r\nfree for all(1).got\r\ngame\r\ngame\\1trigtext\r\ngame\\1umber.pcx\r\ngame\\aggicons.pcx\r\ngame\\blink.grp\r\ngame\\conover.pcx\r\ngame\\console.pcx\r\ngame\\icons.grp\r\ngame\\nconover.pcx\r\ngame\\nconsole.pcx\r\ngame\\pbrempt.pcx\r\ngame\\pbrfull.pcx\r\ngame\\pconover.pcx\r\ngame\\pconsole.pcx\r\ngame\\ppbrempt.pcx\r\ngame\\ppbrfull.pcx\r\ngame\\pumber.pcx\r\ngame\\ScorePd\\tminimap.pcx\r\ngame\\ScorePv\\tminimap.pcx\r\ngame\\ScoreTd\\tminimap.pcx\r\ngame\\ScoreTv\\tminimap.pcx\r\ngame\\ScoreZd\\tminimap.pcx\r\ngame\\ScoreZv\\tminimap.pcx\r\ngame\\tblink.pcx\r\ngame\\tconover.pcx\r\ngame\\tconsole.pcx\r\ngame\\tfontgam.pcx\r\ngame\\thpbar.pcx\r\ngame\\tminimap.pcx\r\ngame\\tpbrempt.pcx\r\ngame\\tpbrfull.pcx\r\ngame\\trigtext\r\ngame\\tselect.pcx\r\ngame\\tumber.pcx\r\ngame\\tunit.pcx\r\ngame\\twire.pcx\r\ngame\\umber.pcx\r\ngame\\zconover.pcx\r\ngame\\zconsole.pcx\r\ngame\\zpbrempt.pcx\r\ngame\\zpbrfull.pcx\r\ngame\\zumber.pcx\r\nGateways.txt\r\ngendata\\cut2.cel\r\ngendata\\cut2.pal\r\ngendata\\cut3.cel\r\ngendata\\cut3.pal\r\ngendata\\cut4.cel\r\ngendata\\cut4.pal\r\ngendata\\cutgate.cel\r\ngendata\\cutgate.pal\r\ngendata\\cutl1d.cel\r\ngendata\\cutl1d.pal\r\nGendata\\Cutportl.cel\r\ngendata\\cutportl.pal\r\ngendata\\cutportr.cel\r\ngendata\\cutportr.pal\r\ngendata\\cutstart.cel\r\ngendata\\cutstart.pal\r\ngendata\\cuttt.cel\r\ngendata\\cuttt.pal\r\ngendata\\diabend.smk\r\ngendata\\diablo1.smk\r\ngendata\\diabvic1.smk\r\ngendata\\diabvic2.smk\r\ngendata\\diabvic3.smk\r\ngendata\\doom.smk\r\ngendata\\fprst3.smk\r\ngendata\\Hellfire.smk\r\ngendata\\logo.smk\r\ngendata\\loopdend.smk\r\ngluall.000\r\ngluall.001\r\ngluall.003\r\ngluall.005\r\ngluall.006\r\ngluall.007\r\ngluall.009\r\ngluall.00a\r\ngluall.00b\r\ngluAll.00c\r\ngluall.00f\r\ngluall.010\r\ngluall.014\r\ngluall.015\r\ngluAll.01c\r\ngluall.01d\r\ngluall.022\r\ngluall.025\r\ngluAll.02c\r\ngluall.02e\r\ngluAll.030\r\ngluall.038\r\ngluAll.03c\r\ngluall.03e\r\ngluall.03f\r\ngluAll.042\r\ngluAll.04c\r\ngluall.04e\r\ngluall.050\r\ngluAll.054\r\ngluall.057\r\ngluall.064\r\ngluall.070\r\ngluAll.tbl\r\ngluAll_Mac.tbl\r\ngluBNRes.001\r\ngluBNRes.004\r\ngluBNRes.007\r\ngluBNRes.00a\r\ngluBNRes.00d\r\ngluBNRes.res\r\ngluChat.000\r\ngluChat.003\r\ngluChat.006\r\ngluChat.009\r\ngluChat.00c\r\ngluChat.bin\r\ngluCmpgn.000\r\ngluCmpgn.003\r\ngluCmpgn.006\r\ngluCmpgn.009\r\ngluCmpgn.00c\r\ngluCmpgn.bin\r\ngluConn.007\r\ngluConn.017\r\ngluconn.018\r\ngluConn.019\r\ngluconn.01d\r\ngluconn.020\r\ngluConn.027\r\ngluconn.029\r\ngluConn.02b\r\ngluconn.033\r\ngluConn.037\r\ngluconn.039\r\ngluconn.03a\r\ngluConn.03d\r\ngluConn.047\r\ngluconn.049\r\ngluconn.04b\r\ngluConn.04f\r\ngluconn.052\r\ngluconn.05f\r\ngluconn.06b\r\ngluConn.bin\r\ngluCreat.001\r\ngluCreat.004\r\ngluCreat.007\r\ngluCreat.00a\r\ngluCreat.00d\r\ngluCreat.bin\r\ngluCustm.002\r\ngluCustm.005\r\ngluCustm.008\r\ngluCustm.00b\r\ngluCustm.00e\r\ngluCustm.bin\r\nglue\\battle.net\\backgrounds\\blankprofile.pcx\r\nglue\\battle.net\\backgrounds\\bn_bkg.pcx\r\nglue\\battle.net\\backgrounds\\bnconnect.pcx\r\nglue\\battle.net\\backgrounds\\bnfile.pcx\r\nglue\\battle.net\\backgrounds\\bnjoinbg.pcx\r\nglue\\battle.net\\backgrounds\\bnladder.pcx\r\nglue\\battle.net\\backgrounds\\bnlogin.pcx\r\nglue\\battle.net\\backgrounds\\bnprofile.pcx\r\nglue\\battle.net\\backgrounds\\bnselchn.pcx\r\nglue\\battle.net\\backgrounds\\bnviewprofile.pcx\r\nglue\\battle.net\\backgrounds\\changepassword.pcx\r\nglue\\battle.net\\backgrounds\\chat_bkg.pcx\r\nglue\\battle.net\\backgrounds\\creat_bg.pcx\r\nglue\\battle.net\\backgrounds\\filters.pcx\r\nglue\\battle.net\\backgrounds\\newaccount.pcx\r\nglue\\battle.net\\backgrounds\\profilebkg.pcx\r\nglue\\battle.net\\backgrounds\\profileexp.pcx\r\nglue\\battle.net\\backgrounds\\tos.pcx\r\nglue\\battle.net\\generic\\icons\\but_110x35.pcx\r\nglue\\battle.net\\generic\\icons\\but_75x35.pcx\r\nglue\\battle.net\\generic\\icons\\but_checkbox.pcx\r\nglue\\battle.net\\generic\\icons\\but_checkboxt.pcx\r\nglue\\battle.net\\generic\\icons\\but_checkoff.pcx\r\nglue\\battle.net\\generic\\icons\\but_checkon.pcx\r\nglue\\battle.net\\generic\\icons\\but_lrg.pcx\r\nglue\\battle.net\\generic\\icons\\but_med.pcx\r\nglue\\battle.net\\generic\\icons\\but_sml.pcx\r\nglue\\battle.net\\generic\\icons\\but_square.pcx\r\nglue\\battle.net\\generic\\icons\\but_xsm.pcx\r\nglue\\battle.net\\generic\\icons\\cmbc.pcx\r\nglue\\battle.net\\generic\\icons\\cmbl.pcx\r\nglue\\battle.net\\generic\\icons\\cmbr.pcx\r\nglue\\battle.net\\generic\\icons\\cmec.pcx\r\nglue\\battle.net\\generic\\icons\\cmel.pcx\r\nglue\\battle.net\\generic\\icons\\cmer.pcx\r\nglue\\battle.net\\generic\\icons\\cmmc.pcx\r\nglue\\battle.net\\generic\\icons\\cmml.pcx\r\nglue\\battle.net\\generic\\icons\\cmmr.pcx\r\nglue\\battle.net\\generic\\icons\\prog_bg.pcx\r\nglue\\battle.net\\generic\\icons\\prog_fil.pcx\r\nglue\\battle.net\\generic\\icons\\slfocus.pcx\r\nglue\\battle.net\\generic\\icons\\slgray.pcx\r\nglue\\battle.net\\generic\\icons\\slleft.pcx\r\nglue\\battle.net\\generic\\icons\\slmiddle.pcx\r\nglue\\battle.net\\generic\\icons\\slright.pcx\r\nglue\\battle.net\\generic\\icons\\slthumb.pcx\r\nglue\\battle.net\\generic\\popups\\epopup.pcx\r\nglue\\battle.net\\generic\\popups\\hpopup.pcx\r\nglue\\battle.net\\generic\\popups\\lepopup.pcx\r\nglue\\battle.net\\generic\\popups\\lpopup.pcx\r\nglue\\battle.net\\generic\\popups\\lrpopup.pcx\r\nglue\\battle.net\\generic\\popups\\spopup.pcx\r\nglue\\battle.net\\generic\\popups\\srpopup.pcx\r\nglue\\battle.net\\icons\\arrows.pcx\r\nglue\\battle.net\\icons\\bar.pcx\r\nglue\\battle.net\\icons\\bnbuttns.pcx\r\nglue\\battle.net\\icons\\cd-icons.pcx\r\nglue\\battle.net\\icons\\cmbc.pcx\r\nglue\\battle.net\\icons\\cmbl.pcx\r\nglue\\battle.net\\icons\\cmbr.pcx\r\nglue\\battle.net\\icons\\cmec.pcx\r\nglue\\battle.net\\icons\\cmel.pcx\r\nglue\\battle.net\\icons\\cmer.pcx\r\nglue\\battle.net\\icons\\cmmc.pcx\r\nglue\\battle.net\\icons\\cmml.pcx\r\nglue\\battle.net\\icons\\cmmr.pcx\r\nglue\\battle.net\\icons\\difficulty.pcx\r\nglue\\battle.net\\icons\\disconnected.pcx\r\nglue\\battle.net\\icons\\gameicons.pcx\r\nglue\\battle.net\\icons\\greenlag.pcx\r\nglue\\battle.net\\icons\\iblizzard.pcx\r\nglue\\battle.net\\icons\\iclosed.pcx\r\nglue\\battle.net\\icons\\iclosedsel.pcx\r\nglue\\battle.net\\icons\\icons.pcx\r\nglue\\battle.net\\icons\\iladder.pcx\r\nglue\\battle.net\\icons\\imap.pcx\r\nglue\\battle.net\\icons\\imapsel.pcx\r\nglue\\battle.net\\icons\\iopen.pcx\r\nglue\\battle.net\\icons\\medals.pcx\r\nglue\\battle.net\\icons\\number.pcx\r\nglue\\battle.net\\icons\\redlag.pcx\r\nglue\\battle.net\\icons\\special.pcx\r\nglue\\battle.net\\icons\\spwnport.pcx\r\nglue\\battle.net\\icons\\thumb.pcx\r\nglue\\battle.net\\icons\\yellolag.pcx\r\nglue\\battle.net\\logos\\connect_logo.pcx\r\nglue\\battle.net\\popups\\create.pcx\r\nglue\\battle.net\\popups\\login.pcx\r\nglue\\battle.net\\popups\\welcome.pcx\r\nglue\\campaign\\disk.smk\r\nglue\\campaign\\pbotl.pcx\r\nglue\\campaign\\pbotr.pcx\r\nglue\\campaign\\phist.pcx\r\nglue\\campaign\\prot.smk\r\nglue\\campaign\\proton.smk\r\nglue\\campaign\\protonde.smk\r\nglue\\campaign\\protones.smk\r\nglue\\campaign\\protonfr.smk\r\nglue\\campaign\\protonit.smk\r\nglue\\campaign\\ptopl.pcx\r\nglue\\campaign\\ptopr.pcx\r\nglue\\campaign\\terr.smk\r\nglue\\campaign\\terron.smk\r\nglue\\campaign\\terronde.smk\r\nglue\\campaign\\terrones.smk\r\nglue\\campaign\\terronfr.smk\r\nglue\\campaign\\terronit.smk\r\nglue\\campaign\\zerg.smk\r\nglue\\campaign\\zergon.smk\r\nglue\\campaign\\zergonde.smk\r\nglue\\campaign\\zergones.smk\r\nglue\\campaign\\zergonfr.smk\r\nglue\\campaign\\zergonit.smk\r\nglue\\chatroom\\ichat.grp\r\nglue\\chatroom\\pchat.pcx\r\nglue\\chatroom\\pjoin.pcx\r\nglue\\chatroom\\plist.pcx\r\nglue\\create\\icreate.grp\r\nglue\\create\\pinfo.pcx\r\nglue\\create\\plistmap.pcx\r\nglue\\create\\plistmap2.pcx\r\nglue\\create\\plistmaptall.pcx\r\nglue\\create\\poptions.pcx\r\nglue\\create\\pslots.pcx\r\nglue\\expcampaign\\disk.smk\r\nglue\\expcampaign\\xprot.smk\r\nglue\\expcampaign\\xproton.smk\r\nglue\\expcampaign\\xterr.smk\r\nglue\\expcampaign\\xterron.smk\r\nglue\\expcampaign\\xzerg.smk\r\nglue\\expcampaign\\xzergon.smk\r\nglue\\gamemode\\temp.pcx\r\nglue\\gamesel\\pjoin.pcx\r\nglue\\gamesel\\plistlrg.pcx\r\nglue\\load\\pinfo.pcx\r\nglue\\load\\plist.pcx\r\nglue\\login\\pinfo.pcx\r\nglue\\login\\plist.pcx\r\nglue\\mainmenu\\editor.smk\r\nglue\\mainmenu\\editoron.smk\r\nglue\\mainmenu\\editoronde.smk\r\nglue\\mainmenu\\editorones.smk\r\nglue\\mainmenu\\editoronfr.smk\r\nglue\\mainmenu\\editoronit.smk\r\nglue\\mainmenu\\etail.pcx\r\nglue\\mainmenu\\exit.smk\r\nglue\\mainmenu\\exiton.smk\r\nglue\\mainmenu\\exitonde.smk\r\nglue\\mainmenu\\exitones.smk\r\nglue\\mainmenu\\exitonfr.smk\r\nglue\\mainmenu\\exitonit.smk\r\nglue\\mainmenu\\expansion.smk\r\nglue\\mainmenu\\expansionon.smk\r\nglue\\mainmenu\\expansiononde.smk\r\nglue\\mainmenu\\expansionones.smk\r\nglue\\mainmenu\\expansiononfr.smk\r\nglue\\mainmenu\\expansiononit.smk\r\nglue\\mainmenu\\multi.smk\r\nglue\\mainmenu\\multion.smk\r\nglue\\mainmenu\\multionde.smk\r\nglue\\mainmenu\\multiones.smk\r\nglue\\mainmenu\\multionfr.smk\r\nglue\\mainmenu\\multionit.smk\r\nglue\\mainmenu\\pcredit.pcx\r\nglue\\mainmenu\\pintro.pcx\r\nglue\\mainmenu\\single.smk\r\nglue\\mainmenu\\singleon.smk\r\nglue\\mainmenu\\singleonde.smk\r\nglue\\mainmenu\\singleones.smk\r\nglue\\mainmenu\\singleonfr.smk\r\nglue\\mainmenu\\singleonit.smk\r\nglue\\modem\\pentry.pcx\r\nglue\\modem\\pinfo.pcx\r\nglue\\modem\\pphones.pcx\r\nglue\\modem\\pselect.pcx\r\nglue\\modem\\pstatus.pcx\r\nglue\\palcs\\arrhot.pcx\r\nglue\\palcs\\arrow.grp\r\nglue\\palcs\\arrow.smk\r\nglue\\palcs\\backgnd.pcx\r\nglue\\palcs\\dlg.grp\r\nglue\\palcs\\pcancel.pcx\r\nglue\\palcs\\pdpopup.pcx\r\nglue\\palcs\\pepopup.pcx\r\nglue\\palcs\\pok.pcx\r\nglue\\palcs\\popopup.pcx\r\nglue\\palcs\\teffect.pcx\r\nglue\\palcs\\tfont.pcx\r\nglue\\palcs\\tile.grp\r\nglue\\palmm\\arrhot.pcx\r\nglue\\palmm\\arrow.grp\r\nglue\\palmm\\arrow.smk\r\nglue\\palmm\\backgnd.pcx\r\nglue\\palmm\\dlg.grp\r\nglue\\palmm\\pcancel.pcx\r\nglue\\palmm\\pdpopup.pcx\r\nglue\\palmm\\pepopup.pcx\r\nglue\\palmm\\pok.pcx\r\nglue\\palmm\\popopup.pcx\r\nglue\\palmm\\retail_ex.pcx\r\nglue\\palmm\\teffect.pcx\r\nglue\\palmm\\tfont.pcx\r\nglue\\palmm\\tile.grp\r\nGLUE\\PALNL\\arrhot.pcx\r\nglue\\palnl\\arrow.grp\r\nglue\\palnl\\arrow.smk\r\nglue\\palnl\\backgnd.pcx\r\nglue\\palnl\\dlg.grp\r\nglue\\palnl\\pcancel.pcx\r\nglue\\palnl\\pdpopup.pcx\r\nglue\\palnl\\pepopup.pcx\r\nglue\\palnl\\pok.pcx\r\nglue\\palnl\\popopup.pcx\r\nglue\\palnl\\teffect.pcx\r\nglue\\palnl\\tfont.pcx\r\nglue\\palnl\\tile.grp\r\nglue\\palpa\\blank.pcx\r\nglue\\palpa\\protossa.pcx\r\nglue\\palpa\\tfont.pcx\r\nglue\\palpax\\blank.pcx\r\nglue\\palpax\\tfont.pcx\r\nglue\\palpax\\xprotosa.pcx\r\nglue\\palpb\\blank.pcx\r\nglue\\palpb\\protossb.pcx\r\nglue\\palpb\\tfont.pcx\r\nglue\\palpbx\\blank.pcx\r\nglue\\palpbx\\tfont.pcx\r\nglue\\palpbx\\xprotosb.pcx\r\nglue\\palpc\\blank.pcx\r\nglue\\palpc\\protossc.pcx\r\nglue\\palpc\\tfont.pcx\r\nglue\\palpcx\\blank.pcx\r\nglue\\palpcx\\tfont.pcx\r\nglue\\palpcx\\xprotosc.pcx\r\nGLUE\\PALPD\\arrhot.pcx\r\nglue\\palpd\\arrow.grp\r\nglue\\palpd\\arrow.smk\r\nglue\\palpd\\backgnd.pcx\r\nglue\\palpd\\dlg.grp\r\nglue\\palpd\\pcancel.pcx\r\nglue\\palpd\\pdpopup.pcx\r\nglue\\palpd\\pepopup.pcx\r\nglue\\palpd\\pok.pcx\r\nglue\\palpd\\popopup.pcx\r\nglue\\palpd\\teffect.pcx\r\nglue\\palpd\\tfont.pcx\r\nglue\\palpd\\tile.grp\r\nGLUE\\PALPV\\arrhot.pcx\r\nglue\\palpv\\arrow.grp\r\nglue\\palpv\\arrow.smk\r\nglue\\palpv\\backgnd.pcx\r\nglue\\palpv\\dlg.grp\r\nglue\\palpv\\pcancel.pcx\r\nglue\\palpv\\pdpopup.pcx\r\nglue\\palpv\\pepopup.pcx\r\nglue\\palpv\\pok.pcx\r\nglue\\palpv\\popopup.pcx\r\nglue\\palpv\\teffect.pcx\r\nglue\\palpv\\tfont.pcx\r\nglue\\palpv\\tile.grp\r\nglue\\palrp\\arrow.grp\r\nglue\\palrp\\backgnd.pcx\r\nglue\\palrp\\dlg.grp\r\nglue\\palrp\\pcancel.pcx\r\nglue\\palrp\\pdpopup.pcx\r\nglue\\palrp\\pepopup.pcx\r\nglue\\palrp\\pok.pcx\r\nglue\\palrp\\popopup.pcx\r\nglue\\palrp\\teffect.pcx\r\nglue\\palrp\\tfont.pcx\r\nglue\\palrp\\tile.grp\r\nglue\\palrt\\arrow.grp\r\nglue\\palrt\\backgnd.pcx\r\nglue\\palrt\\dlg.grp\r\nglue\\palrt\\pcancel.pcx\r\nglue\\palrt\\pdpopup.pcx\r\nglue\\palrt\\pepopup.pcx\r\nglue\\palrt\\pok.pcx\r\nglue\\palrt\\popopup.pcx\r\nglue\\palrt\\teffect.pcx\r\nglue\\palrt\\tfont.pcx\r\nglue\\palrt\\tile.grp\r\nglue\\palrz\\arrow.grp\r\nglue\\palrz\\backgnd.pcx\r\nglue\\palrz\\dlg.grp\r\nglue\\palrz\\pcancel.pcx\r\nglue\\palrz\\pdpopup.pcx\r\nglue\\palrz\\pepopup.pcx\r\nglue\\palrz\\pok.pcx\r\nglue\\palrz\\popopup.pcx\r\nglue\\palrz\\teffect.pcx\r\nglue\\palrz\\tfont.pcx\r\nglue\\palrz\\tile.grp\r\nglue\\palta\\blank.pcx\r\nglue\\palta\\terrana.pcx\r\nglue\\palta\\tfont.pcx\r\nglue\\paltax\\blank.pcx\r\nglue\\paltax\\tfont.pcx\r\nglue\\paltax\\xterrana.pcx\r\nglue\\paltb\\blank.pcx\r\nglue\\paltb\\terranb.pcx\r\nglue\\paltb\\tfont.pcx\r\nglue\\paltbx\\blank.pcx\r\nglue\\paltbx\\tfont.pcx\r\nglue\\paltbx\\xterranb.pcx\r\nglue\\paltc\\blank.pcx\r\nglue\\paltc\\terranc.pcx\r\nglue\\paltc\\tfont.pcx\r\nglue\\paltcx\\blank.pcx\r\nglue\\paltcx\\tfont.pcx\r\nglue\\paltcx\\xterranc.pcx\r\nGLUE\\PALTD\\arrhot.pcx\r\nglue\\paltd\\arrow.grp\r\nglue\\paltd\\arrow.smk\r\nglue\\paltd\\backgnd.pcx\r\nglue\\paltd\\dlg.grp\r\nglue\\paltd\\pcancel.pcx\r\nglue\\paltd\\pdpopup.pcx\r\nglue\\paltd\\pepopup.pcx\r\nglue\\paltd\\pok.pcx\r\nglue\\paltd\\popopup.pcx\r\nglue\\paltd\\teffect.pcx\r\nglue\\paltd\\tfont.pcx\r\nglue\\paltd\\tile.grp\r\nGLUE\\PALTV\\arrhot.pcx\r\nglue\\paltv\\arrow.grp\r\nglue\\paltv\\arrow.smk\r\nglue\\paltv\\backgnd.pcx\r\nglue\\paltv\\dlg.grp\r\nglue\\paltv\\pcancel.pcx\r\nglue\\paltv\\pdpopup.pcx\r\nglue\\paltv\\pepopup.pcx\r\nglue\\paltv\\pok.pcx\r\nglue\\paltv\\popopup.pcx\r\nglue\\paltv\\teffect.pcx\r\nglue\\paltv\\tfont.pcx\r\nglue\\paltv\\tile.grp\r\nglue\\palza\\blank.pcx\r\nglue\\palza\\tfont.pcx\r\nglue\\palza\\zerga.pcx\r\nglue\\palzax\\blank.pcx\r\nglue\\palzax\\tfont.pcx\r\nglue\\palzax\\xzerga.pcx\r\nglue\\palzb\\blank.pcx\r\nglue\\palzb\\tfont.pcx\r\nglue\\palzb\\zergb.pcx\r\nglue\\palzbx\\blank.pcx\r\nglue\\palzbx\\tfont.pcx\r\nglue\\palzbx\\xzergb.pcx\r\nglue\\palzc\\blank.pcx\r\nglue\\palzc\\tfont.pcx\r\nglue\\palzc\\zergc.pcx\r\nglue\\palzcx\\blank.pcx\r\nglue\\palzcx\\tfont.pcx\r\nglue\\palzcx\\xzergc.pcx\r\nGLUE\\PALZD\\arrhot.pcx\r\nglue\\palzd\\arrow.grp\r\nglue\\palzd\\arrow.smk\r\nglue\\palzd\\backgnd.pcx\r\nglue\\palzd\\dlg.grp\r\nglue\\palzd\\pcancel.pcx\r\nglue\\palzd\\pdpopup.pcx\r\nglue\\palzd\\pepopup.pcx\r\nglue\\palzd\\pok.pcx\r\nglue\\palzd\\popopup.pcx\r\nglue\\palzd\\teffect.pcx\r\nglue\\palzd\\tfont.pcx\r\nglue\\palzd\\tile.grp\r\nGLUE\\PALZV\\arrhot.pcx\r\nglue\\palzv\\arrow.grp\r\nglue\\palzv\\arrow.smk\r\nglue\\palzv\\backgnd.pcx\r\nglue\\palzv\\dlg.grp\r\nglue\\palzv\\pcancel.pcx\r\nglue\\palzv\\pdpopup.pcx\r\nglue\\palzv\\pepopup.pcx\r\nglue\\palzv\\pok.pcx\r\nglue\\palzv\\popopup.pcx\r\nglue\\palzv\\teffect.pcx\r\nglue\\palzv\\tfont.pcx\r\nglue\\palzv\\tile.grp\r\nglue\\readyp\\butprot.pcx\r\nglue\\readyp\\glow.smk\r\nglue\\readyp\\objprot.pcx\r\nglue\\readyp\\p1prot.pcx\r\nglue\\readyp\\p2prot.pcx\r\nglue\\readyp\\p3prot.pcx\r\nglue\\readyp\\p4prot.pcx\r\nglue\\readyp\\p_cancel.pcx\r\nglue\\readyp\\p_ok.pcx\r\nglue\\readyp\\pframe1.pcx\r\nglue\\readyp\\pframe2.pcx\r\nglue\\readyp\\pframe3.pcx\r\nglue\\readyp\\pframe4.pcx\r\nglue\\readyp\\pframeh1.pcx\r\nglue\\readyp\\pframeh2.pcx\r\nglue\\readyp\\pframeh3.pcx\r\nglue\\readyp\\pframeh4.pcx\r\nglue\\readyp\\protframe.pcx\r\nglue\\readyp\\protframeh.pcx\r\nglue\\readyp\\ring.smk\r\nglue\\readyp\\tutbtn.pcx\r\nglue\\readyt\\butterr.pcx\r\nglue\\readyt\\objterr.pcx\r\nglue\\readyt\\p1terr.pcx\r\nglue\\readyt\\p2terr.pcx\r\nglue\\readyt\\p3terr.pcx\r\nglue\\readyt\\p4terr.pcx\r\nglue\\readyt\\proj.smk\r\nglue\\readyt\\proloop.smk\r\nglue\\readyt\\start.smk\r\nglue\\readyt\\starton.smk\r\nglue\\readyt\\terrframe.pcx\r\nglue\\readyt\\terrframeh.pcx\r\nglue\\readyt\\tframe1.pcx\r\nglue\\readyt\\tframe2.pcx\r\nglue\\readyt\\tframe3.pcx\r\nglue\\readyt\\tframe4.pcx\r\nglue\\readyt\\tframeh1.pcx\r\nglue\\readyt\\tframeh2.pcx\r\nglue\\readyt\\tframeh3.pcx\r\nglue\\readyt\\tframeh4.pcx\r\nglue\\readyt\\tutbtn.pcx\r\nglue\\readyz\\butzerg.pcx\r\nglue\\readyz\\drip.smk\r\nglue\\readyz\\objzerg.pcx\r\nglue\\readyz\\p1zerg.pcx\r\nglue\\readyz\\p2zerg.pcx\r\nglue\\readyz\\p3zerg.pcx\r\nglue\\readyz\\p4zerg.pcx\r\nglue\\readyz\\start.smk\r\nglue\\readyz\\starton.smk\r\nglue\\readyz\\tutbtn.pcx\r\nglue\\readyz\\z_cancel.pcx\r\nglue\\readyz\\z_ok.pcx\r\nglue\\readyz\\zergframe.pcx\r\nglue\\readyz\\zergframeh.pcx\r\nglue\\readyz\\zframe1.pcx\r\nglue\\readyz\\zframe2.pcx\r\nglue\\readyz\\zframe3.pcx\r\nglue\\readyz\\zframe4.pcx\r\nglue\\readyz\\zframeh1.pcx\r\nglue\\readyz\\zframeh2.pcx\r\nglue\\readyz\\zframeh3.pcx\r\nglue\\readyz\\zframeh4.pcx\r\nglue\\scorepd\\iscore.grp\r\nglue\\scorepd\\pinset.pcx\r\nglue\\scorepd\\pmain.pcx\r\nglue\\scorepd\\scorebox.pcx\r\nglue\\scorepd\\tminimap.pcx\r\nglue\\scorepd\\untab.pcx\r\nglue\\scorepv\\iscore.grp\r\nglue\\scorepv\\pinset.pcx\r\nglue\\scorepv\\pmain.pcx\r\nglue\\scorepv\\scorebox.pcx\r\nglue\\scorepv\\tminimap.pcx\r\nglue\\scorepv\\untab.pcx\r\nglue\\scoretd\\iscore.grp\r\nglue\\scoretd\\pinset.pcx\r\nglue\\scoretd\\pmain.pcx\r\nglue\\scoretd\\scorebox.pcx\r\nglue\\scoretd\\tminimap.pcx\r\nglue\\scoretd\\untab.pcx\r\nglue\\scoretv\\iscore.grp\r\nglue\\scoretv\\pinset.pcx\r\nglue\\scoretv\\pmain.pcx\r\nglue\\scoretv\\scorebox.pcx\r\nglue\\scoretv\\tminimap.pcx\r\nglue\\scoretv\\untab.pcx\r\nglue\\scorezd\\iscore.grp\r\nglue\\scorezd\\pinset.pcx\r\nglue\\scorezd\\pmain.pcx\r\nglue\\scorezd\\scorebox.pcx\r\nglue\\scorezd\\tminimap.pcx\r\nglue\\scorezd\\untab.pcx\r\nglue\\scorezv\\iscore.grp\r\nglue\\scorezv\\pinset.pcx\r\nglue\\scorezv\\pmain.pcx\r\nglue\\scorezv\\scorebox.pcx\r\nglue\\scorezv\\tminimap.pcx\r\nglue\\scorezv\\untab.pcx\r\nglue\\selconn\\pgateway.pcx\r\nglue\\selconn\\pinfo.pcx\r\nglue\\selconn\\plistsml.pcx\r\nglue\\title\\tfont-beta.pcx\r\nglue\\title\\tfont.pcx\r\nglue\\title\\title-beta.pcx\r\nglue\\title\\title.pcx\r\ngluExpCmpgn.000\r\ngluExpCmpgn.001\r\ngluExpCmpgn.002\r\ngluExpCmpgn.003\r\ngluExpCmpgn.004\r\ngluExpCmpgn.bin\r\ngluScore.008\r\ngluScore.018\r\ngluscore.019\r\ngluScore.01a\r\ngluscore.01e\r\ngluscore.021\r\ngluScore.028\r\ngluscore.02a\r\ngluScore.02c\r\ngluscore.034\r\ngluScore.038\r\ngluscore.03a\r\ngluscore.03b\r\ngluScore.03e\r\ngluScore.048\r\ngluscore.04a\r\ngluscore.04c\r\ngluScore.050\r\ngluscore.053\r\ngluscore.060\r\ngluscore.06c\r\ngluScore.bin\r\nhdfiles.lst\r\nhellfire.ini\r\nhellfire.mpq\r\nhellfrui.dll\r\nhero\r\nhfmonk.mpq\r\nhfmusic.mpq\r\nhfopt1.mpq\r\nhfopt2.mpq\r\nhfvoice.mpq\r\nicons.pcx\r\nimages.dat\r\nimages.tbl\r\ninstall.lst\r\ninstall_s.lst\r\ninstcc.exe\r\nipxtest.snp\r\nISCRIPT.BIN\r\niscriptx.bin\r\nitems\\armor2.cel\r\nitems\\axe.cel\r\nitems\\bldstn.cel\r\nItems\\bombs1.cel\r\nitems\\bow.cel\r\nitems\\cleaver.cel\r\nItems\\cows1.cel\r\nitems\\crownf.cel\r\nItems\\donkys1.cel\r\nitems\\duricons.cel\r\nitems\\fanvil.cel\r\nitems\\fbook.cel\r\nitems\\fbow.cel\r\nitems\\fbrain.cel\r\nitems\\fbttle.cel\r\nitems\\fbttlebb.cel\r\nitems\\fbttlebl.cel\r\nitems\\fbttlebr.cel\r\nitems\\fbttleby.cel\r\nitems\\fbttledb.cel\r\nitems\\fbttledy.cel\r\nitems\\fbttleor.cel\r\nitems\\fbttlewh.cel\r\nitems\\fear.cel\r\nitems\\feye.cel\r\nitems\\flazstaf.cel\r\nitems\\fmush.cel\r\nitems\\food.cel\r\nItems\\FPlateAr.cel\r\nitems\\goldflip.cel\r\nItems\\halfps1.cel\r\nitems\\helmut.cel\r\nitems\\innsign.cel\r\nitems\\larmor.cel\r\nitems\\mace.cel\r\nitems\\map\\mapz0000.cel\r\nitems\\map\\mapz0001.cel\r\nitems\\map\\mapz0002.cel\r\nitems\\map\\mapz0003.cel\r\nitems\\map\\mapz0004.cel\r\nitems\\map\\mapz0005.cel\r\nitems\\map\\mapz0006.cel\r\nitems\\map\\mapz0007.cel\r\nitems\\map\\mapz0008.cel\r\nitems\\map\\mapz0009.cel\r\nitems\\map\\mapz0010.cel\r\nitems\\map\\mapz0011.cel\r\nitems\\map\\mapz0012.cel\r\nitems\\map\\mapz0013.cel\r\nitems\\map\\mapz0014.cel\r\nitems\\map\\mapz0015.cel\r\nitems\\map\\mapz0016.cel\r\nitems\\map\\mapz0017.cel\r\nitems\\map\\mapz0018.cel\r\nitems\\map\\mapz0019.cel\r\nitems\\map\\mapz0020.cel\r\nitems\\map\\mapz0021.cel\r\nitems\\map\\mapz0022.cel\r\nitems\\map\\mapz0023.cel\r\nitems\\map\\mapz0024.cel\r\nitems\\map\\mapz0025.cel\r\nitems\\map\\mapz0026.cel\r\nitems\\map\\mapz0027.cel\r\nitems\\map\\mapz0028.cel\r\nitems\\map\\mapz0029.cel\r\nitems\\map\\mapz0030.cel\r\nitems\\map\\mapzdoom.cel\r\nItems\\Map\\MapZtown.cel\r\nItems\\mooses1.cel\r\nitems\\ring.cel\r\nitems\\rock.cel\r\nItems\\runes1.cel\r\nitems\\scroll.cel\r\nitems\\shield.cel\r\nitems\\staff.cel\r\nitems\\swrdflip.cel\r\nItems\\teddys1.cel\r\nitems\\wand.cel\r\nItems\\wholeps1.cel\r\nitems\\wshield.cel\r\nkbk beginner(1).00e\r\nkbk beginner(1).00f\r\nkbk beginner(1).024\r\nkbk beginner(1).028\r\nkbk beginner(1).03a\r\nkbk beginner(1).041\r\nkbk beginner(1).050\r\nkbk beginner(1).05a\r\nkbk beginner(1).066\r\nkbk beginner(1).073\r\nkbk beginner(1).got\r\nkbk game room(1).00f\r\nkbk game room(1).010\r\nkbk game room(1).025\r\nkbk game room(1).029\r\nkbk game room(1).03b\r\nkbk game room(1).042\r\nkbk game room(1).051\r\nkbk game room(1).05b\r\nkbk game room(1).067\r\nkbk game room(1).074\r\nkbk game room(1).got\r\nkbk pro(1).010\r\nkbk pro(1).011\r\nkbk pro(1).026\r\nkbk pro(1).02a\r\nkbk pro(1).03c\r\nkbk pro(1).043\r\nkbk pro(1).052\r\nkbk pro(1).05c\r\nkbk pro(1).068\r\nkbk pro(1).075\r\nkbk pro(1).got\r\nkbk singles(1).011\r\nkbk singles(1).012\r\nkbk singles(1).027\r\nkbk singles(1).02b\r\nkbk singles(1).03d\r\nkbk singles(1).044\r\nkbk singles(1).053\r\nkbk singles(1).05d\r\nkbk singles(1).069\r\nkbk singles(1).076\r\nkbk singles(1).got\r\nkbk team(1).012\r\nkbk team(1).013\r\nkbk team(1).028\r\nkbk team(1).02c\r\nkbk team(1).03e\r\nkbk team(1).045\r\nkbk team(1).054\r\nkbk team(1).05e\r\nkbk team(1).06a\r\nkbk team(1).077\r\nkbk team(1).got\r\nkbk zone(1).013\r\nkbk zone(1).014\r\nkbk zone(1).029\r\nkbk zone(1).02d\r\nkbk zone(1).03f\r\nkbk zone(1).046\r\nkbk zone(1).055\r\nkbk zone(1).05f\r\nkbk zone(1).06b\r\nkbk zone(1).078\r\nkbk zone(1).got\r\nkbk(1).got\r\nladder(1).003\r\nladder(1).004\r\nladder(1).008\r\nladder(1).009\r\nladder(1).00d\r\nladder(1).00e\r\nladder(1).012\r\nladder(1).013\r\nladder(1).015\r\nladder(1).017\r\nladder(1).018\r\nladder(1).02e\r\nladder(1).047\r\nladder(1).060\r\nladder(1).079\r\nladder(1).got\r\nladder(2).004\r\nladder(2).005\r\nladder(2).009\r\nladder(2).00a\r\nladder(2).00e\r\nladder(2).00f\r\nladder(2).013\r\nladder(2).014\r\nladder(2).016\r\nladder(2).018\r\nladder(2).019\r\nladder(2).02f\r\nladder(2).048\r\nladder(2).061\r\nladder(2).07a\r\nladder(2).got\r\nLadder.cnd\r\nladder_2.cnd\r\nladder_3.cnd\r\nladder_4.cnd\r\nlevels\\l1data\\banner1.dun\r\nlevels\\l1data\\banner2.dun\r\nLevels\\L1Data\\L1.amp\r\nlevels\\l1data\\l1.cel\r\nlevels\\l1data\\l1.min\r\nlevels\\l1data\\l1.pal\r\nlevels\\l1data\\l1.sol\r\nlevels\\l1data\\l1.til\r\nlevels\\l1data\\l1_1.pal\r\nlevels\\l1data\\l1_2.pal\r\nlevels\\l1data\\l1_3.pal\r\nlevels\\l1data\\l1_4.pal\r\nlevels\\l1data\\l1_5.pal\r\nlevels\\l1data\\l1s.cel\r\nlevels\\l1data\\lv1mazea.dun\r\nlevels\\l1data\\lv1mazeb.dun\r\nlevels\\l1data\\rnd1.dun\r\nlevels\\l1data\\rnd2.dun\r\nlevels\\l1data\\rnd3.dun\r\nlevels\\l1data\\rnd4.dun\r\nlevels\\l1data\\rnd5.dun\r\nlevels\\l1data\\rnd6.dun\r\nlevels\\l1data\\sklkng1.dun\r\nlevels\\l1data\\sklkng2.dun\r\nlevels\\l1data\\skngdo.dun\r\nlevels\\l1data\\vile1.dun\r\nlevels\\l1data\\vile2.dun\r\nlevels\\l2data\\blind1.dun\r\nlevels\\l2data\\blind2.dun\r\nlevels\\l2data\\blood1.dun\r\nlevels\\l2data\\blood2.dun\r\nLevels\\L2Data\\Bonecha1.dun\r\nlevels\\l2data\\bonecha2.dun\r\nlevels\\l2data\\bonestr1.dun\r\nLevels\\L2Data\\Bonestr2.dun\r\nlevels\\l2data\\l2.amp\r\nlevels\\l2data\\l2.cel\r\nlevels\\l2data\\l2.min\r\nlevels\\l2data\\l2.pal\r\nlevels\\l2data\\l2.sol\r\nlevels\\l2data\\l2.til\r\nlevels\\l2data\\l2_1.pal\r\nlevels\\l2data\\l2_2.pal\r\nlevels\\l2data\\l2_3.pal\r\nlevels\\l2data\\l2_4.pal\r\nlevels\\l2data\\l2_5.pal\r\nlevels\\l2data\\l2s.cel\r\nlevels\\l3data\\anvil.dun\r\nlevels\\l3data\\foulwatr.dun\r\nlevels\\l3data\\l3.amp\r\nlevels\\l3data\\l3.cel\r\nlevels\\l3data\\l3.min\r\nlevels\\l3data\\l3.pal\r\nlevels\\l3data\\l3.sol\r\nlevels\\l3data\\l3.til\r\nlevels\\l3data\\l3_1.pal\r\nlevels\\l3data\\l3_2.pal\r\nlevels\\l3data\\l3_3.pal\r\nlevels\\l3data\\l3_4.pal\r\nlevels\\l3data\\l3pfoul.pal\r\nlevels\\l3data\\l3pwater.pal\r\nlevels\\l4data\\diab1.dun\r\nlevels\\l4data\\diab2a.dun\r\nlevels\\l4data\\diab2b.dun\r\nlevels\\l4data\\diab3a.dun\r\nlevels\\l4data\\diab3b.dun\r\nlevels\\l4data\\diab4a.dun\r\nlevels\\l4data\\diab4b.dun\r\nLevels\\L4Data\\L4.amp\r\nlevels\\l4data\\l4.cel\r\nlevels\\l4data\\l4.min\r\nLevels\\L4Data\\L4.SOL\r\nlevels\\l4data\\l4.til\r\nlevels\\l4data\\l4_1.pal\r\nlevels\\l4data\\l4_2.pal\r\nlevels\\l4data\\l4_3.pal\r\nlevels\\l4data\\l4_4.pal\r\nlevels\\l4data\\vile1.dun\r\nlevels\\l4data\\warlord.dun\r\nlevels\\l4data\\warlord2.dun\r\nlevels\\towndata\\sector1s.dun\r\nlevels\\towndata\\sector2s.dun\r\nlevels\\towndata\\sector3s.dun\r\nlevels\\towndata\\sector4s.dun\r\nlevels\\towndata\\town.cel\r\nlevels\\towndata\\town.min\r\nlevels\\towndata\\town.pal\r\nlevels\\towndata\\town.sol\r\nlevels\\towndata\\town.til\r\nlevels\\towndata\\towns.cel\r\nLicense.html\r\nlicense.txt\r\nlocal.dll\r\nmacfiles\\broodwar\\df.bwbanner.jpg\r\nmacfiles\\broodwar\\df.corsairface.jpg\r\nmacfiles\\broodwar\\df.corsairfull.jpg\r\nmacfiles\\broodwar\\df.corsairunit.jpg\r\nmacfiles\\broodwar\\df.darchonface.jpg\r\nmacfiles\\broodwar\\df.darchonfull.jpg\r\nmacfiles\\broodwar\\df.darchonunit.jpg\r\nmacfiles\\broodwar\\df.devourerface.jpg\r\nmacfiles\\broodwar\\df.devourerfull.jpg\r\nmacfiles\\broodwar\\df.devourerunit.jpg\r\nmacfiles\\broodwar\\df.dtemplarface.jpg\r\nmacfiles\\broodwar\\df.dtemplarunit.jpg\r\nmacfiles\\broodwar\\df.lurkerface.jpg\r\nmacfiles\\broodwar\\df.lurkerfull.jpg\r\nmacfiles\\broodwar\\df.lurkerunit.jpg\r\nmacfiles\\broodwar\\df.medicface.jpg\r\nmacfiles\\broodwar\\df.medicfull.jpg\r\nmacfiles\\broodwar\\df.medicunit.jpg\r\nmacfiles\\broodwar\\df.valkyrieface.jpg\r\nmacfiles\\broodwar\\df.valkyriefull.jpg\r\nmacfiles\\broodwar\\df.valkyrieunit.jpg\r\nmacfiles\\broodwar\\df.zeratulfull.jpg\r\nmacfiles\\broodwar\\rf.bwbanner.jpg\r\nmacfiles\\broodwar\\rf.lurkerfull.jpg\r\nmacfiles\\df.battle.net\r\nmacfiles\\df.bnupdate\r\nmacfiles\\df.brood war read me\r\nmacfiles\\df.brood war units.html\r\nmacfiles\\df.drawsprocketlib\r\nmacfiles\\df.editlocal\r\nmacfiles\\df.inputsprocket ch\r\nmacfiles\\df.inputsprocket ch trackball\r\nmacfiles\\df.inputsprocket contour\r\nmacfiles\\df.inputsprocket gravis\r\nmacfiles\\df.inputsprocket kensington\r\nmacfiles\\df.inputsprocket keyboard\r\nmacfiles\\df.inputsprocket macally\r\nmacfiles\\df.inputsprocket microspeed\r\nmacfiles\\df.inputsprocket mouse\r\nmacfiles\\df.inputsprocket nohandsmouse\r\nmacfiles\\df.inputsprocket sidewinder 3d\r\nmacfiles\\df.inputsprocket speech\r\nmacfiles\\df.inputsprocket thrustmaster\r\nmacfiles\\df.inputsprocket usb\r\nmacfiles\\df.inputsprocketlib\r\nmacfiles\\df.license\r\nmacfiles\\df.local\r\nmacfiles\\df.macipx\r\nmacfiles\\df.macipx appletalk\r\nmacfiles\\df.macipx ethernet\r\nmacfiles\\df.macipx token ring\r\nmacfiles\\df.seditenu\r\nmacfiles\\df.standard\r\nmacfiles\\df.starcraft\r\nmacfiles\\df.starcraft mac data\r\nmacfiles\\df.starcraft read me\r\nmacfiles\\df.staredit\r\nmacfiles\\df.staredit help\r\nmacfiles\\df.storm\r\nmacfiles\\df.usbhiduniversalmodule\r\nmacfiles\\help\\df.basics.html\r\nmacfiles\\help\\df.black.jpg\r\nmacfiles\\help\\df.contact.html\r\nmacfiles\\help\\df.editing.html\r\nmacfiles\\help\\df.eula.html\r\nmacfiles\\help\\df.file.html\r\nmacfiles\\help\\df.globalsettings.html\r\nmacfiles\\help\\df.index.html\r\nmacfiles\\help\\df.keyboard.html\r\nmacfiles\\help\\df.misc.html\r\nmacfiles\\help\\df.overview.html\r\nmacfiles\\help\\df.playersettings.html\r\nmacfiles\\help\\df.sccampaignhelp70.jpg\r\nmacfiles\\help\\df.scenario.html\r\nmacfiles\\help\\df.triggers.html\r\nmacfiles\\help\\df.tutorials.html\r\nmacfiles\\rf.battle.net\r\nmacfiles\\rf.bnupdate\r\nmacfiles\\rf.brood war read me\r\nmacfiles\\rf.drawsprocketlib\r\nmacfiles\\rf.editlocal\r\nmacfiles\\rf.inputsprocket ch\r\nmacfiles\\rf.inputsprocket ch trackball\r\nmacfiles\\rf.inputsprocket contour\r\nmacfiles\\rf.inputsprocket gravis\r\nmacfiles\\rf.inputsprocket kensington\r\nmacfiles\\rf.inputsprocket keyboard\r\nmacfiles\\rf.inputsprocket macally\r\nmacfiles\\rf.inputsprocket microspeed\r\nmacfiles\\rf.inputsprocket mouse\r\nmacfiles\\rf.inputsprocket nohandsmouse\r\nmacfiles\\rf.inputsprocket sidewinder 3d\r\nmacfiles\\rf.inputsprocket speech\r\nmacfiles\\rf.inputsprocket thrustmaster\r\nmacfiles\\rf.inputsprocket usb\r\nmacfiles\\rf.inputsprocketlib\r\nmacfiles\\rf.license\r\nmacfiles\\rf.local\r\nmacfiles\\rf.macipx\r\nmacfiles\\rf.macipx appletalk\r\nmacfiles\\rf.macipx ethernet\r\nmacfiles\\rf.macipx token ring\r\nmacfiles\\rf.seditenu\r\nmacfiles\\rf.standard\r\nmacfiles\\rf.starcraft\r\nmacfiles\\rf.starcraft read me\r\nmacfiles\\rf.staredit\r\nmacfiles\\rf.storm\r\nmacfiles\\rf.usbhiduniversalmodule\r\nmacfilesb\\df.starcraft\r\nmacfilesb\\df.starcraft read me\r\nmacfilesb\\df.storm\r\nmacfilesb\\rf.starcraft\r\nmacfilesb\\rf.starcraft read me\r\nmacfilesb\\rf.storm\r\nmapdata.dat\r\nmapdata.tbl\r\nmaps\\128x128_ash4.scm\r\nmaps\\128x128_space4.scm\r\nmaps\\128x128_wasteland4.scm\r\nmaps\\96x96_ash4.scm\r\nmaps\\96x96_space4.scm\r\nmaps\\96x96_wasteland4.scm\r\nMiniMapPreview.bin\r\nMissiles\\Acidbf.cl2\r\nmissiles\\acidbf1.cl2\r\nmissiles\\acidbf10.cl2\r\nmissiles\\acidbf11.cl2\r\nmissiles\\acidbf12.cl2\r\nmissiles\\acidbf13.cl2\r\nmissiles\\acidbf14.cl2\r\nmissiles\\acidbf15.cl2\r\nmissiles\\acidbf16.cl2\r\nmissiles\\acidbf2.cl2\r\nmissiles\\acidbf3.cl2\r\nmissiles\\acidbf4.cl2\r\nmissiles\\acidbf5.cl2\r\nmissiles\\acidbf6.cl2\r\nmissiles\\acidbf7.cl2\r\nmissiles\\acidbf8.cl2\r\nmissiles\\acidbf9.cl2\r\nMissiles\\Acidpud.cl2\r\nmissiles\\acidpud1.cl2\r\nmissiles\\acidpud2.cl2\r\nmissiles\\acidspla.cl2\r\nmissiles\\arrows.cl2\r\nmissiles\\bigexp.cl2\r\nMissiles\\Blodbur.cl2\r\nmissiles\\blodbur1.cl2\r\nmissiles\\blodbur2.cl2\r\nMissiles\\Blood.cl2\r\nmissiles\\blood1.cl2\r\nmissiles\\blood2.cl2\r\nmissiles\\blood3.cl2\r\nmissiles\\blood4.cl2\r\nmissiles\\bluexbk.cl2\r\nmissiles\\bluexfr.cl2\r\nMissiles\\Bone.cl2\r\nmissiles\\bone1.cl2\r\nmissiles\\bone2.cl2\r\nmissiles\\bone3.cl2\r\nMissiles\\Doom.cl2\r\nmissiles\\doom1.cl2\r\nmissiles\\doom2.cl2\r\nmissiles\\doom3.cl2\r\nmissiles\\doom4.cl2\r\nmissiles\\doom5.cl2\r\nmissiles\\doom6.cl2\r\nmissiles\\doom7.cl2\r\nmissiles\\doom8.cl2\r\nmissiles\\doom9.cl2\r\nmissiles\\ethrshld.cl2\r\nMissiles\\ex_blu2.cl2\r\nMissiles\\ex_blu3.cl2\r\nMissiles\\ex_ora1.cl2\r\nMissiles\\ex_red3.cl2\r\nMissiles\\ex_yel2.cl2\r\nMissiles\\Farrow.cl2\r\nmissiles\\farrow1.cl2\r\nmissiles\\farrow10.cl2\r\nmissiles\\farrow11.cl2\r\nmissiles\\farrow12.cl2\r\nmissiles\\farrow13.cl2\r\nmissiles\\farrow14.cl2\r\nmissiles\\farrow15.cl2\r\nmissiles\\farrow16.cl2\r\nmissiles\\farrow2.cl2\r\nmissiles\\farrow3.cl2\r\nmissiles\\farrow4.cl2\r\nmissiles\\farrow5.cl2\r\nmissiles\\farrow6.cl2\r\nmissiles\\farrow7.cl2\r\nmissiles\\farrow8.cl2\r\nmissiles\\farrow9.cl2\r\nmissiles\\firarwex.cl2\r\nMissiles\\Fireba.cl2\r\nmissiles\\fireba1.cl2\r\nmissiles\\fireba10.cl2\r\nmissiles\\fireba11.cl2\r\nmissiles\\fireba12.cl2\r\nmissiles\\fireba13.cl2\r\nmissiles\\fireba14.cl2\r\nmissiles\\fireba15.cl2\r\nmissiles\\fireba16.cl2\r\nmissiles\\fireba2.cl2\r\nmissiles\\fireba3.cl2\r\nmissiles\\fireba4.cl2\r\nmissiles\\fireba5.cl2\r\nmissiles\\fireba6.cl2\r\nmissiles\\fireba7.cl2\r\nmissiles\\fireba8.cl2\r\nmissiles\\fireba9.cl2\r\nMissiles\\Fireplar.cl2\r\nMissiles\\Firerun.cl2\r\nmissiles\\firerun1.cl2\r\nmissiles\\firerun2.cl2\r\nmissiles\\firerun3.cl2\r\nmissiles\\firerun4.cl2\r\nmissiles\\firerun5.cl2\r\nmissiles\\firerun6.cl2\r\nmissiles\\firerun7.cl2\r\nmissiles\\firerun8.cl2\r\nMissiles\\Firewal.cl2\r\nmissiles\\firewal1.cl2\r\nmissiles\\firewal2.cl2\r\nmissiles\\flamel1.cel\r\nmissiles\\flamel10.cel\r\nmissiles\\flamel11.cel\r\nmissiles\\flamel12.cel\r\nmissiles\\flamel13.cel\r\nmissiles\\flamel14.cel\r\nmissiles\\flamel15.cel\r\nmissiles\\flamel16.cel\r\nmissiles\\flamel2.cel\r\nmissiles\\flamel3.cel\r\nmissiles\\flamel4.cel\r\nmissiles\\flamel5.cel\r\nmissiles\\flamel6.cel\r\nmissiles\\flamel7.cel\r\nmissiles\\flamel8.cel\r\nmissiles\\flamel9.cel\r\nmissiles\\flames1.cel\r\nmissiles\\flames10.cel\r\nmissiles\\flames11.cel\r\nmissiles\\flames12.cel\r\nmissiles\\flames13.cel\r\nmissiles\\flames14.cel\r\nmissiles\\flames15.cel\r\nmissiles\\flames16.cel\r\nmissiles\\flames2.cel\r\nmissiles\\flames3.cel\r\nmissiles\\flames4.cel\r\nmissiles\\flames5.cel\r\nmissiles\\flames6.cel\r\nmissiles\\flames7.cel\r\nmissiles\\flames8.cel\r\nmissiles\\flames9.cel\r\nmissiles\\flare.cl2\r\nmissiles\\flareexp.cl2\r\nMissiles\\Guard.cl2\r\nmissiles\\guard1.cl2\r\nmissiles\\guard2.cl2\r\nmissiles\\guard3.cl2\r\nmissiles\\holy1.cl2\r\nmissiles\\holy10.cl2\r\nmissiles\\holy11.cl2\r\nmissiles\\holy12.cl2\r\nmissiles\\holy13.cl2\r\nmissiles\\holy14.cl2\r\nmissiles\\holy15.cl2\r\nmissiles\\holy16.cl2\r\nmissiles\\holy2.cl2\r\nmissiles\\holy3.cl2\r\nmissiles\\holy4.cl2\r\nmissiles\\holy5.cl2\r\nmissiles\\holy6.cl2\r\nmissiles\\holy7.cl2\r\nmissiles\\holy8.cl2\r\nmissiles\\holy9.cl2\r\nmissiles\\holyexpl.cl2\r\nmissiles\\inferno.cl2\r\nmissiles\\krull.cl2\r\nMissiles\\Larrow.cl2\r\nmissiles\\larrow1.cl2\r\nmissiles\\larrow10.cl2\r\nmissiles\\larrow11.cl2\r\nmissiles\\larrow12.cl2\r\nmissiles\\larrow13.cl2\r\nmissiles\\larrow14.cl2\r\nmissiles\\larrow15.cl2\r\nmissiles\\larrow16.cl2\r\nmissiles\\larrow2.cl2\r\nmissiles\\larrow3.cl2\r\nmissiles\\larrow4.cl2\r\nmissiles\\larrow5.cl2\r\nmissiles\\larrow6.cl2\r\nmissiles\\larrow7.cl2\r\nmissiles\\larrow8.cl2\r\nmissiles\\larrow9.cl2\r\nmissiles\\lghning.cl2\r\nMissiles\\Magball.cl2\r\nmissiles\\magball1.cl2\r\nmissiles\\magball2.cl2\r\nmissiles\\magball3.cl2\r\nmissiles\\magball4.cl2\r\nmissiles\\magball5.cl2\r\nmissiles\\magball6.cl2\r\nmissiles\\magball7.cl2\r\nmissiles\\magball8.cl2\r\nmissiles\\magblos.cl2\r\nmissiles\\manashld.cl2\r\nMissiles\\Metlhit.cl2\r\nmissiles\\metlhit1.cl2\r\nmissiles\\metlhit2.cl2\r\nmissiles\\metlhit3.cl2\r\nmissiles\\miniltng.cl2\r\nMissiles\\ms_bla.cl2\r\nMissiles\\ms_blb.cl2\r\nMissiles\\ms_ora.cl2\r\nMissiles\\ms_reb.cl2\r\nMissiles\\ms_yeb.cl2\r\nmissiles\\newexp.cl2\r\nMissiles\\Portal.cl2\r\nmissiles\\portal1.cl2\r\nmissiles\\portal2.cl2\r\nMissiles\\reflect.cl2\r\nmissiles\\ressur1.cl2\r\nMissiles\\rglows1.cl2\r\nMissiles\\Rportal.cl2\r\nmissiles\\rportal1.cl2\r\nmissiles\\rportal2.cl2\r\nmissiles\\scbsexpb.cl2\r\nMissiles\\Scbsexpc.cl2\r\nMissiles\\Scbsexpd.cl2\r\nmissiles\\scubmisb.cl2\r\nMissiles\\Scubmisc.cl2\r\nMissiles\\Scubmisd.cl2\r\nmissiles\\shatter1.cl2\r\nMissiles\\Sklball.cl2\r\nmissiles\\sklball1.cl2\r\nmissiles\\sklball2.cl2\r\nmissiles\\sklball3.cl2\r\nmissiles\\sklball4.cl2\r\nmissiles\\sklball5.cl2\r\nmissiles\\sklball6.cl2\r\nmissiles\\sklball7.cl2\r\nmissiles\\sklball8.cl2\r\nmissiles\\sklball9.cl2\r\nMissiles\\spawns.cl2\r\nmissiles\\thinlght.cl2\r\nmodem.doc\r\nmonsters\\acid\\acida.cl2\r\nmonsters\\acid\\acida1.wav\r\nmonsters\\acid\\acida2.wav\r\nmonsters\\acid\\acidb.trn\r\nmonsters\\acid\\acidblk.trn\r\nmonsters\\acid\\acidd.cl2\r\nmonsters\\acid\\acidd1.wav\r\nmonsters\\acid\\acidd2.wav\r\nmonsters\\acid\\acidh.cl2\r\nmonsters\\acid\\acidh1.wav\r\nmonsters\\acid\\acidh2.wav\r\nmonsters\\acid\\acidn.cl2\r\nmonsters\\acid\\acidr.trn\r\nmonsters\\acid\\acids.cl2\r\nmonsters\\acid\\acids1.wav\r\nmonsters\\acid\\acids2.wav\r\nmonsters\\acid\\acidw.cl2\r\nMonsters\\AntWorm\\Worma.cl2\r\nMonsters\\AntWorm\\Wormd.cl2\r\nMonsters\\AntWorm\\Wormh.cl2\r\nMonsters\\AntWorm\\Wormn.cl2\r\nMonsters\\AntWorm\\Wormw.cl2\r\nmonsters\\bat\\bata.cl2\r\nmonsters\\bat\\bata1.wav\r\nmonsters\\bat\\bata2.wav\r\nmonsters\\bat\\batd.cl2\r\nmonsters\\bat\\batd1.wav\r\nmonsters\\bat\\batd2.wav\r\nmonsters\\bat\\bath.cl2\r\nmonsters\\bat\\bath1.wav\r\nmonsters\\bat\\bath2.wav\r\nmonsters\\bat\\batn.cl2\r\nmonsters\\bat\\bats1.wav\r\nmonsters\\bat\\bats2.wav\r\nmonsters\\bat\\batw.cl2\r\nmonsters\\bat\\grey.trn\r\nmonsters\\bat\\orange.trn\r\nmonsters\\bat\\red.trn\r\nmonsters\\bigfall\\bfala.cl2\r\nmonsters\\bigfall\\bfala1.wav\r\nmonsters\\bigfall\\bfala2.wav\r\nmonsters\\bigfall\\bfald.cl2\r\nmonsters\\bigfall\\bfald1.wav\r\nmonsters\\bigfall\\bfald2.wav\r\nmonsters\\bigfall\\bfalh1.wav\r\nmonsters\\bigfall\\bfalh2.wav\r\nmonsters\\bigfall\\bfals1.wav\r\nmonsters\\bigfall\\bfals2.wav\r\nmonsters\\bigfall\\fallga.cl2\r\nmonsters\\bigfall\\fallgd.cl2\r\nmonsters\\bigfall\\fallgh.cl2\r\nmonsters\\bigfall\\fallgn.cl2\r\nmonsters\\bigfall\\fallgw.cl2\r\nmonsters\\black\\blacka.cl2\r\nmonsters\\black\\blacka1.wav\r\nmonsters\\black\\blacka2.wav\r\nmonsters\\black\\blackd.cl2\r\nmonsters\\black\\blackd1.wav\r\nmonsters\\black\\blackd2.wav\r\nmonsters\\black\\blackh.cl2\r\nmonsters\\black\\blackh1.wav\r\nmonsters\\black\\blackh2.wav\r\nmonsters\\black\\blackn.cl2\r\nmonsters\\black\\blacks1.wav\r\nmonsters\\black\\blacks2.wav\r\nmonsters\\black\\blackw.cl2\r\nmonsters\\black\\blkkntbe.trn\r\nmonsters\\black\\blkkntbt.trn\r\nmonsters\\black\\blkkntrt.trn\r\nMonsters\\bSpidr\\bSpidra.cl2\r\nMonsters\\bSpidr\\bSpidrd.cl2\r\nMonsters\\bSpidr\\bSpidrh.cl2\r\nMonsters\\bSpidr\\bSpidrn.cl2\r\nMonsters\\bSpidr\\bSpidrs.cl2\r\nMonsters\\bSpidr\\bSpidrw.cl2\r\nMonsters\\Bubba\\Bubbaa.cl2\r\nMonsters\\Bubba\\Bubbad.cl2\r\nMonsters\\Bubba\\Bubbah.cl2\r\nMonsters\\Bubba\\Bubban.cl2\r\nMonsters\\Bubba\\Bubbaw.cl2\r\nMonsters\\Byclps\\Byclpsa.cl2\r\nMonsters\\Byclps\\Byclpsd.cl2\r\nMonsters\\Byclps\\Byclpsh.cl2\r\nMonsters\\Byclps\\Byclpsn.cl2\r\nMonsters\\Byclps\\Byclpsw.cl2\r\nMonsters\\Clasp\\Claspa.cl2\r\nMonsters\\Clasp\\Claspd.cl2\r\nMonsters\\Clasp\\Clasph.cl2\r\nMonsters\\Clasp\\Claspn.cl2\r\nMonsters\\Clasp\\Claspw.cl2\r\nmonsters\\darkmage\\dmaga1.wav\r\nmonsters\\darkmage\\dmaga2.wav\r\nmonsters\\darkmage\\dmagd1.wav\r\nmonsters\\darkmage\\dmagd2.wav\r\nmonsters\\darkmage\\dmagea.cl2\r\nmonsters\\darkmage\\dmaged.cl2\r\nmonsters\\darkmage\\dmageh.cl2\r\nmonsters\\darkmage\\dmagen.cl2\r\nmonsters\\darkmage\\dmages.cl2\r\nmonsters\\darkmage\\dmagew.cl2\r\nmonsters\\darkmage\\dmagh1.wav\r\nmonsters\\darkmage\\dmagh2.wav\r\nmonsters\\darkmage\\dmags1.wav\r\nmonsters\\darkmage\\dmags2.wav\r\nmonsters\\demskel\\demskla.cl2\r\nmonsters\\demskel\\demskld.cl2\r\nmonsters\\demskel\\demsklh.cl2\r\nmonsters\\demskel\\demskln.cl2\r\nmonsters\\demskel\\demskls.cl2\r\nmonsters\\demskel\\demsklw.cl2\r\nmonsters\\diablo\\diabloa.cl2\r\nmonsters\\diablo\\diabloa1.wav\r\nmonsters\\diablo\\diabloa2.wav\r\nmonsters\\diablo\\diablod.cl2\r\nmonsters\\diablo\\diablod1.wav\r\nmonsters\\diablo\\diablod2.wav\r\nmonsters\\diablo\\diabloh.cl2\r\nmonsters\\diablo\\diabloh1.wav\r\nmonsters\\diablo\\diabloh2.wav\r\nmonsters\\diablo\\diablon.cl2\r\nmonsters\\diablo\\diablos.cl2\r\nmonsters\\diablo\\diablos1.wav\r\nmonsters\\diablo\\diablos2.wav\r\nmonsters\\diablo\\diablow.cl2\r\nMonsters\\Eye2\\Eye2a.cl2\r\nMonsters\\Eye2\\Eye2d.cl2\r\nMonsters\\Eye2\\Eye2h.cl2\r\nMonsters\\Eye2\\Eye2n.cl2\r\nMonsters\\Eye2\\Eye2w.cl2\r\nMonsters\\Eye\\Eyea.cl2\r\nMonsters\\Eye\\Eyed.cl2\r\nMonsters\\Eye\\Eyeh.cl2\r\nMonsters\\Eye\\Eyen.cl2\r\nMonsters\\Eye\\Eyew.cl2\r\nmonsters\\falspear\\blue.trn\r\nmonsters\\falspear\\dark.trn\r\nmonsters\\falspear\\fallent.trn\r\nmonsters\\falspear\\phalla.cl2\r\nmonsters\\falspear\\phalla1.wav\r\nmonsters\\falspear\\phalla2.wav\r\nmonsters\\falspear\\phalld.cl2\r\nmonsters\\falspear\\phalld1.wav\r\nmonsters\\falspear\\phalld2.wav\r\nmonsters\\falspear\\phallh.cl2\r\nmonsters\\falspear\\phallh1.wav\r\nmonsters\\falspear\\phallh2.wav\r\nmonsters\\falspear\\phalln.cl2\r\nmonsters\\falspear\\phalls.cl2\r\nmonsters\\falspear\\phalls1.wav\r\nmonsters\\falspear\\phalls2.wav\r\nmonsters\\falspear\\phallw.cl2\r\nmonsters\\falspear\\yellow.trn\r\nmonsters\\falsword\\blue.trn\r\nmonsters\\falsword\\dark.trn\r\nmonsters\\falsword\\falla.cl2\r\nmonsters\\falsword\\falla1.wav\r\nmonsters\\falsword\\falla2.wav\r\nmonsters\\falsword\\falld.cl2\r\nmonsters\\falsword\\falld1.wav\r\nmonsters\\falsword\\falld2.wav\r\nmonsters\\falsword\\fallent.trn\r\nmonsters\\falsword\\fallh.cl2\r\nmonsters\\falsword\\fallh1.wav\r\nmonsters\\falsword\\fallh2.wav\r\nmonsters\\falsword\\falln.cl2\r\nmonsters\\falsword\\falls.cl2\r\nmonsters\\falsword\\falls1.wav\r\nmonsters\\falsword\\falls2.wav\r\nmonsters\\falsword\\fallw.cl2\r\nmonsters\\falsword\\yellow.trn\r\nmonsters\\fat\\blue.trn\r\nmonsters\\fat\\fata.cl2\r\nmonsters\\fat\\fata1.wav\r\nmonsters\\fat\\fata2.wav\r\nmonsters\\fat\\fatb.trn\r\nmonsters\\fat\\fatd.cl2\r\nmonsters\\fat\\fatd1.wav\r\nmonsters\\fat\\fatd2.wav\r\nmonsters\\fat\\fatf.trn\r\nmonsters\\fat\\fath.cl2\r\nmonsters\\fat\\fath1.wav\r\nmonsters\\fat\\fath2.wav\r\nmonsters\\fat\\fatn.cl2\r\nmonsters\\fat\\fats.cl2\r\nmonsters\\fat\\fats1.wav\r\nmonsters\\fat\\fats2.wav\r\nmonsters\\fat\\fatw.cl2\r\nmonsters\\fatc\\fatca.cl2\r\nmonsters\\fatc\\fatca1.wav\r\nmonsters\\fatc\\fatca2.wav\r\nmonsters\\fatc\\fatcd.cl2\r\nmonsters\\fatc\\fatcd1.wav\r\nmonsters\\fatc\\fatcd2.wav\r\nmonsters\\fatc\\fatch.cl2\r\nmonsters\\fatc\\fatch1.wav\r\nmonsters\\fatc\\fatch2.wav\r\nmonsters\\fatc\\fatcn.cl2\r\nmonsters\\fatc\\fatcs1.wav\r\nmonsters\\fatc\\fatcs2.wav\r\nmonsters\\fatc\\fatcw.cl2\r\nmonsters\\fireman\\firema.cl2\r\nmonsters\\fireman\\firemd.cl2\r\nmonsters\\fireman\\firemh.cl2\r\nmonsters\\fireman\\firemn.cl2\r\nmonsters\\fireman\\firems.cl2\r\nmonsters\\fireman\\firemw.cl2\r\nMonsters\\Flesh\\Flesha.cl2\r\nMonsters\\Flesh\\Fleshd.cl2\r\nMonsters\\Flesh\\Fleshh.cl2\r\nMonsters\\Flesh\\Fleshn.cl2\r\nMonsters\\Flesh\\Fleshw.cl2\r\nMonsters\\Fork\\Forka.cl2\r\nMonsters\\Fork\\Forkd.cl2\r\nMonsters\\Fork\\Forkh.cl2\r\nMonsters\\Fork\\Forkn.cl2\r\nMonsters\\Fork\\Forkw.cl2\r\nmonsters\\gargoyle\\gare.trn\r\nmonsters\\gargoyle\\gargb.trn\r\nmonsters\\gargoyle\\gargbr.trn\r\nmonsters\\gargoyle\\gargoa.cl2\r\nmonsters\\gargoyle\\gargoa1.wav\r\nmonsters\\gargoyle\\gargoa2.wav\r\nmonsters\\gargoyle\\gargod.cl2\r\nmonsters\\gargoyle\\gargod1.wav\r\nmonsters\\gargoyle\\gargod2.wav\r\nmonsters\\gargoyle\\gargoh.cl2\r\nmonsters\\gargoyle\\gargoh1.wav\r\nmonsters\\gargoyle\\gargoh2.wav\r\nmonsters\\gargoyle\\gargon.cl2\r\nmonsters\\gargoyle\\gargos.cl2\r\nmonsters\\gargoyle\\gargos1.wav\r\nmonsters\\gargoyle\\gargos2.wav\r\nmonsters\\gargoyle\\gargow.cl2\r\nmonsters\\goatbow\\beige.trn\r\nmonsters\\goatbow\\goatba.cl2\r\nmonsters\\goatbow\\goatba1.wav\r\nmonsters\\goatbow\\goatba2.wav\r\nmonsters\\goatbow\\goatbd.cl2\r\nmonsters\\goatbow\\goatbd1.wav\r\nmonsters\\goatbow\\goatbd2.wav\r\nmonsters\\goatbow\\goatbh.cl2\r\nmonsters\\goatbow\\goatbh1.wav\r\nmonsters\\goatbow\\goatbh2.wav\r\nmonsters\\goatbow\\goatbn.cl2\r\nmonsters\\goatbow\\goatbs1.wav\r\nmonsters\\goatbow\\goatbs2.wav\r\nmonsters\\goatbow\\goatbw.cl2\r\nmonsters\\goatbow\\gray.trn\r\nmonsters\\goatbow\\red.trn\r\nmonsters\\goatlord\\goatla.cl2\r\nmonsters\\goatlord\\goatla1.wav\r\nmonsters\\goatlord\\goatla2.wav\r\nmonsters\\goatlord\\goatld.cl2\r\nmonsters\\goatlord\\goatld1.wav\r\nmonsters\\goatlord\\goatld2.wav\r\nmonsters\\goatlord\\goatlh.cl2\r\nmonsters\\goatlord\\goatlh1.wav\r\nmonsters\\goatlord\\goatlh2.wav\r\nmonsters\\goatlord\\goatln.cl2\r\nmonsters\\goatlord\\goatlw.cl2\r\nmonsters\\goatmace\\beige.trn\r\nmonsters\\goatmace\\goata.cl2\r\nmonsters\\goatmace\\goata1.wav\r\nmonsters\\goatmace\\goata2.wav\r\nmonsters\\goatmace\\goatd.cl2\r\nmonsters\\goatmace\\goatd1.wav\r\nmonsters\\goatmace\\goatd2.wav\r\nmonsters\\goatmace\\goath.cl2\r\nmonsters\\goatmace\\goath1.wav\r\nmonsters\\goatmace\\goath2.wav\r\nmonsters\\goatmace\\goatn.cl2\r\nmonsters\\goatmace\\goats.cl2\r\nmonsters\\goatmace\\goats1.wav\r\nmonsters\\goatmace\\goats2.wav\r\nmonsters\\goatmace\\goatw.cl2\r\nmonsters\\goatmace\\gray.trn\r\nmonsters\\goatmace\\red.trn\r\nmonsters\\golem\\golema.cl2\r\nmonsters\\golem\\golemd.cl2\r\nmonsters\\golem\\golems.cl2\r\nmonsters\\golem\\golemw.cl2\r\nmonsters\\golem\\golma1.wav\r\nmonsters\\golem\\golma2.wav\r\nmonsters\\golem\\golmd1.wav\r\nmonsters\\golem\\golmd2.wav\r\nmonsters\\golem\\golmh1.wav\r\nmonsters\\golem\\golmh2.wav\r\nMonsters\\Gravdg\\Gravdga.cl2\r\nMonsters\\Gravdg\\Gravdgd.cl2\r\nMonsters\\Gravdg\\Gravdgh.cl2\r\nMonsters\\Gravdg\\Gravdgn.cl2\r\nMonsters\\Gravdg\\Gravdgs.cl2\r\nMonsters\\Gravdg\\Gravdgw.cl2\r\nMonsters\\Hellbat2\\bhelbta.cl2\r\nMonsters\\Hellbat2\\bhelbtd.cl2\r\nMonsters\\Hellbat2\\bhelbth.cl2\r\nMonsters\\Hellbat2\\bhelbtn.cl2\r\nMonsters\\Hellbat2\\bhelbts.cl2\r\nMonsters\\Hellbat2\\bhelbtw.cl2\r\nMonsters\\Hellbat\\Helbata.cl2\r\nMonsters\\Hellbat\\Helbatd.cl2\r\nMonsters\\Hellbat\\Helbath.cl2\r\nMonsters\\Hellbat\\Helbatn.cl2\r\nMonsters\\Hellbat\\Helbats.cl2\r\nMonsters\\Hellbat\\Helbatw.cl2\r\nMonsters\\Hellbug\\Hellbga.cl2\r\nMonsters\\Hellbug\\Hellbgd.cl2\r\nMonsters\\Hellbug\\Hellbgh.cl2\r\nMonsters\\Hellbug\\Hellbgn.cl2\r\nMonsters\\Hellbug\\Hellbgs.cl2\r\nMonsters\\Hellbug\\Hellbgw.cl2\r\nMonsters\\HorkD\\HorkDa.cl2\r\nMonsters\\HorkD\\HorkDd.cl2\r\nMonsters\\HorkD\\HorkDh.cl2\r\nMonsters\\HorkD\\HorkDn.cl2\r\nMonsters\\HorkD\\HorkDs.cl2\r\nMonsters\\HorkD\\HorkDw.cl2\r\nMonsters\\Lich2\\Lich2a.cl2\r\nMonsters\\Lich2\\Lich2d.cl2\r\nMonsters\\Lich2\\Lich2h.cl2\r\nMonsters\\Lich2\\Lich2n.cl2\r\nMonsters\\Lich2\\Lich2w.cl2\r\nMonsters\\Lich\\Licha.cl2\r\nMonsters\\Lich\\Lichd.cl2\r\nMonsters\\Lich\\Lichh.cl2\r\nMonsters\\Lich\\Lichn.cl2\r\nMonsters\\Lich\\Lichw.cl2\r\nmonsters\\mage\\cnselbk.trn\r\nmonsters\\mage\\cnselg.trn\r\nmonsters\\mage\\cnselgd.trn\r\nmonsters\\mage\\magea.cl2\r\nmonsters\\mage\\magea1.wav\r\nmonsters\\mage\\magea2.wav\r\nmonsters\\mage\\maged.cl2\r\nmonsters\\mage\\maged1.wav\r\nmonsters\\mage\\maged2.wav\r\nmonsters\\mage\\mageh.cl2\r\nmonsters\\mage\\mageh1.wav\r\nmonsters\\mage\\mageh2.wav\r\nmonsters\\mage\\magen.cl2\r\nmonsters\\mage\\mages.cl2\r\nmonsters\\mage\\mages1.wav\r\nmonsters\\mage\\mages2.wav\r\nmonsters\\mage\\magew.cl2\r\nmonsters\\magma\\blue.trn\r\nmonsters\\magma\\magmaa.cl2\r\nmonsters\\magma\\magmaa1.wav\r\nmonsters\\magma\\magmaa2.wav\r\nmonsters\\magma\\magmad.cl2\r\nmonsters\\magma\\magmad1.wav\r\nmonsters\\magma\\magmad2.wav\r\nmonsters\\magma\\magmah.cl2\r\nmonsters\\magma\\magmah1.wav\r\nmonsters\\magma\\magmah2.wav\r\nmonsters\\magma\\magman.cl2\r\nmonsters\\magma\\magmas.cl2\r\nmonsters\\magma\\magmas1.wav\r\nmonsters\\magma\\magmas2.wav\r\nmonsters\\magma\\magmaw.cl2\r\nmonsters\\magma\\wierd.trn\r\nmonsters\\magma\\yellow.trn\r\nmonsters\\mega\\balr.trn\r\nmonsters\\mega\\guard.trn\r\nmonsters\\mega\\megaa.cl2\r\nmonsters\\mega\\megaa1.wav\r\nmonsters\\mega\\megaa2.wav\r\nmonsters\\mega\\megad.cl2\r\nmonsters\\mega\\megad1.wav\r\nmonsters\\mega\\megad2.wav\r\nmonsters\\mega\\megah.cl2\r\nmonsters\\mega\\megah1.wav\r\nmonsters\\mega\\megah2.wav\r\nmonsters\\mega\\megan.cl2\r\nmonsters\\mega\\megas.cl2\r\nmonsters\\mega\\megas1.wav\r\nmonsters\\mega\\megas2.wav\r\nmonsters\\mega\\megaw.cl2\r\nmonsters\\mega\\vtexl.trn\r\nmonsters\\monsters\\bashtb.trn\r\nmonsters\\monsters\\bfds.trn\r\nmonsters\\monsters\\bftp.trn\r\nmonsters\\monsters\\bhbs.trn\r\nmonsters\\monsters\\bhka.trn\r\nmonsters\\monsters\\bhsm.trn\r\nmonsters\\monsters\\blkjd.trn\r\nmonsters\\monsters\\bng.trn\r\nmonsters\\monsters\\br.trn\r\nmonsters\\monsters\\bsdb.trn\r\nmonsters\\monsters\\bsts.trn\r\nmonsters\\monsters\\db.trn\r\nmonsters\\monsters\\de.trn\r\nmonsters\\monsters\\dsfm.trn\r\nmonsters\\monsters\\eth.trn\r\nmonsters\\monsters\\general.trn\r\nmonsters\\monsters\\genrl.trn\r\nmonsters\\monsters\\gtq.trn\r\nmonsters\\monsters\\mtd.trn\r\nmonsters\\monsters\\pmr.trn\r\nmonsters\\monsters\\ptu.trn\r\nmonsters\\monsters\\rcrn.trn\r\nmonsters\\monsters\\redv.trn\r\nmonsters\\monsters\\shbt.trn\r\nmonsters\\monsters\\shcr.trn\r\nmonsters\\monsters\\shdr.trn\r\nmonsters\\monsters\\skfr.trn\r\nmonsters\\monsters\\tspo.trn\r\nmonsters\\monsters\\wftd.trn\r\nMonsters\\newsfx\\Biclopa1.wav\r\nMonsters\\newsfx\\Biclopa2.wav\r\nMonsters\\newsfx\\Biclopd1.wav\r\nMonsters\\newsfx\\Biclopd2.wav\r\nMonsters\\newsfx\\Bicloph1.wav\r\nMonsters\\newsfx\\Bicloph2.wav\r\nMonsters\\newsfx\\Crypta1.wav\r\nMonsters\\newsfx\\Crypta2.wav\r\nMonsters\\newsfx\\Cryptd1.wav\r\nMonsters\\newsfx\\Cryptd2.wav\r\nMonsters\\newsfx\\Crypth1.wav\r\nMonsters\\newsfx\\Crypth2.wav\r\nMonsters\\newsfx\\Crypts1.wav\r\nMonsters\\newsfx\\Crypts2.wav\r\nMonsters\\newsfx\\Defilea1.wav\r\nMonsters\\newsfx\\Defilea2.wav\r\nMonsters\\newsfx\\Defiled1.wav\r\nMonsters\\newsfx\\Defiled2.wav\r\nMonsters\\newsfx\\Defileh1.wav\r\nMonsters\\newsfx\\Defileh2.wav\r\nMonsters\\newsfx\\Defiles1.wav\r\nMonsters\\newsfx\\Defiles2.wav\r\nMonsters\\newsfx\\FleshTa1.wav\r\nMonsters\\newsfx\\FleshTa2.wav\r\nMonsters\\newsfx\\FleshTd1.wav\r\nMonsters\\newsfx\\FleshTd2.wav\r\nMonsters\\newsfx\\FleshTh1.wav\r\nMonsters\\newsfx\\FleshTh2.wav\r\nMonsters\\newsfx\\FleshTs1.wav\r\nMonsters\\newsfx\\FleshTs2.wav\r\nMonsters\\newsfx\\FTwina1.wav\r\nMonsters\\newsfx\\FTwina2.wav\r\nMonsters\\newsfx\\FTwind1.wav\r\nMonsters\\newsfx\\FTwind2.wav\r\nMonsters\\newsfx\\FTwinh1.wav\r\nMonsters\\newsfx\\FTwinh2.wav\r\nMonsters\\newsfx\\GDiggra1.wav\r\nMonsters\\newsfx\\GDiggra2.wav\r\nMonsters\\newsfx\\GDiggrd1.wav\r\nMonsters\\newsfx\\GDiggrd2.wav\r\nMonsters\\newsfx\\GDiggrh1.wav\r\nMonsters\\newsfx\\GDiggrh2.wav\r\nMonsters\\newsfx\\GDiggrs1.wav\r\nMonsters\\newsfx\\GDiggrs2.wav\r\nMonsters\\newsfx\\HBoara1.wav\r\nMonsters\\newsfx\\HBoara2.wav\r\nMonsters\\newsfx\\HBoard1.wav\r\nMonsters\\newsfx\\HBoard2.wav\r\nMonsters\\newsfx\\HBoarh1.wav\r\nMonsters\\newsfx\\HBoarh2.wav\r\nMonsters\\newsfx\\HDemona1.wav\r\nMonsters\\newsfx\\HDemona2.wav\r\nMonsters\\newsfx\\HDemond1.wav\r\nMonsters\\newsfx\\HDemond2.wav\r\nMonsters\\newsfx\\HDemonh1.wav\r\nMonsters\\newsfx\\HDemonh2.wav\r\nMonsters\\newsfx\\HDemons1.wav\r\nMonsters\\newsfx\\HDemons2.wav\r\nMonsters\\newsfx\\HelBata1.wav\r\nMonsters\\newsfx\\HelBata2.wav\r\nMonsters\\newsfx\\HelBatd1.wav\r\nMonsters\\newsfx\\HelBatd2.wav\r\nMonsters\\newsfx\\HelBath1.wav\r\nMonsters\\newsfx\\HelBath2.wav\r\nMonsters\\newsfx\\HSpawna1.wav\r\nMonsters\\newsfx\\HSpawna2.wav\r\nMonsters\\newsfx\\HSpawnd1.wav\r\nMonsters\\newsfx\\HSpawnd2.wav\r\nMonsters\\newsfx\\HSpawnh1.wav\r\nMonsters\\newsfx\\HSpawnh2.wav\r\nMonsters\\newsfx\\HSpawns1.wav\r\nMonsters\\newsfx\\HSpawns2.wav\r\nMonsters\\newsfx\\KBrutea1.wav\r\nMonsters\\newsfx\\KBrutea2.wav\r\nMonsters\\newsfx\\KBruted1.wav\r\nMonsters\\newsfx\\KBruted2.wav\r\nMonsters\\newsfx\\KBruteh1.wav\r\nMonsters\\newsfx\\KBruteh2.wav\r\nMonsters\\newsfx\\Licha1.wav\r\nMonsters\\newsfx\\Licha2.wav\r\nMonsters\\newsfx\\Lichd1.wav\r\nMonsters\\newsfx\\Lichd2.wav\r\nMonsters\\newsfx\\Lichh1.wav\r\nMonsters\\newsfx\\Lichh2.wav\r\nMonsters\\newsfx\\Lichs1.wav\r\nMonsters\\newsfx\\Lichs2.wav\r\nMonsters\\newsfx\\Lworma1.wav\r\nMonsters\\newsfx\\Lworma2.wav\r\nMonsters\\newsfx\\Lwormd1.wav\r\nMonsters\\newsfx\\Lwormd2.wav\r\nMonsters\\newsfx\\Lwormh1.wav\r\nMonsters\\newsfx\\Lwormh2.wav\r\nMonsters\\newsfx\\Nakrula1.wav\r\nMonsters\\newsfx\\Nakrula2.wav\r\nMonsters\\newsfx\\Nakruld1.wav\r\nMonsters\\newsfx\\Nakruld2.wav\r\nMonsters\\newsfx\\Nakrulh1.wav\r\nMonsters\\newsfx\\Nakrulh2.wav\r\nMonsters\\newsfx\\Nakruls1.wav\r\nMonsters\\newsfx\\Nakruls2.wav\r\nMonsters\\newsfx\\psycoa1.wav\r\nMonsters\\newsfx\\psycoa2.wav\r\nMonsters\\newsfx\\psycod1.wav\r\nMonsters\\newsfx\\psycod2.wav\r\nMonsters\\newsfx\\psycoh1.wav\r\nMonsters\\newsfx\\psycoh2.wav\r\nMonsters\\newsfx\\Reapera1.wav\r\nMonsters\\newsfx\\Reapera2.wav\r\nMonsters\\newsfx\\Reaperd1.wav\r\nMonsters\\newsfx\\Reaperd2.wav\r\nMonsters\\newsfx\\Reaperh1.wav\r\nMonsters\\newsfx\\Reaperh2.wav\r\nMonsters\\newsfx\\Satyra1.wav\r\nMonsters\\newsfx\\Satyra2.wav\r\nMonsters\\newsfx\\Satyrd1.wav\r\nMonsters\\newsfx\\Satyrd2.wav\r\nMonsters\\newsfx\\Satyrh1.wav\r\nMonsters\\newsfx\\Satyrh2.wav\r\nMonsters\\newsfx\\Shreda1.wav\r\nMonsters\\newsfx\\Shreda2.wav\r\nMonsters\\newsfx\\Shredd1.wav\r\nMonsters\\newsfx\\Shredd2.wav\r\nMonsters\\newsfx\\Shredh1.wav\r\nMonsters\\newsfx\\Shredh2.wav\r\nMonsters\\newsfx\\SLorda1.wav\r\nMonsters\\newsfx\\SLorda2.wav\r\nMonsters\\newsfx\\SLordd1.wav\r\nMonsters\\newsfx\\SLordd2.wav\r\nMonsters\\newsfx\\SLordh1.wav\r\nMonsters\\newsfx\\SLordh2.wav\r\nMonsters\\newsfx\\SLords1.wav\r\nMonsters\\newsfx\\SLords2.wav\r\nMonsters\\newsfx\\Stingra1.wav\r\nMonsters\\newsfx\\Stingra2.wav\r\nMonsters\\newsfx\\Stingrd1.wav\r\nMonsters\\newsfx\\Stingrd2.wav\r\nMonsters\\newsfx\\Stingrh1.wav\r\nMonsters\\newsfx\\Stingrh2.wav\r\nMonsters\\newsfx\\SWinga1.wav\r\nMonsters\\newsfx\\SWinga2.wav\r\nMonsters\\newsfx\\SWingd1.wav\r\nMonsters\\newsfx\\SWingd2.wav\r\nMonsters\\newsfx\\SWingh1.wav\r\nMonsters\\newsfx\\SWingh2.wav\r\nMonsters\\newsfx\\SWings1.wav\r\nMonsters\\newsfx\\SWings2.wav\r\nMonsters\\newsfx\\TchAnta1.wav\r\nMonsters\\newsfx\\TchAnta2.wav\r\nMonsters\\newsfx\\TchAntd1.wav\r\nMonsters\\newsfx\\TchAntd2.wav\r\nMonsters\\newsfx\\TchAnth1.wav\r\nMonsters\\newsfx\\TchAnth2.wav\r\nMonsters\\newsfx\\TmbRata1.wav\r\nMonsters\\newsfx\\TmbRata2.wav\r\nMonsters\\newsfx\\TmbRatd1.wav\r\nMonsters\\newsfx\\TmbRatd2.wav\r\nMonsters\\newsfx\\TmbRath1.wav\r\nMonsters\\newsfx\\TmbRath2.wav\r\nMonsters\\Nkr\\Nkra.cl2\r\nMonsters\\Nkr\\Nkrd.cl2\r\nMonsters\\Nkr\\Nkrh.cl2\r\nMonsters\\Nkr\\Nkrn.cl2\r\nMonsters\\Nkr\\Nkrs.cl2\r\nMonsters\\Nkr\\Nkrw.cl2\r\nMonsters\\Rat\\Rata.cl2\r\nMonsters\\Rat\\Ratd.cl2\r\nMonsters\\Rat\\Rath.cl2\r\nMonsters\\Rat\\Ratn.cl2\r\nMonsters\\Rat\\Ratw.cl2\r\nMonsters\\Reaper\\Reapa.cl2\r\nMonsters\\Reaper\\Reapd.cl2\r\nMonsters\\Reaper\\Reaph.cl2\r\nMonsters\\Reaper\\Reapn.cl2\r\nMonsters\\Reaper\\Reapw.cl2\r\nmonsters\\rhino\\blue.trn\r\nmonsters\\rhino\\orange.trn\r\nmonsters\\rhino\\rhinoa.cl2\r\nmonsters\\rhino\\rhinoa1.wav\r\nmonsters\\rhino\\rhinoa2.wav\r\nmonsters\\rhino\\rhinob.trn\r\nmonsters\\rhino\\rhinod.cl2\r\nmonsters\\rhino\\rhinod1.wav\r\nmonsters\\rhino\\rhinod2.wav\r\nmonsters\\rhino\\rhinoh.cl2\r\nmonsters\\rhino\\rhinoh1.wav\r\nmonsters\\rhino\\rhinoh2.wav\r\nmonsters\\rhino\\rhinon.cl2\r\nmonsters\\rhino\\rhinos.cl2\r\nmonsters\\rhino\\rhinos1.wav\r\nmonsters\\rhino\\rhinos2.wav\r\nmonsters\\rhino\\rhinow.cl2\r\nmonsters\\scav\\scava.cl2\r\nmonsters\\scav\\scava1.wav\r\nmonsters\\scav\\scava2.wav\r\nmonsters\\scav\\scavbe.trn\r\nmonsters\\scav\\scavbr.trn\r\nmonsters\\scav\\scavd.cl2\r\nmonsters\\scav\\scavd1.wav\r\nmonsters\\scav\\scavd2.wav\r\nmonsters\\scav\\scavh.cl2\r\nmonsters\\scav\\scavh1.wav\r\nmonsters\\scav\\scavh2.wav\r\nmonsters\\scav\\scavn.cl2\r\nmonsters\\scav\\scavs.cl2\r\nmonsters\\scav\\scavs1.wav\r\nmonsters\\scav\\scavs2.wav\r\nmonsters\\scav\\scavw.cl2\r\nmonsters\\scav\\scavw.trn\r\nMonsters\\Scorp\\Scorp%c.cl2\r\nmonsters\\skelaxe\\black.trn\r\nmonsters\\skelaxe\\skelt.trn\r\nmonsters\\skelaxe\\sklaxa.cl2\r\nmonsters\\skelaxe\\sklaxa1.wav\r\nmonsters\\skelaxe\\sklaxa2.wav\r\nmonsters\\skelaxe\\sklaxd.cl2\r\nmonsters\\skelaxe\\sklaxd1.wav\r\nmonsters\\skelaxe\\sklaxd2.wav\r\nmonsters\\skelaxe\\sklaxh.cl2\r\nmonsters\\skelaxe\\sklaxh1.wav\r\nmonsters\\skelaxe\\sklaxh2.wav\r\nmonsters\\skelaxe\\sklaxn.cl2\r\nmonsters\\skelaxe\\sklaxs.cl2\r\nmonsters\\skelaxe\\sklaxw.cl2\r\nmonsters\\skelaxe\\white.trn\r\nmonsters\\skelbow\\black.trn\r\nmonsters\\skelbow\\skelt.trn\r\nmonsters\\skelbow\\sklbwa.cl2\r\nmonsters\\skelbow\\sklbwa1.wav\r\nmonsters\\skelbow\\sklbwa2.wav\r\nmonsters\\skelbow\\sklbwd.cl2\r\nmonsters\\skelbow\\sklbwd1.wav\r\nmonsters\\skelbow\\sklbwd2.wav\r\nmonsters\\skelbow\\sklbwh.cl2\r\nmonsters\\skelbow\\sklbwh1.wav\r\nmonsters\\skelbow\\sklbwh2.wav\r\nmonsters\\skelbow\\sklbwn.cl2\r\nmonsters\\skelbow\\sklbws.cl2\r\nmonsters\\skelbow\\sklbws1.wav\r\nmonsters\\skelbow\\sklbws2.wav\r\nmonsters\\skelbow\\sklbww.cl2\r\nmonsters\\skelbow\\white.trn\r\nmonsters\\skelsd\\black.trn\r\nmonsters\\skelsd\\skelt.trn\r\nmonsters\\skelsd\\sklsra.cl2\r\nmonsters\\skelsd\\sklsra1.wav\r\nmonsters\\skelsd\\sklsra2.wav\r\nmonsters\\skelsd\\sklsrd.cl2\r\nmonsters\\skelsd\\sklsrd1.wav\r\nmonsters\\skelsd\\sklsrd2.wav\r\nmonsters\\skelsd\\sklsrh.cl2\r\nmonsters\\skelsd\\sklsrh1.wav\r\nmonsters\\skelsd\\sklsrh2.wav\r\nmonsters\\skelsd\\sklsrn.cl2\r\nmonsters\\skelsd\\sklsrs.cl2\r\nmonsters\\skelsd\\sklsrs1.wav\r\nmonsters\\skelsd\\sklsrs2.wav\r\nmonsters\\skelsd\\sklsrw.cl2\r\nmonsters\\skelsd\\white.trn\r\nmonsters\\sking\\skinga.cl2\r\nmonsters\\sking\\skinga1.wav\r\nmonsters\\sking\\skinga2.wav\r\nmonsters\\sking\\skingd.cl2\r\nmonsters\\sking\\skingd1.wav\r\nmonsters\\sking\\skingd2.wav\r\nmonsters\\sking\\skingh.cl2\r\nmonsters\\sking\\skingh1.wav\r\nmonsters\\sking\\skingh2.wav\r\nmonsters\\sking\\skingn.cl2\r\nmonsters\\sking\\skings.cl2\r\nmonsters\\sking\\skings1.wav\r\nmonsters\\sking\\skings2.wav\r\nmonsters\\sking\\skingw.cl2\r\nmonsters\\snake\\snakb.trn\r\nmonsters\\snake\\snakea.cl2\r\nmonsters\\snake\\snakea1.wav\r\nmonsters\\snake\\snakea2.wav\r\nmonsters\\snake\\snaked.cl2\r\nmonsters\\snake\\snaked1.wav\r\nmonsters\\snake\\snaked2.wav\r\nmonsters\\snake\\snakeh.cl2\r\nmonsters\\snake\\snakeh1.wav\r\nmonsters\\snake\\snakeh2.wav\r\nmonsters\\snake\\snaken.cl2\r\nmonsters\\snake\\snakes.cl2\r\nmonsters\\snake\\snakes1.wav\r\nmonsters\\snake\\snakes2.wav\r\nmonsters\\snake\\snakew.cl2\r\nmonsters\\snake\\snakg.trn\r\nmonsters\\snake\\snakr.trn\r\nmonsters\\sneak\\sneaka.cl2\r\nmonsters\\sneak\\sneaka1.wav\r\nmonsters\\sneak\\sneaka2.wav\r\nmonsters\\sneak\\sneakd.cl2\r\nmonsters\\sneak\\sneakd1.wav\r\nmonsters\\sneak\\sneakd2.wav\r\nmonsters\\sneak\\sneakh.cl2\r\nmonsters\\sneak\\sneakh1.wav\r\nmonsters\\sneak\\sneakh2.wav\r\nmonsters\\sneak\\sneakn.cl2\r\nmonsters\\sneak\\sneaks.cl2\r\nmonsters\\sneak\\sneaks1.wav\r\nmonsters\\sneak\\sneaks2.wav\r\nmonsters\\sneak\\sneakv1.trn\r\nmonsters\\sneak\\sneakv2.trn\r\nmonsters\\sneak\\sneakv3.trn\r\nmonsters\\sneak\\sneakw.cl2\r\nMonsters\\Spawn\\Spawna.cl2\r\nMonsters\\Spawn\\Spawnd.cl2\r\nMonsters\\Spawn\\Spawnh.cl2\r\nMonsters\\Spawn\\Spawnn.cl2\r\nMonsters\\Spawn\\Spawnw.cl2\r\nMonsters\\Spider\\Spidera.cl2\r\nMonsters\\Spider\\Spiderd.cl2\r\nMonsters\\Spider\\Spiderh.cl2\r\nMonsters\\Spider\\Spidern.cl2\r\nMonsters\\Spider\\Spiderw.cl2\r\nmonsters\\succ\\scbsa.cl2\r\nmonsters\\succ\\scbsa1.wav\r\nmonsters\\succ\\scbsa2.wav\r\nmonsters\\succ\\scbsd.cl2\r\nmonsters\\succ\\scbsd1.wav\r\nmonsters\\succ\\scbsd2.wav\r\nmonsters\\succ\\scbsh.cl2\r\nmonsters\\succ\\scbsh1.wav\r\nmonsters\\succ\\scbsh2.wav\r\nmonsters\\succ\\scbsn.cl2\r\nmonsters\\succ\\scbsw.cl2\r\nmonsters\\succ\\succb.trn\r\nmonsters\\succ\\succbw.trn\r\nmonsters\\succ\\succrw.trn\r\nmonsters\\thin\\thina.cl2\r\nmonsters\\thin\\thina1.wav\r\nmonsters\\thin\\thina2.wav\r\nmonsters\\thin\\thind.cl2\r\nmonsters\\thin\\thind1.wav\r\nmonsters\\thin\\thind2.wav\r\nmonsters\\thin\\thinh.cl2\r\nmonsters\\thin\\thinh1.wav\r\nmonsters\\thin\\thinh2.wav\r\nmonsters\\thin\\thinn.cl2\r\nmonsters\\thin\\thins.cl2\r\nmonsters\\thin\\thins1.wav\r\nmonsters\\thin\\thins2.wav\r\nmonsters\\thin\\thinv1.trn\r\nmonsters\\thin\\thinv2.trn\r\nmonsters\\thin\\thinv3.trn\r\nmonsters\\thin\\thinw.cl2\r\nmonsters\\tsneak\\sneakla1.wav\r\nmonsters\\tsneak\\sneakla2.wav\r\nmonsters\\tsneak\\sneakld1.wav\r\nmonsters\\tsneak\\sneakld2.wav\r\nmonsters\\tsneak\\sneaklh1.wav\r\nmonsters\\tsneak\\sneaklh2.wav\r\nmonsters\\tsneak\\tsneaka.cl2\r\nmonsters\\tsneak\\tsneakd.cl2\r\nmonsters\\tsneak\\tsneakh.cl2\r\nmonsters\\tsneak\\tsneakn.cl2\r\nmonsters\\tsneak\\tsneakw.cl2\r\nmonsters\\unrav\\unrava.cl2\r\nmonsters\\unrav\\unravd.cl2\r\nmonsters\\unrav\\unravh.cl2\r\nmonsters\\unrav\\unravn.cl2\r\nmonsters\\unrav\\unravs.cl2\r\nMonsters\\Unrav\\Unravw.cl2\r\nmonsters\\worm\\worma1.wav\r\nmonsters\\worm\\worma2.wav\r\nmonsters\\worm\\wormd1.wav\r\nmonsters\\worm\\wormd2.wav\r\nmonsters\\worm\\wormh1.wav\r\nmonsters\\worm\\wormh2.wav\r\nmonsters\\worm\\worms1.wav\r\nmonsters\\worm\\worms2.wav\r\nMonsters\\WScorp\\WScorpa.cl2\r\nMonsters\\WScorp\\WScorpd.cl2\r\nMonsters\\WScorp\\WScorph.cl2\r\nMonsters\\WScorp\\WScorpn.cl2\r\nMonsters\\WScorp\\WScorpw.cl2\r\nmonsters\\zombie\\bluered.trn\r\nmonsters\\zombie\\grey.trn\r\nmonsters\\zombie\\yellow.trn\r\nmonsters\\zombie\\zombiea.cl2\r\nmonsters\\zombie\\zombiea1.wav\r\nmonsters\\zombie\\zombiea2.wav\r\nmonsters\\zombie\\zombied.cl2\r\nmonsters\\zombie\\zombied1.wav\r\nmonsters\\zombie\\zombied2.wav\r\nmonsters\\zombie\\zombieh.cl2\r\nmonsters\\zombie\\zombieh1.wav\r\nmonsters\\zombie\\zombieh2.wav\r\nmonsters\\zombie\\zombien.cl2\r\nmonsters\\zombie\\zombies.cl2\r\nmonsters\\zombie\\zombies1.wav\r\nmonsters\\zombie\\zombies2.wav\r\nmonsters\\zombie\\zombiew.cl2\r\nmpq\\format.mcm\r\nmultimaps\\(2)challenger.scm\r\nmultimaps\\(2)river crossing.scm\r\nmultimaps\\(2)road war.scm\r\nmultimaps\\(2)showdown.scx\r\nmultimaps\\(2)space madness.scm\r\nmultimaps\\(2)the small divide.scm\r\nmultimaps\\(2)volcanis.scm\r\nmultimaps\\(3)holy ground.scm\r\nmultimaps\\(3)meltdown.scm\r\nmultimaps\\(3)three kingdoms.scm\r\nmultimaps\\(3)triumvirate.scm\r\nmultimaps\\(4)alpha draconis.scm\r\nmultimaps\\(4)blood bath.scm\r\nmultimaps\\(4)bridge too near.scm\r\nmultimaps\\(4)cyclone.scm\r\nmultimaps\\(4)dark crystal.scm\r\nmultimaps\\(4)dark star.scm\r\nmultimaps\\(4)forsaken valley.scx\r\nmultimaps\\(4)lost civilization.scm\r\nmultimaps\\(4)opposing city states '98.scm\r\nmultimaps\\(4)orbital relay.scm\r\nmultimaps\\(4)power lines.scm\r\nmultimaps\\(4)ruins of the ancients.scm\r\nmultimaps\\(4)sanctuary.scx\r\nmultimaps\\(4)tarsonis orbital.scm\r\nmultimaps\\(5)diablo.scm\r\nmultimaps\\(5)island hop.scm\r\nmultimaps\\(5)jeweled river.scm\r\nmultimaps\\(5)sherwood forest.scm\r\nmultimaps\\(6)close encounters.scx\r\nmultimaps\\(6)ground zero.scm\r\nmultimaps\\(6)hidden shrine.scm\r\nmultimaps\\(6)new gettysburg.scm\r\nmultimaps\\(6)winter conquest.scx\r\nmultimaps\\(7)continental divide.scm\r\nmultimaps\\(7)river war.scm\r\nmultimaps\\(8)bridge to bridge '98.scm\r\nmultimaps\\(8)char magma.scm\r\nmultimaps\\(8)frozen sea.scx\r\nmultimaps\\(8)green valleys.scm\r\nmultimaps\\(8)homeworld.scm\r\nmultimaps\\(8)killing fields.scm\r\nmultimaps\\(8)orbital death.scm\r\nmultimaps\\(8)plains of snow '98.scm\r\nmultimaps\\(8)station unrest.scm\r\nmultimaps\\(8)the hunters.scm\r\nmultimaps\\broodwar\\(2)astral balance.scm\r\nmultimaps\\broodwar\\(2)baby steps.scm\r\nmultimaps\\broodwar\\(2)binary burghs.scx\r\nmultimaps\\broodwar\\(2)crystallis.scm\r\nmultimaps\\broodwar\\(2)double jeopardy.scm\r\nmultimaps\\broodwar\\(2)fire walker.scm\r\nmultimaps\\broodwar\\(2)full circle.scm\r\nmultimaps\\broodwar\\(2)ice floes.scx\r\nmultimaps\\broodwar\\(2)midnight lagoon.scx\r\nmultimaps\\broodwar\\(2)switchback.scm\r\nmultimaps\\broodwar\\(3)ice mountain.scx\r\nmultimaps\\broodwar\\(3)overlook.scm\r\nmultimaps\\broodwar\\(3)stepping stones.scm\r\nmultimaps\\broodwar\\(3)trench wars.scx\r\nmultimaps\\broodwar\\(3)triad.scm\r\nmultimaps\\broodwar\\(3)triskelion.scx\r\nmultimaps\\broodwar\\(4)archipelago.scm\r\nmultimaps\\broodwar\\(4)arctic station.scx\r\nmultimaps\\broodwar\\(4)boxed in.scm\r\nmultimaps\\broodwar\\(4)caldera.scm\r\nmultimaps\\broodwar\\(4)crescent moon.scx\r\nmultimaps\\broodwar\\(4)cross the line.scx\r\nmultimaps\\broodwar\\(4)desolation.scx\r\nmultimaps\\broodwar\\(4)dust bowl.scx\r\nmultimaps\\broodwar\\(4)entanglement.scm\r\nmultimaps\\broodwar\\(4)eye of the storm.scx\r\nmultimaps\\broodwar\\(4)frenzy.scm\r\nmultimaps\\broodwar\\(4)gladiator pits.scm\r\nmultimaps\\broodwar\\(4)greener pastures.scx\r\nmultimaps\\broodwar\\(4)heartwood.scm\r\nmultimaps\\broodwar\\(4)hot zone.scx\r\nmultimaps\\broodwar\\(4)jungle siege.scm\r\nmultimaps\\broodwar\\(4)kakaru keys.scx\r\nmultimaps\\broodwar\\(4)lake shore.scm\r\nmultimaps\\broodwar\\(4)landslide.scm\r\nmultimaps\\broodwar\\(4)mausoleum.scx\r\nmultimaps\\broodwar\\(4)molten playground.scm\r\nmultimaps\\broodwar\\(4)nightfall.scx\r\nmultimaps\\broodwar\\(4)no way out.scm\r\nmultimaps\\broodwar\\(4)orbital gully.scm\r\nmultimaps\\broodwar\\(4)path of sorrow.scx\r\nmultimaps\\broodwar\\(4)ramparts.scm\r\nmultimaps\\broodwar\\(4)red canyons.scm\r\nmultimaps\\broodwar\\(4)river lethe.scx\r\nmultimaps\\broodwar\\(4)road to nowhere.scm\r\nmultimaps\\broodwar\\(4)sanctuary.scx\r\nmultimaps\\broodwar\\(4)scorched earth.scx\r\nmultimaps\\broodwar\\(4)shadowlands.scx\r\nmultimaps\\broodwar\\(4)shroud platform.scm\r\nmultimaps\\broodwar\\(4)space atoll.scm\r\nmultimaps\\broodwar\\(4)space debris.scm\r\nmultimaps\\broodwar\\(4)spring thaw.scx\r\nmultimaps\\broodwar\\(4)wasteland.scx\r\nmultimaps\\broodwar\\(4)water's edge.scm\r\nmultimaps\\broodwar\\(4)waypoint junction.scm\r\nmultimaps\\broodwar\\(5)ebon lakes.scx\r\nmultimaps\\broodwar\\(5)lake of fire.scm\r\nmultimaps\\broodwar\\(5)rosewood.scm\r\nmultimaps\\broodwar\\(5)sandstorm.scx\r\nmultimaps\\broodwar\\(5)twilight star.scx\r\nmultimaps\\broodwar\\(6)across the cape.scm\r\nmultimaps\\broodwar\\(6)aftershock.scm\r\nmultimaps\\broodwar\\(6)avalanche.scx\r\nmultimaps\\broodwar\\(6)azure plains.scx\r\nmultimaps\\broodwar\\(6)cauldron.scx\r\nmultimaps\\broodwar\\(6)close encounters.scx\r\nmultimaps\\broodwar\\(6)crazy critters.scm\r\nmultimaps\\broodwar\\(6)flooded plains.scx\r\nmultimaps\\broodwar\\(6)funeral pyre.scm\r\nmultimaps\\broodwar\\(6)hypothermia.scx\r\nmultimaps\\broodwar\\(6)river of light.scm\r\nmultimaps\\broodwar\\(6)sapphire isles.scx\r\nmultimaps\\broodwar\\(6)sirocco.scx\r\nmultimaps\\broodwar\\(6)tale of two cities.scm\r\nmultimaps\\broodwar\\(6)thin ice.scx\r\nmultimaps\\broodwar\\(6)valley of re.scx\r\nmultimaps\\broodwar\\(7)black lotus.scx\r\nmultimaps\\broodwar\\(7)broken steppes.scm\r\nmultimaps\\broodwar\\(7)nightshade.scx\r\nmultimaps\\broodwar\\(8)dark continent.scx\r\nmultimaps\\broodwar\\(8)frozen sea.scx\r\nmultimaps\\broodwar\\(8)hellfire.scm\r\nmultimaps\\broodwar\\(8)octopus.scx\r\nmultimaps\\broodwar\\(8)primeval isles.scx\r\nmultimaps\\broodwar\\(8)theatre of war.scm\r\nmultimaps\\broodwar\\(8)tribes.scm\r\nmultimaps\\broodwar\\(8)wheel of war.scm\r\nmultimaps\\broodwar\\allied\\(4)highland denizens.scm\r\nmultimaps\\broodwar\\allied\\(4)the gardens.scm\r\nmultimaps\\broodwar\\allied\\(6)grand canyon.scm\r\nmultimaps\\broodwar\\allied\\(6)razor thicket.scm\r\nmultimaps\\broodwar\\allied\\(6)triple team.scm\r\nmultimaps\\broodwar\\allied\\(8)allied fortress.scm\r\nmultimaps\\broodwar\\allied\\(8)border dispute.scm\r\nmultimaps\\broodwar\\allied\\(8)crystal castles.scm\r\nmultimaps\\broodwar\\allied\\(8)double diamond.scm\r\nmultimaps\\broodwar\\allied\\(8)friends in space.scm\r\nmultimaps\\broodwar\\ladder\\(2)fading realm.scx\r\nmultimaps\\broodwar\\ladder\\(2)showdown.scx\r\nmultimaps\\broodwar\\ladder\\(4)forsaken valley.scx\r\nmultimaps\\broodwar\\ladder\\(4)snowbound.scx\r\nmultimaps\\broodwar\\ladder\\(6)medusa.scx\r\nmultimaps\\broodwar\\ladder\\(6)winter conquest.scx\r\nmultimaps\\broodwar\\webmaps\\(2)jacobs ladder.scm\r\nmultimaps\\broodwar\\webmaps\\(2)zerg soccer.scm\r\nmultimaps\\broodwar\\webmaps\\(4)brushfire.scm\r\nmultimaps\\broodwar\\webmaps\\(4)catwalk alley.scm\r\nmultimaps\\broodwar\\webmaps\\(4)crossroads.scm\r\nmultimaps\\broodwar\\webmaps\\(4)inferno.scm\r\nmultimaps\\broodwar\\webmaps\\(4)novastation.scm\r\nmultimaps\\broodwar\\webmaps\\(4)steal the beacon.scm\r\nmultimaps\\broodwar\\webmaps\\(4)the highway.scm\r\nmultimaps\\broodwar\\webmaps\\(4)warp gates.scm\r\nmultimaps\\broodwar\\webmaps\\(5)predators.scm\r\nmultimaps\\broodwar\\webmaps\\(5)typhoon.scm\r\nmultimaps\\broodwar\\webmaps\\(6)blast furnace.scm\r\nmultimaps\\broodwar\\webmaps\\(6)bunkercommand.scm\r\nmultimaps\\broodwar\\webmaps\\(6)chain lightning.scm\r\nmultimaps\\broodwar\\webmaps\\(6)divided factions.scm\r\nmultimaps\\broodwar\\webmaps\\(6)ghost town.scm\r\nmultimaps\\broodwar\\webmaps\\(6)legacy.scm\r\nmultimaps\\broodwar\\webmaps\\(8)aurora.scm\r\nmultimaps\\broodwar\\webmaps\\(8)backwoods.scm\r\nmultimaps\\broodwar\\webmaps\\(8)big game hunters.scm\r\nmultimaps\\broodwar\\webmaps\\(8)elderlands.scm\r\nmultimaps\\broodwar\\webmaps\\(8)enigma.scm\r\nmultimaps\\broodwar\\webmaps\\(8)eruption.scm\r\nmultimaps\\broodwar\\webmaps\\(8)expedition.scm\r\nmultimaps\\broodwar\\webmaps\\(8)friends98.scm\r\nmultimaps\\broodwar\\webmaps\\(8)garden of aiur.scm\r\nmultimaps\\broodwar\\webmaps\\(8)labyrinth.scm\r\nmultimaps\\broodwar\\webmaps\\(8)turbo.scm\r\nmultimaps\\campaign\\(1)enslavers01.scm\r\nmultimaps\\campaign\\(1)enslavers02a.scm\r\nmultimaps\\campaign\\(1)enslavers02b.scm\r\nmultimaps\\campaign\\(1)enslavers03a.scm\r\nmultimaps\\campaign\\(1)enslavers03b.scm\r\nmultimaps\\ladder\\(2)discovery.scm\r\nmultimaps\\ladder\\(2)river styx.scm\r\nmultimaps\\ladder\\(2)solar station.scm\r\nmultimaps\\ladder\\(4)ashrigo.scm\r\nmultimaps\\ladder\\(4)crusader.scm\r\nmultimaps\\ladder\\(4)dire straits.scm\r\nmultimaps\\ladder\\(4)lost temple.scm\r\nmultimaps\\ladder\\(4)proving grounds.scm\r\nmultimaps\\ladder\\(4)rivalry.scm\r\nmultimaps\\ladder\\(6)acropolis.scm\r\nmultimaps\\ladder\\(6)polaris prime.scm\r\nmultimaps\\oldladder\\(2)discovery.scm\r\nmultimaps\\oldladder\\(2)gauntlet.scm\r\nmultimaps\\oldladder\\(2)river styx.scm\r\nmultimaps\\oldladder\\(2)solar station.scm\r\nmultimaps\\oldladder\\(4)bone canyon.scm\r\nmultimaps\\oldladder\\(4)crusader.scm\r\nmultimaps\\oldladder\\(4)remote outpost.scm\r\nmultimaps\\oldladder\\(8)green valleys.scm\r\nmultimaps\\scenario\\(2)pro bowl.scm\r\nmultimaps\\scenario\\(2)wakka wakka.scm\r\nmultimaps\\scenario\\(3)defenders of the galaxy.scm\r\nmultimaps\\scenario\\(4)king of the hill.scm\r\nmultimaps\\scenario\\(4)old faithful.scm\r\nmultimaps\\scenario\\(4)steal the bacon.scm\r\nmultimaps\\scenario\\(4)zergling round-up.scm\r\nmultimaps\\scenario\\(4)zoo keeper.scm\r\nmultimaps\\scenario\\(5)race of death.scm\r\nmultimaps\\scenario\\(8)starcraft fortress.scm\r\nmusic\\dintro.wav\r\nmusic\\dlvla.wav\r\nmusic\\dlvlb.wav\r\nmusic\\dlvlc.wav\r\nmusic\\dlvld.wav\r\nMusic\\DLvlE.wav\r\nMusic\\DLvlF.wav\r\nmusic\\dtowne.wav\r\nmusic\\pdefeat.wav\r\nmusic\\prdyroom.wav\r\nmusic\\protoss1.wav\r\nmusic\\protoss2.wav\r\nmusic\\protoss3.wav\r\nmusic\\protoss4.wav\r\nmusic\\protoss5.wav\r\nmusic\\protoss6.wav\r\nmusic\\protoss7.wav\r\nmusic\\pvict.wav\r\nmusic\\radiofreezerg.wav\r\nmusic\\tdefeat.wav\r\nmusic\\terran1.wav\r\nmusic\\terran2.wav\r\nmusic\\terran3.wav\r\nmusic\\terran4.wav\r\nmusic\\terran5.wav\r\nmusic\\terran6.wav\r\nmusic\\terran7.wav\r\nmusic\\title.wav\r\nmusic\\trdyroom.wav\r\nmusic\\tvict.wav\r\nmusic\\vssver.scc\r\nmusic\\zdefeat.wav\r\nmusic\\zerg1.wav\r\nmusic\\zerg2.wav\r\nmusic\\zerg3.wav\r\nmusic\\zerg4.wav\r\nmusic\\zerg5.wav\r\nmusic\\zerg6.wav\r\nmusic\\zerg7.wav\r\nmusic\\zrdyroom.wav\r\nmusic\\zvict.wav\r\nNConOver.pcx\r\nNConsole.pcx\r\nnetwork.00b\r\nnetwork.01b\r\nnetwork.01c\r\nnetwork.021\r\nnetwork.024\r\nnetwork.02b\r\nnetwork.02d\r\nnetwork.037\r\nnetwork.03b\r\nnetwork.03d\r\nnetwork.03e\r\nnetwork.04b\r\nnetwork.04d\r\nnetwork.04f\r\nnetwork.056\r\nnetwork.063\r\nnetwork.06f\r\nnetwork.doc\r\nnetwork.tbl\r\nNlevels\\Cutl5.cel\r\nNlevels\\Cutl5.pal\r\nNlevels\\cutl6.cel\r\nNlevels\\Cutl6.pal\r\nNLevels\\L%iData\\L%iBase%i.PAL\r\nNLevels\\L5Data\\L5.amp\r\nNLevels\\L5Data\\L5.cel\r\nNLevels\\L5Data\\L5.MIN\r\nNLevels\\L5Data\\L5.SOL\r\nNLevels\\L5Data\\L5.TIL\r\nNLevels\\L5Data\\L5Base.PAL\r\nNLevels\\L5Data\\L5S.cel\r\nNLevels\\L6Data\\L6.amp\r\nNLevels\\L6Data\\L6.cel\r\nNLevels\\L6Data\\L6.MIN\r\nNLevels\\L6Data\\L6.SOL\r\nNLevels\\L6Data\\L6.TIL\r\nNLevels\\TownData\\Town.cel\r\nNLevels\\TownData\\Town.min\r\nNLevels\\TownData\\Town.sol\r\nNLevels\\TownData\\Town.til\r\nNT\\comctl32.dll\r\nobjects\\altboy.cel\r\nobjects\\angel.cel\r\nobjects\\armstand.cel\r\nobjects\\banner.cel\r\nobjects\\barrel.cel\r\nobjects\\barrelex.cel\r\nobjects\\bcase.cel\r\nobjects\\bkslbrnt.cel\r\nobjects\\bloodfnt.cel\r\nobjects\\book1.cel\r\nobjects\\book2.cel\r\nobjects\\bshelf.cel\r\nobjects\\burncros.cel\r\nobjects\\candle2.cel\r\nobjects\\cauldren.cel\r\nobjects\\chest1.cel\r\nobjects\\chest2.cel\r\nobjects\\chest3.cel\r\nobjects\\cruxsk1.cel\r\nobjects\\cruxsk2.cel\r\nobjects\\cruxsk3.cel\r\nobjects\\decap.cel\r\nobjects\\flame1.cel\r\nobjects\\goatshrn.cel\r\nobjects\\l1braz.cel\r\nobjects\\l1doors.cel\r\nobjects\\l2doors.cel\r\nobjects\\l3doors.cel\r\nobjects\\lever.cel\r\nobjects\\lshrineg.cel\r\nobjects\\lzstand.cel\r\nobjects\\mcirl.cel\r\nobjects\\mfountn.cel\r\nobjects\\miniwatr.cel\r\nobjects\\mushptch.cel\r\nobjects\\nude2.cel\r\nobjects\\pedistl.cel\r\nobjects\\pfountn.cel\r\nobjects\\prsrplt1.cel\r\nobjects\\rockstan.cel\r\nobjects\\rshrineg.cel\r\nobjects\\sarc.cel\r\nobjects\\skulfire.cel\r\nobjects\\skulpile.cel\r\nobjects\\skulstik.cel\r\nobjects\\switch2.cel\r\nobjects\\switch3.cel\r\nobjects\\switch4.cel\r\nobjects\\tfountn.cel\r\nobjects\\tnudem.cel\r\nobjects\\tnudew.cel\r\nobjects\\traphole.cel\r\nobjects\\tsoul.cel\r\nobjects\\weapstnd.cel\r\nobjects\\wtorch1.cel\r\nobjects\\wtorch2.cel\r\nobjects\\wtorch3.cel\r\nobjects\\wtorch4.cel\r\norders.dat\r\nparallax\\star.spk\r\npatch.cmd\r\npatch.lst\r\npatch.mpq\r\npatch.txt\r\npatch_rt.mpq\r\npatch_sh.mpq\r\npBotL.pcx\r\npBotR.pcx\r\npGateway.pcx\r\nPGL(1).got\r\nPGL.cnd\r\nPGL_2.cnd\r\npillboxt.grp\r\nplrgfx\\infra.trn\r\nplrgfx\\monk\\mha\\mhaas.cl2\r\nplrgfx\\monk\\mha\\mhaat.cl2\r\nplrgfx\\monk\\mha\\mhaaw.cl2\r\nplrgfx\\monk\\mha\\mhafm.cl2\r\nplrgfx\\monk\\mha\\mhaht.cl2\r\nplrgfx\\monk\\mha\\mhalm.cl2\r\nplrgfx\\monk\\mha\\mhaqm.cl2\r\nplrgfx\\monk\\mha\\mhast.cl2\r\nplrgfx\\monk\\mha\\mhawl.cl2\r\nplrgfx\\monk\\mhb\\mhbas.cl2\r\nplrgfx\\monk\\mhb\\mhbat.cl2\r\nplrgfx\\monk\\mhb\\mhbaw.cl2\r\nplrgfx\\monk\\mhb\\mhbfm.cl2\r\nplrgfx\\monk\\mhb\\mhbht.cl2\r\nplrgfx\\monk\\mhb\\mhblm.cl2\r\nplrgfx\\monk\\mhb\\mhbqm.cl2\r\nplrgfx\\monk\\mhb\\mhbst.cl2\r\nplrgfx\\monk\\mhb\\mhbwl.cl2\r\nplrgfx\\monk\\mhd\\mhdas.cl2\r\nplrgfx\\monk\\mhd\\mhdat.cl2\r\nplrgfx\\monk\\mhd\\mhdaw.cl2\r\nplrgfx\\monk\\mhd\\mhdbl.cl2\r\nplrgfx\\monk\\mhd\\mhdfm.cl2\r\nplrgfx\\monk\\mhd\\mhdht.cl2\r\nplrgfx\\monk\\mhd\\mhdlm.cl2\r\nplrgfx\\monk\\mhd\\mhdqm.cl2\r\nplrgfx\\monk\\mhd\\mhdst.cl2\r\nplrgfx\\monk\\mhd\\mhdwl.cl2\r\nplrgfx\\monk\\mhh\\mhhas.cl2\r\nplrgfx\\monk\\mhh\\mhhat.cl2\r\nplrgfx\\monk\\mhh\\mhhaw.cl2\r\nplrgfx\\monk\\mhh\\mhhbl.cl2\r\nplrgfx\\monk\\mhh\\mhhfm.cl2\r\nplrgfx\\monk\\mhh\\mhhht.cl2\r\nplrgfx\\monk\\mhh\\mhhlm.cl2\r\nplrgfx\\monk\\mhh\\mhhqm.cl2\r\nplrgfx\\monk\\mhh\\mhhst.cl2\r\nplrgfx\\monk\\mhh\\mhhwl.cl2\r\nplrgfx\\monk\\mhm\\mhmas.cl2\r\nplrgfx\\monk\\mhm\\mhmat.cl2\r\nplrgfx\\monk\\mhm\\mhmaw.cl2\r\nplrgfx\\monk\\mhm\\mhmfm.cl2\r\nplrgfx\\monk\\mhm\\mhmht.cl2\r\nplrgfx\\monk\\mhm\\mhmlm.cl2\r\nplrgfx\\monk\\mhm\\mhmqm.cl2\r\nplrgfx\\monk\\mhm\\mhmst.cl2\r\nplrgfx\\monk\\mhm\\mhmwl.cl2\r\nplrgfx\\monk\\mhn\\mhnas.cl2\r\nplrgfx\\monk\\mhn\\mhnat.cl2\r\nplrgfx\\monk\\mhn\\mhnaw.cl2\r\nplrgfx\\monk\\mhn\\mhndt.cl2\r\nplrgfx\\monk\\mhn\\mhnfm.cl2\r\nplrgfx\\monk\\mhn\\mhnht.cl2\r\nplrgfx\\monk\\mhn\\mhnlm.cl2\r\nplrgfx\\monk\\mhn\\mhnqm.cl2\r\nplrgfx\\monk\\mhn\\mhnst.cl2\r\nplrgfx\\monk\\mhn\\mhnwl.cl2\r\nplrgfx\\monk\\mhs\\mhsas.cl2\r\nplrgfx\\monk\\mhs\\mhsat.cl2\r\nplrgfx\\monk\\mhs\\mhsaw.cl2\r\nplrgfx\\monk\\mhs\\mhsfm.cl2\r\nplrgfx\\monk\\mhs\\mhsht.cl2\r\nplrgfx\\monk\\mhs\\mhslm.cl2\r\nplrgfx\\monk\\mhs\\mhsqm.cl2\r\nplrgfx\\monk\\mhs\\mhsst.cl2\r\nplrgfx\\monk\\mhs\\mhswl.cl2\r\nplrgfx\\monk\\mht\\mhtas.cl2\r\nplrgfx\\monk\\mht\\mhtat.cl2\r\nplrgfx\\monk\\mht\\mhtaw.cl2\r\nplrgfx\\monk\\mht\\mhtfm.cl2\r\nplrgfx\\monk\\mht\\mhtht.cl2\r\nplrgfx\\monk\\mht\\mhtlm.cl2\r\nplrgfx\\monk\\mht\\mhtqm.cl2\r\nplrgfx\\monk\\mht\\mhtst.cl2\r\nplrgfx\\monk\\mht\\mhtwl.cl2\r\nplrgfx\\monk\\mhu\\mhuas.cl2\r\nplrgfx\\monk\\mhu\\mhuat.cl2\r\nplrgfx\\monk\\mhu\\mhuaw.cl2\r\nplrgfx\\monk\\mhu\\mhubl.cl2\r\nplrgfx\\monk\\mhu\\mhufm.cl2\r\nplrgfx\\monk\\mhu\\mhuht.cl2\r\nplrgfx\\monk\\mhu\\mhulm.cl2\r\nplrgfx\\monk\\mhu\\mhuqm.cl2\r\nplrgfx\\monk\\mhu\\mhust.cl2\r\nplrgfx\\monk\\mhu\\mhuwl.cl2\r\nplrgfx\\monk\\mla\\mlaas.cl2\r\nplrgfx\\monk\\mla\\mlaat.cl2\r\nplrgfx\\monk\\mla\\mlaaw.cl2\r\nplrgfx\\monk\\mla\\mlafm.cl2\r\nplrgfx\\monk\\mla\\mlaht.cl2\r\nplrgfx\\monk\\mla\\mlalm.cl2\r\nplrgfx\\monk\\mla\\mlaqm.cl2\r\nplrgfx\\monk\\mla\\mlast.cl2\r\nplrgfx\\monk\\mla\\mlawl.cl2\r\nplrgfx\\monk\\mlb\\mlbas.cl2\r\nplrgfx\\monk\\mlb\\mlbat.cl2\r\nplrgfx\\monk\\mlb\\mlbaw.cl2\r\nplrgfx\\monk\\mlb\\mlbfm.cl2\r\nplrgfx\\monk\\mlb\\mlbht.cl2\r\nplrgfx\\monk\\mlb\\mlblm.cl2\r\nplrgfx\\monk\\mlb\\mlbqm.cl2\r\nplrgfx\\monk\\mlb\\mlbst.cl2\r\nplrgfx\\monk\\mlb\\mlbwl.cl2\r\nplrgfx\\monk\\mld\\mldas.cl2\r\nplrgfx\\monk\\mld\\mldat.cl2\r\nplrgfx\\monk\\mld\\mldaw.cl2\r\nplrgfx\\monk\\mld\\mldbl.cl2\r\nplrgfx\\monk\\mld\\mldfm.cl2\r\nplrgfx\\monk\\mld\\mldht.cl2\r\nplrgfx\\monk\\mld\\mldlm.cl2\r\nplrgfx\\monk\\mld\\mldqm.cl2\r\nplrgfx\\monk\\mld\\mldst.cl2\r\nplrgfx\\monk\\mld\\mldwl.cl2\r\nplrgfx\\monk\\mlh\\mlhas.cl2\r\nplrgfx\\monk\\mlh\\mlhat.cl2\r\nplrgfx\\monk\\mlh\\mlhaw.cl2\r\nplrgfx\\monk\\mlh\\mlhbl.cl2\r\nplrgfx\\monk\\mlh\\mlhfm.cl2\r\nplrgfx\\monk\\mlh\\mlhht.cl2\r\nplrgfx\\monk\\mlh\\mlhlm.cl2\r\nplrgfx\\monk\\mlh\\mlhqm.cl2\r\nplrgfx\\monk\\mlh\\mlhst.cl2\r\nplrgfx\\monk\\mlh\\mlhwl.cl2\r\nplrgfx\\monk\\mlm\\mlmas.cl2\r\nplrgfx\\monk\\mlm\\mlmat.cl2\r\nplrgfx\\monk\\mlm\\mlmaw.cl2\r\nplrgfx\\monk\\mlm\\mlmfm.cl2\r\nplrgfx\\monk\\mlm\\mlmht.cl2\r\nplrgfx\\monk\\mlm\\mlmlm.cl2\r\nplrgfx\\monk\\mlm\\mlmqm.cl2\r\nplrgfx\\monk\\mlm\\mlmst.cl2\r\nplrgfx\\monk\\mlm\\mlmwl.cl2\r\nplrgfx\\monk\\mln\\mlnas.cl2\r\nplrgfx\\monk\\mln\\mlnat.cl2\r\nplrgfx\\monk\\mln\\mlnaw.cl2\r\nplrgfx\\monk\\mln\\mlndt.cl2\r\nplrgfx\\monk\\mln\\mlnfm.cl2\r\nplrgfx\\monk\\mln\\mlnht.cl2\r\nplrgfx\\monk\\mln\\mlnlm.cl2\r\nplrgfx\\monk\\mln\\mlnqm.cl2\r\nplrgfx\\monk\\mln\\mlnst.cl2\r\nplrgfx\\monk\\mln\\mlnwl.cl2\r\nplrgfx\\monk\\mls\\mlsas.cl2\r\nplrgfx\\monk\\mls\\mlsat.cl2\r\nplrgfx\\monk\\mls\\mlsaw.cl2\r\nplrgfx\\monk\\mls\\mlsfm.cl2\r\nplrgfx\\monk\\mls\\mlsht.cl2\r\nplrgfx\\monk\\mls\\mlslm.cl2\r\nplrgfx\\monk\\mls\\mlsqm.cl2\r\nplrgfx\\monk\\mls\\mlsst.cl2\r\nplrgfx\\monk\\mls\\mlswl.cl2\r\nplrgfx\\monk\\mlt\\mltas.cl2\r\nplrgfx\\monk\\mlt\\mltat.cl2\r\nplrgfx\\monk\\mlt\\mltaw.cl2\r\nplrgfx\\monk\\mlt\\mltfm.cl2\r\nplrgfx\\monk\\mlt\\mltht.cl2\r\nplrgfx\\monk\\mlt\\mltlm.cl2\r\nplrgfx\\monk\\mlt\\mltqm.cl2\r\nplrgfx\\monk\\mlt\\mltst.cl2\r\nplrgfx\\monk\\mlt\\mltwl.cl2\r\nplrgfx\\monk\\mlu\\mluas.cl2\r\nplrgfx\\monk\\mlu\\mluat.cl2\r\nplrgfx\\monk\\mlu\\mluaw.cl2\r\nplrgfx\\monk\\mlu\\mlubl.cl2\r\nplrgfx\\monk\\mlu\\mlufm.cl2\r\nplrgfx\\monk\\mlu\\mluht.cl2\r\nplrgfx\\monk\\mlu\\mlulm.cl2\r\nplrgfx\\monk\\mlu\\mluqm.cl2\r\nplrgfx\\monk\\mlu\\mlust.cl2\r\nplrgfx\\monk\\mlu\\mluwl.cl2\r\nplrgfx\\monk\\mma\\mmaas.cl2\r\nplrgfx\\monk\\mma\\mmaat.cl2\r\nplrgfx\\monk\\mma\\mmaaw.cl2\r\nplrgfx\\monk\\mma\\mmafm.cl2\r\nplrgfx\\monk\\mma\\mmaht.cl2\r\nplrgfx\\monk\\mma\\mmalm.cl2\r\nplrgfx\\monk\\mma\\mmaqm.cl2\r\nplrgfx\\monk\\mma\\mmast.cl2\r\nplrgfx\\monk\\mma\\mmawl.cl2\r\nplrgfx\\monk\\mmb\\mmbas.cl2\r\nplrgfx\\monk\\mmb\\mmbat.cl2\r\nplrgfx\\monk\\mmb\\mmbaw.cl2\r\nplrgfx\\monk\\mmb\\mmbfm.cl2\r\nplrgfx\\monk\\mmb\\mmbht.cl2\r\nplrgfx\\monk\\mmb\\mmblm.cl2\r\nplrgfx\\monk\\mmb\\mmbqm.cl2\r\nplrgfx\\monk\\mmb\\mmbst.cl2\r\nplrgfx\\monk\\mmb\\mmbwl.cl2\r\nplrgfx\\monk\\mmd\\mmdas.cl2\r\nplrgfx\\monk\\mmd\\mmdat.cl2\r\nplrgfx\\monk\\mmd\\mmdaw.cl2\r\nplrgfx\\monk\\mmd\\mmdbl.cl2\r\nplrgfx\\monk\\mmd\\mmdfm.cl2\r\nplrgfx\\monk\\mmd\\mmdht.cl2\r\nplrgfx\\monk\\mmd\\mmdlm.cl2\r\nplrgfx\\monk\\mmd\\mmdqm.cl2\r\nplrgfx\\monk\\mmd\\mmdst.cl2\r\nplrgfx\\monk\\mmd\\mmdwl.cl2\r\nplrgfx\\monk\\mmh\\mmhas.cl2\r\nplrgfx\\monk\\mmh\\mmhat.cl2\r\nplrgfx\\monk\\mmh\\mmhaw.cl2\r\nplrgfx\\monk\\mmh\\mmhbl.cl2\r\nplrgfx\\monk\\mmh\\mmhfm.cl2\r\nplrgfx\\monk\\mmh\\mmhht.cl2\r\nplrgfx\\monk\\mmh\\mmhlm.cl2\r\nplrgfx\\monk\\mmh\\mmhqm.cl2\r\nplrgfx\\monk\\mmh\\mmhst.cl2\r\nplrgfx\\monk\\mmh\\mmhwl.cl2\r\nplrgfx\\monk\\mmm\\mmmas.cl2\r\nplrgfx\\monk\\mmm\\mmmat.cl2\r\nplrgfx\\monk\\mmm\\mmmaw.cl2\r\nplrgfx\\monk\\mmm\\mmmfm.cl2\r\nplrgfx\\monk\\mmm\\mmmht.cl2\r\nplrgfx\\monk\\mmm\\mmmlm.cl2\r\nplrgfx\\monk\\mmm\\mmmqm.cl2\r\nplrgfx\\monk\\mmm\\mmmst.cl2\r\nplrgfx\\monk\\mmm\\mmmwl.cl2\r\nplrgfx\\monk\\mmn\\mmnas.cl2\r\nplrgfx\\monk\\mmn\\mmnat.cl2\r\nplrgfx\\monk\\mmn\\mmnaw.cl2\r\nplrgfx\\monk\\mmn\\mmndt.cl2\r\nplrgfx\\monk\\mmn\\mmnfm.cl2\r\nplrgfx\\monk\\mmn\\mmnht.cl2\r\nplrgfx\\monk\\mmn\\mmnlm.cl2\r\nplrgfx\\monk\\mmn\\mmnqm.cl2\r\nplrgfx\\monk\\mmn\\mmnst.cl2\r\nplrgfx\\monk\\mmn\\mmnwl.cl2\r\nplrgfx\\monk\\mms\\mmsas.cl2\r\nplrgfx\\monk\\mms\\mmsat.cl2\r\nplrgfx\\monk\\mms\\mmsaw.cl2\r\nplrgfx\\monk\\mms\\mmsfm.cl2\r\nplrgfx\\monk\\mms\\mmsht.cl2\r\nplrgfx\\monk\\mms\\mmslm.cl2\r\nplrgfx\\monk\\mms\\mmsqm.cl2\r\nplrgfx\\monk\\mms\\mmsst.cl2\r\nplrgfx\\monk\\mms\\mmswl.cl2\r\nplrgfx\\monk\\mmt\\mmtas.cl2\r\nplrgfx\\monk\\mmt\\mmtat.cl2\r\nplrgfx\\monk\\mmt\\mmtaw.cl2\r\nplrgfx\\monk\\mmt\\mmtfm.cl2\r\nplrgfx\\monk\\mmt\\mmtht.cl2\r\nplrgfx\\monk\\mmt\\mmtlm.cl2\r\nplrgfx\\monk\\mmt\\mmtqm.cl2\r\nplrgfx\\monk\\mmt\\mmtst.cl2\r\nplrgfx\\monk\\mmt\\mmtwl.cl2\r\nplrgfx\\monk\\mmu\\mmuas.cl2\r\nplrgfx\\monk\\mmu\\mmuat.cl2\r\nplrgfx\\monk\\mmu\\mmuaw.cl2\r\nplrgfx\\monk\\mmu\\mmubl.cl2\r\nplrgfx\\monk\\mmu\\mmufm.cl2\r\nplrgfx\\monk\\mmu\\mmuht.cl2\r\nplrgfx\\monk\\mmu\\mmulm.cl2\r\nplrgfx\\monk\\mmu\\mmuqm.cl2\r\nplrgfx\\monk\\mmu\\mmust.cl2\r\nplrgfx\\monk\\mmu\\mmuwl.cl2\r\nplrgfx\\rogue\\rha\\rhaas.cl2\r\nplrgfx\\rogue\\rha\\rhaat.cl2\r\nplrgfx\\rogue\\rha\\rhaaw.cl2\r\nplrgfx\\rogue\\rha\\rhafm.cl2\r\nplrgfx\\rogue\\rha\\rhaht.cl2\r\nplrgfx\\rogue\\rha\\rhalm.cl2\r\nplrgfx\\rogue\\rha\\rhaqm.cl2\r\nplrgfx\\rogue\\rha\\rhast.cl2\r\nplrgfx\\rogue\\rha\\rhawl.cl2\r\nplrgfx\\rogue\\rhb\\rhbas.cl2\r\nplrgfx\\rogue\\rhb\\rhbat.cl2\r\nplrgfx\\rogue\\rhb\\rhbaw.cl2\r\nplrgfx\\rogue\\rhb\\rhbfm.cl2\r\nplrgfx\\rogue\\rhb\\rhbht.cl2\r\nplrgfx\\rogue\\rhb\\rhblm.cl2\r\nplrgfx\\rogue\\rhb\\rhbqm.cl2\r\nplrgfx\\rogue\\rhb\\rhbst.cl2\r\nplrgfx\\rogue\\rhb\\rhbwl.cl2\r\nplrgfx\\rogue\\rhd\\rhdas.cl2\r\nplrgfx\\rogue\\rhd\\rhdat.cl2\r\nplrgfx\\rogue\\rhd\\rhdaw.cl2\r\nplrgfx\\rogue\\rhd\\rhdbl.cl2\r\nplrgfx\\rogue\\rhd\\rhdfm.cl2\r\nplrgfx\\rogue\\rhd\\rhdht.cl2\r\nplrgfx\\rogue\\rhd\\rhdlm.cl2\r\nplrgfx\\rogue\\rhd\\rhdqm.cl2\r\nplrgfx\\rogue\\rhd\\rhdst.cl2\r\nplrgfx\\rogue\\rhd\\rhdwl.cl2\r\nplrgfx\\rogue\\rhh\\rhhas.cl2\r\nplrgfx\\rogue\\rhh\\rhhat.cl2\r\nplrgfx\\rogue\\rhh\\rhhaw.cl2\r\nplrgfx\\rogue\\rhh\\rhhbl.cl2\r\nplrgfx\\rogue\\rhh\\rhhfm.cl2\r\nplrgfx\\rogue\\rhh\\rhhht.cl2\r\nplrgfx\\rogue\\rhh\\rhhlm.cl2\r\nplrgfx\\rogue\\rhh\\rhhqm.cl2\r\nplrgfx\\rogue\\rhh\\rhhst.cl2\r\nplrgfx\\rogue\\rhh\\rhhwl.cl2\r\nplrgfx\\rogue\\rhm\\rhmas.cl2\r\nplrgfx\\rogue\\rhm\\rhmat.cl2\r\nplrgfx\\rogue\\rhm\\rhmaw.cl2\r\nplrgfx\\rogue\\rhm\\rhmfm.cl2\r\nplrgfx\\rogue\\rhm\\rhmht.cl2\r\nplrgfx\\rogue\\rhm\\rhmlm.cl2\r\nplrgfx\\rogue\\rhm\\rhmqm.cl2\r\nplrgfx\\rogue\\rhm\\rhmst.cl2\r\nplrgfx\\rogue\\rhm\\rhmwl.cl2\r\nplrgfx\\rogue\\rhn\\rhnas.cl2\r\nplrgfx\\rogue\\rhn\\rhnat.cl2\r\nplrgfx\\rogue\\rhn\\rhnaw.cl2\r\nplrgfx\\rogue\\rhn\\rhndt.cl2\r\nplrgfx\\rogue\\rhn\\rhnfm.cl2\r\nplrgfx\\rogue\\rhn\\rhnht.cl2\r\nplrgfx\\rogue\\rhn\\rhnlm.cl2\r\nplrgfx\\rogue\\rhn\\rhnqm.cl2\r\nplrgfx\\rogue\\rhn\\rhnst.cl2\r\nplrgfx\\rogue\\rhn\\rhnwl.cl2\r\nplrgfx\\rogue\\rhs\\rhsas.cl2\r\nplrgfx\\rogue\\rhs\\rhsat.cl2\r\nplrgfx\\rogue\\rhs\\rhsaw.cl2\r\nplrgfx\\rogue\\rhs\\rhsfm.cl2\r\nplrgfx\\rogue\\rhs\\rhsht.cl2\r\nplrgfx\\rogue\\rhs\\rhslm.cl2\r\nplrgfx\\rogue\\rhs\\rhsqm.cl2\r\nplrgfx\\rogue\\rhs\\rhsst.cl2\r\nplrgfx\\rogue\\rhs\\rhswl.cl2\r\nplrgfx\\rogue\\rht\\rhtas.cl2\r\nplrgfx\\rogue\\rht\\rhtat.cl2\r\nplrgfx\\rogue\\rht\\rhtaw.cl2\r\nplrgfx\\rogue\\rht\\rhtfm.cl2\r\nplrgfx\\rogue\\rht\\rhtht.cl2\r\nplrgfx\\rogue\\rht\\rhtlm.cl2\r\nplrgfx\\rogue\\rht\\rhtqm.cl2\r\nplrgfx\\rogue\\rht\\rhtst.cl2\r\nplrgfx\\rogue\\rht\\rhtwl.cl2\r\nplrgfx\\rogue\\rhu\\rhuas.cl2\r\nplrgfx\\rogue\\rhu\\rhuat.cl2\r\nplrgfx\\rogue\\rhu\\rhuaw.cl2\r\nplrgfx\\rogue\\rhu\\rhubl.cl2\r\nplrgfx\\rogue\\rhu\\rhufm.cl2\r\nplrgfx\\rogue\\rhu\\rhuht.cl2\r\nplrgfx\\rogue\\rhu\\rhulm.cl2\r\nplrgfx\\rogue\\rhu\\rhuqm.cl2\r\nplrgfx\\rogue\\rhu\\rhust.cl2\r\nplrgfx\\rogue\\rhu\\rhuwl.cl2\r\nplrgfx\\rogue\\rla\\rlaas.cl2\r\nplrgfx\\rogue\\rla\\rlaat.cl2\r\nplrgfx\\rogue\\rla\\rlaaw.cl2\r\nplrgfx\\rogue\\rla\\rlafm.cl2\r\nplrgfx\\rogue\\rla\\rlaht.cl2\r\nplrgfx\\rogue\\rla\\rlalm.cl2\r\nplrgfx\\rogue\\rla\\rlaqm.cl2\r\nplrgfx\\rogue\\rla\\rlast.cl2\r\nplrgfx\\rogue\\rla\\rlawl.cl2\r\nplrgfx\\rogue\\rlb\\rlbas.cl2\r\nplrgfx\\rogue\\rlb\\rlbat.cl2\r\nplrgfx\\rogue\\rlb\\rlbaw.cl2\r\nplrgfx\\rogue\\rlb\\rlbfm.cl2\r\nplrgfx\\rogue\\rlb\\rlbht.cl2\r\nplrgfx\\rogue\\rlb\\rlblm.cl2\r\nplrgfx\\rogue\\rlb\\rlbqm.cl2\r\nplrgfx\\rogue\\rlb\\rlbst.cl2\r\nplrgfx\\rogue\\rlb\\rlbwl.cl2\r\nplrgfx\\rogue\\rld\\rldas.cl2\r\nplrgfx\\rogue\\rld\\rldat.cl2\r\nplrgfx\\rogue\\rld\\rldaw.cl2\r\nplrgfx\\rogue\\rld\\rldbl.cl2\r\nplrgfx\\rogue\\rld\\rldfm.cl2\r\nplrgfx\\rogue\\rld\\rldht.cl2\r\nplrgfx\\rogue\\rld\\rldlm.cl2\r\nplrgfx\\rogue\\rld\\rldqm.cl2\r\nplrgfx\\rogue\\rld\\rldst.cl2\r\nplrgfx\\rogue\\rld\\rldwl.cl2\r\nplrgfx\\rogue\\rlh\\rlhas.cl2\r\nplrgfx\\rogue\\rlh\\rlhat.cl2\r\nplrgfx\\rogue\\rlh\\rlhaw.cl2\r\nplrgfx\\rogue\\rlh\\rlhbl.cl2\r\nplrgfx\\rogue\\rlh\\rlhfm.cl2\r\nplrgfx\\rogue\\rlh\\rlhht.cl2\r\nplrgfx\\rogue\\rlh\\rlhlm.cl2\r\nplrgfx\\rogue\\rlh\\rlhqm.cl2\r\nplrgfx\\rogue\\rlh\\rlhst.cl2\r\nplrgfx\\rogue\\rlh\\rlhwl.cl2\r\nplrgfx\\rogue\\rlm\\rlmas.cl2\r\nplrgfx\\rogue\\rlm\\rlmat.cl2\r\nplrgfx\\rogue\\rlm\\rlmaw.cl2\r\nplrgfx\\rogue\\rlm\\rlmfm.cl2\r\nplrgfx\\rogue\\rlm\\rlmht.cl2\r\nplrgfx\\rogue\\rlm\\rlmlm.cl2\r\nplrgfx\\rogue\\rlm\\rlmqm.cl2\r\nplrgfx\\rogue\\rlm\\rlmst.cl2\r\nplrgfx\\rogue\\rlm\\rlmwl.cl2\r\nplrgfx\\rogue\\rln\\rlnas.cl2\r\nplrgfx\\rogue\\rln\\rlnat.cl2\r\nplrgfx\\rogue\\rln\\rlnaw.cl2\r\nplrgfx\\rogue\\rln\\rlndt.cl2\r\nplrgfx\\rogue\\rln\\rlnfm.cl2\r\nplrgfx\\rogue\\rln\\rlnht.cl2\r\nplrgfx\\rogue\\rln\\rlnlm.cl2\r\nplrgfx\\rogue\\rln\\rlnqm.cl2\r\nplrgfx\\rogue\\rln\\rlnst.cl2\r\nplrgfx\\rogue\\rln\\rlnwl.cl2\r\nplrgfx\\rogue\\rls\\rlsas.cl2\r\nplrgfx\\rogue\\rls\\rlsat.cl2\r\nplrgfx\\rogue\\rls\\rlsaw.cl2\r\nplrgfx\\rogue\\rls\\rlsfm.cl2\r\nplrgfx\\rogue\\rls\\rlsht.cl2\r\nplrgfx\\rogue\\rls\\rlslm.cl2\r\nplrgfx\\rogue\\rls\\rlsqm.cl2\r\nplrgfx\\rogue\\rls\\rlsst.cl2\r\nplrgfx\\rogue\\rls\\rlswl.cl2\r\nplrgfx\\rogue\\rlt\\rltas.cl2\r\nplrgfx\\rogue\\rlt\\rltat.cl2\r\nplrgfx\\rogue\\rlt\\rltaw.cl2\r\nplrgfx\\rogue\\rlt\\rltfm.cl2\r\nplrgfx\\rogue\\rlt\\rltht.cl2\r\nplrgfx\\rogue\\rlt\\rltlm.cl2\r\nplrgfx\\rogue\\rlt\\rltqm.cl2\r\nplrgfx\\rogue\\rlt\\rltst.cl2\r\nplrgfx\\rogue\\rlt\\rltwl.cl2\r\nplrgfx\\rogue\\rlu\\rluas.cl2\r\nplrgfx\\rogue\\rlu\\rluat.cl2\r\nplrgfx\\rogue\\rlu\\rluaw.cl2\r\nplrgfx\\rogue\\rlu\\rlubl.cl2\r\nplrgfx\\rogue\\rlu\\rlufm.cl2\r\nplrgfx\\rogue\\rlu\\rluht.cl2\r\nplrgfx\\rogue\\rlu\\rlulm.cl2\r\nplrgfx\\rogue\\rlu\\rluqm.cl2\r\nplrgfx\\rogue\\rlu\\rlust.cl2\r\nplrgfx\\rogue\\rlu\\rluwl.cl2\r\nplrgfx\\rogue\\rma\\rmaas.cl2\r\nplrgfx\\rogue\\rma\\rmaat.cl2\r\nplrgfx\\rogue\\rma\\rmaaw.cl2\r\nplrgfx\\rogue\\rma\\rmafm.cl2\r\nplrgfx\\rogue\\rma\\rmaht.cl2\r\nplrgfx\\rogue\\rma\\rmalm.cl2\r\nplrgfx\\rogue\\rma\\rmaqm.cl2\r\nplrgfx\\rogue\\rma\\rmast.cl2\r\nplrgfx\\rogue\\rma\\rmawl.cl2\r\nplrgfx\\rogue\\rmb\\rmbas.cl2\r\nplrgfx\\rogue\\rmb\\rmbat.cl2\r\nplrgfx\\rogue\\rmb\\rmbaw.cl2\r\nplrgfx\\rogue\\rmb\\rmbfm.cl2\r\nplrgfx\\rogue\\rmb\\rmbht.cl2\r\nplrgfx\\rogue\\rmb\\rmblm.cl2\r\nplrgfx\\rogue\\rmb\\rmbqm.cl2\r\nplrgfx\\rogue\\rmb\\rmbst.cl2\r\nplrgfx\\rogue\\rmb\\rmbwl.cl2\r\nplrgfx\\rogue\\rmd\\rmdas.cl2\r\nplrgfx\\rogue\\rmd\\rmdat.cl2\r\nplrgfx\\rogue\\rmd\\rmdaw.cl2\r\nplrgfx\\rogue\\rmd\\rmdbl.cl2\r\nplrgfx\\rogue\\rmd\\rmdfm.cl2\r\nplrgfx\\rogue\\rmd\\rmdht.cl2\r\nplrgfx\\rogue\\rmd\\rmdlm.cl2\r\nplrgfx\\rogue\\rmd\\rmdqm.cl2\r\nplrgfx\\rogue\\rmd\\rmdst.cl2\r\nplrgfx\\rogue\\rmd\\rmdwl.cl2\r\nplrgfx\\rogue\\rmh\\rmhas.cl2\r\nplrgfx\\rogue\\rmh\\rmhat.cl2\r\nplrgfx\\rogue\\rmh\\rmhaw.cl2\r\nplrgfx\\rogue\\rmh\\rmhbl.cl2\r\nplrgfx\\rogue\\rmh\\rmhfm.cl2\r\nplrgfx\\rogue\\rmh\\rmhht.cl2\r\nplrgfx\\rogue\\rmh\\rmhlm.cl2\r\nplrgfx\\rogue\\rmh\\rmhqm.cl2\r\nplrgfx\\rogue\\rmh\\rmhst.cl2\r\nplrgfx\\rogue\\rmh\\rmhwl.cl2\r\nplrgfx\\rogue\\rmm\\rmmas.cl2\r\nplrgfx\\rogue\\rmm\\rmmat.cl2\r\nplrgfx\\rogue\\rmm\\rmmaw.cl2\r\nplrgfx\\rogue\\rmm\\rmmfm.cl2\r\nplrgfx\\rogue\\rmm\\rmmht.cl2\r\nplrgfx\\rogue\\rmm\\rmmlm.cl2\r\nplrgfx\\rogue\\rmm\\rmmqm.cl2\r\nplrgfx\\rogue\\rmm\\rmmst.cl2\r\nplrgfx\\rogue\\rmm\\rmmwl.cl2\r\nplrgfx\\rogue\\rmn\\rmnas.cl2\r\nplrgfx\\rogue\\rmn\\rmnat.cl2\r\nplrgfx\\rogue\\rmn\\rmnaw.cl2\r\nplrgfx\\rogue\\rmn\\rmndt.cl2\r\nplrgfx\\rogue\\rmn\\rmnfm.cl2\r\nplrgfx\\rogue\\rmn\\rmnht.cl2\r\nplrgfx\\rogue\\rmn\\rmnlm.cl2\r\nplrgfx\\rogue\\rmn\\rmnqm.cl2\r\nplrgfx\\rogue\\rmn\\rmnst.cl2\r\nplrgfx\\rogue\\rmn\\rmnwl.cl2\r\nplrgfx\\rogue\\rms\\rmsas.cl2\r\nplrgfx\\rogue\\rms\\rmsat.cl2\r\nplrgfx\\rogue\\rms\\rmsaw.cl2\r\nplrgfx\\rogue\\rms\\rmsfm.cl2\r\nplrgfx\\rogue\\rms\\rmsht.cl2\r\nplrgfx\\rogue\\rms\\rmslm.cl2\r\nplrgfx\\rogue\\rms\\rmsqm.cl2\r\nplrgfx\\rogue\\rms\\rmsst.cl2\r\nplrgfx\\rogue\\rms\\rmswl.cl2\r\nplrgfx\\rogue\\rmt\\rmtas.cl2\r\nplrgfx\\rogue\\rmt\\rmtat.cl2\r\nplrgfx\\rogue\\rmt\\rmtaw.cl2\r\nplrgfx\\rogue\\rmt\\rmtfm.cl2\r\nplrgfx\\rogue\\rmt\\rmtht.cl2\r\nplrgfx\\rogue\\rmt\\rmtlm.cl2\r\nplrgfx\\rogue\\rmt\\rmtqm.cl2\r\nplrgfx\\rogue\\rmt\\rmtst.cl2\r\nplrgfx\\rogue\\rmt\\rmtwl.cl2\r\nplrgfx\\rogue\\rmu\\rmuas.cl2\r\nplrgfx\\rogue\\rmu\\rmuat.cl2\r\nplrgfx\\rogue\\rmu\\rmuaw.cl2\r\nplrgfx\\rogue\\rmu\\rmubl.cl2\r\nplrgfx\\rogue\\rmu\\rmufm.cl2\r\nplrgfx\\rogue\\rmu\\rmuht.cl2\r\nplrgfx\\rogue\\rmu\\rmulm.cl2\r\nplrgfx\\rogue\\rmu\\rmuqm.cl2\r\nplrgfx\\rogue\\rmu\\rmust.cl2\r\nplrgfx\\rogue\\rmu\\rmuwl.cl2\r\nplrgfx\\sorceror\\sha\\shaas.cl2\r\nplrgfx\\sorceror\\sha\\shaat.cl2\r\nplrgfx\\sorceror\\sha\\shaaw.cl2\r\nplrgfx\\sorceror\\sha\\shafm.cl2\r\nplrgfx\\sorceror\\sha\\shaht.cl2\r\nplrgfx\\sorceror\\sha\\shalm.cl2\r\nplrgfx\\sorceror\\sha\\shaqm.cl2\r\nplrgfx\\sorceror\\sha\\shast.cl2\r\nplrgfx\\sorceror\\sha\\shawl.cl2\r\nplrgfx\\sorceror\\shb\\shbas.cl2\r\nplrgfx\\sorceror\\shb\\shbat.cl2\r\nplrgfx\\sorceror\\shb\\shbaw.cl2\r\nplrgfx\\sorceror\\shb\\shbfm.cl2\r\nplrgfx\\sorceror\\shb\\shbht.cl2\r\nplrgfx\\sorceror\\shb\\shblm.cl2\r\nplrgfx\\sorceror\\shb\\shbqm.cl2\r\nplrgfx\\sorceror\\shb\\shbst.cl2\r\nplrgfx\\sorceror\\shb\\shbwl.cl2\r\nplrgfx\\sorceror\\shd\\shdas.cl2\r\nplrgfx\\sorceror\\shd\\shdat.cl2\r\nplrgfx\\sorceror\\shd\\shdaw.cl2\r\nplrgfx\\sorceror\\shd\\shdbl.cl2\r\nplrgfx\\sorceror\\shd\\shdfm.cl2\r\nplrgfx\\sorceror\\shd\\shdht.cl2\r\nplrgfx\\sorceror\\shd\\shdlm.cl2\r\nplrgfx\\sorceror\\shd\\shdqm.cl2\r\nplrgfx\\sorceror\\shd\\shdst.cl2\r\nplrgfx\\sorceror\\shd\\shdwl.cl2\r\nplrgfx\\sorceror\\shh\\shhas.cl2\r\nplrgfx\\sorceror\\shh\\shhat.cl2\r\nplrgfx\\sorceror\\shh\\shhaw.cl2\r\nplrgfx\\sorceror\\shh\\shhbl.cl2\r\nplrgfx\\sorceror\\shh\\shhfm.cl2\r\nplrgfx\\sorceror\\shh\\shhht.cl2\r\nplrgfx\\sorceror\\shh\\shhlm.cl2\r\nplrgfx\\sorceror\\shh\\shhqm.cl2\r\nplrgfx\\sorceror\\shh\\shhst.cl2\r\nplrgfx\\sorceror\\shh\\shhwl.cl2\r\nplrgfx\\sorceror\\shm\\shmas.cl2\r\nplrgfx\\sorceror\\shm\\shmat.cl2\r\nplrgfx\\sorceror\\shm\\shmaw.cl2\r\nplrgfx\\sorceror\\shm\\shmfm.cl2\r\nplrgfx\\sorceror\\shm\\shmht.cl2\r\nplrgfx\\sorceror\\shm\\shmlm.cl2\r\nplrgfx\\sorceror\\shm\\shmqm.cl2\r\nplrgfx\\sorceror\\shm\\shmst.cl2\r\nplrgfx\\sorceror\\shm\\shmwl.cl2\r\nplrgfx\\sorceror\\shn\\shnas.cl2\r\nplrgfx\\sorceror\\shn\\shnat.cl2\r\nplrgfx\\sorceror\\shn\\shnaw.cl2\r\nplrgfx\\sorceror\\shn\\shndt.cl2\r\nplrgfx\\sorceror\\shn\\shnfm.cl2\r\nplrgfx\\sorceror\\shn\\shnht.cl2\r\nplrgfx\\sorceror\\shn\\shnlm.cl2\r\nplrgfx\\sorceror\\shn\\shnqm.cl2\r\nplrgfx\\sorceror\\shn\\shnst.cl2\r\nplrgfx\\sorceror\\shn\\shnwl.cl2\r\nplrgfx\\sorceror\\shs\\shsas.cl2\r\nplrgfx\\sorceror\\shs\\shsat.cl2\r\nplrgfx\\sorceror\\shs\\shsaw.cl2\r\nplrgfx\\sorceror\\shs\\shsfm.cl2\r\nplrgfx\\sorceror\\shs\\shsht.cl2\r\nplrgfx\\sorceror\\shs\\shslm.cl2\r\nplrgfx\\sorceror\\shs\\shsqm.cl2\r\nplrgfx\\sorceror\\shs\\shsst.cl2\r\nplrgfx\\sorceror\\shs\\shswl.cl2\r\nplrgfx\\sorceror\\sht\\shtas.cl2\r\nplrgfx\\sorceror\\sht\\shtat.cl2\r\nplrgfx\\sorceror\\sht\\shtaw.cl2\r\nplrgfx\\sorceror\\sht\\shtfm.cl2\r\nplrgfx\\sorceror\\sht\\shtht.cl2\r\nplrgfx\\sorceror\\sht\\shtlm.cl2\r\nplrgfx\\sorceror\\sht\\shtqm.cl2\r\nplrgfx\\sorceror\\sht\\shtst.cl2\r\nplrgfx\\sorceror\\sht\\shtwl.cl2\r\nplrgfx\\sorceror\\shu\\shuas.cl2\r\nplrgfx\\sorceror\\shu\\shuat.cl2\r\nplrgfx\\sorceror\\shu\\shuaw.cl2\r\nplrgfx\\sorceror\\shu\\shubl.cl2\r\nplrgfx\\sorceror\\shu\\shufm.cl2\r\nplrgfx\\sorceror\\shu\\shuht.cl2\r\nplrgfx\\sorceror\\shu\\shulm.cl2\r\nplrgfx\\sorceror\\shu\\shuqm.cl2\r\nplrgfx\\sorceror\\shu\\shust.cl2\r\nplrgfx\\sorceror\\shu\\shuwl.cl2\r\nplrgfx\\sorceror\\sla\\slaas.cl2\r\nplrgfx\\sorceror\\sla\\slaat.cl2\r\nplrgfx\\sorceror\\sla\\slaaw.cl2\r\nplrgfx\\sorceror\\sla\\slafm.cl2\r\nplrgfx\\sorceror\\sla\\slaht.cl2\r\nplrgfx\\sorceror\\sla\\slalm.cl2\r\nplrgfx\\sorceror\\sla\\slaqm.cl2\r\nplrgfx\\sorceror\\sla\\slast.cl2\r\nplrgfx\\sorceror\\sla\\slawl.cl2\r\nplrgfx\\sorceror\\slb\\slbas.cl2\r\nplrgfx\\sorceror\\slb\\slbat.cl2\r\nplrgfx\\sorceror\\slb\\slbaw.cl2\r\nplrgfx\\sorceror\\slb\\slbfm.cl2\r\nplrgfx\\sorceror\\slb\\slbht.cl2\r\nplrgfx\\sorceror\\slb\\slblm.cl2\r\nplrgfx\\sorceror\\slb\\slbqm.cl2\r\nplrgfx\\sorceror\\slb\\slbst.cl2\r\nplrgfx\\sorceror\\slb\\slbwl.cl2\r\nplrgfx\\sorceror\\sld\\sldas.cl2\r\nplrgfx\\sorceror\\sld\\sldat.cl2\r\nplrgfx\\sorceror\\sld\\sldaw.cl2\r\nplrgfx\\sorceror\\sld\\sldbl.cl2\r\nplrgfx\\sorceror\\sld\\sldfm.cl2\r\nplrgfx\\sorceror\\sld\\sldht.cl2\r\nplrgfx\\sorceror\\sld\\sldlm.cl2\r\nplrgfx\\sorceror\\sld\\sldqm.cl2\r\nplrgfx\\sorceror\\sld\\sldst.cl2\r\nplrgfx\\sorceror\\sld\\sldwl.cl2\r\nplrgfx\\sorceror\\slh\\slhas.cl2\r\nplrgfx\\sorceror\\slh\\slhat.cl2\r\nplrgfx\\sorceror\\slh\\slhaw.cl2\r\nplrgfx\\sorceror\\slh\\slhbl.cl2\r\nplrgfx\\sorceror\\slh\\slhfm.cl2\r\nplrgfx\\sorceror\\slh\\slhht.cl2\r\nplrgfx\\sorceror\\slh\\slhlm.cl2\r\nplrgfx\\sorceror\\slh\\slhqm.cl2\r\nplrgfx\\sorceror\\slh\\slhst.cl2\r\nplrgfx\\sorceror\\slh\\slhwl.cl2\r\nplrgfx\\sorceror\\slm\\slmas.cl2\r\nplrgfx\\sorceror\\slm\\slmat.cl2\r\nplrgfx\\sorceror\\slm\\slmaw.cl2\r\nplrgfx\\sorceror\\slm\\slmfm.cl2\r\nplrgfx\\sorceror\\slm\\slmht.cl2\r\nplrgfx\\sorceror\\slm\\slmlm.cl2\r\nplrgfx\\sorceror\\slm\\slmqm.cl2\r\nplrgfx\\sorceror\\slm\\slmst.cl2\r\nplrgfx\\sorceror\\slm\\slmwl.cl2\r\nplrgfx\\sorceror\\sln\\slnas.cl2\r\nplrgfx\\sorceror\\sln\\slnat.cl2\r\nplrgfx\\sorceror\\sln\\slnaw.cl2\r\nplrgfx\\sorceror\\sln\\slndt.cl2\r\nplrgfx\\sorceror\\sln\\slnfm.cl2\r\nplrgfx\\sorceror\\sln\\slnht.cl2\r\nplrgfx\\sorceror\\sln\\slnlm.cl2\r\nplrgfx\\sorceror\\sln\\slnqm.cl2\r\nplrgfx\\sorceror\\sln\\slnst.cl2\r\nplrgfx\\sorceror\\sln\\slnwl.cl2\r\nplrgfx\\sorceror\\sls\\slsas.cl2\r\nplrgfx\\sorceror\\sls\\slsat.cl2\r\nplrgfx\\sorceror\\sls\\slsaw.cl2\r\nplrgfx\\sorceror\\sls\\slsfm.cl2\r\nplrgfx\\sorceror\\sls\\slsht.cl2\r\nplrgfx\\sorceror\\sls\\slslm.cl2\r\nplrgfx\\sorceror\\sls\\slsqm.cl2\r\nplrgfx\\sorceror\\sls\\slsst.cl2\r\nplrgfx\\sorceror\\sls\\slswl.cl2\r\nplrgfx\\sorceror\\slt\\sltas.cl2\r\nplrgfx\\sorceror\\slt\\sltat.cl2\r\nplrgfx\\sorceror\\slt\\sltaw.cl2\r\nplrgfx\\sorceror\\slt\\sltfm.cl2\r\nplrgfx\\sorceror\\slt\\sltht.cl2\r\nplrgfx\\sorceror\\slt\\sltlm.cl2\r\nplrgfx\\sorceror\\slt\\sltqm.cl2\r\nplrgfx\\sorceror\\slt\\sltst.cl2\r\nplrgfx\\sorceror\\slt\\sltwl.cl2\r\nplrgfx\\sorceror\\slu\\sluas.cl2\r\nplrgfx\\sorceror\\slu\\sluat.cl2\r\nplrgfx\\sorceror\\slu\\sluaw.cl2\r\nplrgfx\\sorceror\\slu\\slubl.cl2\r\nplrgfx\\sorceror\\slu\\slufm.cl2\r\nplrgfx\\sorceror\\slu\\sluht.cl2\r\nplrgfx\\sorceror\\slu\\slulm.cl2\r\nplrgfx\\sorceror\\slu\\sluqm.cl2\r\nplrgfx\\sorceror\\slu\\slust.cl2\r\nplrgfx\\sorceror\\slu\\sluwl.cl2\r\nplrgfx\\sorceror\\sma\\smaas.cl2\r\nplrgfx\\sorceror\\sma\\smaat.cl2\r\nplrgfx\\sorceror\\sma\\smaaw.cl2\r\nplrgfx\\sorceror\\sma\\smafm.cl2\r\nplrgfx\\sorceror\\sma\\smaht.cl2\r\nplrgfx\\sorceror\\sma\\smalm.cl2\r\nplrgfx\\sorceror\\sma\\smaqm.cl2\r\nplrgfx\\sorceror\\sma\\smast.cl2\r\nplrgfx\\sorceror\\sma\\smawl.cl2\r\nplrgfx\\sorceror\\smb\\smbas.cl2\r\nplrgfx\\sorceror\\smb\\smbat.cl2\r\nplrgfx\\sorceror\\smb\\smbaw.cl2\r\nplrgfx\\sorceror\\smb\\smbfm.cl2\r\nplrgfx\\sorceror\\smb\\smbht.cl2\r\nplrgfx\\sorceror\\smb\\smblm.cl2\r\nplrgfx\\sorceror\\smb\\smbqm.cl2\r\nplrgfx\\sorceror\\smb\\smbst.cl2\r\nplrgfx\\sorceror\\smb\\smbwl.cl2\r\nplrgfx\\sorceror\\smd\\smdas.cl2\r\nplrgfx\\sorceror\\smd\\smdat.cl2\r\nplrgfx\\sorceror\\smd\\smdaw.cl2\r\nplrgfx\\sorceror\\smd\\smdbl.cl2\r\nplrgfx\\sorceror\\smd\\smdfm.cl2\r\nplrgfx\\sorceror\\smd\\smdht.cl2\r\nplrgfx\\sorceror\\smd\\smdlm.cl2\r\nplrgfx\\sorceror\\smd\\smdqm.cl2\r\nplrgfx\\sorceror\\smd\\smdst.cl2\r\nplrgfx\\sorceror\\smd\\smdwl.cl2\r\nplrgfx\\sorceror\\smh\\smhas.cl2\r\nplrgfx\\sorceror\\smh\\smhat.cl2\r\nplrgfx\\sorceror\\smh\\smhaw.cl2\r\nplrgfx\\sorceror\\smh\\smhbl.cl2\r\nplrgfx\\sorceror\\smh\\smhfm.cl2\r\nplrgfx\\sorceror\\smh\\smhht.cl2\r\nplrgfx\\sorceror\\smh\\smhlm.cl2\r\nplrgfx\\sorceror\\smh\\smhqm.cl2\r\nplrgfx\\sorceror\\smh\\smhst.cl2\r\nplrgfx\\sorceror\\smh\\smhwl.cl2\r\nplrgfx\\sorceror\\smm\\smmas.cl2\r\nplrgfx\\sorceror\\smm\\smmat.cl2\r\nplrgfx\\sorceror\\smm\\smmaw.cl2\r\nplrgfx\\sorceror\\smm\\smmfm.cl2\r\nplrgfx\\sorceror\\smm\\smmht.cl2\r\nplrgfx\\sorceror\\smm\\smmlm.cl2\r\nplrgfx\\sorceror\\smm\\smmqm.cl2\r\nplrgfx\\sorceror\\smm\\smmst.cl2\r\nplrgfx\\sorceror\\smm\\smmwl.cl2\r\nplrgfx\\sorceror\\smn\\smnas.cl2\r\nplrgfx\\sorceror\\smn\\smnat.cl2\r\nplrgfx\\sorceror\\smn\\smnaw.cl2\r\nplrgfx\\sorceror\\smn\\smndt.cl2\r\nplrgfx\\sorceror\\smn\\smnfm.cl2\r\nplrgfx\\sorceror\\smn\\smnht.cl2\r\nplrgfx\\sorceror\\smn\\smnlm.cl2\r\nplrgfx\\sorceror\\smn\\smnqm.cl2\r\nplrgfx\\sorceror\\smn\\smnst.cl2\r\nplrgfx\\sorceror\\smn\\smnwl.cl2\r\nplrgfx\\sorceror\\sms\\smsas.cl2\r\nplrgfx\\sorceror\\sms\\smsat.cl2\r\nplrgfx\\sorceror\\sms\\smsaw.cl2\r\nplrgfx\\sorceror\\sms\\smsfm.cl2\r\nplrgfx\\sorceror\\sms\\smsht.cl2\r\nplrgfx\\sorceror\\sms\\smslm.cl2\r\nplrgfx\\sorceror\\sms\\smsqm.cl2\r\nplrgfx\\sorceror\\sms\\smsst.cl2\r\nplrgfx\\sorceror\\sms\\smswl.cl2\r\nplrgfx\\sorceror\\smt\\smtas.cl2\r\nplrgfx\\sorceror\\smt\\smtat.cl2\r\nplrgfx\\sorceror\\smt\\smtaw.cl2\r\nplrgfx\\sorceror\\smt\\smtfm.cl2\r\nplrgfx\\sorceror\\smt\\smtht.cl2\r\nplrgfx\\sorceror\\smt\\smtlm.cl2\r\nplrgfx\\sorceror\\smt\\smtqm.cl2\r\nplrgfx\\sorceror\\smt\\smtst.cl2\r\nplrgfx\\sorceror\\smt\\smtwl.cl2\r\nplrgfx\\sorceror\\smu\\smuas.cl2\r\nplrgfx\\sorceror\\smu\\smuat.cl2\r\nplrgfx\\sorceror\\smu\\smuaw.cl2\r\nplrgfx\\sorceror\\smu\\smubl.cl2\r\nplrgfx\\sorceror\\smu\\smufm.cl2\r\nplrgfx\\sorceror\\smu\\smuht.cl2\r\nplrgfx\\sorceror\\smu\\smulm.cl2\r\nplrgfx\\sorceror\\smu\\smuqm.cl2\r\nplrgfx\\sorceror\\smu\\smust.cl2\r\nplrgfx\\sorceror\\smu\\smuwl.cl2\r\nplrgfx\\stone.trn\r\nplrgfx\\warrior\\wha\\whaas.cl2\r\nplrgfx\\warrior\\wha\\whaat.cl2\r\nplrgfx\\warrior\\wha\\whaaw.cl2\r\nplrgfx\\warrior\\wha\\whafm.cl2\r\nplrgfx\\warrior\\wha\\whaht.cl2\r\nplrgfx\\warrior\\wha\\whalm.cl2\r\nplrgfx\\warrior\\wha\\whaqm.cl2\r\nplrgfx\\warrior\\wha\\whast.cl2\r\nplrgfx\\warrior\\wha\\whawl.cl2\r\nplrgfx\\warrior\\whb\\whbas.cl2\r\nplrgfx\\warrior\\whb\\whbat.cl2\r\nplrgfx\\warrior\\whb\\whbaw.cl2\r\nplrgfx\\warrior\\whb\\whbfm.cl2\r\nplrgfx\\warrior\\whb\\whbht.cl2\r\nplrgfx\\warrior\\whb\\whblm.cl2\r\nplrgfx\\warrior\\whb\\whbqm.cl2\r\nplrgfx\\warrior\\whb\\whbst.cl2\r\nplrgfx\\warrior\\whb\\whbwl.cl2\r\nplrgfx\\warrior\\whd\\whdas.cl2\r\nplrgfx\\warrior\\whd\\whdat.cl2\r\nplrgfx\\warrior\\whd\\whdaw.cl2\r\nplrgfx\\warrior\\whd\\whdbl.cl2\r\nplrgfx\\warrior\\whd\\whdfm.cl2\r\nplrgfx\\warrior\\whd\\whdht.cl2\r\nplrgfx\\warrior\\whd\\whdlm.cl2\r\nplrgfx\\warrior\\whd\\whdqm.cl2\r\nplrgfx\\warrior\\whd\\whdst.cl2\r\nplrgfx\\warrior\\whd\\whdwl.cl2\r\nplrgfx\\warrior\\whh\\whhas.cl2\r\nplrgfx\\warrior\\whh\\whhat.cl2\r\nplrgfx\\warrior\\whh\\whhaw.cl2\r\nplrgfx\\warrior\\whh\\whhbl.cl2\r\nplrgfx\\warrior\\whh\\whhfm.cl2\r\nplrgfx\\warrior\\whh\\whhht.cl2\r\nplrgfx\\warrior\\whh\\whhlm.cl2\r\nplrgfx\\warrior\\whh\\whhqm.cl2\r\nplrgfx\\warrior\\whh\\whhst.cl2\r\nplrgfx\\warrior\\whh\\whhwl.cl2\r\nplrgfx\\warrior\\whm\\whmas.cl2\r\nplrgfx\\warrior\\whm\\whmat.cl2\r\nplrgfx\\warrior\\whm\\whmaw.cl2\r\nplrgfx\\warrior\\whm\\whmfm.cl2\r\nplrgfx\\warrior\\whm\\whmht.cl2\r\nplrgfx\\warrior\\whm\\whmlm.cl2\r\nplrgfx\\warrior\\whm\\whmqm.cl2\r\nplrgfx\\warrior\\whm\\whmst.cl2\r\nplrgfx\\warrior\\whm\\whmwl.cl2\r\nplrgfx\\warrior\\whn\\whnas.cl2\r\nplrgfx\\warrior\\whn\\whnat.cl2\r\nplrgfx\\warrior\\whn\\whnaw.cl2\r\nplrgfx\\warrior\\whn\\whndt.cl2\r\nplrgfx\\warrior\\whn\\whnfm.cl2\r\nplrgfx\\warrior\\whn\\whnht.cl2\r\nplrgfx\\warrior\\whn\\whnlm.cl2\r\nplrgfx\\warrior\\whn\\whnqm.cl2\r\nplrgfx\\warrior\\whn\\whnst.cl2\r\nplrgfx\\warrior\\whn\\whnwl.cl2\r\nplrgfx\\warrior\\whs\\whsas.cl2\r\nplrgfx\\warrior\\whs\\whsat.cl2\r\nplrgfx\\warrior\\whs\\whsaw.cl2\r\nplrgfx\\warrior\\whs\\whsfm.cl2\r\nplrgfx\\warrior\\whs\\whsht.cl2\r\nplrgfx\\warrior\\whs\\whslm.cl2\r\nplrgfx\\warrior\\whs\\whsqm.cl2\r\nplrgfx\\warrior\\whs\\whsst.cl2\r\nplrgfx\\warrior\\whs\\whswl.cl2\r\nplrgfx\\warrior\\wht\\whtas.cl2\r\nplrgfx\\warrior\\wht\\whtat.cl2\r\nplrgfx\\warrior\\wht\\whtaw.cl2\r\nplrgfx\\warrior\\wht\\whtfm.cl2\r\nplrgfx\\warrior\\wht\\whtht.cl2\r\nplrgfx\\warrior\\wht\\whtlm.cl2\r\nplrgfx\\warrior\\wht\\whtqm.cl2\r\nplrgfx\\warrior\\wht\\whtst.cl2\r\nplrgfx\\warrior\\wht\\whtwl.cl2\r\nplrgfx\\warrior\\whu\\whuas.cl2\r\nplrgfx\\warrior\\whu\\whuat.cl2\r\nplrgfx\\warrior\\whu\\whuaw.cl2\r\nplrgfx\\warrior\\whu\\whubl.cl2\r\nplrgfx\\warrior\\whu\\whufm.cl2\r\nplrgfx\\warrior\\whu\\whuht.cl2\r\nplrgfx\\warrior\\whu\\whulm.cl2\r\nplrgfx\\warrior\\whu\\whuqm.cl2\r\nplrgfx\\warrior\\whu\\whust.cl2\r\nplrgfx\\warrior\\whu\\whuwl.cl2\r\nplrgfx\\warrior\\wla\\wlaas.cl2\r\nplrgfx\\warrior\\wla\\wlaat.cl2\r\nplrgfx\\warrior\\wla\\wlaaw.cl2\r\nplrgfx\\warrior\\wla\\wlafm.cl2\r\nplrgfx\\warrior\\wla\\wlaht.cl2\r\nplrgfx\\warrior\\wla\\wlalm.cl2\r\nplrgfx\\warrior\\wla\\wlaqm.cl2\r\nplrgfx\\warrior\\wla\\wlast.cl2\r\nplrgfx\\warrior\\wla\\wlawl.cl2\r\nplrgfx\\warrior\\wlb\\wlbas.cl2\r\nplrgfx\\warrior\\wlb\\wlbat.cl2\r\nplrgfx\\warrior\\wlb\\wlbaw.cl2\r\nplrgfx\\warrior\\wlb\\wlbfm.cl2\r\nplrgfx\\warrior\\wlb\\wlbht.cl2\r\nplrgfx\\warrior\\wlb\\wlblm.cl2\r\nplrgfx\\warrior\\wlb\\wlbqm.cl2\r\nplrgfx\\warrior\\wlb\\wlbst.cl2\r\nplrgfx\\warrior\\wlb\\wlbwl.cl2\r\nplrgfx\\warrior\\wld\\wldas.cl2\r\nplrgfx\\warrior\\wld\\wldat.cl2\r\nplrgfx\\warrior\\wld\\wldaw.cl2\r\nplrgfx\\warrior\\wld\\wldbl.cl2\r\nplrgfx\\warrior\\wld\\wldfm.cl2\r\nplrgfx\\warrior\\wld\\wldht.cl2\r\nplrgfx\\warrior\\wld\\wldlm.cl2\r\nplrgfx\\warrior\\wld\\wldqm.cl2\r\nplrgfx\\warrior\\wld\\wldst.cl2\r\nplrgfx\\warrior\\wld\\wldwl.cl2\r\nplrgfx\\warrior\\wlh\\wlhas.cl2\r\nplrgfx\\warrior\\wlh\\wlhat.cl2\r\nplrgfx\\warrior\\wlh\\wlhaw.cl2\r\nplrgfx\\warrior\\wlh\\wlhbl.cl2\r\nplrgfx\\warrior\\wlh\\wlhfm.cl2\r\nplrgfx\\warrior\\wlh\\wlhht.cl2\r\nplrgfx\\warrior\\wlh\\wlhlm.cl2\r\nplrgfx\\warrior\\wlh\\wlhqm.cl2\r\nplrgfx\\warrior\\wlh\\wlhst.cl2\r\nplrgfx\\warrior\\wlh\\wlhwl.cl2\r\nplrgfx\\warrior\\wlm\\wlmas.cl2\r\nplrgfx\\warrior\\wlm\\wlmat.cl2\r\nplrgfx\\warrior\\wlm\\wlmaw.cl2\r\nplrgfx\\warrior\\wlm\\wlmfm.cl2\r\nplrgfx\\warrior\\wlm\\wlmht.cl2\r\nplrgfx\\warrior\\wlm\\wlmlm.cl2\r\nplrgfx\\warrior\\wlm\\wlmqm.cl2\r\nplrgfx\\warrior\\wlm\\wlmst.cl2\r\nplrgfx\\warrior\\wlm\\wlmwl.cl2\r\nplrgfx\\warrior\\wln\\wlnas.cl2\r\nplrgfx\\warrior\\wln\\wlnat.cl2\r\nplrgfx\\warrior\\wln\\wlnaw.cl2\r\nplrgfx\\warrior\\wln\\wlndt.cl2\r\nplrgfx\\warrior\\wln\\wlnfm.cl2\r\nplrgfx\\warrior\\wln\\wlnht.cl2\r\nplrgfx\\warrior\\wln\\wlnlm.cl2\r\nplrgfx\\warrior\\wln\\wlnqm.cl2\r\nplrgfx\\warrior\\wln\\wlnst.cl2\r\nplrgfx\\warrior\\wln\\wlnwl.cl2\r\nplrgfx\\warrior\\wls\\wlsas.cl2\r\nplrgfx\\warrior\\wls\\wlsat.cl2\r\nplrgfx\\warrior\\wls\\wlsaw.cl2\r\nplrgfx\\warrior\\wls\\wlsfm.cl2\r\nplrgfx\\warrior\\wls\\wlsht.cl2\r\nplrgfx\\warrior\\wls\\wlslm.cl2\r\nplrgfx\\warrior\\wls\\wlsqm.cl2\r\nplrgfx\\warrior\\wls\\wlsst.cl2\r\nplrgfx\\warrior\\wls\\wlswl.cl2\r\nplrgfx\\warrior\\wlt\\wltas.cl2\r\nplrgfx\\warrior\\wlt\\wltat.cl2\r\nplrgfx\\warrior\\wlt\\wltaw.cl2\r\nplrgfx\\warrior\\wlt\\wltfm.cl2\r\nplrgfx\\warrior\\wlt\\wltht.cl2\r\nplrgfx\\warrior\\wlt\\wltlm.cl2\r\nplrgfx\\warrior\\wlt\\wltqm.cl2\r\nplrgfx\\warrior\\wlt\\wltst.cl2\r\nplrgfx\\warrior\\wlt\\wltwl.cl2\r\nplrgfx\\warrior\\wlu\\wluas.cl2\r\nplrgfx\\warrior\\wlu\\wluat.cl2\r\nplrgfx\\warrior\\wlu\\wluaw.cl2\r\nplrgfx\\warrior\\wlu\\wlubl.cl2\r\nplrgfx\\warrior\\wlu\\wlufm.cl2\r\nplrgfx\\warrior\\wlu\\wluht.cl2\r\nplrgfx\\warrior\\wlu\\wlulm.cl2\r\nplrgfx\\warrior\\wlu\\wluqm.cl2\r\nplrgfx\\warrior\\wlu\\wlust.cl2\r\nplrgfx\\warrior\\wlu\\wluwl.cl2\r\nplrgfx\\warrior\\wma\\wmaas.cl2\r\nplrgfx\\warrior\\wma\\wmaat.cl2\r\nplrgfx\\warrior\\wma\\wmaaw.cl2\r\nplrgfx\\warrior\\wma\\wmafm.cl2\r\nplrgfx\\warrior\\wma\\wmaht.cl2\r\nplrgfx\\warrior\\wma\\wmalm.cl2\r\nplrgfx\\warrior\\wma\\wmaqm.cl2\r\nplrgfx\\warrior\\wma\\wmast.cl2\r\nplrgfx\\warrior\\wma\\wmawl.cl2\r\nplrgfx\\warrior\\wmb\\wmbas.cl2\r\nplrgfx\\warrior\\wmb\\wmbat.cl2\r\nplrgfx\\warrior\\wmb\\wmbaw.cl2\r\nplrgfx\\warrior\\wmb\\wmbfm.cl2\r\nplrgfx\\warrior\\wmb\\wmbht.cl2\r\nplrgfx\\warrior\\wmb\\wmblm.cl2\r\nplrgfx\\warrior\\wmb\\wmbqm.cl2\r\nplrgfx\\warrior\\wmb\\wmbst.cl2\r\nplrgfx\\warrior\\wmb\\wmbwl.cl2\r\nplrgfx\\warrior\\wmd\\wmdas.cl2\r\nplrgfx\\warrior\\wmd\\wmdat.cl2\r\nplrgfx\\warrior\\wmd\\wmdaw.cl2\r\nplrgfx\\warrior\\wmd\\wmdbl.cl2\r\nplrgfx\\warrior\\wmd\\wmdfm.cl2\r\nplrgfx\\warrior\\wmd\\wmdht.cl2\r\nplrgfx\\warrior\\wmd\\wmdlm.cl2\r\nplrgfx\\warrior\\wmd\\wmdqm.cl2\r\nplrgfx\\warrior\\wmd\\wmdst.cl2\r\nplrgfx\\warrior\\wmd\\wmdwl.cl2\r\nplrgfx\\warrior\\wmh\\wmhas.cl2\r\nplrgfx\\warrior\\wmh\\wmhat.cl2\r\nplrgfx\\warrior\\wmh\\wmhaw.cl2\r\nplrgfx\\warrior\\wmh\\wmhbl.cl2\r\nplrgfx\\warrior\\wmh\\wmhfm.cl2\r\nplrgfx\\warrior\\wmh\\wmhht.cl2\r\nplrgfx\\warrior\\wmh\\wmhlm.cl2\r\nplrgfx\\warrior\\wmh\\wmhqm.cl2\r\nplrgfx\\warrior\\wmh\\wmhst.cl2\r\nplrgfx\\warrior\\wmh\\wmhwl.cl2\r\nplrgfx\\warrior\\wmm\\wmmas.cl2\r\nplrgfx\\warrior\\wmm\\wmmat.cl2\r\nplrgfx\\warrior\\wmm\\wmmaw.cl2\r\nplrgfx\\warrior\\wmm\\wmmfm.cl2\r\nplrgfx\\warrior\\wmm\\wmmht.cl2\r\nplrgfx\\warrior\\wmm\\wmmlm.cl2\r\nplrgfx\\warrior\\wmm\\wmmqm.cl2\r\nplrgfx\\warrior\\wmm\\wmmst.cl2\r\nplrgfx\\warrior\\wmm\\wmmwl.cl2\r\nplrgfx\\warrior\\wmn\\wmnas.cl2\r\nplrgfx\\warrior\\wmn\\wmnat.cl2\r\nplrgfx\\warrior\\wmn\\wmnaw.cl2\r\nplrgfx\\warrior\\wmn\\wmndt.cl2\r\nplrgfx\\warrior\\wmn\\wmnfm.cl2\r\nplrgfx\\warrior\\wmn\\wmnht.cl2\r\nplrgfx\\warrior\\wmn\\wmnlm.cl2\r\nplrgfx\\warrior\\wmn\\wmnqm.cl2\r\nplrgfx\\warrior\\wmn\\wmnst.cl2\r\nplrgfx\\warrior\\wmn\\wmnwl.cl2\r\nplrgfx\\warrior\\wms\\wmsas.cl2\r\nplrgfx\\warrior\\wms\\wmsat.cl2\r\nplrgfx\\warrior\\wms\\wmsaw.cl2\r\nplrgfx\\warrior\\wms\\wmsfm.cl2\r\nplrgfx\\warrior\\wms\\wmsht.cl2\r\nplrgfx\\warrior\\wms\\wmslm.cl2\r\nplrgfx\\warrior\\wms\\wmsqm.cl2\r\nplrgfx\\warrior\\wms\\wmsst.cl2\r\nplrgfx\\warrior\\wms\\wmswl.cl2\r\nplrgfx\\warrior\\wmt\\wmtas.cl2\r\nplrgfx\\warrior\\wmt\\wmtat.cl2\r\nplrgfx\\warrior\\wmt\\wmtaw.cl2\r\nplrgfx\\warrior\\wmt\\wmtfm.cl2\r\nplrgfx\\warrior\\wmt\\wmtht.cl2\r\nplrgfx\\warrior\\wmt\\wmtlm.cl2\r\nplrgfx\\warrior\\wmt\\wmtqm.cl2\r\nplrgfx\\warrior\\wmt\\wmtst.cl2\r\nplrgfx\\warrior\\wmt\\wmtwl.cl2\r\nplrgfx\\warrior\\wmu\\wmuas.cl2\r\nplrgfx\\warrior\\wmu\\wmuat.cl2\r\nplrgfx\\warrior\\wmu\\wmuaw.cl2\r\nplrgfx\\warrior\\wmu\\wmubl.cl2\r\nplrgfx\\warrior\\wmu\\wmufm.cl2\r\nplrgfx\\warrior\\wmu\\wmuht.cl2\r\nplrgfx\\warrior\\wmu\\wmulm.cl2\r\nplrgfx\\warrior\\wmu\\wmuqm.cl2\r\nplrgfx\\warrior\\wmu\\wmust.cl2\r\nplrgfx\\warrior\\wmu\\wmuwl.cl2\r\npMain.000\r\npMain.001\r\npMain.002\r\npMain.003\r\npMain.004\r\npMain.pcx\r\nportdata.dat\r\nportdata.tbl\r\nportrait\\nadvisor\\nadfid00.smk\r\nportrait\\nadvisor\\nadfid01.smk\r\nportrait\\nadvisor\\nadfid02.smk\r\nportrait\\nadvisor\\nadfid03.smk\r\nportrait\\nadvisor\\nadtlk00.smk\r\nportrait\\nadvisor\\nadtlk01.smk\r\nportrait\\nadvisor\\nadtlk02.smk\r\nportrait\\nbadcrit\\nbcfid00.smk\r\nportrait\\nbadcrit\\nbcfid01.smk\r\nportrait\\nbadcrit\\nbcfid02.smk\r\nportrait\\nbadcrit\\nbcfid03.smk\r\nportrait\\nbadcrit\\nbctlk00.smk\r\nportrait\\nbadcrit\\nbctlk01.smk\r\nportrait\\nbadcrit\\nbctlk02.smk\r\nportrait\\nbiker\\nbifid00.smk\r\nportrait\\nbiker\\nbifid01.smk\r\nportrait\\nbiker\\nbifid02.smk\r\nportrait\\nbiker\\nbifid03.smk\r\nportrait\\nbiker\\nbitlk00.smk\r\nportrait\\nbiker\\nbitlk01.smk\r\nportrait\\nbiker\\nbitlk02.smk\r\nportrait\\nblucrit\\nlcfid00.smk\r\nportrait\\nblucrit\\nlcfid01.smk\r\nportrait\\nblucrit\\nlcfid02.smk\r\nportrait\\nblucrit\\nlcfid03.smk\r\nportrait\\nblucrit\\nlctlk00.smk\r\nportrait\\nblucrit\\nlctlk01.smk\r\nportrait\\nblucrit\\nlctlk02.smk\r\nportrait\\NBluCrit\\NLCTlk03.smk\r\nportrait\\ncivilian\\ncifid00.smk\r\nportrait\\ncivilian\\ncifid01.smk\r\nportrait\\ncivilian\\ncifid02.smk\r\nportrait\\ncivilian\\ncitlk00.smk\r\nportrait\\ncivilian\\ncitlk01.smk\r\nportrait\\ncivilian\\ncitlk02.smk\r\nportrait\\ngassac\\ngsfid00.smk\r\nportrait\\ngastank\\ngtfid00.smk\r\nportrait\\ngorb\\ngofid00.smk\r\nportrait\\nicecrit\\nicfid00.smk\r\nportrait\\nicecrit\\nicfid01.smk\r\nportrait\\nicecrit\\nicfid02.smk\r\nportrait\\nicecrit\\nicfid03.smk\r\nportrait\\nicecrit\\nictlk00.smk\r\nportrait\\nicecrit\\nictlk01.smk\r\nportrait\\nicecrit\\nictlk02.smk\r\nportrait\\NIceCrit\\NICTlk03.smk\r\nportrait\\njungcrit\\njcfid00.smk\r\nportrait\\njungcrit\\njcfid01.smk\r\nportrait\\njungcrit\\njcfid02.smk\r\nportrait\\njungcrit\\njcfid03.smk\r\nportrait\\njungcrit\\njctlk00.smk\r\nportrait\\njungcrit\\njctlk01.smk\r\nportrait\\njungcrit\\njctlk02.smk\r\nportrait\\nlavacrit\\nlcfid00.smk\r\nportrait\\nlavacrit\\nlcfid01.smk\r\nportrait\\nlavacrit\\nlctlk00.smk\r\nportrait\\nlavacrit\\nlctlk01.smk\r\nportrait\\nlavacrit\\nlctlk02.smk\r\nportrait\\nore\\nocfid00.smk\r\nportrait\\nredcrit\\nrdfid00.smk\r\nportrait\\nredcrit\\nrdfid01.smk\r\nportrait\\nredcrit\\nrdfid02.smk\r\nportrait\\nredcrit\\nrdfid03.smk\r\nportrait\\nredcrit\\nrdtlk00.smk\r\nportrait\\nredcrit\\nrdtlk01.smk\r\nportrait\\nredcrit\\nrdtlk02.smk\r\nportrait\\NRedCrit\\NRDTlk03.smk\r\nportrait\\padvisor\\padfid00.smk\r\nportrait\\padvisor\\padfid01.smk\r\nportrait\\padvisor\\padfid02.smk\r\nportrait\\padvisor\\padfid03.smk\r\nportrait\\padvisor\\padtlk00.smk\r\nportrait\\padvisor\\padtlk01.smk\r\nportrait\\padvisor\\padtlk02.smk\r\nportrait\\parbiter\\pabfid00.smk\r\nportrait\\parbiter\\pabfid01.smk\r\nportrait\\parbiter\\pabfid02.smk\r\nportrait\\parbiter\\pabfid03.smk\r\nportrait\\parbiter\\pabtlk00.smk\r\nportrait\\parbiter\\pabtlk01.smk\r\nportrait\\parbiter\\pabtlk02.smk\r\nportrait\\parchon\\parfid00.smk\r\nportrait\\parchon\\parfid01.smk\r\nportrait\\parchon\\parfid02.smk\r\nportrait\\parchon\\parfid03.smk\r\nportrait\\parchon\\partlk00.smk\r\nportrait\\parchon\\partlk01.smk\r\nportrait\\parchon\\partlk02.smk\r\nportrait\\partanis\\patfid00.smk\r\nportrait\\partanis\\patfid01.smk\r\nportrait\\partanis\\patfid02.smk\r\nportrait\\partanis\\patfid03.smk\r\nportrait\\partanis\\pattlk00.smk\r\nportrait\\partanis\\pattlk01.smk\r\nportrait\\partanis\\pattlk02.smk\r\nportrait\\PArtanis\\PatTlk03.smk\r\nportrait\\pcarrier\\pcafid00.smk\r\nportrait\\pcarrier\\pcafid01.smk\r\nportrait\\pcarrier\\pcafid02.smk\r\nportrait\\pcarrier\\pcafid03.smk\r\nportrait\\pcarrier\\pcatlk00.smk\r\nportrait\\pcarrier\\pcatlk01.smk\r\nportrait\\pcarrier\\pcatlk02.smk\r\nportrait\\pcorsair\\pcsfid00.smk\r\nportrait\\pcorsair\\pcsfid01.smk\r\nportrait\\pcorsair\\pcsfid02.smk\r\nportrait\\pcorsair\\pcsfid03.smk\r\nportrait\\pcorsair\\pcstlk00.smk\r\nportrait\\pcorsair\\pcstlk01.smk\r\nportrait\\pcorsair\\pcstlk02.smk\r\nportrait\\PCorsair\\PCsTlk03.smk\r\nportrait\\pdarchon\\pdafid00.smk\r\nportrait\\pdarchon\\pdafid01.smk\r\nportrait\\pdarchon\\pdafid02.smk\r\nportrait\\pdarchon\\pdafid03.smk\r\nportrait\\pdarchon\\pdatlk00.smk\r\nportrait\\pdarchon\\pdatlk01.smk\r\nportrait\\pdarchon\\pdatlk02.smk\r\nportrait\\PDarchon\\PDaTlk03.smk\r\nportrait\\pdragoon\\pdrfid00.smk\r\nportrait\\pdragoon\\pdrfid01.smk\r\nportrait\\pdragoon\\pdrfid02.smk\r\nportrait\\pdragoon\\pdrfid03.smk\r\nportrait\\pdragoon\\pdrtlk00.smk\r\nportrait\\pdragoon\\pdrtlk01.smk\r\nportrait\\pdragoon\\pdrtlk02.smk\r\nportrait\\pinterce\\pinfid00.smk\r\nportrait\\pinterce\\pinfid01.smk\r\nportrait\\pinterce\\pinfid02.smk\r\nportrait\\pinterce\\pinfid03.smk\r\nportrait\\pinterce\\pintlk00.smk\r\nportrait\\pinterce\\pintlk01.smk\r\nportrait\\pinterce\\pintlk02.smk\r\nportrait\\pprobe\\pprfid00.smk\r\nportrait\\pprobe\\pprfid01.smk\r\nportrait\\pprobe\\pprfid02.smk\r\nportrait\\pprobe\\pprfid03.smk\r\nportrait\\pprobe\\pprtlk00.smk\r\nportrait\\pprobe\\pprtlk01.smk\r\nportrait\\pprobe\\pprtlk02.smk\r\nportrait\\praz\\przfid00.smk\r\nportrait\\praz\\przfid01.smk\r\nportrait\\praz\\przfid02.smk\r\nportrait\\praz\\przfid03.smk\r\nportrait\\praz\\prztlk00.smk\r\nportrait\\praz\\prztlk01.smk\r\nportrait\\praz\\prztlk02.smk\r\nportrait\\PRaz\\PRzTlk03.smk\r\nportrait\\pscout\\pscfid00.smk\r\nportrait\\pscout\\pscfid01.smk\r\nportrait\\pscout\\pscfid02.smk\r\nportrait\\pscout\\pscfid03.smk\r\nportrait\\pscout\\psctlk00.smk\r\nportrait\\pscout\\psctlk01.smk\r\nportrait\\pshuttle\\pshfid00.smk\r\nportrait\\pshuttle\\pshfid01.smk\r\nportrait\\pshuttle\\pshfid02.smk\r\nportrait\\pshuttle\\pshfid03.smk\r\nportrait\\pshuttle\\pshtlk00.smk\r\nportrait\\pshuttle\\pshtlk01.smk\r\nportrait\\pshuttle\\pshtlk02.smk\r\nportrait\\ptemplar\\ptefid00.smk\r\nportrait\\ptemplar\\ptefid01.smk\r\nportrait\\ptemplar\\ptefid02.smk\r\nportrait\\ptemplar\\ptefid03.smk\r\nportrait\\ptemplar\\ptetlk00.smk\r\nportrait\\ptemplar\\ptetlk01.smk\r\nportrait\\ptemplar\\ptetlk02.smk\r\nportrait\\ptrilo\\ptrfid00.smk\r\nportrait\\ptrilo\\ptrfid01.smk\r\nportrait\\ptrilo\\ptrfid02.smk\r\nportrait\\ptrilo\\ptrfid03.smk\r\nportrait\\ptrilo\\ptrtlk00.smk\r\nportrait\\ptrilo\\ptrtlk01.smk\r\nportrait\\ptrilo\\ptrtlk02.smk\r\nportrait\\pwitness\\pwifid00.smk\r\nportrait\\pwitness\\pwifid01.smk\r\nportrait\\pwitness\\pwifid02.smk\r\nportrait\\pwitness\\pwifid03.smk\r\nportrait\\pwitness\\pwitlk00.smk\r\nportrait\\pwitness\\pwitlk01.smk\r\nportrait\\pwitness\\pwitlk02.smk\r\nportrait\\pzealot\\pzefid00.smk\r\nportrait\\pzealot\\pzefid01.smk\r\nportrait\\pzealot\\pzefid02.smk\r\nportrait\\pzealot\\pzetlk00.smk\r\nportrait\\pzealot\\pzetlk01.smk\r\nportrait\\static\\statin.smk\r\nportrait\\static\\statout.smk\r\nportrait\\tadvisor\\tadfid00.smk\r\nportrait\\tadvisor\\tadfid01.smk\r\nportrait\\tadvisor\\tadfid02.smk\r\nportrait\\tadvisor\\tadfid03.smk\r\nportrait\\tadvisor\\tadtlk00.smk\r\nportrait\\tadvisor\\tadtlk01.smk\r\nportrait\\tadvisor\\tadtlk02.smk\r\nportrait\\talex\\taxfid00.smk\r\nportrait\\talex\\taxfid01.smk\r\nportrait\\talex\\taxfid02.smk\r\nportrait\\talex\\taxfid03.smk\r\nportrait\\talex\\taxtlk00.smk\r\nportrait\\talex\\taxtlk01.smk\r\nportrait\\talex\\taxtlk02.smk\r\nportrait\\Talex\\TaxTlk03.smk\r\nportrait\\tbattlec\\tbafid00.smk\r\nportrait\\tbattlec\\tbafid01.smk\r\nportrait\\tbattlec\\tbafid02.smk\r\nportrait\\tbattlec\\tbafid03.smk\r\nportrait\\tbattlec\\tbatlk00.smk\r\nportrait\\tbattlec\\tbatlk01.smk\r\nportrait\\tbattlec\\tbatlk02.smk\r\nportrait\\tbomber\\tbmfid00.smk\r\nportrait\\tbomber\\tbmfid01.smk\r\nportrait\\tbomber\\tbmfid02.smk\r\nportrait\\tbomber\\tbmfid03.smk\r\nportrait\\tbomber\\tbmtlk00.smk\r\nportrait\\tbomber\\tbmtlk01.smk\r\nportrait\\tbomber\\tbmtlk02.smk\r\nportrait\\TBomber\\TBmTlk03.smk\r\nportrait\\tdropshi\\tdrfid00.smk\r\nportrait\\tdropshi\\tdrfid01.smk\r\nportrait\\tdropshi\\tdrfid02.smk\r\nportrait\\tdropshi\\tdrfid03.smk\r\nportrait\\tdropshi\\tdrtlk00.smk\r\nportrait\\tdropshi\\tdrtlk01.smk\r\nportrait\\tdropshi\\tdrtlk02.smk\r\nportrait\\tdugal\\udgfid00.smk\r\nportrait\\tdugal\\udgfid01.smk\r\nportrait\\tdugal\\udgfid02.smk\r\nportrait\\tdugal\\udgfid03.smk\r\nportrait\\tdugal\\udgtlk00.smk\r\nportrait\\tdugal\\udgtlk01.smk\r\nportrait\\tdugal\\udgtlk02.smk\r\nportrait\\TDugal\\UdgTlk03.smk\r\nportrait\\tfirebat\\tfbfid00.smk\r\nportrait\\tfirebat\\tfbfid01.smk\r\nportrait\\tfirebat\\tfbfid02.smk\r\nportrait\\tfirebat\\tfbfid03.smk\r\nportrait\\tfirebat\\tfbtlk00.smk\r\nportrait\\tfirebat\\tfbtlk01.smk\r\nportrait\\tghost\\tghfid00.smk\r\nportrait\\tghost\\tghfid01.smk\r\nportrait\\tghost\\tghfid02.smk\r\nportrait\\tghost\\tghfid03.smk\r\nportrait\\tghost\\tghtlk00.smk\r\nportrait\\tgoliath\\tgofid00.smk\r\nportrait\\tgoliath\\tgofid01.smk\r\nportrait\\tgoliath\\tgofid02.smk\r\nportrait\\tgoliath\\tgotlk00.smk\r\nportrait\\tgoliath\\tgotlk01.smk\r\nportrait\\tmarine\\tmafid00.smk\r\nportrait\\tmarine\\tmafid01.smk\r\nportrait\\tmarine\\tmafid02.smk\r\nportrait\\tmarine\\tmafid03.smk\r\nportrait\\tmarine\\tmatlk00.smk\r\nportrait\\tmarine\\tmatlk01.smk\r\nportrait\\tmarine\\tmatlk02.smk\r\nportrait\\tmedic\\tmefid00.smk\r\nportrait\\tmedic\\tmefid01.smk\r\nportrait\\tmedic\\tmefid02.smk\r\nportrait\\tmedic\\tmefid03.smk\r\nportrait\\tmedic\\tmetlk00.smk\r\nportrait\\tmedic\\tmetlk01.smk\r\nportrait\\tmedic\\tmetlk02.smk\r\nportrait\\tphoenix\\tphfid00.smk\r\nportrait\\tphoenix\\tphfid01.smk\r\nportrait\\tphoenix\\tphfid02.smk\r\nportrait\\tphoenix\\tphtlk00.smk\r\nportrait\\tphoenix\\tphtlk01.smk\r\nportrait\\tphoenix\\tphtlk02.smk\r\nportrait\\tsam\\tsmfid00.smk\r\nportrait\\tsam\\tsmfid01.smk\r\nportrait\\tsam\\tsmfid02.smk\r\nportrait\\tsam\\tsmfid03.smk\r\nportrait\\tsam\\tsmtlk00.smk\r\nportrait\\tsam\\tsmtlk01.smk\r\nportrait\\tsam\\tsmtlk02.smk\r\nportrait\\TSam\\TsmTlk03.smk\r\nportrait\\tscv\\tscfid00.smk\r\nportrait\\tscv\\tscfid01.smk\r\nportrait\\tscv\\tscfid02.smk\r\nportrait\\tscv\\tscfid03.smk\r\nportrait\\tscv\\tsctlk00.smk\r\nportrait\\tscv\\tsctlk01.smk\r\nportrait\\tscv\\tsctlk02.smk\r\nportrait\\tspider\\tmnfid00.smk\r\nportrait\\tspider\\tmnfid01.smk\r\nportrait\\tspider\\tmntlk00.smk\r\nportrait\\ttank\\ttafid00.smk\r\nportrait\\ttank\\ttafid01.smk\r\nportrait\\ttank\\ttafid02.smk\r\nportrait\\ttank\\ttafid03.smk\r\nportrait\\ttank\\ttatlk00.smk\r\nportrait\\ttank\\ttatlk01.smk\r\nportrait\\ttank\\ttatlk02.smk\r\nportrait\\tvessel\\tvefid00.smk\r\nportrait\\tvessel\\tvefid01.smk\r\nportrait\\tvessel\\tvefid02.smk\r\nportrait\\tvessel\\tvefid03.smk\r\nportrait\\tvessel\\tvetlk00.smk\r\nportrait\\tvessel\\tvetlk01.smk\r\nportrait\\tvessel\\tvetlk02.smk\r\nportrait\\tvulture\\tvufid00.smk\r\nportrait\\tvulture\\tvufid01.smk\r\nportrait\\tvulture\\tvufid02.smk\r\nportrait\\tvulture\\tvufid03.smk\r\nportrait\\tvulture\\tvutlk00.smk\r\nportrait\\tvulture\\tvutlk01.smk\r\nportrait\\udagg\\udgfid00.smk\r\nportrait\\udagg\\udgfid01.smk\r\nportrait\\udagg\\udgfid02.smk\r\nportrait\\udagg\\udgtlk00.smk\r\nportrait\\udagg\\udgtlk01.smk\r\nportrait\\udagg\\udgtlk02.smk\r\nportrait\\udisk\\uddfid00.smk\r\nportrait\\udisk\\uddtlk00.smk\r\nportrait\\udtemplar\\udtfid00.smk\r\nportrait\\udtemplar\\udtfid01.smk\r\nportrait\\udtemplar\\udtfid02.smk\r\nportrait\\udtemplar\\udttlk00.smk\r\nportrait\\udtemplar\\udttlk01.smk\r\nportrait\\udtemplar\\udttlk02.smk\r\nportrait\\uduke\\udufid00.smk\r\nportrait\\uduke\\udufid01.smk\r\nportrait\\uduke\\udufid02.smk\r\nportrait\\uduke\\udufid03.smk\r\nportrait\\uduke\\udutlk00.smk\r\nportrait\\uduke\\udutlk01.smk\r\nportrait\\uduke\\udutlk02.smk\r\nportrait\\ufendrag\\ufdfid00.smk\r\nportrait\\ufendrag\\ufdfid01.smk\r\nportrait\\ufendrag\\ufdfid02.smk\r\nportrait\\ufendrag\\ufdfid03.smk\r\nportrait\\ufendrag\\ufdtlk00.smk\r\nportrait\\ufendrag\\ufdtlk01.smk\r\nportrait\\ufendrag\\ufdtlk02.smk\r\nportrait\\ufenzeal\\ufefid00.smk\r\nportrait\\ufenzeal\\ufefid01.smk\r\nportrait\\ufenzeal\\ufefid02.smk\r\nportrait\\ufenzeal\\ufefid03.smk\r\nportrait\\ufenzeal\\ufetlk00.smk\r\nportrait\\ufenzeal\\ufetlk01.smk\r\nportrait\\ufenzeal\\ufetlk02.smk\r\nportrait\\uflag10\\uf10fid00.smk\r\nportrait\\uflag10\\uf10tlk00.smk\r\nportrait\\uflag11\\uf11fid00.smk\r\nportrait\\uflag11\\uf11tlk00.smk\r\nportrait\\uflag12\\uf12fid00.smk\r\nportrait\\uflag12\\uf12tlk00.smk\r\nportrait\\uflag1\\uf1fid00.smk\r\nportrait\\uflag1\\uf1tlk00.smk\r\nportrait\\uflag2\\uf2fid00.smk\r\nportrait\\uflag2\\uf2tlk00.smk\r\nportrait\\uflag3\\uf3fid00.smk\r\nportrait\\uflag3\\uf3tlk00.smk\r\nportrait\\uflag4\\uf4fid00.smk\r\nportrait\\uflag4\\uf4tlk00.smk\r\nportrait\\uflag5\\uf5fid00.smk\r\nportrait\\uflag5\\uf5tlk00.smk\r\nportrait\\uflag6\\uf6fid00.smk\r\nportrait\\uflag6\\uf6tlk00.smk\r\nportrait\\uflag7\\uf7fid00.smk\r\nportrait\\uflag7\\uf7tlk00.smk\r\nportrait\\uflag8\\uf8fid00.smk\r\nportrait\\uflag8\\uf8tlk00.smk\r\nportrait\\uflag9\\uf9fid00.smk\r\nportrait\\uflag9\\uf9tlk00.smk\r\nportrait\\uflag\\uflfid00.smk\r\nportrait\\uflag\\ufltlk00.smk\r\nportrait\\uhunters\\uhufid00.smk\r\nportrait\\uhunters\\uhufid01.smk\r\nportrait\\uhunters\\uhufid02.smk\r\nportrait\\uhunters\\uhutlk00.smk\r\nportrait\\uhunters\\uhutlk01.smk\r\nportrait\\uhunters\\uhutlk02.smk\r\nportrait\\uikerr\\uikfid00.smk\r\nportrait\\uikerr\\uikfid01.smk\r\nportrait\\uikerr\\uikfid02.smk\r\nportrait\\uikerr\\uiktlk00.smk\r\nportrait\\uikerr\\uiktlk01.smk\r\nportrait\\uikerr\\uiktlk02.smk\r\nportrait\\ujim\\urafid00.smk\r\nportrait\\ujim\\urafid01.smk\r\nportrait\\ujim\\urafid02.smk\r\nportrait\\ujim\\urafid03.smk\r\nportrait\\ujim\\uratlk00.smk\r\nportrait\\ujim\\uratlk01.smk\r\nportrait\\ujim\\uratlk02.smk\r\nportrait\\ukerr\\ukefid00.smk\r\nportrait\\ukerr\\ukefid01.smk\r\nportrait\\ukerr\\ukefid02.smk\r\nportrait\\ukerr\\ukefid03.smk\r\nportrait\\ukerr\\uketlk00.smk\r\nportrait\\ukerr\\uketlk01.smk\r\nportrait\\ukerr\\uketlk02.smk\r\nportrait\\ukhad\\ncrfid00.smk\r\nportrait\\ukhad\\ncrtlk00.smk\r\nportrait\\ukhadchunk\\ncrfid00.smk\r\nportrait\\ukhadchunk\\ncrtlk00.smk\r\nportrait\\ukhalis\\uksfid00.smk\r\nportrait\\ukhalis\\ukstlk00.smk\r\nportrait\\umengsk\\umefid00.smk\r\nportrait\\umengsk\\umefid01.smk\r\nportrait\\umengsk\\umefid02.smk\r\nportrait\\umengsk\\umefid03.smk\r\nportrait\\umengsk\\umetlk00.smk\r\nportrait\\umengsk\\umetlk01.smk\r\nportrait\\umengsk\\umetlk02.smk\r\nportrait\\upsi\\upsfid00.smk\r\nportrait\\upsi\\upstlk00.smk\r\nportrait\\ushard\\ushfid00.smk\r\nportrait\\ushard\\ushtlk00.smk\r\nportrait\\utassadar\\utafid00.smk\r\nportrait\\utassadar\\utafid01.smk\r\nportrait\\utassadar\\utafid02.smk\r\nportrait\\utassadar\\utatlk00.smk\r\nportrait\\utassadar\\utatlk01.smk\r\nportrait\\uuraj\\uujfid00.smk\r\nportrait\\uuraj\\uujtlk00.smk\r\nportrait\\uzasz\\fid00.smk\r\nportrait\\uzasz\\fid01.smk\r\nportrait\\uzasz\\fid02.smk\r\nportrait\\uzasz\\tlk00.smk\r\nportrait\\uzasz\\tlk01.smk\r\nportrait\\uzasz\\tlk02.smk\r\nportrait\\uzeratul\\uzefid00.smk\r\nportrait\\uzeratul\\uzefid01.smk\r\nportrait\\uzeratul\\uzefid02.smk\r\nportrait\\uzeratul\\uzefid03.smk\r\nportrait\\uzeratul\\uzetlk00.smk\r\nportrait\\uzeratul\\uzetlk01.smk\r\nportrait\\uzeratul\\uzetlk02.smk\r\nportrait\\zadvisor\\zadfid00.smk\r\nportrait\\zadvisor\\zadfid01.smk\r\nportrait\\zadvisor\\zadfid02.smk\r\nportrait\\zadvisor\\zadfid03.smk\r\nportrait\\zadvisor\\zadtlk00.smk\r\nportrait\\zadvisor\\zadtlk01.smk\r\nportrait\\zadvisor\\zadtlk02.smk\r\nportrait\\zavenger\\zavfid00.smk\r\nportrait\\zavenger\\zavfid01.smk\r\nportrait\\zavenger\\zavfid02.smk\r\nportrait\\zavenger\\zavfid03.smk\r\nportrait\\zavenger\\zavtlk00.smk\r\nportrait\\zavenger\\zavtlk01.smk\r\nportrait\\zavenger\\zavtlk02.smk\r\nportrait\\zbrood\\zbrfid00.smk\r\nportrait\\zbrood\\zbrfid01.smk\r\nportrait\\zbrood\\zbrfid02.smk\r\nportrait\\zbrood\\zbrfid03.smk\r\nportrait\\zbrood\\zbrtlk00.smk\r\nportrait\\zbrood\\zbrtlk01.smk\r\nportrait\\zbrood\\zbrtlk02.smk\r\nportrait\\zchrysalis\\zchfid00.smk\r\nportrait\\zchrysalis\\zchfid01.smk\r\nportrait\\zchrysalis\\zchfid02.smk\r\nportrait\\zcocoon\\zcofid00.smk\r\nportrait\\zcocoon\\zcofid01.smk\r\nportrait\\zcocoon\\zcofid02.smk\r\nportrait\\zdefiler\\zdefid00.smk\r\nportrait\\zdefiler\\zdefid01.smk\r\nportrait\\zdefiler\\zdefid02.smk\r\nportrait\\zdefiler\\zdefid03.smk\r\nportrait\\zdefiler\\zdetlk00.smk\r\nportrait\\zdefiler\\zdetlk01.smk\r\nportrait\\zdevour\\zdvfid00.smk\r\nportrait\\zdevour\\zdvfid01.smk\r\nportrait\\zdevour\\zdvfid02.smk\r\nportrait\\zdevour\\zdvfid03.smk\r\nportrait\\zdevour\\zdvtlk00.smk\r\nportrait\\zdevour\\zdvtlk01.smk\r\nportrait\\zdevour\\zdvtlk02.smk\r\nportrait\\Zdevour\\ZDvtlk03.smk\r\nportrait\\zdrone\\zdrfid00.smk\r\nportrait\\zdrone\\zdrfid01.smk\r\nportrait\\zdrone\\zdrfid02.smk\r\nportrait\\zdrone\\zdrfid03.smk\r\nportrait\\zdrone\\zdrtlk00.smk\r\nportrait\\zdrone\\zdrtlk01.smk\r\nportrait\\zdrone\\zdrtlk02.smk\r\nportrait\\zegg\\zegfid00.smk\r\nportrait\\zegg\\zegfid01.smk\r\nportrait\\zegg\\zegfid02.smk\r\nportrait\\zegg\\zegfid03.smk\r\nportrait\\zegg\\zegtlk00.smk\r\nportrait\\zegg\\zegtlk01.smk\r\nportrait\\zegg\\zegtlk02.smk\r\nportrait\\zguard\\zgufid00.smk\r\nportrait\\zguard\\zgufid01.smk\r\nportrait\\zguard\\zgufid02.smk\r\nportrait\\zguard\\zgufid03.smk\r\nportrait\\zguard\\zgutlk00.smk\r\nportrait\\zguard\\zgutlk01.smk\r\nportrait\\zguard\\zgutlk02.smk\r\nportrait\\zhydra\\zhyfid00.smk\r\nportrait\\zhydra\\zhyfid01.smk\r\nportrait\\zhydra\\zhyfid02.smk\r\nportrait\\zhydra\\zhyfid03.smk\r\nportrait\\zhydra\\zhytlk00.smk\r\nportrait\\zhydra\\zhytlk01.smk\r\nportrait\\zhydra\\zhytlk02.smk\r\nportrait\\zinfestt\\zbgfid00.smk\r\nportrait\\zinfestt\\zbgfid01.smk\r\nportrait\\zinfestt\\zbgfid02.smk\r\nportrait\\zinfestt\\zbgfid03.smk\r\nportrait\\zinfestt\\zbgtlk00.smk\r\nportrait\\zinfestt\\zbgtlk01.smk\r\nportrait\\zinfestt\\zbgtlk02.smk\r\nportrait\\zlarva\\zlafid00.smk\r\nportrait\\zlarva\\zlatlk00.smk\r\nportrait\\zlurker\\zlufid00.smk\r\nportrait\\zlurker\\zlufid01.smk\r\nportrait\\zlurker\\zlufid02.smk\r\nportrait\\zlurker\\zlufid03.smk\r\nportrait\\zlurker\\zlutlk00.smk\r\nportrait\\zlurker\\zlutlk01.smk\r\nportrait\\zlurker\\zlutlk02.smk\r\nportrait\\ZLurker\\ZLutlk03.smk\r\nportrait\\zmutalid\\zmufid00.smk\r\nportrait\\zmutalid\\zmufid01.smk\r\nportrait\\zmutalid\\zmufid02.smk\r\nportrait\\zmutalid\\zmufid03.smk\r\nportrait\\zmutalid\\zmutlk00.smk\r\nportrait\\zmutalid\\zmutlk01.smk\r\nportrait\\zmutalid\\zmutlk02.smk\r\nportrait\\zover\\zovfid00.smk\r\nportrait\\zover\\zovfid01.smk\r\nportrait\\zover\\zovfid02.smk\r\nportrait\\zover\\zovfid03.smk\r\nportrait\\zover\\zovtlk00.smk\r\nportrait\\zover\\zovtlk01.smk\r\nportrait\\zover\\zovtlk02.smk\r\nportrait\\zqueen\\zqufid00.smk\r\nportrait\\zqueen\\zqufid01.smk\r\nportrait\\zqueen\\zqufid02.smk\r\nportrait\\zqueen\\zqufid03.smk\r\nportrait\\zqueen\\zqutlk00.smk\r\nportrait\\zultra\\zulfid00.smk\r\nportrait\\zultra\\zulfid01.smk\r\nportrait\\zultra\\zulfid02.smk\r\nportrait\\zultra\\zultlk00.smk\r\nportrait\\zultra\\zultlk01.smk\r\nportrait\\zultra\\zultlk02.smk\r\nportrait\\zzergl\\zzefid00.smk\r\nportrait\\zzergl\\zzefid01.smk\r\nportrait\\zzergl\\zzefid02.smk\r\nportrait\\zzergl\\zzefid03.smk\r\nportrait\\zzergl\\zzetlk00.smk\r\nportrait\\zzergl\\zzetlk01.smk\r\nportrait\\zzergl\\zzetlk02.smk\r\nprepatch.lst\r\nprofile\\age\r\nprofile\\description\r\nprofile\\location\r\nprofile\\sex\r\nprotoss.grp\r\nquitrepl.009\r\nquitrepl.019\r\nquitrepl.01a\r\nquitrepl.01f\r\nquitrepl.022\r\nquitrepl.029\r\nquitrepl.02b\r\nquitrepl.035\r\nquitrepl.039\r\nquitrepl.03b\r\nquitrepl.03c\r\nquitrepl.049\r\nquitrepl.04b\r\nquitrepl.04d\r\nquitrepl.054\r\nquitrepl.061\r\nquitrepl.06d\r\nquitrepl.bin\r\nreadme.cnt\r\nreadme.hlp\r\nreadme.txt\r\nRecord\\Star\\0\\disconnects\r\nRecord\\Star\\0\\last game\r\nRecord\\Star\\0\\last game result\r\nRecord\\Star\\0\\losses\r\nRecord\\Star\\0\\wins\r\nRecord\\Star\\1\\disconnects\r\nRecord\\Star\\1\\high rank\r\nRecord\\Star\\1\\high rating\r\nRecord\\Star\\1\\last game\r\nRecord\\Star\\1\\last game result\r\nRecord\\Star\\1\\losses\r\nRecord\\Star\\1\\rank\r\nRecord\\Star\\1\\rating\r\nRecord\\Star\\1\\wins\r\nRegisterEmail.057\r\nregisteremail.05c\r\nRegisterEmail.pcx\r\nrevert.lst\r\nrez\\1textbox.bin\r\nrez\\abrtmenu.bin\r\nrez\\abrtmenu_mac.bin\r\nrez\\allyfltr.bin\r\nrez\\bigok.bin\r\nrez\\bnbeta.txt\r\nrez\\bncache.dat\r\nrez\\bnetunin.exe\r\nrez\\bnupdate.exe\r\nrez\\cancel.bin\r\nrez\\cdver_sw.txt\r\nrez\\cdversion.txt\r\nrez\\crdt_exp.txt\r\nrez\\crdt_lst.tbl\r\nrez\\crdt_lst.txt\r\nrez\\crdt_sw.txt\r\nrez\\credits.bin\r\nrez\\dataver_sw.txt\r\nrez\\dataversion.txt\r\nrez\\delete.lst\r\nrez\\delete.txt\r\nrez\\dfinale.bin\r\nrez\\dlgfatal.bin\r\nrez\\epilog.txt\r\nrez\\epiloged.txt\r\nrez\\epilogsw.txt\r\nrez\\epilogx.txt\r\nrez\\estp01.txt\r\nrez\\estp01x.txt\r\nrez\\estp02.txt\r\nrez\\estp02x.txt\r\nrez\\estp03.txt\r\nrez\\estp03x.txt\r\nrez\\estp04.txt\r\nrez\\estp04x.txt\r\nrez\\estp05.txt\r\nrez\\estp05x.txt\r\nrez\\estp06.txt\r\nrez\\estp06x.txt\r\nrez\\estp07.txt\r\nrez\\estp07x.txt\r\nrez\\estp08.txt\r\nrez\\estp08x.txt\r\nrez\\estp09.txt\r\nrez\\estp0t.txt\r\nrez\\estp10.txt\r\nrez\\estt01.txt\r\nrez\\estt01ed.txt\r\nrez\\estt01sw.txt\r\nrez\\estt01x.txt\r\nrez\\estt02.txt\r\nrez\\estt02ed.txt\r\nrez\\estt02sw.txt\r\nrez\\estt02x.txt\r\nrez\\estt03.txt\r\nrez\\estt03ed.txt\r\nrez\\estt03sw.txt\r\nrez\\estt03x.txt\r\nrez\\estt04.txt\r\nrez\\estt04sw.txt\r\nrez\\estt04x.txt\r\nrez\\estt05.txt\r\nrez\\estt05ax.txt\r\nrez\\estt05bx.txt\r\nrez\\estt05sw.txt\r\nrez\\estt06.txt\r\nrez\\estt06x.txt\r\nrez\\estt07.txt\r\nrez\\estt07x.txt\r\nrez\\estt08.txt\r\nrez\\estt08x.txt\r\nrez\\estt09.txt\r\nrez\\estt0t.txt\r\nrez\\estt0ted.txt\r\nrez\\estt0tsw.txt\r\nrez\\estt10.txt\r\nrez\\estt11.txt\r\nrez\\estt12.txt\r\nrez\\estz01.txt\r\nrez\\estz01x.txt\r\nrez\\estz02.txt\r\nrez\\estz02x.txt\r\nrez\\estz03.txt\r\nrez\\estz03x.txt\r\nrez\\estz04.txt\r\nrez\\estz04x.txt\r\nrez\\estz05.txt\r\nrez\\estz05x.txt\r\nrez\\estz06.txt\r\nrez\\estz06x.txt\r\nrez\\estz07.txt\r\nrez\\estz07x.txt\r\nrez\\estz08.txt\r\nrez\\estz08x.txt\r\nrez\\estz09.txt\r\nrez\\estz09bx.txt\r\nrez\\estz09x.txt\r\nrez\\estz0t.txt\r\nrez\\estz10.txt\r\nrez\\estz10x.txt\r\nrez\\expansion.txt\r\nrez\\finaldlg.bin\r\nrez\\finale.tbl\r\nrez\\finz09bx.txt\r\nrez\\gamemenu.bin\r\nrez\\gamemenu_mac.bin\r\nrez\\gateways.txt\r\nrez\\gluall.tbl\r\nrez\\gluall_mac.tbl\r\nrez\\gluatzonelist.bin\r\nrez\\glubnres.res\r\nrez\\gluchat.bin\r\nrez\\gluchatpopup.bin\r\nrez\\glucmpgn.bin\r\nrez\\gluconn.bin\r\nrez\\glucreat.bin\r\nrez\\glucustm.bin\r\nrez\\gludelch.bin\r\nrez\\gluexpcmpgn.bin\r\nrez\\glugamemode.bin\r\nrez\\gluhist.bin\r\nrez\\gluhist.tbl\r\nrez\\glujoin.bin\r\nrez\\gluload.bin\r\nrez\\glulogin.bin\r\nrez\\glumain.bin\r\nrez\\glumodem.bin\r\nrez\\glumodementry.bin\r\nrez\\glumodemlist.bin\r\nrez\\glumodemstatus.bin\r\nrez\\glunewch.bin\r\nrez\\glupedit.bin\r\nrez\\glupok.bin\r\nrez\\glupokcancel.bin\r\nrez\\glupoksplit.bin\r\nrez\\glurdyp.bin\r\nrez\\glurdyt.bin\r\nrez\\glurdyz.bin\r\nrez\\gluscore.bin\r\nrez\\help.bin\r\nrez\\help_txt.tbl\r\nrez\\helpmenu.bin\r\nrez\\license.txt\r\nrez\\lmission.bin\r\nrez\\loadgame.bin\r\nrez\\minimap.bin\r\nrez\\msgfltr.bin\r\nrez\\msnstat2.bin\r\nrez\\msnstat4.bin\r\nrez\\msnstat6.bin\r\nrez\\msnstats.bin\r\nrez\\netdlg.bin\r\nrez\\netwait.bin\r\nrez\\network.tbl\r\nrez\\objctdlg.bin\r\nrez\\objctivs.tbl\r\nrez\\ok.bin\r\nrez\\okcancel.bin\r\nrez\\options.bin\r\nrez\\ptextbox.bin\r\nrez\\quit.bin\r\nrez\\quit2mnu.bin\r\nrez\\quit2mnu_mac.bin\r\nrez\\quit_mac.bin\r\nrez\\quitrepl.bin\r\nrez\\rank_txt.tbl\r\nrez\\restart.bin\r\nrez\\savegame.bin\r\nrez\\snd_dlg.bin\r\nrez\\spd_dlg.bin\r\nrez\\stat_f10.bin\r\nrez\\stat_txt.tbl\r\nrez\\statbtn%c.bin\r\nrez\\statbtn1.bin\r\nrez\\statbtnn.bin\r\nrez\\statbtnp.bin\r\nrez\\statbtnt.bin\r\nrez\\statbtnz.bin\r\nrez\\statdata.bin\r\nrez\\statfluf.bin\r\nrez\\statlb.bin\r\nrez\\statport.bin\r\nrez\\statres.bin\r\nrez\\teamfltr.bin\r\nrez\\timeout.bin\r\nrez\\tips.tbl\r\nrez\\tips_dlg.bin\r\nrez\\tipssw.tbl\r\nrez\\titledlg.bin\r\nrez\\tos.txt\r\nrez\\ttextbox.bin\r\nrez\\video.bin\r\nrez\\voice.bin\r\nrez\\wait.bin\r\nrez\\wmission.bin\r\nrez\\ztextbox.bin\r\nrf.battle.net (carbon)\r\nrf.bnupdate (carbon)\r\nrf.standard (carbon)\r\nrf.starcraft (carbon)\r\nrf.storm (carbon)\r\nriched20.dll\r\nsave\\gluall.tbl\r\nsave\\stat_txt.004\r\nsave\\stat_txt.tbl\r\nsavegame.00a\r\nsavegame.01a\r\nsavegame.01b\r\nsavegame.020\r\nsavegame.023\r\nsavegame.02a\r\nsavegame.02c\r\nsavegame.036\r\nsavegame.03a\r\nsavegame.03c\r\nsavegame.03d\r\nsavegame.04a\r\nsavegame.04c\r\nsavegame.04e\r\nsavegame.055\r\nsavegame.062\r\nsavegame.06e\r\nsavegame.bin\r\nscripts\\aiscript.bin\r\nscripts\\bwscript.bin\r\nscripts\\iscript.bin\r\nscripts\\iscriptx.bin\r\nSEditDEU.loc\r\nSEditENU.loc\r\nSEditESP.loc\r\nSEditFRA.loc\r\nSEditITA.loc\r\nSEditPTB.loc\r\nseditptg.loc\r\nserial.doc\r\nsetupdat\\95\\comctl32.dll\r\nsetupdat\\audio\\battlenetclick.wav\r\nsetupdat\\audio\\installermusic.wav\r\nsetupdat\\audio\\mousedown.wav\r\nsetupdat\\audio\\mouseover.wav\r\nsetupdat\\bwunin.exe\r\nsetupdat\\bwunin.pif\r\nsetupdat\\cleanup.ins\r\nsetupdat\\debug.ins\r\nsetupdat\\defaults.vis\r\nsetupdat\\directx.ins\r\nsetupdat\\font\\font.ccd\r\nsetupdat\\font\\font16.fnt\r\nsetupdat\\font\\font16x.fnt\r\nsetupdat\\font\\font32.fnt\r\nsetupdat\\gen\\allied.lst\r\nsetupdat\\gen\\broodwar.lst\r\nsetupdat\\gen\\bwladder.lst\r\nsetupdat\\gen\\campaign.lst\r\nsetupdat\\gen\\ladder.lst\r\nsetupdat\\gen\\maps.lst\r\nsetupdat\\gen\\multimaps.lst\r\nsetupdat\\gen\\oldladder.lst\r\nsetupdat\\gen\\scenario.lst\r\nsetupdat\\gen\\v105.lst\r\nsetupdat\\gen\\v105bw.lst\r\nsetupdat\\gen\\webmaps.lst\r\nsetupdat\\gendefs.ins\r\nsetupdat\\hasbwar.ins\r\nsetupdat\\images\\install.pcx\r\nsetupdat\\inst.ins\r\nsetupdat\\inst.vis\r\nsetupdat\\inst_files.ins\r\nsetupdat\\inst_gen.ins\r\nsetupdat\\inst_regs.ins\r\nsetupdat\\inst_sys.ins\r\nsetupdat\\installed.ins\r\nsetupdat\\instcc.exe\r\nsetupdat\\instgen.ins\r\nsetupdat\\iswinnt.ins\r\nsetupdat\\license.txt\r\nsetupdat\\mainplay.vis\r\nsetupdat\\noboot.dat\r\nsetupdat\\normal.ins\r\nsetupdat\\nt\\comctl32.dll\r\nsetupdat\\optvox.vis\r\nsetupdat\\prepbrood.ins\r\nsetupdat\\riched20.dll\r\nsetupdat\\savetemp.ins\r\nsetupdat\\scedunin.exe\r\nsetupdat\\scedunin.pif\r\nsetupdat\\scr_blizzard.vis\r\nsetupdat\\scr_isp.vis\r\nsetupdat\\scr_main.vis\r\nsetupdat\\scr_options.vis\r\nsetupdat\\scunin.exe\r\nsetupdat\\scunin.pif\r\nsetupdat\\setup.vis\r\nsetupdat\\single.ins\r\nsetupdat\\spawn.ins\r\nsetupdat\\spawn.vis\r\nSetupDat\\stardat.mpq\r\nsetupdat\\starunin.exe\r\nsetupdat\\strings.ins\r\nsetupdat\\templates.ins\r\nsetupdat\\upbwsucc.ins\r\nsetupdat\\upgrade.ins\r\nsetupdat\\upgrade.vis\r\nsetupdat\\upgrbw.ins\r\nsetupdat\\upgrbw.vis\r\nSfx\\Hellfire\\COWSUT1.wav\r\nSfx\\Hellfire\\COWSUT10.wav\r\nSfx\\Hellfire\\COWSUT11.wav\r\nSfx\\Hellfire\\COWSUT12.wav\r\nSfx\\Hellfire\\COWSUT2.wav\r\nSfx\\Hellfire\\COWSUT3.wav\r\nSfx\\Hellfire\\COWSUT4.wav\r\nSfx\\Hellfire\\COWSUT4A.wav\r\nSfx\\Hellfire\\COWSUT5.wav\r\nSfx\\Hellfire\\COWSUT6.wav\r\nSfx\\Hellfire\\COWSUT7.wav\r\nSfx\\Hellfire\\COWSUT8.wav\r\nSfx\\Hellfire\\COWSUT9.wav\r\nSfx\\Hellfire\\DEFILER1.wav\r\nSfx\\Hellfire\\DEFILER2.wav\r\nSfx\\Hellfire\\DEFILER3.wav\r\nSfx\\Hellfire\\DEFILER4.wav\r\nSfx\\Hellfire\\DEFILER6.wav\r\nSfx\\Hellfire\\DEFILER7.wav\r\nSfx\\Hellfire\\DEFILER8.wav\r\nSfx\\Hellfire\\Farmer1.wav\r\nSfx\\Hellfire\\Farmer2.wav\r\nSfx\\Hellfire\\Farmer2A.wav\r\nSfx\\Hellfire\\Farmer3.wav\r\nSfx\\Hellfire\\Farmer4.wav\r\nSfx\\Hellfire\\Farmer5.wav\r\nSfx\\Hellfire\\Farmer6.wav\r\nSfx\\Hellfire\\Farmer7.wav\r\nSfx\\Hellfire\\Farmer8.wav\r\nSfx\\Hellfire\\Farmer9.wav\r\nSfx\\Hellfire\\NAKRUL1.wav\r\nSfx\\Hellfire\\NAKRUL2.wav\r\nSfx\\Hellfire\\NAKRUL3.wav\r\nSfx\\Hellfire\\NAKRUL4.wav\r\nSfx\\Hellfire\\NAKRUL5.wav\r\nSfx\\Hellfire\\NAKRUL6.wav\r\nSfx\\Hellfire\\NARATR3.wav\r\nSfx\\Hellfire\\Naratr4.wav\r\nSfx\\Hellfire\\Naratr5.wav\r\nSfx\\Hellfire\\Naratr6.wav\r\nSfx\\Hellfire\\Naratr7.wav\r\nSfx\\Hellfire\\Naratr8.wav\r\nSfx\\Hellfire\\Naratr9.wav\r\nSfx\\Hellfire\\Skljrn1.wav\r\nSfx\\Hellfire\\TEDDYBR1.wav\r\nSfx\\Hellfire\\TEDDYBR2.wav\r\nSfx\\Hellfire\\TEDDYBR3.wav\r\nSfx\\Hellfire\\TEDDYBR4.wav\r\nSfx\\Hellfire\\TRADER1.wav\r\nsfx\\items\\armrfkd.wav\r\nsfx\\items\\barlfire.wav\r\nsfx\\items\\barrel.wav\r\nsfx\\items\\bhit.wav\r\nsfx\\items\\bhit1.wav\r\nsfx\\items\\chest.wav\r\nSfx\\Items\\Crclos.wav\r\nSfx\\Items\\Cropen.wav\r\nsfx\\items\\doorclos.wav\r\nsfx\\items\\dooropen.wav\r\nsfx\\items\\flipanvl.wav\r\nsfx\\items\\flipaxe.wav\r\nsfx\\items\\flipblst.wav\r\nsfx\\items\\flipbody.wav\r\nsfx\\items\\flipbook.wav\r\nsfx\\items\\flipbow.wav\r\nsfx\\items\\flipcap.wav\r\nsfx\\items\\flipharm.wav\r\nsfx\\items\\fliplarm.wav\r\nsfx\\items\\flipmag.wav\r\nsfx\\items\\flipmag1.wav\r\nsfx\\items\\flipmush.wav\r\nsfx\\items\\flippot.wav\r\nsfx\\items\\flipring.wav\r\nsfx\\items\\fliprock.wav\r\nsfx\\items\\flipscrl.wav\r\nsfx\\items\\flipshld.wav\r\nsfx\\items\\flipsign.wav\r\nsfx\\items\\flipstaf.wav\r\nsfx\\items\\flipswor.wav\r\nsfx\\items\\gold.wav\r\nsfx\\items\\hlmtfkd.wav\r\nsfx\\items\\invanvl.wav\r\nsfx\\items\\invaxe.wav\r\nsfx\\items\\invblst.wav\r\nsfx\\items\\invbody.wav\r\nsfx\\items\\invbook.wav\r\nsfx\\items\\invbow.wav\r\nsfx\\items\\invcap.wav\r\nsfx\\items\\invgrab.wav\r\nsfx\\items\\invharm.wav\r\nsfx\\items\\invlarm.wav\r\nsfx\\items\\invmush.wav\r\nsfx\\items\\invpot.wav\r\nsfx\\items\\invring.wav\r\nsfx\\items\\invrock.wav\r\nsfx\\items\\invscrol.wav\r\nsfx\\items\\invshiel.wav\r\nsfx\\items\\invsign.wav\r\nsfx\\items\\invstaf.wav\r\nsfx\\items\\invsword.wav\r\nsfx\\items\\lever.wav\r\nsfx\\items\\magic.wav\r\nSfx\\Items\\Magic1.wav\r\nSfx\\Items\\PodPop5.wav\r\nSfx\\Items\\PodPop8.wav\r\nsfx\\items\\readbook.wav\r\nsfx\\items\\sarc.wav\r\nsfx\\items\\shielfkd.wav\r\nSfx\\Items\\Swrdfkd.wav\r\nsfx\\items\\titlemov.wav\r\nsfx\\items\\titlslct.wav\r\nSfx\\Items\\Trap.wav\r\nSfx\\Items\\UrnPop2.wav\r\nSfx\\Items\\UrnPop3.wav\r\nsfx\\misc\\acids1.wav\r\nsfx\\misc\\acids2.wav\r\nsfx\\misc\\apoc.wav\r\nsfx\\misc\\arrowall.wav\r\nsfx\\misc\\bfire.wav\r\nsfx\\misc\\blank.wav\r\nsfx\\misc\\bldboil.wav\r\nsfx\\misc\\blodstar.wav\r\nsfx\\misc\\blsimpt.wav\r\nsfx\\misc\\bonesp.wav\r\nsfx\\misc\\bsimpct.wav\r\nsfx\\misc\\caldron.wav\r\nsfx\\misc\\cast1.wav\r\nSfx\\Misc\\Cast10.wav\r\nsfx\\misc\\cast12.wav\r\nsfx\\misc\\cast2.wav\r\nsfx\\misc\\cast3.wav\r\nsfx\\misc\\cast4.wav\r\nsfx\\misc\\cast5.wav\r\nsfx\\misc\\cast6.wav\r\nsfx\\misc\\cast7.wav\r\nsfx\\misc\\cast8.wav\r\nsfx\\misc\\cast9.wav\r\nsfx\\misc\\cbolt.wav\r\nsfx\\misc\\chltning.wav\r\nsfx\\misc\\dead.wav\r\nsfx\\misc\\dserp.wav\r\nsfx\\misc\\elecimp1.wav\r\nsfx\\misc\\elementl.wav\r\nsfx\\misc\\ethereal.wav\r\nsfx\\misc\\fball.wav\r\nSfx\\Misc\\FBallBow.wav\r\nsfx\\misc\\fbolt1.wav\r\nsfx\\misc\\fbolt2.wav\r\nsfx\\misc\\firimp1.wav\r\nsfx\\misc\\firimp2.wav\r\nsfx\\misc\\flamwave.wav\r\nsfx\\misc\\flash.wav\r\nsfx\\misc\\fmag.wav\r\nsfx\\misc\\fountain.wav\r\nsfx\\misc\\golum.wav\r\nsfx\\misc\\golumded.wav\r\nsfx\\misc\\grdlanch.wav\r\nsfx\\misc\\gshrine.wav\r\nsfx\\misc\\guard.wav\r\nsfx\\misc\\healing.wav\r\nsfx\\misc\\holybolt.wav\r\nsfx\\misc\\hyper.wav\r\nsfx\\misc\\infravis.wav\r\nsfx\\misc\\invisibl.wav\r\nsfx\\misc\\invpot.wav\r\nsfx\\misc\\lghit.wav\r\nsfx\\misc\\lghit1.wav\r\nSfx\\Misc\\LMag.wav\r\nsfx\\misc\\lning1.wav\r\nsfx\\misc\\ltning.wav\r\nsfx\\misc\\lvl16int.wav\r\nsfx\\misc\\mshield.wav\r\nSfx\\Misc\\NestXpld.wav\r\nsfx\\misc\\nova.wav\r\nsfx\\misc\\portal.wav\r\nsfx\\misc\\puddle.wav\r\nsfx\\misc\\questdon.wav\r\nsfx\\misc\\repair.wav\r\nsfx\\misc\\resur.wav\r\nsfx\\misc\\scurimp.wav\r\nsfx\\misc\\scurse.wav\r\nsfx\\misc\\sentinel.wav\r\nsfx\\misc\\shatter.wav\r\nsfx\\misc\\soulfire.wav\r\nsfx\\misc\\spoutlop.wav\r\nsfx\\misc\\spoutstr.wav\r\nSfx\\Misc\\Sting1.wav\r\nsfx\\misc\\storm.wav\r\nsfx\\misc\\swing.wav\r\nsfx\\misc\\swing2.wav\r\nsfx\\misc\\teleport.wav\r\nsfx\\misc\\tmag.wav\r\nsfx\\misc\\trapdis.wav\r\nsfx\\misc\\vtheft.wav\r\nsfx\\misc\\walk1.wav\r\nsfx\\misc\\walk2.wav\r\nsfx\\misc\\walk3.wav\r\nsfx\\misc\\walk4.wav\r\nsfx\\misc\\wallloop.wav\r\nsfx\\misc\\wallstrt.wav\r\nSfx\\Monk\\Monk01.wav\r\nSfx\\Monk\\Monk08.wav\r\nSfx\\Monk\\Monk09.wav\r\nSfx\\Monk\\Monk10.wav\r\nSfx\\Monk\\Monk11.wav\r\nSfx\\Monk\\Monk12.wav\r\nSfx\\Monk\\Monk13.wav\r\nSfx\\Monk\\Monk14.wav\r\nSfx\\Monk\\Monk15.wav\r\nSfx\\Monk\\Monk16.wav\r\nSfx\\Monk\\Monk24.wav\r\nSfx\\Monk\\Monk27.wav\r\nSfx\\Monk\\Monk29.wav\r\nSfx\\Monk\\Monk34.wav\r\nSfx\\Monk\\Monk35.wav\r\nSfx\\Monk\\Monk43.wav\r\nSfx\\Monk\\Monk46.wav\r\nSfx\\Monk\\Monk49.wav\r\nSfx\\Monk\\Monk50.wav\r\nSfx\\Monk\\Monk52.wav\r\nSfx\\Monk\\Monk54.wav\r\nSfx\\Monk\\Monk55.wav\r\nSfx\\Monk\\Monk56.wav\r\nSfx\\Monk\\Monk61.wav\r\nSfx\\Monk\\Monk62.wav\r\nSfx\\Monk\\Monk68.wav\r\nSfx\\Monk\\Monk69.wav\r\nSfx\\Monk\\Monk69b.wav\r\nSfx\\Monk\\Monk70.wav\r\nSfx\\Monk\\Monk71.wav\r\nSfx\\Monk\\Monk79.wav\r\nSfx\\Monk\\Monk80.wav\r\nSfx\\Monk\\Monk82.wav\r\nSfx\\Monk\\Monk83.wav\r\nSfx\\Monk\\Monk87.wav\r\nSfx\\Monk\\Monk88.wav\r\nSfx\\Monk\\Monk89.wav\r\nSfx\\Monk\\Monk91.wav\r\nSfx\\Monk\\Monk92.wav\r\nSfx\\Monk\\Monk94.wav\r\nSfx\\Monk\\Monk95.wav\r\nSfx\\Monk\\Monk96.wav\r\nSfx\\Monk\\Monk97.wav\r\nSfx\\Monk\\Monk98.wav\r\nSfx\\Monk\\Monk99.wav\r\nsfx\\monsters\\butcher.wav\r\nsfx\\monsters\\diablod.wav\r\nsfx\\monsters\\garbud01.wav\r\nsfx\\monsters\\garbud02.wav\r\nsfx\\monsters\\garbud03.wav\r\nsfx\\monsters\\garbud04.wav\r\nsfx\\monsters\\izual01.wav\r\nsfx\\monsters\\lach01.wav\r\nsfx\\monsters\\lach02.wav\r\nsfx\\monsters\\lach03.wav\r\nsfx\\monsters\\laz01.wav\r\nsfx\\monsters\\laz02.wav\r\nsfx\\monsters\\sking01.wav\r\nsfx\\monsters\\snot01.wav\r\nsfx\\monsters\\snot02.wav\r\nsfx\\monsters\\snot03.wav\r\nsfx\\monsters\\warlrd01.wav\r\nsfx\\monsters\\wlock01.wav\r\nsfx\\monsters\\zhar01.wav\r\nsfx\\monsters\\zhar02.wav\r\nsfx\\narrator\\nar01.wav\r\nsfx\\narrator\\nar02.wav\r\nsfx\\narrator\\nar03.wav\r\nsfx\\narrator\\nar04.wav\r\nsfx\\narrator\\nar05.wav\r\nsfx\\narrator\\nar06.wav\r\nsfx\\narrator\\nar07.wav\r\nsfx\\narrator\\nar08.wav\r\nsfx\\narrator\\nar09.wav\r\nsfx\\rogue\\rogue01.wav\r\nsfx\\rogue\\rogue02.wav\r\nsfx\\rogue\\rogue03.wav\r\nsfx\\rogue\\rogue04.wav\r\nsfx\\rogue\\rogue05.wav\r\nsfx\\rogue\\rogue06.wav\r\nsfx\\rogue\\rogue07.wav\r\nsfx\\rogue\\rogue08.wav\r\nsfx\\rogue\\rogue09.wav\r\nsfx\\rogue\\rogue10.wav\r\nsfx\\rogue\\rogue100.wav\r\nsfx\\rogue\\rogue101.wav\r\nsfx\\rogue\\rogue102.wav\r\nsfx\\rogue\\rogue11.wav\r\nsfx\\rogue\\rogue12.wav\r\nsfx\\rogue\\rogue13.wav\r\nsfx\\rogue\\rogue14.wav\r\nsfx\\rogue\\rogue15.wav\r\nsfx\\rogue\\rogue16.wav\r\nsfx\\rogue\\rogue17.wav\r\nsfx\\rogue\\rogue18.wav\r\nsfx\\rogue\\rogue19.wav\r\nsfx\\rogue\\rogue20.wav\r\nsfx\\rogue\\rogue21.wav\r\nsfx\\rogue\\rogue22.wav\r\nsfx\\rogue\\rogue23.wav\r\nsfx\\rogue\\rogue24.wav\r\nsfx\\rogue\\rogue25.wav\r\nsfx\\rogue\\rogue26.wav\r\nsfx\\rogue\\rogue27.wav\r\nsfx\\rogue\\rogue28.wav\r\nsfx\\rogue\\rogue29.wav\r\nsfx\\rogue\\rogue30.wav\r\nsfx\\rogue\\rogue31.wav\r\nsfx\\rogue\\rogue32.wav\r\nsfx\\rogue\\rogue33.wav\r\nsfx\\rogue\\rogue34.wav\r\nsfx\\rogue\\rogue35.wav\r\nsfx\\rogue\\rogue36.wav\r\nsfx\\rogue\\rogue37.wav\r\nsfx\\rogue\\rogue38.wav\r\nsfx\\rogue\\rogue39.wav\r\nsfx\\rogue\\rogue40.wav\r\nsfx\\rogue\\rogue41.wav\r\nsfx\\rogue\\rogue42.wav\r\nsfx\\rogue\\rogue43.wav\r\nsfx\\rogue\\rogue44.wav\r\nsfx\\rogue\\rogue45.wav\r\nsfx\\rogue\\rogue46.wav\r\nsfx\\rogue\\rogue47.wav\r\nsfx\\rogue\\rogue48.wav\r\nsfx\\rogue\\rogue49.wav\r\nsfx\\rogue\\rogue50.wav\r\nsfx\\rogue\\rogue51.wav\r\nsfx\\rogue\\rogue52.wav\r\nsfx\\rogue\\rogue53.wav\r\nsfx\\rogue\\rogue54.wav\r\nsfx\\rogue\\rogue55.wav\r\nsfx\\rogue\\rogue56.wav\r\nsfx\\rogue\\rogue57.wav\r\nsfx\\rogue\\rogue58.wav\r\nsfx\\rogue\\rogue59.wav\r\nsfx\\rogue\\rogue60.wav\r\nsfx\\rogue\\rogue61.wav\r\nsfx\\rogue\\rogue62.wav\r\nsfx\\rogue\\rogue63.wav\r\nsfx\\rogue\\rogue64.wav\r\nsfx\\rogue\\rogue65.wav\r\nsfx\\rogue\\rogue66.wav\r\nsfx\\rogue\\rogue67.wav\r\nsfx\\rogue\\rogue68.wav\r\nsfx\\rogue\\rogue69.wav\r\nsfx\\rogue\\rogue69b.wav\r\nsfx\\rogue\\rogue70.wav\r\nsfx\\rogue\\rogue71.wav\r\nsfx\\rogue\\rogue72.wav\r\nsfx\\rogue\\rogue73.wav\r\nsfx\\rogue\\rogue74.wav\r\nsfx\\rogue\\rogue75.wav\r\nsfx\\rogue\\rogue76.wav\r\nsfx\\rogue\\rogue77.wav\r\nsfx\\rogue\\rogue78.wav\r\nsfx\\rogue\\rogue79.wav\r\nsfx\\rogue\\rogue80.wav\r\nsfx\\rogue\\rogue81.wav\r\nsfx\\rogue\\rogue82.wav\r\nsfx\\rogue\\rogue83.wav\r\nsfx\\rogue\\rogue84.wav\r\nsfx\\rogue\\rogue85.wav\r\nsfx\\rogue\\rogue86.wav\r\nsfx\\rogue\\rogue87.wav\r\nsfx\\rogue\\rogue88.wav\r\nsfx\\rogue\\rogue89.wav\r\nsfx\\rogue\\rogue90.wav\r\nsfx\\rogue\\rogue91.wav\r\nsfx\\rogue\\rogue92.wav\r\nsfx\\rogue\\rogue93.wav\r\nsfx\\rogue\\rogue94.wav\r\nsfx\\rogue\\rogue95.wav\r\nsfx\\rogue\\rogue96.wav\r\nsfx\\rogue\\rogue97.wav\r\nsfx\\rogue\\rogue98.wav\r\nsfx\\rogue\\rogue99.wav\r\nsfx\\sorceror\\mage01.wav\r\nsfx\\sorceror\\mage02.wav\r\nsfx\\sorceror\\mage03.wav\r\nsfx\\sorceror\\mage04.wav\r\nsfx\\sorceror\\mage05.wav\r\nsfx\\sorceror\\mage06.wav\r\nsfx\\sorceror\\mage07.wav\r\nsfx\\sorceror\\mage08.wav\r\nsfx\\sorceror\\mage09.wav\r\nsfx\\sorceror\\mage10.wav\r\nsfx\\sorceror\\mage100.wav\r\nsfx\\sorceror\\mage101.wav\r\nsfx\\sorceror\\mage102.wav\r\nsfx\\sorceror\\mage11.wav\r\nsfx\\sorceror\\mage12.wav\r\nsfx\\sorceror\\mage13.wav\r\nsfx\\sorceror\\mage14.wav\r\nsfx\\sorceror\\mage15.wav\r\nsfx\\sorceror\\mage16.wav\r\nsfx\\sorceror\\mage17.wav\r\nsfx\\sorceror\\mage18.wav\r\nsfx\\sorceror\\mage19.wav\r\nsfx\\sorceror\\mage20.wav\r\nsfx\\sorceror\\mage21.wav\r\nsfx\\sorceror\\mage22.wav\r\nsfx\\sorceror\\mage23.wav\r\nsfx\\sorceror\\mage24.wav\r\nsfx\\sorceror\\mage25.wav\r\nsfx\\sorceror\\mage26.wav\r\nsfx\\sorceror\\mage27.wav\r\nsfx\\sorceror\\mage28.wav\r\nsfx\\sorceror\\mage29.wav\r\nsfx\\sorceror\\mage30.wav\r\nsfx\\sorceror\\mage31.wav\r\nsfx\\sorceror\\mage32.wav\r\nsfx\\sorceror\\mage33.wav\r\nsfx\\sorceror\\mage34.wav\r\nsfx\\sorceror\\mage35.wav\r\nsfx\\sorceror\\mage36.wav\r\nsfx\\sorceror\\mage37.wav\r\nsfx\\sorceror\\mage38.wav\r\nsfx\\sorceror\\mage39.wav\r\nsfx\\sorceror\\mage40.wav\r\nsfx\\sorceror\\mage41.wav\r\nsfx\\sorceror\\mage42.wav\r\nsfx\\sorceror\\mage43.wav\r\nsfx\\sorceror\\mage44.wav\r\nsfx\\sorceror\\mage45.wav\r\nsfx\\sorceror\\mage46.wav\r\nsfx\\sorceror\\mage47.wav\r\nsfx\\sorceror\\mage48.wav\r\nsfx\\sorceror\\mage49.wav\r\nsfx\\sorceror\\mage50.wav\r\nsfx\\sorceror\\mage51.wav\r\nsfx\\sorceror\\mage52.wav\r\nsfx\\sorceror\\mage53.wav\r\nsfx\\sorceror\\mage54.wav\r\nsfx\\sorceror\\mage55.wav\r\nsfx\\sorceror\\mage56.wav\r\nsfx\\sorceror\\mage57.wav\r\nsfx\\sorceror\\mage58.wav\r\nsfx\\sorceror\\mage59.wav\r\nsfx\\sorceror\\mage60.wav\r\nsfx\\sorceror\\mage61.wav\r\nsfx\\sorceror\\mage62.wav\r\nsfx\\sorceror\\mage63.wav\r\nsfx\\sorceror\\mage64.wav\r\nsfx\\sorceror\\mage65.wav\r\nsfx\\sorceror\\mage66.wav\r\nsfx\\sorceror\\mage67.wav\r\nsfx\\sorceror\\mage68.wav\r\nsfx\\sorceror\\mage69.wav\r\nsfx\\sorceror\\mage69b.wav\r\nsfx\\sorceror\\mage70.wav\r\nsfx\\sorceror\\mage71.wav\r\nsfx\\sorceror\\mage72.wav\r\nsfx\\sorceror\\mage73.wav\r\nsfx\\sorceror\\mage74.wav\r\nsfx\\sorceror\\mage75.wav\r\nsfx\\sorceror\\mage76.wav\r\nsfx\\sorceror\\mage77.wav\r\nsfx\\sorceror\\mage78.wav\r\nsfx\\sorceror\\mage79.wav\r\nsfx\\sorceror\\mage80.wav\r\nsfx\\sorceror\\mage81.wav\r\nsfx\\sorceror\\mage82.wav\r\nsfx\\sorceror\\mage83.wav\r\nsfx\\sorceror\\mage84.wav\r\nsfx\\sorceror\\mage85.wav\r\nsfx\\sorceror\\mage86.wav\r\nsfx\\sorceror\\mage87.wav\r\nsfx\\sorceror\\mage88.wav\r\nsfx\\sorceror\\mage89.wav\r\nsfx\\sorceror\\mage90.wav\r\nsfx\\sorceror\\mage91.wav\r\nsfx\\sorceror\\mage92.wav\r\nsfx\\sorceror\\mage93.wav\r\nsfx\\sorceror\\mage94.wav\r\nsfx\\sorceror\\mage95.wav\r\nsfx\\sorceror\\mage96.wav\r\nsfx\\sorceror\\mage97.wav\r\nsfx\\sorceror\\mage98.wav\r\nsfx\\sorceror\\mage99.wav\r\nSfx\\Towners\\Bmaid01.wav\r\nSfx\\Towners\\Bmaid02.wav\r\nSfx\\Towners\\Bmaid03.wav\r\nSfx\\Towners\\Bmaid04.wav\r\nSfx\\Towners\\Bmaid05.wav\r\nSfx\\Towners\\Bmaid06.wav\r\nSfx\\Towners\\Bmaid07.wav\r\nSfx\\Towners\\Bmaid08.wav\r\nSfx\\Towners\\Bmaid09.wav\r\nSfx\\Towners\\Bmaid10.wav\r\nSfx\\Towners\\Bmaid11.wav\r\nSfx\\Towners\\Bmaid12.wav\r\nSfx\\Towners\\Bmaid13.wav\r\nSfx\\Towners\\Bmaid14.wav\r\nSfx\\Towners\\Bmaid15.wav\r\nSfx\\Towners\\Bmaid16.wav\r\nSfx\\Towners\\Bmaid17.wav\r\nSfx\\Towners\\Bmaid18.wav\r\nSfx\\Towners\\Bmaid19.wav\r\nSfx\\Towners\\Bmaid20.wav\r\nSfx\\Towners\\Bmaid21.wav\r\nSfx\\Towners\\Bmaid22.wav\r\nSfx\\Towners\\Bmaid23.wav\r\nSfx\\Towners\\Bmaid24.wav\r\nSfx\\Towners\\Bmaid25.wav\r\nSfx\\Towners\\Bmaid26.wav\r\nSfx\\Towners\\Bmaid27.wav\r\nSfx\\Towners\\Bmaid28.wav\r\nSfx\\Towners\\Bmaid29.wav\r\nSfx\\Towners\\Bmaid30.wav\r\nSfx\\Towners\\Bmaid31.wav\r\nSfx\\Towners\\Bmaid32.wav\r\nSfx\\Towners\\Bmaid33.wav\r\nSfx\\Towners\\Bmaid34.wav\r\nSfx\\Towners\\Bmaid35.wav\r\nSfx\\Towners\\Bmaid36.wav\r\nSfx\\Towners\\Bmaid37.wav\r\nSfx\\Towners\\Bmaid38.wav\r\nSfx\\Towners\\Bmaid39.wav\r\nSfx\\Towners\\Bmaid40.wav\r\nSfx\\Towners\\Bsmith01.wav\r\nSfx\\Towners\\Bsmith02.wav\r\nSfx\\Towners\\Bsmith03.wav\r\nSfx\\Towners\\Bsmith04.wav\r\nSfx\\Towners\\Bsmith05.wav\r\nSfx\\Towners\\Bsmith06.wav\r\nSfx\\Towners\\Bsmith07.wav\r\nSfx\\Towners\\Bsmith08.wav\r\nSfx\\Towners\\Bsmith09.wav\r\nSfx\\Towners\\Bsmith10.wav\r\nSfx\\Towners\\Bsmith11.wav\r\nSfx\\Towners\\Bsmith12.wav\r\nSfx\\Towners\\Bsmith13.wav\r\nSfx\\Towners\\Bsmith14.wav\r\nSfx\\Towners\\Bsmith15.wav\r\nSfx\\Towners\\Bsmith16.wav\r\nSfx\\Towners\\Bsmith17.wav\r\nSfx\\Towners\\Bsmith18.wav\r\nSfx\\Towners\\Bsmith19.wav\r\nSfx\\Towners\\Bsmith20.wav\r\nSfx\\Towners\\Bsmith21.wav\r\nSfx\\Towners\\Bsmith22.wav\r\nSfx\\Towners\\Bsmith23.wav\r\nSfx\\Towners\\Bsmith24.wav\r\nSfx\\Towners\\Bsmith25.wav\r\nSfx\\Towners\\Bsmith26.wav\r\nSfx\\Towners\\Bsmith27.wav\r\nSfx\\Towners\\Bsmith28.wav\r\nSfx\\Towners\\Bsmith29.wav\r\nSfx\\Towners\\Bsmith30.wav\r\nSfx\\Towners\\Bsmith31.wav\r\nSfx\\Towners\\Bsmith32.wav\r\nSfx\\Towners\\Bsmith33.wav\r\nSfx\\Towners\\Bsmith34.wav\r\nSfx\\Towners\\Bsmith35.wav\r\nSfx\\Towners\\Bsmith36.wav\r\nSfx\\Towners\\Bsmith37.wav\r\nSfx\\Towners\\Bsmith38.wav\r\nSfx\\Towners\\Bsmith39.wav\r\nSfx\\Towners\\Bsmith40.wav\r\nSfx\\Towners\\Bsmith41.wav\r\nSfx\\Towners\\Bsmith42.wav\r\nSfx\\Towners\\Bsmith43.wav\r\nSfx\\Towners\\Bsmith44.wav\r\nSfx\\Towners\\Bsmith45.wav\r\nSfx\\Towners\\Bsmith46.wav\r\nSfx\\Towners\\Bsmith47.wav\r\nSfx\\Towners\\Bsmith48.wav\r\nSfx\\Towners\\Bsmith49.wav\r\nSfx\\Towners\\Bsmith50.wav\r\nSfx\\Towners\\Bsmith51.wav\r\nSfx\\Towners\\Bsmith52.wav\r\nSfx\\Towners\\Bsmith53.wav\r\nSfx\\Towners\\Bsmith54.wav\r\nSfx\\Towners\\Bsmith55.wav\r\nSfx\\Towners\\Bsmith56.wav\r\nSfx\\Towners\\Cow1.wav\r\nSfx\\Towners\\Cow2.wav\r\nsfx\\towners\\cow3.wav\r\nsfx\\towners\\cow4.wav\r\nsfx\\towners\\cow5.wav\r\nsfx\\towners\\cow6.wav\r\nsfx\\towners\\cow7.wav\r\nsfx\\towners\\cow8.wav\r\nSfx\\Towners\\Deadguy2.wav\r\nSfx\\Towners\\Drunk01.wav\r\nSfx\\Towners\\Drunk02.wav\r\nSfx\\Towners\\Drunk03.wav\r\nSfx\\Towners\\Drunk04.wav\r\nSfx\\Towners\\Drunk05.wav\r\nSfx\\Towners\\Drunk06.wav\r\nSfx\\Towners\\Drunk07.wav\r\nSfx\\Towners\\Drunk08.wav\r\nSfx\\Towners\\Drunk09.wav\r\nSfx\\Towners\\Drunk10.wav\r\nSfx\\Towners\\Drunk11.wav\r\nSfx\\Towners\\Drunk12.wav\r\nSfx\\Towners\\Drunk13.wav\r\nSfx\\Towners\\Drunk14.wav\r\nSfx\\Towners\\Drunk15.wav\r\nSfx\\Towners\\Drunk16.wav\r\nSfx\\Towners\\Drunk17.wav\r\nSfx\\Towners\\Drunk18.wav\r\nSfx\\Towners\\Drunk19.wav\r\nSfx\\Towners\\Drunk20.wav\r\nSfx\\Towners\\Drunk21.wav\r\nSfx\\Towners\\Drunk22.wav\r\nSfx\\Towners\\Drunk23.wav\r\nSfx\\Towners\\Drunk24.wav\r\nSfx\\Towners\\Drunk25.wav\r\nSfx\\Towners\\Drunk26.wav\r\nSfx\\Towners\\Drunk27.wav\r\nSfx\\Towners\\Drunk28.wav\r\nSfx\\Towners\\Drunk29.wav\r\nSfx\\Towners\\Drunk30.wav\r\nSfx\\Towners\\Drunk31.wav\r\nSfx\\Towners\\Drunk32.wav\r\nSfx\\Towners\\Drunk33.wav\r\nSfx\\Towners\\Drunk34.wav\r\nSfx\\Towners\\Drunk35.wav\r\nSfx\\Towners\\Healer01.wav\r\nSfx\\Towners\\Healer02.wav\r\nSfx\\Towners\\Healer03.wav\r\nSfx\\Towners\\Healer04.wav\r\nSfx\\Towners\\Healer05.wav\r\nsfx\\towners\\healer06.wav\r\nsfx\\towners\\healer07.wav\r\nsfx\\towners\\healer08.wav\r\nSfx\\Towners\\Healer09.wav\r\nsfx\\towners\\healer10.wav\r\nSfx\\Towners\\Healer11.wav\r\nsfx\\towners\\healer12.wav\r\nsfx\\towners\\healer13.wav\r\nSfx\\Towners\\Healer14.wav\r\nSfx\\Towners\\Healer15.wav\r\nsfx\\towners\\healer16.wav\r\nSfx\\Towners\\Healer17.wav\r\nSfx\\Towners\\Healer18.wav\r\nsfx\\towners\\healer19.wav\r\nSfx\\Towners\\Healer20.wav\r\nsfx\\towners\\healer21.wav\r\nSfx\\Towners\\Healer22.wav\r\nSfx\\Towners\\Healer23.wav\r\nSfx\\Towners\\Healer24.wav\r\nSfx\\Towners\\Healer25.wav\r\nsfx\\towners\\healer26.wav\r\nSfx\\Towners\\Healer27.wav\r\nsfx\\towners\\healer28.wav\r\nSfx\\Towners\\Healer29.wav\r\nsfx\\towners\\healer30.wav\r\nSfx\\Towners\\Healer31.wav\r\nSfx\\Towners\\Healer32.wav\r\nSfx\\Towners\\Healer33.wav\r\nSfx\\Towners\\Healer34.wav\r\nSfx\\Towners\\Healer35.wav\r\nSfx\\Towners\\Healer36.wav\r\nSfx\\Towners\\Healer37.wav\r\nSfx\\Towners\\Healer38.wav\r\nSfx\\Towners\\Healer39.wav\r\nSfx\\Towners\\Healer40.wav\r\nSfx\\Towners\\Healer41.wav\r\nsfx\\towners\\healer42.wav\r\nSfx\\Towners\\Healer43.wav\r\nsfx\\towners\\healer44.wav\r\nsfx\\towners\\healer45.wav\r\nsfx\\towners\\healer46.wav\r\nsfx\\towners\\healer47.wav\r\nsfx\\towners\\pegboy01.wav\r\nSfx\\Towners\\Pegboy02.wav\r\nsfx\\towners\\pegboy03.wav\r\nSfx\\Towners\\Pegboy04.wav\r\nsfx\\towners\\pegboy05.wav\r\nsfx\\towners\\pegboy06.wav\r\nSfx\\Towners\\Pegboy07.wav\r\nsfx\\towners\\pegboy08.wav\r\nSfx\\Towners\\Pegboy09.wav\r\nsfx\\towners\\pegboy10.wav\r\nsfx\\towners\\pegboy11.wav\r\nSfx\\Towners\\Pegboy12.wav\r\nSfx\\Towners\\Pegboy13.wav\r\nSfx\\Towners\\Pegboy14.wav\r\nsfx\\towners\\pegboy15.wav\r\nsfx\\towners\\pegboy16.wav\r\nSfx\\Towners\\Pegboy17.wav\r\nsfx\\towners\\pegboy18.wav\r\nsfx\\towners\\pegboy19.wav\r\nsfx\\towners\\pegboy20.wav\r\nSfx\\Towners\\Pegboy21.wav\r\nsfx\\towners\\pegboy22.wav\r\nsfx\\towners\\pegboy23.wav\r\nsfx\\towners\\pegboy24.wav\r\nSfx\\Towners\\Pegboy25.wav\r\nsfx\\towners\\pegboy26.wav\r\nSfx\\Towners\\Pegboy27.wav\r\nSfx\\Towners\\Pegboy28.wav\r\nSfx\\Towners\\Pegboy29.wav\r\nsfx\\towners\\pegboy30.wav\r\nSfx\\Towners\\Pegboy31.wav\r\nSfx\\Towners\\Pegboy32.wav\r\nSfx\\Towners\\Pegboy33.wav\r\nSfx\\Towners\\Pegboy34.wav\r\nsfx\\towners\\pegboy35.wav\r\nsfx\\towners\\pegboy36.wav\r\nsfx\\towners\\pegboy37.wav\r\nsfx\\towners\\pegboy38.wav\r\nSfx\\Towners\\Pegboy39.wav\r\nsfx\\towners\\pegboy40.wav\r\nsfx\\towners\\pegboy41.wav\r\nSfx\\Towners\\Pegboy42.wav\r\nsfx\\towners\\pegboy43.wav\r\nSfx\\Towners\\Priest00.wav\r\nsfx\\towners\\priest01.wav\r\nSfx\\Towners\\Priest02.wav\r\nSfx\\Towners\\Priest03.wav\r\nsfx\\towners\\priest04.wav\r\nSfx\\Towners\\Priest05.wav\r\nSfx\\Towners\\Priest06.wav\r\nSfx\\Towners\\Priest07.wav\r\nSfx\\Towners\\Storyt00.wav\r\nSfx\\Towners\\Storyt01.wav\r\nSfx\\Towners\\Storyt02.wav\r\nsfx\\towners\\storyt03.wav\r\nSfx\\Towners\\Storyt04.wav\r\nsfx\\towners\\storyt05.wav\r\nsfx\\towners\\storyt06.wav\r\nSfx\\Towners\\Storyt07.wav\r\nsfx\\towners\\storyt08.wav\r\nSfx\\Towners\\Storyt09.wav\r\nsfx\\towners\\storyt10.wav\r\nsfx\\towners\\storyt11.wav\r\nsfx\\towners\\storyt12.wav\r\nsfx\\towners\\storyt13.wav\r\nSfx\\Towners\\Storyt14.wav\r\nsfx\\towners\\storyt15.wav\r\nsfx\\towners\\storyt16.wav\r\nsfx\\towners\\storyt17.wav\r\nSfx\\Towners\\Storyt18.wav\r\nSfx\\Towners\\Storyt19.wav\r\nsfx\\towners\\storyt20.wav\r\nSfx\\Towners\\Storyt21.wav\r\nsfx\\towners\\storyt22.wav\r\nSfx\\Towners\\Storyt23.wav\r\nSfx\\Towners\\Storyt24.wav\r\nsfx\\towners\\storyt25.wav\r\nSfx\\Towners\\Storyt26.wav\r\nSfx\\Towners\\Storyt27.wav\r\nsfx\\towners\\storyt28.wav\r\nsfx\\towners\\storyt29.wav\r\nsfx\\towners\\storyt30.wav\r\nSfx\\Towners\\Storyt31.wav\r\nsfx\\towners\\storyt32.wav\r\nsfx\\towners\\storyt33.wav\r\nsfx\\towners\\storyt34.wav\r\nsfx\\towners\\storyt35.wav\r\nsfx\\towners\\storyt36.wav\r\nSfx\\Towners\\Storyt37.wav\r\nSfx\\Towners\\Storyt38.wav\r\nSfx\\Towners\\Tavown00.wav\r\nsfx\\towners\\tavown01.wav\r\nSfx\\Towners\\Tavown02.wav\r\nSfx\\Towners\\Tavown03.wav\r\nsfx\\towners\\tavown04.wav\r\nSfx\\Towners\\Tavown05.wav\r\nSfx\\Towners\\Tavown06.wav\r\nsfx\\towners\\tavown07.wav\r\nSfx\\Towners\\Tavown08.wav\r\nSfx\\Towners\\Tavown09.wav\r\nsfx\\towners\\tavown10.wav\r\nsfx\\towners\\tavown11.wav\r\nSfx\\Towners\\Tavown12.wav\r\nsfx\\towners\\tavown13.wav\r\nSfx\\Towners\\Tavown14.wav\r\nsfx\\towners\\tavown15.wav\r\nSfx\\Towners\\Tavown16.wav\r\nSfx\\Towners\\Tavown17.wav\r\nsfx\\towners\\tavown18.wav\r\nsfx\\towners\\tavown19.wav\r\nSfx\\Towners\\Tavown20.wav\r\nSfx\\Towners\\Tavown21.wav\r\nsfx\\towners\\tavown22.wav\r\nsfx\\towners\\tavown23.wav\r\nsfx\\towners\\tavown24.wav\r\nSfx\\Towners\\Tavown25.wav\r\nsfx\\towners\\tavown26.wav\r\nSfx\\Towners\\Tavown27.wav\r\nsfx\\towners\\tavown28.wav\r\nSfx\\Towners\\Tavown29.wav\r\nsfx\\towners\\tavown30.wav\r\nSfx\\Towners\\Tavown31.wav\r\nSfx\\Towners\\Tavown32.wav\r\nsfx\\towners\\tavown33.wav\r\nsfx\\towners\\tavown34.wav\r\nSfx\\Towners\\Tavown35.wav\r\nsfx\\towners\\tavown36.wav\r\nsfx\\towners\\tavown37.wav\r\nsfx\\towners\\tavown38.wav\r\nsfx\\towners\\tavown39.wav\r\nSfx\\Towners\\Tavown40.wav\r\nSfx\\Towners\\Tavown41.wav\r\nsfx\\towners\\tavown42.wav\r\nSfx\\Towners\\Tavown43.wav\r\nSfx\\Towners\\Tavown44.wav\r\nsfx\\towners\\tavown45.wav\r\nSfx\\Towners\\Witch01.wav\r\nsfx\\towners\\witch02.wav\r\nSfx\\Towners\\Witch03.wav\r\nsfx\\towners\\witch04.wav\r\nSfx\\Towners\\Witch05.wav\r\nSfx\\Towners\\Witch06.wav\r\nsfx\\towners\\witch07.wav\r\nsfx\\towners\\witch08.wav\r\nSfx\\Towners\\Witch09.wav\r\nsfx\\towners\\witch10.wav\r\nSfx\\Towners\\Witch11.wav\r\nsfx\\towners\\witch12.wav\r\nsfx\\towners\\witch13.wav\r\nSfx\\Towners\\Witch14.wav\r\nsfx\\towners\\witch15.wav\r\nsfx\\towners\\witch16.wav\r\nSfx\\Towners\\Witch17.wav\r\nsfx\\towners\\witch18.wav\r\nSfx\\Towners\\Witch19.wav\r\nSfx\\Towners\\Witch20.wav\r\nSfx\\Towners\\Witch21.wav\r\nSfx\\Towners\\Witch22.wav\r\nsfx\\towners\\witch23.wav\r\nSfx\\Towners\\Witch24.wav\r\nSfx\\Towners\\Witch25.wav\r\nSfx\\Towners\\Witch26.wav\r\nSfx\\Towners\\Witch27.wav\r\nsfx\\towners\\witch28.wav\r\nsfx\\towners\\witch29.wav\r\nSfx\\Towners\\Witch30.wav\r\nSfx\\Towners\\Witch31.wav\r\nSfx\\Towners\\Witch32.wav\r\nSfx\\Towners\\Witch33.wav\r\nSfx\\Towners\\Witch34.wav\r\nSfx\\Towners\\Witch35.wav\r\nsfx\\towners\\witch36.wav\r\nsfx\\towners\\witch37.wav\r\nSfx\\Towners\\Witch38.wav\r\nSfx\\Towners\\Witch39.wav\r\nSfx\\Towners\\Witch40.wav\r\nSfx\\Towners\\Witch41.wav\r\nSfx\\Towners\\Witch42.wav\r\nSfx\\Towners\\Witch43.wav\r\nSfx\\Towners\\Witch44.wav\r\nSfx\\Towners\\Witch45.wav\r\nSfx\\Towners\\Witch46.wav\r\nsfx\\towners\\witch47.wav\r\nsfx\\towners\\witch48.wav\r\nSfx\\Towners\\Witch49.wav\r\nsfx\\towners\\witch50.wav\r\nSfx\\Towners\\Wound01.wav\r\nSfx\\Warrior\\Wario100.wav\r\nSfx\\Warrior\\Wario101.wav\r\nsfx\\warrior\\wario102.wav\r\nSfx\\Warrior\\Wario14b.wav\r\nSfx\\Warrior\\Wario14c.wav\r\nSfx\\Warrior\\Wario15b.wav\r\nSfx\\Warrior\\Wario15c.wav\r\nSfx\\Warrior\\Wario16b.wav\r\nSfx\\Warrior\\Wario16c.wav\r\nsfx\\warrior\\wario69b.wav\r\nSfx\\Warrior\\Wario95b.wav\r\nSfx\\Warrior\\Wario95c.wav\r\nSfx\\Warrior\\Wario95d.wav\r\nSfx\\Warrior\\Wario95e.wav\r\nSfx\\Warrior\\Wario95f.wav\r\nSfx\\Warrior\\Wario96b.wav\r\nSfx\\Warrior\\Wario96c.wav\r\nSfx\\Warrior\\Wario97.wav\r\nSfx\\Warrior\\Wario98.wav\r\nSfx\\Warrior\\Warior01.wav\r\nSfx\\Warrior\\Warior02.wav\r\nsfx\\warrior\\warior03.wav\r\nSfx\\Warrior\\Warior04.wav\r\nsfx\\warrior\\warior05.wav\r\nSfx\\Warrior\\Warior06.wav\r\nSfx\\Warrior\\Warior07.wav\r\nSfx\\Warrior\\Warior08.wav\r\nSfx\\Warrior\\Warior09.wav\r\nSfx\\Warrior\\Warior10.wav\r\nSfx\\Warrior\\Warior11.wav\r\nSfx\\Warrior\\Warior12.wav\r\nSfx\\Warrior\\Warior13.wav\r\nSfx\\Warrior\\Warior14.wav\r\nSfx\\Warrior\\Warior15.wav\r\nSfx\\Warrior\\Warior16.wav\r\nSfx\\Warrior\\Warior17.wav\r\nSfx\\Warrior\\Warior18.wav\r\nSfx\\Warrior\\Warior19.wav\r\nSfx\\Warrior\\Warior20.wav\r\nSfx\\Warrior\\Warior21.wav\r\nSfx\\Warrior\\Warior22.wav\r\nSfx\\Warrior\\Warior23.wav\r\nSfx\\Warrior\\Warior24.wav\r\nSfx\\Warrior\\Warior25.wav\r\nSfx\\Warrior\\Warior26.wav\r\nsfx\\warrior\\warior27.wav\r\nsfx\\warrior\\warior28.wav\r\nsfx\\warrior\\warior29.wav\r\nsfx\\warrior\\warior30.wav\r\nsfx\\warrior\\warior31.wav\r\nsfx\\warrior\\warior32.wav\r\nsfx\\warrior\\warior33.wav\r\nsfx\\warrior\\warior34.wav\r\nSfx\\Warrior\\Warior35.wav\r\nSfx\\Warrior\\Warior36.wav\r\nSfx\\Warrior\\Warior37.wav\r\nSfx\\Warrior\\Warior38.wav\r\nSfx\\Warrior\\Warior39.wav\r\nsfx\\warrior\\warior40.wav\r\nSfx\\Warrior\\Warior41.wav\r\nsfx\\warrior\\warior42.wav\r\nSfx\\Warrior\\Warior43.wav\r\nSfx\\Warrior\\Warior44.wav\r\nSfx\\Warrior\\Warior45.wav\r\nsfx\\warrior\\warior46.wav\r\nsfx\\warrior\\warior47.wav\r\nSfx\\Warrior\\Warior48.wav\r\nsfx\\warrior\\warior49.wav\r\nsfx\\warrior\\warior50.wav\r\nSfx\\Warrior\\Warior51.wav\r\nsfx\\warrior\\warior52.wav\r\nsfx\\warrior\\warior53.wav\r\nSfx\\Warrior\\Warior54.wav\r\nsfx\\warrior\\warior55.wav\r\nSfx\\Warrior\\Warior56.wav\r\nSfx\\Warrior\\Warior57.wav\r\nSfx\\Warrior\\Warior58.wav\r\nsfx\\warrior\\warior59.wav\r\nSfx\\Warrior\\Warior60.wav\r\nsfx\\warrior\\warior61.wav\r\nsfx\\warrior\\warior62.wav\r\nSfx\\Warrior\\Warior63.wav\r\nSfx\\Warrior\\Warior64.wav\r\nsfx\\warrior\\warior65.wav\r\nsfx\\warrior\\warior66.wav\r\nsfx\\warrior\\warior67.wav\r\nsfx\\warrior\\warior68.wav\r\nsfx\\warrior\\warior69.wav\r\nSfx\\Warrior\\Warior70.wav\r\nSfx\\Warrior\\Warior71.wav\r\nSfx\\Warrior\\Warior72.wav\r\nsfx\\warrior\\warior73.wav\r\nSfx\\Warrior\\Warior74.wav\r\nSfx\\Warrior\\Warior75.wav\r\nSfx\\Warrior\\Warior76.wav\r\nSfx\\Warrior\\Warior77.wav\r\nSfx\\Warrior\\Warior78.wav\r\nSfx\\Warrior\\Warior79.wav\r\nsfx\\warrior\\warior80.wav\r\nSfx\\Warrior\\Warior81.wav\r\nSfx\\Warrior\\Warior82.wav\r\nSfx\\Warrior\\Warior83.wav\r\nsfx\\warrior\\warior84.wav\r\nsfx\\warrior\\warior85.wav\r\nsfx\\warrior\\warior86.wav\r\nsfx\\warrior\\warior87.wav\r\nsfx\\warrior\\warior88.wav\r\nsfx\\warrior\\warior89.wav\r\nsfx\\warrior\\warior90.wav\r\nsfx\\warrior\\warior91.wav\r\nsfx\\warrior\\warior92.wav\r\nSfx\\Warrior\\Warior93.wav\r\nsfx\\warrior\\warior94.wav\r\nSfx\\Warrior\\Warior95.wav\r\nsfx\\warrior\\warior96.wav\r\nsfx\\warrior\\warior97.wav\r\nsfx\\warrior\\warior98.wav\r\nsfx\\warrior\\warior99.wav\r\nsfxdata.dat\r\nsfxdata.tbl\r\nsmackw32.dll\r\nsmk\\blizzard.smk\r\nsmk\\diablo2.smk\r\nsmk\\preprotoss_1.smk\r\nsmk\\preprotoss_2.smk\r\nsmk\\preprotoss_3.smk\r\nsmk\\preterran_1.smk\r\nsmk\\preterran_2.smk\r\nsmk\\preterran_3.smk\r\nsmk\\preterran_4.smk\r\nsmk\\PreZerg_1.smk\r\nsmk\\prezerg_2.smk\r\nsmk\\prezerg_3.smk\r\nsmk\\prezerg_4.smk\r\nsmk\\protoss1.smk\r\nsmk\\protoss2.smk\r\nsmk\\protoss3.smk\r\nsmk\\protoss4.smk\r\nsmk\\starintr.smk\r\nsmk\\starxintr.smk\r\nsmk\\terran1.smk\r\nsmk\\terran2.smk\r\nsmk\\terran3.smk\r\nsmk\\terran4.smk\r\nsmk\\waradven.smk\r\nsmk\\xprotoss.smk\r\nsmk\\xterran.smk\r\nsmk\\xzerg.smk\r\nsmk\\zerg1.smk\r\nsmk\\zerg2.smk\r\nsmk\\zerg3.smk\r\nsmk\\zerg4.smk\r\nsound\\bullet\\blastcan.wav\r\nsound\\bullet\\blastgn2.wav\r\nsound\\bullet\\dragbull.wav\r\nsound\\bullet\\esphit00.wav\r\nsound\\bullet\\hkmissle.wav\r\nsound\\bullet\\laserb.wav\r\nsound\\bullet\\laserblt.wav\r\nsound\\bullet\\laserhit.wav\r\nsound\\bullet\\lasrhit1.wav\r\nsound\\bullet\\lasrhit2.wav\r\nsound\\bullet\\lasrhit3.wav\r\nsound\\bullet\\ncsfir00.wav\r\nsound\\bullet\\ngufir00.wav\r\nsound\\bullet\\parfir00.wav\r\nsound\\Bullet\\PhoAtt00.wav\r\nsound\\bullet\\phofir00.wav\r\nsound\\bullet\\phohit00.wav\r\nsound\\bullet\\psahit00.wav\r\nsound\\bullet\\pshield.wav\r\nsound\\bullet\\psiblade.wav\r\nsound\\bullet\\psibolt.wav\r\nsound\\bullet\\ptehit00.wav\r\nsound\\bullet\\ptrfir00.wav\r\nsound\\bullet\\ptrfir01.wav\r\nsound\\Bullet\\pzeFir00.wav\r\nsound\\bullet\\shcklnch.wav\r\nsound\\bullet\\shockbmb.wav\r\nsound\\bullet\\spooghit.wav\r\nsound\\Bullet\\tbaFir00.wav\r\nsound\\bullet\\tbayam00.wav\r\nsound\\bullet\\tdrfir00.wav\r\nsound\\bullet\\tfrhit.wav\r\nsound\\bullet\\tfrshoot.wav\r\nsound\\bullet\\tghfir00.wav\r\nsound\\bullet\\tgofi200.wav\r\nsound\\bullet\\tgofir00.wav\r\nsound\\bullet\\tmafir00.wav\r\nsound\\bullet\\tnsfir00.wav\r\nsound\\bullet\\tnshit00.wav\r\nsound\\bullet\\tphfi100.wav\r\nsound\\bullet\\tphfi200.wav\r\nsound\\bullet\\tphfi201.wav\r\nsound\\bullet\\tscfir00.wav\r\nsound\\bullet\\ttafi200.wav\r\nsound\\bullet\\ttafir00.wav\r\nsound\\bullet\\ttahi200.wav\r\nsound\\bullet\\ttahit00.wav\r\nsound\\bullet\\tvufir00.wav\r\nsound\\bullet\\tvuhit00.wav\r\nsound\\bullet\\tvuhit01.wav\r\nsound\\bullet\\tvuhit02.wav\r\nsound\\bullet\\ukifir00.wav\r\nsound\\bullet\\uzefir00.wav\r\nsound\\bullet\\zbghit00.wav\r\nsound\\bullet\\zdeatt00.wav\r\nsound\\bullet\\zdrhit00.wav\r\nsound\\bullet\\zgufir00.wav\r\nsound\\bullet\\zguhit00.wav\r\nsound\\bullet\\zhyfir00.wav\r\nsound\\bullet\\zhyhit00.wav\r\nsound\\bullet\\zlrkfir1.wav\r\nsound\\bullet\\zlrkfir2.wav\r\nsound\\bullet\\zlrkhit1.wav\r\nsound\\bullet\\zlrkhit2.wav\r\nsound\\bullet\\zlufir00.wav\r\nsound\\bullet\\zluhit00.wav\r\nsound\\bullet\\zmufir00.wav\r\nsound\\bullet\\zqufir00.wav\r\nsound\\bullet\\zquhit00.wav\r\nsound\\bullet\\zquhit01.wav\r\nsound\\bullet\\zquhit02.wav\r\nsound\\glue\\bnetclick.wav\r\nsound\\glue\\countdown.wav\r\nsound\\glue\\mousedown2.wav\r\nsound\\glue\\mouseover.wav\r\nsound\\glue\\scorefill.wav\r\nsound\\glue\\scorefillend.wav\r\nsound\\glue\\swishin.wav\r\nsound\\glue\\swishlock.wav\r\nsound\\glue\\swishout.wav\r\nsound\\glue\\vssver.scc\r\nsound\\misc\\burrowdn.wav\r\nsound\\misc\\burrowup.wav\r\nsound\\misc\\button.wav\r\nsound\\misc\\buzz.wav\r\nsound\\misc\\chelp1.wav\r\nsound\\misc\\chelp2.wav\r\nsound\\misc\\critters\\bcrdth00.wav\r\nsound\\misc\\critters\\bcrwht00.wav\r\nsound\\misc\\critters\\bcrwht01.wav\r\nsound\\misc\\critters\\bcrwht02.wav\r\nsound\\misc\\critters\\jcrdth00.wav\r\nsound\\misc\\critters\\jcrwht00.wav\r\nsound\\misc\\critters\\jcrwht01.wav\r\nsound\\misc\\critters\\jcrwht02.wav\r\nsound\\misc\\critters\\lcrdth00.wav\r\nsound\\misc\\critters\\lcrwht00.wav\r\nsound\\misc\\critters\\lcrwht01.wav\r\nsound\\misc\\critters\\lcrwht02.wav\r\nsound\\misc\\critters\\pbdeath01.wav\r\nsound\\misc\\critters\\pbwht01.wav\r\nsound\\misc\\critters\\pbwht02.wav\r\nsound\\misc\\critters\\pbwht03.wav\r\nsound\\misc\\critters\\scdeath01.wav\r\nsound\\misc\\critters\\scwht01.wav\r\nsound\\misc\\critters\\scwht02.wav\r\nsound\\misc\\critters\\scwht03.wav\r\nsound\\misc\\critters\\terdeath01.wav\r\nsound\\misc\\critters\\terwht01.wav\r\nsound\\misc\\critters\\terwht02.wav\r\nsound\\misc\\critters\\terwht03.wav\r\nsound\\misc\\door\\door1cls.wav\r\nsound\\misc\\door\\door1opn.wav\r\nsound\\misc\\door\\door2cls.wav\r\nsound\\misc\\door\\door2opn.wav\r\nsound\\misc\\door\\door3cls.wav\r\nsound\\misc\\door\\door3opn.wav\r\nsound\\misc\\door\\door4cls.wav\r\nsound\\misc\\door\\door4opn.wav\r\nsound\\misc\\explo1.wav\r\nsound\\misc\\explo2.wav\r\nsound\\misc\\explo3.wav\r\nsound\\misc\\explo4.wav\r\nsound\\misc\\explo5.wav\r\nsound\\misc\\explolrg.wav\r\nsound\\misc\\explomed.wav\r\nsound\\misc\\explosm.wav\r\nsound\\misc\\intonydus.wav\r\nsound\\misc\\land.wav\r\nsound\\misc\\liftoff.wav\r\nsound\\misc\\onfirsml.wav\r\nsound\\misc\\outofgas.wav\r\nsound\\misc\\pbldgplc.wav\r\nsound\\misc\\perror.wav\r\nsound\\misc\\ppwrdown.wav\r\nsound\\misc\\prescue.wav\r\nsound\\misc\\pshtra00.wav\r\nsound\\misc\\pshtra01.wav\r\nsound\\misc\\ptesum00.wav\r\nsound\\misc\\tbldgplc.wav\r\nsound\\misc\\tdrtra00.wav\r\nsound\\misc\\tdrtra01.wav\r\nsound\\misc\\thunk.wav\r\nsound\\misc\\tpwrdown.wav\r\nsound\\misc\\transmission.wav\r\nsound\\misc\\trescue.wav\r\nsound\\misc\\uicwht00.wav\r\nsound\\misc\\unrwht00.wav\r\nsound\\misc\\upiwht00.wav\r\nsound\\misc\\utmwht00.wav\r\nsound\\misc\\youlose.wav\r\nsound\\misc\\youwin.wav\r\nsound\\misc\\zbldgplc.wav\r\nsound\\misc\\zovtra00.wav\r\nsound\\misc\\zovtra01.wav\r\nsound\\misc\\zpwrdown.wav\r\nsound\\misc\\zrescue.wav\r\nsound\\protoss\\advisor\\paderr00.wav\r\nsound\\protoss\\advisor\\paderr01.wav\r\nsound\\protoss\\advisor\\paderr02.wav\r\nsound\\protoss\\advisor\\paderr06.wav\r\nsound\\protoss\\advisor\\padupd00.wav\r\nsound\\protoss\\advisor\\padupd01.wav\r\nsound\\protoss\\advisor\\padupd02.wav\r\nsound\\protoss\\advisor\\padupd04.wav\r\nsound\\protoss\\advisor\\padupd06.wav\r\nsound\\protoss\\arbiter\\pabcag00.wav\r\nsound\\protoss\\arbiter\\pabdth00.wav\r\nsound\\protoss\\arbiter\\pabfol00.wav\r\nsound\\protoss\\arbiter\\pabfol01.wav\r\nsound\\protoss\\arbiter\\pabfol02.wav\r\nsound\\protoss\\arbiter\\pabfol03.wav\r\nsound\\protoss\\arbiter\\pabpss00.wav\r\nsound\\protoss\\arbiter\\pabpss01.wav\r\nsound\\protoss\\arbiter\\pabpss02.wav\r\nsound\\protoss\\arbiter\\pabpss03.wav\r\nsound\\protoss\\arbiter\\pabpss04.wav\r\nsound\\protoss\\arbiter\\pabrdy00.wav\r\nsound\\protoss\\arbiter\\pabwht00.wav\r\nsound\\protoss\\arbiter\\pabwht01.wav\r\nsound\\protoss\\arbiter\\pabwht02.wav\r\nsound\\protoss\\arbiter\\pabwht03.wav\r\nsound\\protoss\\arbiter\\pabyes00.wav\r\nsound\\protoss\\arbiter\\pabyes01.wav\r\nsound\\protoss\\arbiter\\pabyes02.wav\r\nsound\\protoss\\arbiter\\pabyes03.wav\r\nsound\\protoss\\archon\\pardth00.wav\r\nsound\\protoss\\archon\\parmin00.wav\r\nsound\\protoss\\archon\\parpss00.wav\r\nsound\\protoss\\archon\\parpss01.wav\r\nsound\\protoss\\archon\\parpss02.wav\r\nsound\\protoss\\archon\\parpss03.wav\r\nsound\\protoss\\archon\\parrdy00.wav\r\nsound\\protoss\\archon\\parwht00.wav\r\nsound\\protoss\\archon\\parwht01.wav\r\nsound\\protoss\\archon\\parwht02.wav\r\nsound\\protoss\\archon\\parwht03.wav\r\nsound\\protoss\\archon\\paryes00.wav\r\nsound\\protoss\\archon\\paryes01.wav\r\nsound\\protoss\\archon\\paryes02.wav\r\nsound\\protoss\\archon\\paryes03.wav\r\nsound\\protoss\\artanis\\patpss00.wav\r\nsound\\protoss\\artanis\\patpss01.wav\r\nsound\\protoss\\artanis\\patpss02.wav\r\nsound\\protoss\\artanis\\patpss03.wav\r\nsound\\protoss\\artanis\\patpss04.wav\r\nsound\\protoss\\artanis\\patpss05.wav\r\nsound\\protoss\\artanis\\patwht00.wav\r\nsound\\protoss\\artanis\\patwht01.wav\r\nsound\\protoss\\artanis\\patwht02.wav\r\nsound\\protoss\\artanis\\patwht03.wav\r\nsound\\protoss\\artanis\\patyes00.wav\r\nsound\\protoss\\artanis\\patyes01.wav\r\nsound\\protoss\\artanis\\patyes02.wav\r\nsound\\protoss\\artanis\\patyes03.wav\r\nsound\\protoss\\artanis\\vssver.scc\r\nsound\\protoss\\bldg\\pacwht00.wav\r\nsound\\protoss\\bldg\\paswht00.wav\r\nsound\\protoss\\bldg\\pbaact00.wav\r\nsound\\protoss\\bldg\\pbawht00.wav\r\nsound\\protoss\\bldg\\pbewht00.wav\r\nsound\\protoss\\bldg\\pciwht00.wav\r\nsound\\protoss\\bldg\\pfowht00.wav\r\nsound\\protoss\\bldg\\pgawht00.wav\r\nsound\\protoss\\bldg\\pgcwht00.wav\r\nsound\\protoss\\bldg\\pnawht00.wav\r\nsound\\protoss\\bldg\\pnewht00.wav\r\nsound\\protoss\\bldg\\ppbwht00.wav\r\nsound\\protoss\\bldg\\ppywht00.wav\r\nsound\\protoss\\bldg\\prowht00.wav\r\nsound\\protoss\\bldg\\pstwht00.wav\r\nsound\\protoss\\bldg\\ptrwht00.wav\r\nsound\\protoss\\bldg\\pwawht00.wav\r\nsound\\protoss\\carrier\\pcadth00.wav\r\nsound\\protoss\\carrier\\pcadth01.wav\r\nsound\\protoss\\carrier\\pcahlp00.wav\r\nsound\\protoss\\carrier\\pcahlp01.wav\r\nsound\\protoss\\carrier\\pcapss00.wav\r\nsound\\protoss\\carrier\\pcapss01.wav\r\nsound\\protoss\\carrier\\pcapss02.wav\r\nsound\\protoss\\carrier\\pcapss03.wav\r\nsound\\protoss\\carrier\\pcardy00.wav\r\nsound\\protoss\\carrier\\pcawht00.wav\r\nsound\\protoss\\carrier\\pcawht01.wav\r\nsound\\protoss\\carrier\\pcawht02.wav\r\nsound\\protoss\\carrier\\pcawht03.wav\r\nsound\\protoss\\carrier\\pcayes00.wav\r\nsound\\protoss\\carrier\\pcayes01.wav\r\nsound\\protoss\\carrier\\pcayes02.wav\r\nsound\\protoss\\carrier\\pcayes03.wav\r\nsound\\protoss\\corsair\\pcopss00.wav\r\nsound\\protoss\\corsair\\pcopss01.wav\r\nsound\\protoss\\corsair\\pcopss02.wav\r\nsound\\protoss\\corsair\\pcopss03.wav\r\nsound\\protoss\\corsair\\pcopss04.wav\r\nsound\\protoss\\corsair\\pcopss05.wav\r\nsound\\protoss\\corsair\\pcopss06.wav\r\nsound\\protoss\\corsair\\pcordy00.wav\r\nsound\\protoss\\corsair\\pcorhit1.wav\r\nsound\\protoss\\corsair\\pcorhit2.wav\r\nsound\\protoss\\corsair\\pcorlasr1.wav\r\nsound\\protoss\\corsair\\pcorlasr2.wav\r\nsound\\protoss\\corsair\\pcorlasr3.wav\r\nsound\\protoss\\corsair\\pcorlasr4.wav\r\nsound\\protoss\\corsair\\pcorweb1.wav\r\nsound\\protoss\\corsair\\pcowht00.wav\r\nsound\\protoss\\corsair\\pcowht01.wav\r\nsound\\protoss\\corsair\\pcowht02.wav\r\nsound\\protoss\\corsair\\pcowht03.wav\r\nsound\\protoss\\corsair\\pcoyes00.wav\r\nsound\\protoss\\corsair\\pcoyes01.wav\r\nsound\\protoss\\corsair\\pcoyes02.wav\r\nsound\\protoss\\corsair\\pcoyes03.wav\r\nsound\\protoss\\corsair\\vssver.scc\r\nsound\\protoss\\darchon\\feedback.wav\r\nsound\\protoss\\darchon\\mind.wav\r\nsound\\protoss\\darchon\\paraattk.wav\r\nsound\\protoss\\darchon\\parahit.wav\r\nsound\\protoss\\darchon\\pdapss00.wav\r\nsound\\protoss\\darchon\\pdapss01.wav\r\nsound\\protoss\\darchon\\pdapss02.wav\r\nsound\\protoss\\darchon\\pdapss03.wav\r\nsound\\protoss\\darchon\\pdardy00.wav\r\nsound\\protoss\\darchon\\pdawht00.wav\r\nsound\\protoss\\darchon\\pdawht01.wav\r\nsound\\protoss\\darchon\\pdawht02.wav\r\nsound\\protoss\\darchon\\pdawht03.wav\r\nsound\\protoss\\darchon\\pdayes00.wav\r\nsound\\protoss\\darchon\\pdayes01.wav\r\nsound\\protoss\\darchon\\pdayes02.wav\r\nsound\\protoss\\darchon\\pdayes03.wav\r\nsound\\protoss\\DARCHON\\PDrDth00.wav\r\nsound\\protoss\\darchon\\vssver.scc\r\nsound\\protoss\\darktemplar\\pdtdth00.wav\r\nsound\\protoss\\darktemplar\\pdtpss00.wav\r\nsound\\protoss\\darktemplar\\pdtpss01.wav\r\nsound\\protoss\\darktemplar\\pdtpss02.wav\r\nsound\\protoss\\darktemplar\\pdtpss03.wav\r\nsound\\protoss\\darktemplar\\pdtrdy00.wav\r\nsound\\protoss\\darktemplar\\pdtwht00.wav\r\nsound\\protoss\\darktemplar\\pdtwht01.wav\r\nsound\\protoss\\darktemplar\\pdtwht02.wav\r\nsound\\protoss\\darktemplar\\pdtwht03.wav\r\nsound\\protoss\\darktemplar\\pdtyes00.wav\r\nsound\\protoss\\darktemplar\\pdtyes01.wav\r\nsound\\protoss\\darktemplar\\pdtyes02.wav\r\nsound\\protoss\\darktemplar\\pdtyes03.wav\r\nsound\\protoss\\darktemplar\\vssver.scc\r\nsound\\protoss\\dragoon\\pdrdth00.wav\r\nsound\\protoss\\dragoon\\pdrpss00.wav\r\nsound\\protoss\\dragoon\\pdrpss01.wav\r\nsound\\protoss\\dragoon\\pdrpss02.wav\r\nsound\\protoss\\dragoon\\pdrpss03.wav\r\nsound\\protoss\\dragoon\\pdrrdy00.wav\r\nsound\\protoss\\dragoon\\pdrwht00.wav\r\nsound\\protoss\\dragoon\\pdrwht01.wav\r\nsound\\protoss\\dragoon\\pdrwht02.wav\r\nsound\\protoss\\dragoon\\pdrwht03.wav\r\nsound\\protoss\\dragoon\\pdrwht04.wav\r\nsound\\protoss\\dragoon\\pdrwht05.wav\r\nsound\\protoss\\dragoon\\pdrwht06.wav\r\nsound\\protoss\\dragoon\\pdrwht07.wav\r\nsound\\protoss\\dragoon\\pdryes00.wav\r\nsound\\protoss\\dragoon\\pdryes01.wav\r\nsound\\protoss\\dragoon\\pdryes02.wav\r\nsound\\protoss\\dragoon\\pdryes03.wav\r\nsound\\protoss\\dragoon\\pdryes04.wav\r\nsound\\protoss\\dragoon\\pdryes05.wav\r\nsound\\protoss\\dragoon\\pdryes06.wav\r\nsound\\protoss\\fenixd\\ufdpss00.wav\r\nsound\\protoss\\fenixd\\ufdpss01.wav\r\nsound\\protoss\\fenixd\\ufdpss02.wav\r\nsound\\protoss\\fenixd\\ufdpss03.wav\r\nsound\\protoss\\fenixd\\ufdwht00.wav\r\nsound\\protoss\\fenixd\\ufdwht01.wav\r\nsound\\protoss\\fenixd\\ufdwht02.wav\r\nsound\\protoss\\fenixd\\ufdwht03.wav\r\nsound\\protoss\\fenixd\\ufdyes00.wav\r\nsound\\protoss\\fenixd\\ufdyes01.wav\r\nsound\\protoss\\fenixd\\ufdyes02.wav\r\nsound\\protoss\\fenixd\\ufdyes03.wav\r\nsound\\protoss\\fenixz\\ufedth00.wav\r\nsound\\protoss\\fenixz\\ufepss00.wav\r\nsound\\protoss\\fenixz\\ufepss01.wav\r\nsound\\protoss\\fenixz\\ufepss02.wav\r\nsound\\protoss\\fenixz\\ufepss03.wav\r\nsound\\protoss\\fenixz\\ufewht00.wav\r\nsound\\protoss\\fenixz\\ufewht01.wav\r\nsound\\protoss\\fenixz\\ufewht02.wav\r\nsound\\protoss\\fenixz\\ufewht03.wav\r\nsound\\protoss\\fenixz\\ufeyes00.wav\r\nsound\\protoss\\fenixz\\ufeyes01.wav\r\nsound\\protoss\\fenixz\\ufeyes02.wav\r\nsound\\protoss\\fenixz\\ufeyes03.wav\r\nsound\\protoss\\gantrithor\\utcpss00.wav\r\nsound\\protoss\\gantrithor\\utcpss01.wav\r\nsound\\protoss\\gantrithor\\utcpss02.wav\r\nsound\\protoss\\gantrithor\\utcpss03.wav\r\nsound\\protoss\\gantrithor\\utcwht00.wav\r\nsound\\protoss\\gantrithor\\utcwht01.wav\r\nsound\\protoss\\gantrithor\\utcwht02.wav\r\nsound\\protoss\\gantrithor\\utcwht03.wav\r\nsound\\protoss\\gantrithor\\utcyes00.wav\r\nsound\\protoss\\gantrithor\\utcyes01.wav\r\nsound\\protoss\\gantrithor\\utcyes02.wav\r\nsound\\protoss\\gantrithor\\utcyes03.wav\r\nsound\\protoss\\intercep\\pinlau00.wav\r\nsound\\protoss\\probe\\ppratt00.wav\r\nsound\\protoss\\probe\\ppratt01.wav\r\nsound\\protoss\\probe\\pprdth00.wav\r\nsound\\protoss\\probe\\pprerr00.wav\r\nsound\\protoss\\probe\\pprerr01.wav\r\nsound\\protoss\\probe\\pprmin00.wav\r\nsound\\protoss\\probe\\pprpss00.wav\r\nsound\\protoss\\probe\\pprpss01.wav\r\nsound\\protoss\\probe\\pprpss02.wav\r\nsound\\protoss\\probe\\pprpss03.wav\r\nsound\\protoss\\probe\\pprrdy00.wav\r\nsound\\protoss\\probe\\pprwht00.wav\r\nsound\\protoss\\probe\\pprwht01.wav\r\nsound\\protoss\\probe\\pprwht02.wav\r\nsound\\protoss\\probe\\pprwht03.wav\r\nsound\\protoss\\probe\\ppryes00.wav\r\nsound\\protoss\\probe\\ppryes01.wav\r\nsound\\protoss\\probe\\ppryes02.wav\r\nsound\\protoss\\probe\\ppryes03.wav\r\nsound\\protoss\\scout\\pscdth00.wav\r\nsound\\protoss\\scout\\pschlp00.wav\r\nsound\\protoss\\scout\\pschlp01.wav\r\nsound\\protoss\\scout\\pscpss00.wav\r\nsound\\protoss\\scout\\pscpss01.wav\r\nsound\\protoss\\scout\\pscpss02.wav\r\nsound\\protoss\\scout\\pscpss03.wav\r\nsound\\protoss\\scout\\pscpss04.wav\r\nsound\\protoss\\scout\\pscrdy00.wav\r\nsound\\protoss\\scout\\pscwht00.wav\r\nsound\\protoss\\scout\\pscwht01.wav\r\nsound\\protoss\\scout\\pscwht02.wav\r\nsound\\protoss\\scout\\pscwht03.wav\r\nsound\\protoss\\scout\\pscyes00.wav\r\nsound\\protoss\\scout\\pscyes01.wav\r\nsound\\protoss\\scout\\pscyes02.wav\r\nsound\\protoss\\scout\\pscyes03.wav\r\nsound\\protoss\\shuttle\\pshbld00.wav\r\nsound\\protoss\\shuttle\\pshbld01.wav\r\nsound\\protoss\\shuttle\\pshbld02.wav\r\nsound\\protoss\\shuttle\\pshbld03.wav\r\nsound\\protoss\\shuttle\\pshbld04.wav\r\nsound\\protoss\\shuttle\\pshdth00.wav\r\nsound\\protoss\\shuttle\\pshpss00.wav\r\nsound\\protoss\\shuttle\\pshpss01.wav\r\nsound\\protoss\\shuttle\\pshpss02.wav\r\nsound\\protoss\\shuttle\\pshpss03.wav\r\nsound\\protoss\\shuttle\\pshpss04.wav\r\nsound\\protoss\\shuttle\\pshrdy00.wav\r\nsound\\protoss\\shuttle\\pshwht00.wav\r\nsound\\protoss\\shuttle\\pshwht01.wav\r\nsound\\protoss\\shuttle\\pshwht02.wav\r\nsound\\protoss\\shuttle\\pshwht03.wav\r\nsound\\protoss\\shuttle\\pshyes00.wav\r\nsound\\protoss\\shuttle\\pshyes01.wav\r\nsound\\protoss\\shuttle\\pshyes02.wav\r\nsound\\protoss\\shuttle\\pshyes03.wav\r\nsound\\protoss\\tassadar\\utadth00.wav\r\nsound\\protoss\\tassadar\\utapss00.wav\r\nsound\\protoss\\tassadar\\utapss01.wav\r\nsound\\protoss\\tassadar\\utapss02.wav\r\nsound\\protoss\\tassadar\\utapss03.wav\r\nsound\\protoss\\tassadar\\utawht00.wav\r\nsound\\protoss\\tassadar\\utawht01.wav\r\nsound\\protoss\\tassadar\\utawht02.wav\r\nsound\\protoss\\tassadar\\utawht03.wav\r\nsound\\protoss\\tassadar\\utayes00.wav\r\nsound\\protoss\\tassadar\\utayes01.wav\r\nsound\\protoss\\tassadar\\utayes02.wav\r\nsound\\protoss\\tassadar\\utayes03.wav\r\nsound\\protoss\\templar\\ptedth00.wav\r\nsound\\protoss\\templar\\ptehal00.wav\r\nsound\\protoss\\templar\\ptehal01.wav\r\nsound\\protoss\\templar\\ptemov00.wav\r\nsound\\protoss\\templar\\ptepss00.wav\r\nsound\\protoss\\templar\\ptepss01.wav\r\nsound\\protoss\\templar\\ptepss02.wav\r\nsound\\protoss\\templar\\ptepss03.wav\r\nsound\\protoss\\templar\\pterdy00.wav\r\nsound\\protoss\\templar\\ptesto00.wav\r\nsound\\protoss\\templar\\ptesto01.wav\r\nsound\\protoss\\templar\\ptesum00.wav\r\nsound\\protoss\\templar\\ptewht00.wav\r\nsound\\protoss\\templar\\ptewht01.wav\r\nsound\\protoss\\templar\\ptewht02.wav\r\nsound\\protoss\\templar\\ptewht03.wav\r\nsound\\protoss\\templar\\pteyes00.wav\r\nsound\\protoss\\templar\\pteyes01.wav\r\nsound\\protoss\\templar\\pteyes02.wav\r\nsound\\protoss\\templar\\pteyes03.wav\r\nsound\\protoss\\trilobyte\\ptrdth00.wav\r\nsound\\protoss\\trilobyte\\ptrpss00.wav\r\nsound\\protoss\\trilobyte\\ptrpss01.wav\r\nsound\\protoss\\trilobyte\\ptrpss02.wav\r\nsound\\protoss\\trilobyte\\ptrrdy00.wav\r\nsound\\protoss\\trilobyte\\ptrwht00.wav\r\nsound\\protoss\\trilobyte\\ptrwht01.wav\r\nsound\\protoss\\trilobyte\\ptrwht02.wav\r\nsound\\protoss\\trilobyte\\ptrwht03.wav\r\nsound\\protoss\\trilobyte\\ptryes00.wav\r\nsound\\protoss\\trilobyte\\ptryes01.wav\r\nsound\\protoss\\trilobyte\\ptryes02.wav\r\nsound\\protoss\\trilobyte\\ptryes03.wav\r\nsound\\protoss\\witness\\pwidth00.wav\r\nsound\\protoss\\witness\\pwidth01.wav\r\nsound\\protoss\\witness\\pwipss00.wav\r\nsound\\protoss\\witness\\pwipss01.wav\r\nsound\\protoss\\witness\\pwipss02.wav\r\nsound\\protoss\\witness\\pwipss03.wav\r\nsound\\protoss\\witness\\pwipss04.wav\r\nsound\\protoss\\witness\\pwirdy00.wav\r\nsound\\protoss\\witness\\pwiwht00.wav\r\nsound\\protoss\\witness\\pwiwht01.wav\r\nsound\\protoss\\witness\\pwiyes00.wav\r\nsound\\protoss\\witness\\pwiyes01.wav\r\nsound\\protoss\\zealot\\pzeatt00.wav\r\nsound\\protoss\\zealot\\pzeatt01.wav\r\nsound\\protoss\\zealot\\pzedth00.wav\r\nsound\\protoss\\zealot\\pzehit00.wav\r\nsound\\protoss\\zealot\\pzepss00.wav\r\nsound\\protoss\\zealot\\pzepss01.wav\r\nsound\\protoss\\zealot\\pzepss02.wav\r\nsound\\protoss\\zealot\\pzerag00.wav\r\nsound\\protoss\\zealot\\pzerdy00.wav\r\nsound\\protoss\\zealot\\pzewht00.wav\r\nsound\\protoss\\zealot\\pzewht01.wav\r\nsound\\protoss\\zealot\\pzewht02.wav\r\nsound\\protoss\\zealot\\pzewht03.wav\r\nsound\\protoss\\zealot\\pzeyes00.wav\r\nsound\\protoss\\zealot\\pzeyes01.wav\r\nsound\\protoss\\zealot\\pzeyes02.wav\r\nsound\\protoss\\zealot\\pzeyes03.wav\r\nsound\\protoss\\zeratul\\uzedth00.wav\r\nsound\\protoss\\zeratul\\uzepss00.wav\r\nsound\\protoss\\zeratul\\uzepss01.wav\r\nsound\\protoss\\zeratul\\uzepss02.wav\r\nsound\\protoss\\zeratul\\uzepss03.wav\r\nsound\\protoss\\zeratul\\uzewht00.wav\r\nsound\\protoss\\zeratul\\uzewht01.wav\r\nsound\\protoss\\zeratul\\uzewht02.wav\r\nsound\\protoss\\zeratul\\uzewht03.wav\r\nsound\\protoss\\zeratul\\uzeyes00.wav\r\nsound\\protoss\\zeratul\\uzeyes01.wav\r\nsound\\protoss\\zeratul\\uzeyes02.wav\r\nsound\\protoss\\zeratul\\uzeyes03.wav\r\nsound\\terran\\advisor\\taderr00.wav\r\nsound\\terran\\advisor\\taderr01.wav\r\nsound\\terran\\advisor\\taderr02.wav\r\nsound\\terran\\advisor\\taderr03.wav\r\nsound\\terran\\advisor\\taderr04.wav\r\nsound\\terran\\advisor\\taderr05.wav\r\nsound\\terran\\advisor\\taderr06.wav\r\nsound\\terran\\advisor\\tadupd00.wav\r\nsound\\terran\\advisor\\tadupd01.wav\r\nsound\\terran\\advisor\\tadupd02.wav\r\nsound\\terran\\advisor\\tadupd03.wav\r\nsound\\terran\\advisor\\tadupd04.wav\r\nsound\\terran\\advisor\\tadupd05.wav\r\nsound\\terran\\advisor\\tadupd06.wav\r\nsound\\terran\\advisor\\tadupd07.wav\r\nsound\\terran\\battle\\tbadth00.wav\r\nsound\\terran\\battle\\tbapss00.wav\r\nsound\\terran\\battle\\tbapss01.wav\r\nsound\\terran\\battle\\tbapss02.wav\r\nsound\\terran\\battle\\tbapss03.wav\r\nsound\\terran\\battle\\tbapss04.wav\r\nsound\\terran\\battle\\tbardy00.wav\r\nsound\\terran\\battle\\tbawht00.wav\r\nsound\\terran\\battle\\tbawht01.wav\r\nsound\\terran\\battle\\tbawht02.wav\r\nsound\\terran\\battle\\tbawht03.wav\r\nsound\\terran\\battle\\tbayam01.wav\r\nsound\\terran\\battle\\tbayam02.wav\r\nsound\\terran\\battle\\tbayes00.wav\r\nsound\\terran\\battle\\tbayes01.wav\r\nsound\\terran\\battle\\tbayes02.wav\r\nsound\\terran\\battle\\tbayes03.wav\r\nsound\\terran\\bldg\\onfirlrg.wav\r\nsound\\terran\\bldg\\tacwht00.wav\r\nsound\\terran\\bldg\\tclwht00.wav\r\nsound\\terran\\bldg\\tcssca00.wav\r\nsound\\terran\\bldg\\tcswht00.wav\r\nsound\\terran\\bldg\\tddwht00.wav\r\nsound\\terran\\bldg\\tglwht00.wav\r\nsound\\terran\\bldg\\tmswht00.wav\r\nsound\\terran\\bldg\\tmtwht00.wav\r\nsound\\terran\\bldg\\tnswht00.wav\r\nsound\\terran\\bldg\\tpgwht00.wav\r\nsound\\terran\\bldg\\tplwht00.wav\r\nsound\\terran\\bldg\\trewht00.wav\r\nsound\\terran\\bldg\\trfwht00.wav\r\nsound\\terran\\bldg\\trlwht00.wav\r\nsound\\terran\\bldg\\twpwht00.wav\r\nsound\\terran\\civilian\\tcvdth00.wav\r\nsound\\terran\\civilian\\tcvpss00.wav\r\nsound\\terran\\civilian\\tcvpss01.wav\r\nsound\\terran\\civilian\\tcvpss02.wav\r\nsound\\terran\\civilian\\tcvpss03.wav\r\nsound\\terran\\civilian\\tcvpss04.wav\r\nsound\\terran\\civilian\\tcvrdy00.wav\r\nsound\\terran\\civilian\\tcvwht00.wav\r\nsound\\terran\\civilian\\tcvwht01.wav\r\nsound\\terran\\civilian\\tcvwht02.wav\r\nsound\\terran\\civilian\\tcvwht03.wav\r\nsound\\terran\\civilian\\tcvyes00.wav\r\nsound\\terran\\civilian\\tcvyes01.wav\r\nsound\\terran\\civilian\\tcvyes02.wav\r\nsound\\terran\\civilian\\tcvyes03.wav\r\nsound\\terran\\civilian\\tcvyes04.wav\r\nsound\\terran\\dropship\\tdrdth00.wav\r\nsound\\terran\\dropship\\tdrpss00.wav\r\nsound\\terran\\dropship\\tdrpss01.wav\r\nsound\\terran\\dropship\\tdrpss02.wav\r\nsound\\terran\\dropship\\tdrpss03.wav\r\nsound\\terran\\dropship\\tdrrdy00.wav\r\nsound\\terran\\dropship\\tdrwht00.wav\r\nsound\\terran\\dropship\\tdrwht01.wav\r\nsound\\terran\\dropship\\tdrwht02.wav\r\nsound\\terran\\dropship\\tdrwht03.wav\r\nsound\\terran\\dropship\\tdryes00.wav\r\nsound\\terran\\dropship\\tdryes01.wav\r\nsound\\terran\\dropship\\tdryes02.wav\r\nsound\\terran\\dropship\\tdryes03.wav\r\nsound\\terran\\dropship\\tdryes04.wav\r\nsound\\terran\\dropship\\tdryes05.wav\r\nsound\\terran\\dukeb\\ududth00.wav\r\nsound\\terran\\dukeb\\udupss00.wav\r\nsound\\terran\\dukeb\\udupss01.wav\r\nsound\\terran\\dukeb\\udupss02.wav\r\nsound\\terran\\dukeb\\udupss03.wav\r\nsound\\terran\\dukeb\\udupss04.wav\r\nsound\\terran\\dukeb\\uduwht00.wav\r\nsound\\terran\\dukeb\\uduwht01.wav\r\nsound\\terran\\dukeb\\uduwht02.wav\r\nsound\\terran\\dukeb\\uduwht03.wav\r\nsound\\terran\\dukeb\\uduyes00.wav\r\nsound\\terran\\dukeb\\uduyes01.wav\r\nsound\\terran\\dukeb\\uduyes02.wav\r\nsound\\terran\\dukeb\\uduyes03.wav\r\nsound\\terran\\duket\\udtdth00.wav\r\nsound\\terran\\duket\\udtpss00.wav\r\nsound\\terran\\duket\\udtpss01.wav\r\nsound\\terran\\duket\\udtpss02.wav\r\nsound\\terran\\duket\\udtpss03.wav\r\nsound\\terran\\duket\\udtpss04.wav\r\nsound\\terran\\duket\\udtwht00.wav\r\nsound\\terran\\duket\\udtwht01.wav\r\nsound\\terran\\duket\\udtwht02.wav\r\nsound\\terran\\duket\\udtwht03.wav\r\nsound\\terran\\duket\\udtyes00.wav\r\nsound\\terran\\duket\\udtyes01.wav\r\nsound\\terran\\duket\\udtyes02.wav\r\nsound\\terran\\duket\\udtyes03.wav\r\nsound\\terran\\duran\\tdndth00.wav\r\nsound\\terran\\duran\\tdnpss00.wav\r\nsound\\terran\\duran\\tdnpss01.wav\r\nsound\\terran\\duran\\tdnpss02.wav\r\nsound\\terran\\duran\\tdnpss03.wav\r\nsound\\terran\\duran\\tdnpss04.wav\r\nsound\\terran\\duran\\tdnpss05.wav\r\nsound\\terran\\duran\\tdnpss06.wav\r\nsound\\terran\\duran\\tdnpss07.wav\r\nsound\\terran\\duran\\tdnpss08.wav\r\nsound\\terran\\duran\\tdnwht00.wav\r\nsound\\terran\\duran\\tdnwht01.wav\r\nsound\\terran\\duran\\tdnwht02.wav\r\nsound\\terran\\duran\\tdnwht03.wav\r\nsound\\Terran\\Duran\\TDnWth00.wav\r\nsound\\terran\\duran\\tdnyes00.wav\r\nsound\\terran\\duran\\tdnyes01.wav\r\nsound\\terran\\duran\\tdnyes02.wav\r\nsound\\terran\\duran\\tdnyes03.wav\r\nsound\\terran\\duran\\vssver.scc\r\nsound\\terran\\firebat\\tfbdth00.wav\r\nsound\\terran\\firebat\\tfbdth01.wav\r\nsound\\terran\\firebat\\tfbdth02.wav\r\nsound\\terran\\firebat\\tfbfir00.wav\r\nsound\\terran\\firebat\\tfbfir01.wav\r\nsound\\terran\\firebat\\tfbpss00.wav\r\nsound\\terran\\firebat\\tfbpss01.wav\r\nsound\\terran\\firebat\\tfbpss02.wav\r\nsound\\terran\\firebat\\tfbpss03.wav\r\nsound\\terran\\firebat\\tfbpss04.wav\r\nsound\\terran\\firebat\\tfbpss05.wav\r\nsound\\terran\\firebat\\tfbpss06.wav\r\nsound\\terran\\firebat\\tfbrdy00.wav\r\nsound\\terran\\firebat\\tfbwht00.wav\r\nsound\\terran\\firebat\\tfbwht01.wav\r\nsound\\terran\\firebat\\tfbwht02.wav\r\nsound\\terran\\firebat\\tfbwht03.wav\r\nsound\\terran\\firebat\\tfbyes00.wav\r\nsound\\terran\\firebat\\tfbyes01.wav\r\nsound\\terran\\firebat\\tfbyes02.wav\r\nsound\\terran\\firebat\\tfbyes03.wav\r\nsound\\terran\\frigate\\afteroff.wav\r\nsound\\terran\\frigate\\afteron.wav\r\nsound\\terran\\frigate\\shoot2.wav\r\nsound\\terran\\frigate\\tvkdth00.wav\r\nsound\\terran\\frigate\\tvkpss00.wav\r\nsound\\terran\\frigate\\tvkpss01.wav\r\nsound\\terran\\frigate\\tvkpss02.wav\r\nsound\\terran\\frigate\\tvkpss03.wav\r\nsound\\terran\\frigate\\tvkpss04.wav\r\nsound\\terran\\frigate\\tvkpss05.wav\r\nsound\\terran\\frigate\\tvkrdy00.wav\r\nsound\\terran\\frigate\\tvkwht00.wav\r\nsound\\terran\\frigate\\tvkwht01.wav\r\nsound\\terran\\frigate\\tvkwht02.wav\r\nsound\\terran\\frigate\\tvkwht03.wav\r\nsound\\terran\\frigate\\tvkyes00.wav\r\nsound\\terran\\frigate\\tvkyes01.wav\r\nsound\\terran\\frigate\\tvkyes02.wav\r\nsound\\terran\\frigate\\tvkyes03.wav\r\nsound\\terran\\frigate\\tvkyes04.wav\r\nsound\\terran\\frigate\\vssver.scc\r\nsound\\terran\\ghost\\tghdth00.wav\r\nsound\\terran\\ghost\\tghdth01.wav\r\nsound\\terran\\ghost\\tghlas00.wav\r\nsound\\terran\\ghost\\tghlkd00.wav\r\nsound\\terran\\ghost\\tghpss00.wav\r\nsound\\terran\\ghost\\tghpss01.wav\r\nsound\\terran\\ghost\\tghpss02.wav\r\nsound\\terran\\ghost\\tghpss03.wav\r\nsound\\terran\\ghost\\tghrdy00.wav\r\nsound\\terran\\ghost\\tghwht00.wav\r\nsound\\terran\\ghost\\tghwht01.wav\r\nsound\\terran\\ghost\\tghwht02.wav\r\nsound\\terran\\ghost\\tghwht03.wav\r\nsound\\terran\\ghost\\tghyes00.wav\r\nsound\\terran\\ghost\\tghyes01.wav\r\nsound\\terran\\ghost\\tghyes02.wav\r\nsound\\terran\\ghost\\tghyes03.wav\r\nsound\\terran\\goliath\\tgodth00.wav\r\nsound\\terran\\goliath\\tgopss00.wav\r\nsound\\terran\\goliath\\tgopss01.wav\r\nsound\\terran\\goliath\\tgopss02.wav\r\nsound\\terran\\goliath\\tgopss03.wav\r\nsound\\terran\\goliath\\tgopss04.wav\r\nsound\\terran\\goliath\\tgopss05.wav\r\nsound\\terran\\goliath\\tgordy00.wav\r\nsound\\terran\\goliath\\tgowht00.wav\r\nsound\\terran\\goliath\\tgowht01.wav\r\nsound\\terran\\goliath\\tgowht02.wav\r\nsound\\terran\\goliath\\tgowht03.wav\r\nsound\\terran\\goliath\\tgoyes00.wav\r\nsound\\terran\\goliath\\tgoyes01.wav\r\nsound\\terran\\goliath\\tgoyes02.wav\r\nsound\\terran\\goliath\\tgoyes03.wav\r\nsound\\terran\\kerrigan\\ukedth00.wav\r\nsound\\terran\\kerrigan\\ukedth01.wav\r\nsound\\terran\\kerrigan\\ukepss00.wav\r\nsound\\terran\\kerrigan\\ukepss01.wav\r\nsound\\terran\\kerrigan\\ukepss02.wav\r\nsound\\terran\\kerrigan\\ukepss03.wav\r\nsound\\terran\\kerrigan\\ukepss04.wav\r\nsound\\terran\\kerrigan\\ukewht00.wav\r\nsound\\terran\\kerrigan\\ukewht01.wav\r\nsound\\terran\\kerrigan\\ukewht02.wav\r\nsound\\terran\\kerrigan\\ukewht03.wav\r\nsound\\terran\\kerrigan\\ukeyes00.wav\r\nsound\\terran\\kerrigan\\ukeyes01.wav\r\nsound\\terran\\kerrigan\\ukeyes02.wav\r\nsound\\terran\\kerrigan\\ukeyes03.wav\r\nsound\\terran\\marine\\tmadth00.wav\r\nsound\\terran\\marine\\tmadth01.wav\r\nsound\\terran\\marine\\tmahlp00.wav\r\nsound\\terran\\marine\\tmahlp01.wav\r\nsound\\terran\\marine\\tmapss00.wav\r\nsound\\terran\\marine\\tmapss01.wav\r\nsound\\terran\\marine\\tmapss02.wav\r\nsound\\terran\\marine\\tmapss03.wav\r\nsound\\terran\\marine\\tmapss04.wav\r\nsound\\terran\\marine\\tmapss05.wav\r\nsound\\terran\\marine\\tmapss06.wav\r\nsound\\terran\\marine\\tmardy00.wav\r\nsound\\terran\\marine\\tmasti00.wav\r\nsound\\terran\\marine\\tmasti01.wav\r\nsound\\terran\\marine\\tmawht00.wav\r\nsound\\terran\\marine\\tmawht01.wav\r\nsound\\terran\\marine\\tmawht02.wav\r\nsound\\terran\\marine\\tmawht03.wav\r\nsound\\terran\\marine\\tmayes00.wav\r\nsound\\terran\\marine\\tmayes01.wav\r\nsound\\terran\\marine\\tmayes02.wav\r\nsound\\terran\\marine\\tmayes03.wav\r\nsound\\terran\\medic\\miopia1.wav\r\nsound\\terran\\medic\\tmddth00.wav\r\nsound\\terran\\medic\\tmdpss00.wav\r\nsound\\terran\\medic\\tmdpss01.wav\r\nsound\\terran\\medic\\tmdpss02.wav\r\nsound\\terran\\medic\\tmdpss03.wav\r\nsound\\terran\\medic\\tmdpss04.wav\r\nsound\\terran\\medic\\tmdpss05.wav\r\nsound\\terran\\medic\\tmdpss06.wav\r\nsound\\terran\\medic\\tmdrdy00.wav\r\nsound\\terran\\medic\\tmdwht00.wav\r\nsound\\terran\\medic\\tmdwht01.wav\r\nsound\\terran\\medic\\tmdwht02.wav\r\nsound\\terran\\medic\\tmdwht03.wav\r\nsound\\terran\\medic\\tmdyes00.wav\r\nsound\\terran\\medic\\tmdyes01.wav\r\nsound\\terran\\medic\\tmdyes02.wav\r\nsound\\terran\\medic\\tmdyes03.wav\r\nsound\\terran\\medic\\tmedcure.wav\r\nsound\\terran\\medic\\tmedcure2.wav\r\nsound\\terran\\medic\\tmedflsh.wav\r\nsound\\terran\\medic\\tmedheal.wav\r\nsound\\terran\\medic\\tmedheal2.wav\r\nsound\\terran\\medic\\tmedrest.wav\r\nsound\\terran\\medic\\tmedrest1.wav\r\nsound\\terran\\medic\\vssver.scc\r\nsound\\terran\\phoenix\\tphclo00.wav\r\nsound\\terran\\phoenix\\tphclo01.wav\r\nsound\\terran\\phoenix\\tphdth00.wav\r\nsound\\terran\\phoenix\\tphpss00.wav\r\nsound\\terran\\phoenix\\tphpss01.wav\r\nsound\\terran\\phoenix\\tphpss02.wav\r\nsound\\terran\\phoenix\\tphpss03.wav\r\nsound\\terran\\phoenix\\tphpss04.wav\r\nsound\\terran\\phoenix\\tphpss05.wav\r\nsound\\terran\\phoenix\\tphpss06.wav\r\nsound\\terran\\phoenix\\tphrdy00.wav\r\nsound\\terran\\phoenix\\tphwht00.wav\r\nsound\\terran\\phoenix\\tphwht01.wav\r\nsound\\terran\\phoenix\\tphwht02.wav\r\nsound\\terran\\phoenix\\tphwht03.wav\r\nsound\\terran\\phoenix\\tphyes00.wav\r\nsound\\terran\\phoenix\\tphyes01.wav\r\nsound\\terran\\phoenix\\tphyes02.wav\r\nsound\\terran\\phoenix\\tphyes03.wav\r\nsound\\terran\\raynorm\\uradth00.wav\r\nsound\\terran\\raynorm\\uradth01.wav\r\nsound\\terran\\raynorm\\urapss00.wav\r\nsound\\terran\\raynorm\\urapss01.wav\r\nsound\\terran\\raynorm\\urapss02.wav\r\nsound\\terran\\raynorm\\urapss03.wav\r\nsound\\terran\\raynorm\\urawht00.wav\r\nsound\\terran\\raynorm\\urawht01.wav\r\nsound\\terran\\raynorm\\urawht02.wav\r\nsound\\terran\\raynorm\\urawht03.wav\r\nsound\\terran\\raynorm\\urayes00.wav\r\nsound\\terran\\raynorm\\urayes01.wav\r\nsound\\terran\\raynorm\\urayes02.wav\r\nsound\\terran\\raynorm\\urayes03.wav\r\nsound\\terran\\raynorv\\urvdth00.wav\r\nsound\\terran\\raynorv\\urvpss00.wav\r\nsound\\terran\\raynorv\\urvpss01.wav\r\nsound\\terran\\raynorv\\urvpss02.wav\r\nsound\\terran\\raynorv\\urvpss03.wav\r\nsound\\terran\\raynorv\\urvwht00.wav\r\nsound\\terran\\raynorv\\urvwht01.wav\r\nsound\\terran\\raynorv\\urvwht02.wav\r\nsound\\terran\\raynorv\\urvwht03.wav\r\nsound\\terran\\raynorv\\urvyes00.wav\r\nsound\\terran\\raynorv\\urvyes01.wav\r\nsound\\terran\\raynorv\\urvyes02.wav\r\nsound\\terran\\raynorv\\urvyes03.wav\r\nsound\\terran\\scv\\edrrep00.wav\r\nsound\\terran\\scv\\edrrep01.wav\r\nsound\\terran\\scv\\edrrep02.wav\r\nsound\\terran\\scv\\edrrep03.wav\r\nsound\\terran\\scv\\edrrep04.wav\r\nsound\\terran\\scv\\tscdth00.wav\r\nsound\\terran\\scv\\tscerr00.wav\r\nsound\\terran\\scv\\tscerr01.wav\r\nsound\\terran\\scv\\tscmin00.wav\r\nsound\\terran\\scv\\tscmin01.wav\r\nsound\\terran\\scv\\tscpss00.wav\r\nsound\\terran\\scv\\tscpss01.wav\r\nsound\\terran\\scv\\tscpss02.wav\r\nsound\\terran\\scv\\tscpss03.wav\r\nsound\\terran\\scv\\tscpss04.wav\r\nsound\\terran\\scv\\tscpss05.wav\r\nsound\\terran\\scv\\tscpss06.wav\r\nsound\\terran\\scv\\tscrdy00.wav\r\nsound\\terran\\scv\\tsctra00.wav\r\nsound\\terran\\scv\\tscupd00.wav\r\nsound\\terran\\scv\\tscwht00.wav\r\nsound\\terran\\scv\\tscwht01.wav\r\nsound\\terran\\scv\\tscwht02.wav\r\nsound\\terran\\scv\\tscwht03.wav\r\nsound\\terran\\scv\\tscyes00.wav\r\nsound\\terran\\scv\\tscyes01.wav\r\nsound\\terran\\scv\\tscyes02.wav\r\nsound\\terran\\scv\\tscyes03.wav\r\nsound\\terran\\tank\\ttadth00.wav\r\nsound\\terran\\tank\\ttapss00.wav\r\nsound\\terran\\tank\\ttapss01.wav\r\nsound\\terran\\tank\\ttapss02.wav\r\nsound\\terran\\tank\\ttapss03.wav\r\nsound\\terran\\tank\\ttardy00.wav\r\nsound\\terran\\tank\\ttatra00.wav\r\nsound\\terran\\tank\\ttatra01.wav\r\nsound\\terran\\tank\\ttawht00.wav\r\nsound\\terran\\tank\\ttawht01.wav\r\nsound\\terran\\tank\\ttawht02.wav\r\nsound\\terran\\tank\\ttawht03.wav\r\nsound\\terran\\tank\\ttayes00.wav\r\nsound\\terran\\tank\\ttayes01.wav\r\nsound\\terran\\tank\\ttayes02.wav\r\nsound\\terran\\tank\\ttayes03.wav\r\nsound\\terran\\vessel\\tvedef00.wav\r\nsound\\terran\\vessel\\tvedth00.wav\r\nsound\\terran\\vessel\\tveemp00.wav\r\nsound\\terran\\vessel\\tveirr00.wav\r\nsound\\terran\\vessel\\tvepss00.wav\r\nsound\\terran\\vessel\\tvepss01.wav\r\nsound\\terran\\vessel\\tvepss02.wav\r\nsound\\terran\\vessel\\tvepss03.wav\r\nsound\\terran\\vessel\\tvepss04.wav\r\nsound\\terran\\vessel\\tvepss05.wav\r\nsound\\terran\\vessel\\tvepss06.wav\r\nsound\\terran\\vessel\\tverdy00.wav\r\nsound\\terran\\vessel\\tvewht00.wav\r\nsound\\terran\\vessel\\tvewht01.wav\r\nsound\\terran\\vessel\\tvewht02.wav\r\nsound\\terran\\vessel\\tvewht03.wav\r\nsound\\terran\\vessel\\tveyes00.wav\r\nsound\\terran\\vessel\\tveyes01.wav\r\nsound\\terran\\vessel\\tveyes02.wav\r\nsound\\terran\\vessel\\tveyes03.wav\r\nsound\\terran\\vulture\\tvudth00.wav\r\nsound\\terran\\vulture\\tvumin00.wav\r\nsound\\terran\\vulture\\tvumin01.wav\r\nsound\\terran\\vulture\\tvupss00.wav\r\nsound\\terran\\vulture\\tvupss01.wav\r\nsound\\terran\\vulture\\tvupss02.wav\r\nsound\\terran\\vulture\\tvupss03.wav\r\nsound\\terran\\vulture\\tvurdy00.wav\r\nsound\\terran\\vulture\\tvuwht00.wav\r\nsound\\terran\\vulture\\tvuwht01.wav\r\nsound\\terran\\vulture\\tvuwht02.wav\r\nsound\\terran\\vulture\\tvuwht03.wav\r\nsound\\terran\\vulture\\tvuyes00.wav\r\nsound\\terran\\vulture\\tvuyes01.wav\r\nsound\\terran\\vulture\\tvuyes02.wav\r\nsound\\terran\\vulture\\tvuyes03.wav\r\nsound\\zerg\\advisor\\zaderr00.wav\r\nsound\\zerg\\advisor\\zaderr01.wav\r\nsound\\zerg\\advisor\\zaderr02.wav\r\nsound\\zerg\\advisor\\zaderr03.wav\r\nsound\\zerg\\advisor\\zaderr04.wav\r\nsound\\zerg\\advisor\\zaderr05.wav\r\nsound\\zerg\\advisor\\zaderr06.wav\r\nsound\\zerg\\advisor\\zadupd00.wav\r\nsound\\zerg\\advisor\\zadupd01.wav\r\nsound\\zerg\\advisor\\zadupd02.wav\r\nsound\\zerg\\advisor\\zadupd04.wav\r\nsound\\zerg\\avenger\\zavatt00.wav\r\nsound\\zerg\\avenger\\zavdth00.wav\r\nsound\\zerg\\avenger\\zavhit00.wav\r\nsound\\zerg\\avenger\\zavpss00.wav\r\nsound\\zerg\\avenger\\zavpss01.wav\r\nsound\\zerg\\avenger\\zavrdy00.wav\r\nsound\\zerg\\avenger\\zavwht00.wav\r\nsound\\zerg\\avenger\\zavwht01.wav\r\nsound\\zerg\\avenger\\zavyes00.wav\r\nsound\\zerg\\avenger\\zavyes01.wav\r\nsound\\zerg\\bldg\\zbldgdth.wav\r\nsound\\zerg\\bldg\\zcbwht00.wav\r\nsound\\zerg\\bldg\\zchrdy00.wav\r\nsound\\zerg\\bldg\\zchwht00.wav\r\nsound\\zerg\\bldg\\zevwht00.wav\r\nsound\\zerg\\bldg\\zfcwht00.wav\r\nsound\\zerg\\bldg\\zhawht00.wav\r\nsound\\zerg\\bldg\\zhiwht00.wav\r\nsound\\zerg\\bldg\\zigwht00.wav\r\nsound\\zerg\\bldg\\zlrwht00.wav\r\nsound\\zerg\\bldg\\zluwht00.wav\r\nsound\\zerg\\bldg\\zmcwht00.wav\r\nsound\\zerg\\bldg\\zmhwht00.wav\r\nsound\\zerg\\bldg\\znewht00.wav\r\nsound\\zerg\\bldg\\znywht00.wav\r\nsound\\zerg\\bldg\\zo1wht00.wav\r\nsound\\zerg\\bldg\\zrcwht00.wav\r\nsound\\zerg\\bldg\\zsbwht00.wav\r\nsound\\zerg\\bldg\\zscwht00.wav\r\nsound\\zerg\\bldg\\zspwht00.wav\r\nsound\\zerg\\broodling\\zbratt00.wav\r\nsound\\zerg\\broodling\\zbrdth00.wav\r\nsound\\zerg\\broodling\\zbrpss00.wav\r\nsound\\zerg\\broodling\\zbrpss01.wav\r\nsound\\zerg\\broodling\\zbrpss02.wav\r\nsound\\zerg\\broodling\\zbrpss03.wav\r\nsound\\zerg\\broodling\\zbrrdy00.wav\r\nsound\\zerg\\broodling\\zbrwht00.wav\r\nsound\\zerg\\broodling\\zbrwht01.wav\r\nsound\\zerg\\broodling\\zbrwht02.wav\r\nsound\\zerg\\broodling\\zbrwht03.wav\r\nsound\\zerg\\broodling\\zbryes00.wav\r\nsound\\zerg\\broodling\\zbryes01.wav\r\nsound\\zerg\\broodling\\zbryes02.wav\r\nsound\\zerg\\broodling\\zbryes03.wav\r\nsound\\zerg\\bugguy\\zbgpss00.wav\r\nsound\\zerg\\bugguy\\zbgpss01.wav\r\nsound\\zerg\\bugguy\\zbgpss02.wav\r\nsound\\zerg\\bugguy\\zbgpss03.wav\r\nsound\\zerg\\bugguy\\zbgrdy00.wav\r\nsound\\zerg\\bugguy\\zbgwht00.wav\r\nsound\\zerg\\bugguy\\zbgwht01.wav\r\nsound\\zerg\\bugguy\\zbgwht02.wav\r\nsound\\zerg\\bugguy\\zbgwht03.wav\r\nsound\\zerg\\bugguy\\zbgyes00.wav\r\nsound\\zerg\\bugguy\\zbgyes01.wav\r\nsound\\zerg\\bugguy\\zbgyes02.wav\r\nsound\\zerg\\bugguy\\zbgyes03.wav\r\nsound\\zerg\\defiler\\zdeblo00.wav\r\nsound\\zerg\\defiler\\zdeblo01.wav\r\nsound\\zerg\\defiler\\zdecon00.wav\r\nsound\\zerg\\defiler\\zdedth00.wav\r\nsound\\zerg\\defiler\\zdepss00.wav\r\nsound\\zerg\\defiler\\zdepss01.wav\r\nsound\\zerg\\defiler\\zdepss02.wav\r\nsound\\zerg\\defiler\\zdepss03.wav\r\nsound\\zerg\\defiler\\zderdy00.wav\r\nsound\\zerg\\defiler\\zdewht00.wav\r\nsound\\zerg\\defiler\\zdewht01.wav\r\nsound\\zerg\\defiler\\zdewht02.wav\r\nsound\\zerg\\defiler\\zdewht03.wav\r\nsound\\zerg\\defiler\\zdeyes00.wav\r\nsound\\zerg\\defiler\\zdeyes01.wav\r\nsound\\zerg\\defiler\\zdeyes02.wav\r\nsound\\zerg\\defiler\\zdeyes03.wav\r\nsound\\zerg\\devourer\\firesuck.wav\r\nsound\\zerg\\devourer\\goophit.wav\r\nsound\\zerg\\devourer\\vssver.scc\r\nsound\\zerg\\devourer\\zdvdth00.wav\r\nsound\\zerg\\devourer\\zdvpss00.wav\r\nsound\\zerg\\devourer\\zdvpss01.wav\r\nsound\\zerg\\devourer\\zdvpss02.wav\r\nsound\\zerg\\devourer\\zdvrdy00.wav\r\nsound\\zerg\\devourer\\zdvwht00.wav\r\nsound\\zerg\\devourer\\zdvwht01.wav\r\nsound\\zerg\\devourer\\zdvwht02.wav\r\nsound\\zerg\\devourer\\zdvyes00.wav\r\nsound\\zerg\\devourer\\zdvyes01.wav\r\nsound\\zerg\\devourer\\zdvyes02.wav\r\nsound\\zerg\\devourer\\zdvyes03.wav\r\nsound\\zerg\\drone\\zdrdth00.wav\r\nsound\\zerg\\drone\\zdrerr00.wav\r\nsound\\zerg\\drone\\zdrmin00.wav\r\nsound\\zerg\\drone\\zdrmin01.wav\r\nsound\\zerg\\drone\\zdrmin02.wav\r\nsound\\zerg\\drone\\zdrmin03.wav\r\nsound\\zerg\\drone\\zdrmin04.wav\r\nsound\\zerg\\drone\\zdrpss00.wav\r\nsound\\zerg\\drone\\zdrpss01.wav\r\nsound\\zerg\\drone\\zdrpss02.wav\r\nsound\\zerg\\drone\\zdrrdy00.wav\r\nsound\\zerg\\drone\\zdrwht00.wav\r\nsound\\zerg\\drone\\zdrwht01.wav\r\nsound\\zerg\\drone\\zdrwht02.wav\r\nsound\\zerg\\drone\\zdrwht03.wav\r\nsound\\zerg\\drone\\zdrwht04.wav\r\nsound\\zerg\\drone\\zdryes00.wav\r\nsound\\zerg\\drone\\zdryes01.wav\r\nsound\\zerg\\drone\\zdryes02.wav\r\nsound\\zerg\\drone\\zdryes03.wav\r\nsound\\zerg\\drone\\zdryes04.wav\r\nsound\\zerg\\egg\\zegdth00.wav\r\nsound\\zerg\\egg\\zegpss00.wav\r\nsound\\zerg\\egg\\zegrdy00.wav\r\nsound\\zerg\\egg\\zegwht00.wav\r\nsound\\zerg\\egg\\zegwht01.wav\r\nsound\\zerg\\guardian\\zgudth00.wav\r\nsound\\zerg\\guardian\\zgupss00.wav\r\nsound\\zerg\\guardian\\zgupss01.wav\r\nsound\\zerg\\guardian\\zgupss02.wav\r\nsound\\zerg\\guardian\\zgupss03.wav\r\nsound\\zerg\\guardian\\zgurdy00.wav\r\nsound\\zerg\\guardian\\zguwht00.wav\r\nsound\\zerg\\guardian\\zguwht01.wav\r\nsound\\zerg\\guardian\\zguwht02.wav\r\nsound\\zerg\\guardian\\zguwht03.wav\r\nsound\\zerg\\guardian\\zguyes00.wav\r\nsound\\zerg\\guardian\\zguyes01.wav\r\nsound\\zerg\\guardian\\zguyes02.wav\r\nsound\\zerg\\guardian\\zguyes03.wav\r\nsound\\zerg\\hydra\\spifir00.wav\r\nsound\\zerg\\hydra\\zhydth00.wav\r\nsound\\zerg\\hydra\\zhypss00.wav\r\nsound\\zerg\\hydra\\zhypss01.wav\r\nsound\\zerg\\hydra\\zhyrdy00.wav\r\nsound\\zerg\\hydra\\zhywht00.wav\r\nsound\\zerg\\hydra\\zhywht01.wav\r\nsound\\zerg\\hydra\\zhywht02.wav\r\nsound\\zerg\\hydra\\zhyyes00.wav\r\nsound\\zerg\\hydra\\zhyyes01.wav\r\nsound\\zerg\\hydra\\zhyyes02.wav\r\nsound\\zerg\\hydra\\zhyyes03.wav\r\nsound\\zerg\\larva\\zladth00.wav\r\nsound\\zerg\\larva\\zlapss00.wav\r\nsound\\zerg\\larva\\zlawht00.wav\r\nsound\\zerg\\lurker\\vssver.scc\r\nsound\\zerg\\lurker\\zluburrw.wav\r\nsound\\zerg\\lurker\\zludth00.wav\r\nsound\\zerg\\lurker\\zlupss00.wav\r\nsound\\zerg\\lurker\\zlupss01.wav\r\nsound\\zerg\\lurker\\zlupss02.wav\r\nsound\\zerg\\lurker\\zlupss03.wav\r\nsound\\zerg\\lurker\\zlurdy00.wav\r\nsound\\zerg\\lurker\\zluwht00.wav\r\nsound\\zerg\\lurker\\zluwht01.wav\r\nsound\\zerg\\lurker\\zluwht02.wav\r\nsound\\zerg\\lurker\\zluwht03.wav\r\nsound\\zerg\\lurker\\zluyes00.wav\r\nsound\\zerg\\lurker\\zluyes01.wav\r\nsound\\zerg\\lurker\\zluyes02.wav\r\nsound\\zerg\\lurker\\zluyes03.wav\r\nsound\\zerg\\mutalid\\zmudth00.wav\r\nsound\\zerg\\mutalid\\zmupss00.wav\r\nsound\\zerg\\mutalid\\zmupss01.wav\r\nsound\\zerg\\mutalid\\zmupss02.wav\r\nsound\\zerg\\mutalid\\zmupss03.wav\r\nsound\\zerg\\mutalid\\zmurdy00.wav\r\nsound\\zerg\\mutalid\\zmuwht00.wav\r\nsound\\zerg\\mutalid\\zmuwht01.wav\r\nsound\\zerg\\mutalid\\zmuwht02.wav\r\nsound\\zerg\\mutalid\\zmuwht03.wav\r\nsound\\zerg\\mutalid\\zmuyes00.wav\r\nsound\\zerg\\mutalid\\zmuyes01.wav\r\nsound\\zerg\\mutalid\\zmuyes02.wav\r\nsound\\zerg\\mutalid\\zmuyes03.wav\r\nsound\\zerg\\overlord\\zovdth00.wav\r\nsound\\zerg\\overlord\\zovpss00.wav\r\nsound\\zerg\\overlord\\zovpss01.wav\r\nsound\\zerg\\overlord\\zovpss02.wav\r\nsound\\zerg\\overlord\\zovpss03.wav\r\nsound\\zerg\\overlord\\zovrdy00.wav\r\nsound\\zerg\\overlord\\zovwht00.wav\r\nsound\\zerg\\overlord\\zovwht01.wav\r\nsound\\zerg\\overlord\\zovwht02.wav\r\nsound\\zerg\\overlord\\zovwht03.wav\r\nsound\\zerg\\overlord\\zovyes00.wav\r\nsound\\zerg\\overlord\\zovyes01.wav\r\nsound\\zerg\\overlord\\zovyes02.wav\r\nsound\\zerg\\overlord\\zovyes03.wav\r\nsound\\zerg\\queen\\zqudth00.wav\r\nsound\\zerg\\queen\\zqudth01.wav\r\nsound\\zerg\\queen\\zqudth02.wav\r\nsound\\zerg\\queen\\zquens00.wav\r\nsound\\zerg\\queen\\zqupss00.wav\r\nsound\\zerg\\queen\\zqupss01.wav\r\nsound\\zerg\\queen\\zqupss02.wav\r\nsound\\zerg\\queen\\zqupss03.wav\r\nsound\\zerg\\queen\\zqurdy00.wav\r\nsound\\zerg\\queen\\zquswm00.wav\r\nsound\\zerg\\queen\\zquswm01.wav\r\nsound\\zerg\\queen\\zqutag00.wav\r\nsound\\zerg\\queen\\zqutag01.wav\r\nsound\\zerg\\queen\\zquwht00.wav\r\nsound\\zerg\\queen\\zquwht01.wav\r\nsound\\zerg\\queen\\zquwht02.wav\r\nsound\\zerg\\queen\\zquwht03.wav\r\nsound\\zerg\\queen\\zquyes00.wav\r\nsound\\zerg\\queen\\zquyes01.wav\r\nsound\\zerg\\queen\\zquyes02.wav\r\nsound\\zerg\\queen\\zquyes03.wav\r\nsound\\zerg\\ultra\\zulatt00.wav\r\nsound\\zerg\\ultra\\zulatt01.wav\r\nsound\\zerg\\ultra\\zulatt02.wav\r\nsound\\zerg\\ultra\\zuldth00.wav\r\nsound\\zerg\\ultra\\zulhit00.wav\r\nsound\\zerg\\ultra\\zulhit01.wav\r\nsound\\zerg\\ultra\\zulpss00.wav\r\nsound\\zerg\\ultra\\zulpss01.wav\r\nsound\\zerg\\ultra\\zulpss02.wav\r\nsound\\zerg\\ultra\\zulrdy00.wav\r\nsound\\zerg\\ultra\\zulror00.wav\r\nsound\\zerg\\ultra\\zulwht00.wav\r\nsound\\zerg\\ultra\\zulwht01.wav\r\nsound\\zerg\\ultra\\zulwht02.wav\r\nsound\\zerg\\ultra\\zulwht03.wav\r\nsound\\zerg\\ultra\\zulyes00.wav\r\nsound\\zerg\\ultra\\zulyes01.wav\r\nsound\\zerg\\ultra\\zulyes02.wav\r\nsound\\zerg\\ultra\\zulyes03.wav\r\nsound\\zerg\\zergduran\\vssver.scc\r\nsound\\zerg\\zergduran\\zdndth00.wav\r\nsound\\zerg\\zergduran\\zdnpss00.wav\r\nsound\\zerg\\zergduran\\zdnpss01.wav\r\nsound\\zerg\\zergduran\\zdnpss02.wav\r\nsound\\zerg\\zergduran\\zdnpss03.wav\r\nsound\\zerg\\zergduran\\zdnpss04.wav\r\nsound\\zerg\\zergduran\\zdnpss05.wav\r\nsound\\zerg\\zergduran\\zdnpss06.wav\r\nsound\\zerg\\zergduran\\zdnpss07.wav\r\nsound\\zerg\\zergduran\\zdnpss08.wav\r\nsound\\zerg\\zergduran\\zdnwht00.wav\r\nsound\\zerg\\zergduran\\zdnwht01.wav\r\nsound\\zerg\\zergduran\\zdnwht02.wav\r\nsound\\zerg\\zergduran\\zdnwht03.wav\r\nsound\\zerg\\zergduran\\zdnyes00.wav\r\nsound\\zerg\\zergduran\\zdnyes01.wav\r\nsound\\zerg\\zergduran\\zdnyes02.wav\r\nsound\\zerg\\zergduran\\zdnyes03.wav\r\nsound\\zerg\\zergkerri\\ukidth00.wav\r\nsound\\zerg\\zergkerri\\ukipss00.wav\r\nsound\\zerg\\zergkerri\\ukipss01.wav\r\nsound\\zerg\\zergkerri\\ukipss02.wav\r\nsound\\zerg\\zergkerri\\ukipss03.wav\r\nsound\\zerg\\zergkerri\\ukiwht00.wav\r\nsound\\zerg\\zergkerri\\ukiwht01.wav\r\nsound\\zerg\\zergkerri\\ukiwht02.wav\r\nsound\\zerg\\zergkerri\\ukiwht03.wav\r\nsound\\zerg\\zergkerri\\ukiyes00.wav\r\nsound\\zerg\\zergkerri\\ukiyes01.wav\r\nsound\\zerg\\zergkerri\\ukiyes02.wav\r\nsound\\zerg\\zergkerri\\ukiyes03.wav\r\nsound\\zerg\\zergkrtti\\ukidth00.wav\r\nsound\\zerg\\zergkrtti\\ukipss00.wav\r\nsound\\zerg\\zergkrtti\\ukipss01.wav\r\nsound\\zerg\\zergkrtti\\ukipss02.wav\r\nsound\\zerg\\zergkrtti\\ukipss03.wav\r\nsound\\zerg\\zergkrtti\\ukiyes00.wav\r\nsound\\zerg\\zergkrtti\\ukiyes01.wav\r\nsound\\zerg\\zergkrtti\\ukiyes02.wav\r\nsound\\zerg\\zergkrtti\\ukiyes03.wav\r\nsound\\zerg\\zergling\\zzedth00.wav\r\nsound\\zerg\\zergling\\zzepss00.wav\r\nsound\\zerg\\zergling\\zzepss01.wav\r\nsound\\zerg\\zergling\\zzepss02.wav\r\nsound\\zerg\\zergling\\zzerdy00.wav\r\nsound\\zerg\\zergling\\zzewht00.wav\r\nsound\\zerg\\zergling\\zzewht01.wav\r\nsound\\zerg\\zergling\\zzewht02.wav\r\nsound\\zerg\\zergling\\zzewht03.wav\r\nsound\\zerg\\zergling\\zzeyes00.wav\r\nsound\\zerg\\zergling\\zzeyes01.wav\r\nsound\\zerg\\zergling\\zzeyes02.wav\r\nsound\\zerg\\zergling\\zzeyes03.wav\r\nspawn.mpq\r\nSpd_Dlg.00e\r\nSpd_Dlg.01f\r\nSpd_Dlg.030\r\nSpd_Dlg.041\r\nSpd_Dlg.052\r\nSpd_Dlg.bin\r\nSystemSurvey.exe\r\nsprites.dat\r\nSTANDARD.snp\r\nStarcraft.cnd\r\nstarcraft.exe\r\nstaredit.cnt\r\nStarEdit.exe\r\nstaredit.hlp\r\nstaredit\\scenario.chk\r\nstaredit\\wav\\1assualt.wav\r\nstaredit\\wav\\1coverop.wav\r\nstaredit\\wav\\1demo.wav\r\nstaredit\\wav\\1engineer.wav\r\nstaredit\\wav\\1infantry.wav\r\nstaredit\\wav\\1psychic.wav\r\nstaredit\\wav\\1pyro.wav\r\nstaredit\\wav\\1survey.wav\r\nstaredit\\wav\\alert1.wav\r\nstaredit\\wav\\and here are the beacons!.wav\r\nstaredit\\wav\\andthatistheendotfh.wav\r\nstaredit\\wav\\beacon jak.wav\r\nstaredit\\wav\\beacon lost!.wav\r\nstaredit\\wav\\blue player is about to win!.wav\r\nstaredit\\wav\\carbomb.wav\r\nstaredit\\wav\\cheers.wav\r\nstaredit\\wav\\combeep0.wav\r\nstaredit\\wav\\combeep1.wav\r\nstaredit\\wav\\death.wav\r\nstaredit\\wav\\draw.wav\r\nstaredit\\wav\\duel_of_the_fates.wav\r\nstaredit\\wav\\finishline.wav\r\nstaredit\\wav\\flagtaken.wav\r\nstaredit\\wav\\foekill.wav\r\nstaredit\\wav\\getset.wav\r\nstaredit\\wav\\ghost ready.wav\r\nstaredit\\wav\\go.wav\r\nstaredit\\wav\\goal.wav\r\nstaredit\\wav\\goal2.wav\r\nstaredit\\wav\\hooligans.wav\r\nstaredit\\wav\\hydralisk ready.wav\r\nstaredit\\wav\\levelclear.wav\r\nstaredit\\wav\\marine ready.wav\r\nstaredit\\wav\\more than you can.wav\r\nstaredit\\wav\\new civlians.wav\r\nstaredit\\wav\\newbunker.wav\r\nstaredit\\wav\\ohthat'sgottahurt.wav\r\nstaredit\\wav\\only civilians can steal the beacons.wav\r\nstaredit\\wav\\onyourmarks.wav\r\nstaredit\\wav\\overtime.wav\r\nstaredit\\wav\\playball.wav\r\nstaredit\\wav\\powerdown.wav\r\nstaredit\\wav\\powerup.wav\r\nstaredit\\wav\\pprrdy00.wav\r\nstaredit\\wav\\pprwht01.wav\r\nstaredit\\wav\\pprwht03.wav\r\nstaredit\\wav\\ppryes00.wav\r\nstaredit\\wav\\press start.wav\r\nstaredit\\wav\\purple player is about to win.wav\r\nstaredit\\wav\\red player is about to win!.wav\r\nstaredit\\wav\\six pack.wav\r\nstaredit\\wav\\someone stole your beacon!.wav\r\nstaredit\\wav\\steal!  the!  beacon!!!!.wav\r\nstaredit\\wav\\teal player is about to win.wav\r\nstaredit\\wav\\telefrag.wav\r\nstaredit\\wav\\teleport.wav\r\nstaredit\\wav\\templar ready.wav\r\nstaredit\\wav\\theenemyflaghasbeenretrieved.wav\r\nstaredit\\wav\\trucko'dile.wav\r\nstaredit\\wav\\wakka.wav\r\nstaredit\\wav\\wakkatheme.wav\r\nstaredit\\wav\\yee haw.wav\r\nstaredit\\wav\\you stole the beacon!.wav\r\nstaredit\\wav\\you've lost the beacon!.wav\r\nstaredit\\wav\\yourflagcaptured.wav\r\nstaredit\\wav\\yourflaghasbeenretrieved.wav\r\nstaredit\\wav\\yourteam hastheenemyflag.wav\r\nstaredit\\wav\\yourteamcaptured.wav\r\nstaredit\\wav\\zbgwht00.wav\r\nstaredit\\wav\\zbgwht01.wav\r\nstat_txt.001\r\nstat_txt.002\r\nstat_txt.004\r\nstat_txt.006\r\nstat_txt.007\r\nstat_txt.00a\r\nstat_txt.00b\r\nstat_txt.00c\r\nstat_txt.00d\r\nstat_txt.010\r\nstat_txt.011\r\nstat_txt.015\r\nstat_txt.016\r\nstat_txt.01d\r\nstat_txt.01e\r\nstat_txt.023\r\nstat_txt.026\r\nstat_txt.02d\r\nstat_txt.02f\r\nstat_txt.039\r\nstat_txt.03d\r\nstat_txt.03f\r\nstat_txt.040\r\nstat_txt.04d\r\nstat_txt.04f\r\nstat_txt.051\r\nstat_txt.058\r\nstat_txt.065\r\nstat_txt.071\r\nstat_txt.tbl\r\nstatbtnn.bin\r\nstorm.dll\r\nswar\\h\\storm.h\r\ntechdata.dat\r\ntemplates.lst\r\ntemplates\\capture the flag(1).got\r\ntemplates\\free for all(1).got\r\ntemplates\\greed(1).got\r\ntemplates\\greed(2).got\r\ntemplates\\greed(3).got\r\ntemplates\\greed(4).got\r\ntemplates\\kbk beginner(1).got\r\ntemplates\\kbk game room(1).got\r\ntemplates\\kbk pro(1).got\r\ntemplates\\kbk singles(1).got\r\ntemplates\\kbk team(1).got\r\ntemplates\\kbk zone(1).got\r\ntemplates\\kbk(1).got\r\ntemplates\\ladder(1).got\r\ntemplates\\ladder(2).got\r\ntemplates\\melee(1).got\r\ntemplates\\one on one(1).got\r\ntemplates\\pgl(1).got\r\ntemplates\\scenario(1).got\r\ntemplates\\slaughter(1).got\r\ntemplates\\slaughter(2).got\r\ntemplates\\slaughter(3).got\r\ntemplates\\slaughter(4).got\r\ntemplates\\sudden death(1).got\r\ntemplates\\team capture the flag(1).got\r\ntemplates\\team capture the flag(2).got\r\ntemplates\\team capture the flag(3).got\r\ntemplates\\team free for all(1).got\r\ntemplates\\team free for all(2).got\r\ntemplates\\team free for all(3).got\r\ntemplates\\team melee(1).got\r\ntemplates\\team melee(2).got\r\ntemplates\\team melee(3).got\r\ntemplates\\team scenario(1).got\r\ntemplates\\team scenario(2).got\r\ntemplates\\team scenario(3).got\r\ntemplates\\team sudden death(1).got\r\ntemplates\\team sudden death(2).got\r\ntemplates\\team sudden death(3).got\r\ntemplates\\templates.lst\r\ntemplates\\top vs. bottom(1).got\r\ntemplates\\top vs. bottom(2).got\r\ntemplates\\top vs. bottom(3).got\r\ntemplates\\top vs. bottom(4).got\r\ntemplates\\top vs. bottom(5).got\r\ntemplates\\top vs. bottom(6).got\r\ntemplates\\top vs. bottom(7).got\r\ntemplates\\tournament(1).got\r\ntemplates\\use map settings(1).got\r\nterran.grp\r\ntFontGam.pcx\r\ntileset\\ashworld-nc.cv5\r\ntileset\\ashworld-nc.vf4\r\ntileset\\ashworld-nc.vr4\r\ntileset\\ashworld-nc.vx4\r\ntileset\\ashworld-nc.wpe\r\ntileset\\ashworld.cv5\r\ntileset\\ashworld.cv50\r\ntileset\\ashworld.grp\r\ntileset\\ashworld.vf4\r\ntileset\\ashworld.vr4\r\ntileset\\ashworld.vx4\r\ntileset\\ashworld.wpe\r\ntileset\\ashworld.wpe0\r\ntileset\\ashworld\\bexpl.pcx\r\ntileset\\ashworld\\bfire.pcx\r\ntileset\\ashworld\\blue.pcx\r\ntileset\\ashworld\\cyan.pcx\r\ntileset\\ashworld\\dark.pcx\r\ntileset\\ashworld\\dddata.bin\r\ntileset\\ashworld\\gfire.pcx\r\ntileset\\ashworld\\green.pcx\r\ntileset\\ashworld\\light.pcx\r\ntileset\\ashworld\\ofire.pcx\r\ntileset\\ashworld\\orange.pcx\r\ntileset\\ashworld\\red.pcx\r\ntileset\\ashworld\\shift.pcx\r\ntileset\\ashworld\\trans50.pcx\r\ntileset\\ashworld\\yellow.pcx\r\ntileset\\badlands-nc.cv5\r\ntileset\\badlands-nc.vf4\r\ntileset\\badlands-nc.vr4\r\ntileset\\badlands-nc.vx4\r\ntileset\\badlands-nc.wpe\r\ntileset\\badlands.cv5\r\ntileset\\badlands.grp\r\ntileset\\badlands.vf4\r\ntileset\\badlands.vr4\r\ntileset\\badlands.vx4\r\ntileset\\badlands.wpe\r\ntileset\\badlands\\bexpl.pcx\r\ntileset\\badlands\\bfire.pcx\r\ntileset\\badlands\\blue.pcx\r\ntileset\\badlands\\cyan.pcx\r\ntileset\\badlands\\dark.pcx\r\ntileset\\badlands\\dddata.bin\r\ntileset\\badlands\\gfire.pcx\r\ntileset\\badlands\\green.pcx\r\ntileset\\badlands\\light.pcx\r\ntileset\\badlands\\ofire.pcx\r\ntileset\\badlands\\orange.pcx\r\ntileset\\badlands\\red.pcx\r\ntileset\\badlands\\shift.pcx\r\ntileset\\badlands\\trans50.pcx\r\ntileset\\desert-nc.cv5\r\ntileset\\desert-nc.vf4\r\ntileset\\desert-nc.vr4\r\ntileset\\desert-nc.vx4\r\ntileset\\desert-nc.wpe\r\ntileset\\desert.cv5\r\ntileset\\desert.grp\r\ntileset\\desert.vf4\r\ntileset\\desert.vr4\r\ntileset\\desert.vx4\r\ntileset\\desert.wpe\r\ntileset\\desert\\bexpl.pcx\r\ntileset\\desert\\bfire.pcx\r\ntileset\\desert\\blue.pcx\r\ntileset\\desert\\dark.pcx\r\ntileset\\desert\\dddata.bin\r\ntileset\\desert\\gfire.pcx\r\ntileset\\desert\\green.pcx\r\ntileset\\desert\\light.pcx\r\ntileset\\desert\\ofire.pcx\r\ntileset\\desert\\orange.pcx\r\ntileset\\desert\\red.pcx\r\ntileset\\desert\\shift.pcx\r\ntileset\\desert\\trans50.pcx\r\ntileset\\ice-nc.cv5\r\ntileset\\ice-nc.vf4\r\ntileset\\ice-nc.vr4\r\ntileset\\ice-nc.vx4\r\ntileset\\ice-nc.wpe\r\ntileset\\ice.cv5\r\ntileset\\ice.grp\r\ntileset\\ice.vf4\r\ntileset\\ice.vr4\r\ntileset\\ice.vx4\r\ntileset\\ice.wpe\r\ntileset\\ice\\bexpl.pcx\r\ntileset\\ice\\bfire.pcx\r\ntileset\\ice\\blue.pcx\r\ntileset\\ice\\dark.pcx\r\ntileset\\ice\\dddata.bin\r\ntileset\\ice\\gfire.pcx\r\ntileset\\ice\\green.pcx\r\ntileset\\ice\\light.pcx\r\ntileset\\ice\\ofire.pcx\r\ntileset\\ice\\orange.pcx\r\ntileset\\ice\\red.pcx\r\ntileset\\ice\\shift.pcx\r\ntileset\\ice\\trans50.pcx\r\ntileset\\install.cv5\r\ntileset\\install.grp\r\ntileset\\install.vf4\r\ntileset\\install.vr4\r\ntileset\\install.vx4\r\ntileset\\install.wpe\r\ntileset\\install\\bexpl.pcx\r\ntileset\\install\\bfire.pcx\r\ntileset\\install\\blue.pcx\r\ntileset\\install\\cyan.pcx\r\ntileset\\install\\dark.pcx\r\ntileset\\install\\dddata.bin\r\ntileset\\install\\gfire.pcx\r\ntileset\\install\\green.pcx\r\ntileset\\install\\light.pcx\r\ntileset\\install\\ofire.pcx\r\ntileset\\install\\orange.pcx\r\ntileset\\install\\red.pcx\r\ntileset\\install\\shift.pcx\r\ntileset\\install\\trans50.pcx\r\ntileset\\install\\yellow.pcx\r\ntileset\\jungle-nc.cv5\r\ntileset\\jungle-nc.vf4\r\ntileset\\jungle-nc.vr4\r\ntileset\\jungle-nc.vx4\r\ntileset\\jungle-nc.wpe\r\ntileset\\jungle.cv5\r\ntileset\\jungle.grp\r\ntileset\\jungle.vf4\r\ntileset\\jungle.vr4\r\ntileset\\jungle.vx4\r\ntileset\\jungle.wpe\r\ntileset\\jungle\\bexpl.pcx\r\ntileset\\jungle\\bfire.pcx\r\ntileset\\jungle\\blue.pcx\r\ntileset\\jungle\\dark.pcx\r\ntileset\\jungle\\dddata.bin\r\ntileset\\jungle\\gfire.pcx\r\ntileset\\jungle\\green.pcx\r\ntileset\\jungle\\light.pcx\r\ntileset\\jungle\\ofire.pcx\r\ntileset\\jungle\\orange.pcx\r\ntileset\\jungle\\red.pcx\r\ntileset\\jungle\\shift.pcx\r\ntileset\\jungle\\trans50.pcx\r\ntileset\\mask.vr4\r\ntileset\\mask.vx4\r\ntileset\\platform.cv5\r\ntileset\\platform.grp\r\ntileset\\platform.vf4\r\ntileset\\platform.vr4\r\ntileset\\platform.vx4\r\ntileset\\platform.wpe\r\ntileset\\platform\\bexpl.pcx\r\ntileset\\platform\\bfire.pcx\r\ntileset\\platform\\blue.pcx\r\ntileset\\platform\\cyan.pcx\r\ntileset\\platform\\dark.pcx\r\ntileset\\platform\\dddata.bin\r\ntileset\\platform\\gfire.pcx\r\ntileset\\platform\\green.pcx\r\ntileset\\platform\\light.pcx\r\ntileset\\platform\\ofire.pcx\r\ntileset\\platform\\orange.pcx\r\ntileset\\platform\\red.pcx\r\ntileset\\platform\\shift.pcx\r\ntileset\\platform\\trans50.pcx\r\ntileset\\platform\\yellow.pcx\r\ntileset\\twilight-nc.cv5\r\ntileset\\twilight-nc.vf4\r\ntileset\\twilight-nc.vr4\r\ntileset\\twilight-nc.vx4\r\ntileset\\twilight-nc.wpe\r\ntileset\\twilight.cv5\r\ntileset\\twilight.grp\r\ntileset\\twilight.vf4\r\ntileset\\twilight.vr4\r\ntileset\\twilight.vx4\r\ntileset\\twilight.wpe\r\ntileset\\twilight\\bexpl.pcx\r\ntileset\\twilight\\bfire.pcx\r\ntileset\\twilight\\blue.pcx\r\ntileset\\twilight\\dark.pcx\r\ntileset\\twilight\\dddata.bin\r\ntileset\\twilight\\gfire.pcx\r\ntileset\\twilight\\green.pcx\r\ntileset\\twilight\\light.pcx\r\ntileset\\twilight\\ofire.pcx\r\ntileset\\twilight\\orange.pcx\r\ntileset\\twilight\\red.pcx\r\ntileset\\twilight\\shift.pcx\r\ntileset\\twilight\\trans50.pcx\r\ntitle.bmp\r\ntitledlg.bin\r\ntitledlg_mac.bin\r\nTop Vs. Bottom(1).00e\r\ntop vs. bottom(1).00f\r\ntop vs. bottom(1).014\r\ntop vs. bottom(1).017\r\nTop Vs. Bottom(1).01e\r\ntop vs. bottom(1).020\r\ntop vs. bottom(1).02a\r\nTop Vs. Bottom(1).02e\r\ntop vs. bottom(1).030\r\ntop vs. bottom(1).031\r\nTop Vs. Bottom(1).03e\r\ntop vs. bottom(1).040\r\ntop vs. bottom(1).042\r\ntop vs. bottom(1).049\r\nTop Vs. Bottom(1).04e\r\ntop vs. bottom(1).053\r\ntop vs. bottom(1).056\r\ntop vs. bottom(1).062\r\ntop vs. bottom(1).06c\r\ntop vs. bottom(1).07b\r\nTop Vs. Bottom(1).got\r\nTop Vs. Bottom(2).00f\r\ntop vs. bottom(2).010\r\ntop vs. bottom(2).015\r\ntop vs. bottom(2).018\r\nTop Vs. Bottom(2).01f\r\ntop vs. bottom(2).021\r\ntop vs. bottom(2).02b\r\nTop Vs. Bottom(2).02f\r\ntop vs. bottom(2).031\r\ntop vs. bottom(2).032\r\nTop Vs. Bottom(2).03f\r\ntop vs. bottom(2).041\r\ntop vs. bottom(2).043\r\ntop vs. bottom(2).04a\r\nTop Vs. Bottom(2).04f\r\ntop vs. bottom(2).054\r\ntop vs. bottom(2).057\r\ntop vs. bottom(2).063\r\ntop vs. bottom(2).06d\r\ntop vs. bottom(2).07c\r\nTop Vs. Bottom(2).got\r\nTop Vs. Bottom(3).010\r\ntop vs. bottom(3).011\r\ntop vs. bottom(3).016\r\ntop vs. bottom(3).019\r\nTop Vs. Bottom(3).020\r\ntop vs. bottom(3).022\r\ntop vs. bottom(3).02c\r\nTop Vs. Bottom(3).030\r\ntop vs. bottom(3).032\r\ntop vs. bottom(3).033\r\nTop Vs. Bottom(3).040\r\ntop vs. bottom(3).042\r\ntop vs. bottom(3).044\r\ntop vs. bottom(3).04b\r\nTop Vs. Bottom(3).050\r\ntop vs. bottom(3).055\r\ntop vs. bottom(3).058\r\ntop vs. bottom(3).064\r\ntop vs. bottom(3).06e\r\ntop vs. bottom(3).07d\r\nTop Vs. Bottom(3).got\r\nTop Vs. Bottom(4).011\r\ntop vs. bottom(4).012\r\ntop vs. bottom(4).017\r\ntop vs. bottom(4).01a\r\nTop Vs. Bottom(4).021\r\ntop vs. bottom(4).023\r\ntop vs. bottom(4).02d\r\nTop Vs. Bottom(4).031\r\ntop vs. bottom(4).033\r\ntop vs. bottom(4).034\r\nTop Vs. Bottom(4).041\r\ntop vs. bottom(4).043\r\ntop vs. bottom(4).045\r\ntop vs. bottom(4).04c\r\nTop Vs. Bottom(4).051\r\ntop vs. bottom(4).056\r\ntop vs. bottom(4).059\r\ntop vs. bottom(4).065\r\ntop vs. bottom(4).06f\r\ntop vs. bottom(4).07e\r\nTop Vs. Bottom(4).got\r\nTop Vs. Bottom(5).012\r\ntop vs. bottom(5).013\r\ntop vs. bottom(5).018\r\ntop vs. bottom(5).01b\r\nTop Vs. Bottom(5).022\r\ntop vs. bottom(5).024\r\ntop vs. bottom(5).02e\r\nTop Vs. Bottom(5).032\r\ntop vs. bottom(5).034\r\ntop vs. bottom(5).035\r\nTop Vs. Bottom(5).042\r\ntop vs. bottom(5).044\r\ntop vs. bottom(5).046\r\ntop vs. bottom(5).04d\r\nTop Vs. Bottom(5).052\r\ntop vs. bottom(5).057\r\ntop vs. bottom(5).05a\r\ntop vs. bottom(5).066\r\ntop vs. bottom(5).070\r\ntop vs. bottom(5).07f\r\nTop Vs. Bottom(5).got\r\nTop Vs. Bottom(6).013\r\ntop vs. bottom(6).014\r\ntop vs. bottom(6).019\r\ntop vs. bottom(6).01c\r\nTop Vs. Bottom(6).023\r\ntop vs. bottom(6).025\r\ntop vs. bottom(6).02f\r\nTop Vs. Bottom(6).033\r\ntop vs. bottom(6).035\r\ntop vs. bottom(6).036\r\nTop Vs. Bottom(6).043\r\ntop vs. bottom(6).045\r\ntop vs. bottom(6).047\r\ntop vs. bottom(6).04e\r\nTop Vs. Bottom(6).053\r\ntop vs. bottom(6).058\r\ntop vs. bottom(6).05b\r\ntop vs. bottom(6).067\r\ntop vs. bottom(6).071\r\ntop vs. bottom(6).080\r\nTop Vs. Bottom(6).got\r\nTop Vs. Bottom(7).014\r\ntop vs. bottom(7).015\r\ntop vs. bottom(7).01a\r\ntop vs. bottom(7).01d\r\nTop Vs. Bottom(7).024\r\ntop vs. bottom(7).026\r\ntop vs. bottom(7).030\r\nTop Vs. Bottom(7).034\r\ntop vs. bottom(7).036\r\ntop vs. bottom(7).037\r\nTop Vs. Bottom(7).044\r\ntop vs. bottom(7).046\r\ntop vs. bottom(7).048\r\ntop vs. bottom(7).04f\r\nTop Vs. Bottom(7).054\r\nTop Vs. Bottom(7).055\r\ntop vs. bottom(7).059\r\ntop vs. bottom(7).05a\r\ntop vs. bottom(7).05c\r\ntop vs. bottom(7).068\r\ntop vs. bottom(7).072\r\ntop vs. bottom(7).073\r\ntop vs. bottom(7).081\r\ntop vs. bottom(7).082\r\nTop Vs. Bottom(7).got\r\ntowners\\animals\\cow.cel\r\ntowners\\butch\\deadguy.cel\r\ntowners\\drunk\\twndrunk.cel\r\nTowners\\Farmer\\cfrmrn2.cel\r\nTowners\\Farmer\\Farmrn2.cel\r\nTowners\\Farmer\\mfrmrn2.cel\r\nTowners\\Girl\\Girls1.cel\r\nTowners\\Girl\\Girlw1.cel\r\ntowners\\healer\\healer.cel\r\ntowners\\smith\\smithn.cel\r\ntowners\\strytell\\strytell.cel\r\ntowners\\townboy\\pegkid1.cel\r\ntowners\\townwmn1\\witch.cel\r\ntowners\\townwmn1\\wmnn.cel\r\ntowners\\twnf\\twnfn.cel\r\ntranwire.grp\r\ntriggers\\ctf.trg\r\ntriggers\\greed10.trg\r\ntriggers\\greed10000.trg\r\ntriggers\\greed15.trg\r\ntriggers\\greed20.trg\r\ntriggers\\greed2500.trg\r\ntriggers\\greed5.trg\r\ntriggers\\greed5000.trg\r\ntriggers\\greed7500.trg\r\ntriggers\\melee.trg\r\ntriggers\\slaughter15.trg\r\ntriggers\\slaughter30.trg\r\ntriggers\\slaughter45.trg\r\ntriggers\\slaughter60.trg\r\ntriggers\\suddendeath.trg\r\nui_art\\badconn.pcx\r\nui_art\\black.pcx\r\nui_art\\bn_bkg.pcx\r\nui_art\\bnbuttns.pcx\r\nui_art\\bnjoinbg.pcx\r\nui_art\\bnselchn.pcx\r\nui_art\\but_xsm.pcx\r\nui_art\\button.pcx\r\nui_art\\chat_bkg.pcx\r\nui_art\\creat_bg.pcx\r\nui_art\\credits.pcx\r\nui_art\\diffbtns.pcx\r\nui_art\\epopup.pcx\r\nui_art\\focus16.pcx\r\nui_art\\focus42.pcx\r\nui_art\\font16.bin\r\nui_art\\font16g.pcx\r\nui_art\\font16s.pcx\r\nui_art\\font24.bin\r\nui_art\\font24g.pcx\r\nui_art\\font24s.pcx\r\nui_art\\font30.bin\r\nui_art\\font30g.pcx\r\nui_art\\font30s.pcx\r\nui_art\\font42.bin\r\nui_art\\font42g.pcx\r\nui_art\\font42y.pcx\r\nui_art\\heronum.pcx\r\nui_art\\heroport.pcx\r\nui_art\\heros.pcx\r\nui_art\\hpopup.pcx\r\nui_art\\logo.pcx\r\nui_art\\lpopup.pcx\r\nui_art\\mainmenu.pcx\r\nui_art\\prog_fil.pcx\r\nui_art\\sb_arrow.pcx\r\nui_art\\sb_bg.pcx\r\nui_art\\sb_thumb.pcx\r\nui_art\\scrlarrw.pcx\r\nui_art\\scrlbar.pcx\r\nui_art\\selgame.pcx\r\nui_art\\selhero.pcx\r\nui_art\\smlogo.pcx\r\nui_art\\special.pcx\r\nui_art\\spopup.pcx\r\nui_art\\spwnport.pcx\r\nui_art\\title.pcx\r\nui_art\\welcome.pcx\r\nuninstall.lnk\r\nunit\\bullet\\blastcan.grp\r\nunit\\bullet\\circle14.grp\r\nunit\\bullet\\dragbull.grp\r\nunit\\bullet\\epbbul.grp\r\nunit\\bullet\\ephfire.grp\r\nunit\\bullet\\explo1.grp\r\nunit\\bullet\\eycbull.grp\r\nunit\\bullet\\gemini.grp\r\nunit\\bullet\\grenade.grp\r\nunit\\bullet\\hks.grp\r\nunit\\bullet\\missile.grp\r\nunit\\bullet\\parasite.grp\r\nunit\\bullet\\pdriphit.grp\r\nunit\\bullet\\psibeam.grp\r\nunit\\bullet\\pspark.grp\r\nunit\\bullet\\scvspark.grp\r\nunit\\bullet\\shockbmb.grp\r\nunit\\bullet\\smmissle.grp\r\nunit\\bullet\\spike.grp\r\nunit\\bullet\\spore2.grp\r\nunit\\bullet\\spores.grp\r\nunit\\bullet\\squib1.grp\r\nunit\\bullet\\squib2.grp\r\nunit\\bullet\\tentacle.grp\r\nunit\\bullet\\tspark.grp\r\nunit\\bullet\\zspark.grp\r\nunit\\cmdbtns\\1cmdbtns.grp\r\nunit\\cmdbtns\\cmdicons.grp\r\nunit\\cmdbtns\\pcmdbtns.grp\r\nunit\\cmdbtns\\picon.pcx\r\nunit\\cmdbtns\\tcmdbtns.grp\r\nunit\\cmdbtns\\ticon.pcx\r\nunit\\cmdbtns\\zcmdbtns.grp\r\nunit\\cmdbtns\\zicon.pcx\r\nunit\\flingy\\pg1deb.grp\r\nunit\\flingy\\pg2deb.grp\r\nunit\\flingy\\pg3deb.grp\r\nunit\\flingy\\pg4deb.grp\r\nunit\\flingy\\pg5deb.grp\r\nunit\\flingy\\pscdeb.grp\r\nunit\\flingy\\tg5deb.grp\r\nunit\\neutral\\acritter.grp\r\nunit\\neutral\\bcritter.grp\r\nunit\\neutral\\cantina.grp\r\nunit\\neutral\\cantina.lof\r\nunit\\neutral\\cargo.grp\r\nunit\\neutral\\cbashad.grp\r\nunit\\neutral\\cbattle.grp\r\nunit\\neutral\\civilian.grp\r\nunit\\neutral\\datadisk.grp\r\nunit\\neutral\\flag.grp\r\nunit\\neutral\\gasorb.grp\r\nunit\\neutral\\gassac.grp\r\nunit\\neutral\\gastank.grp\r\nunit\\neutral\\generate.grp\r\nunit\\neutral\\geyser.grp\r\nunit\\neutral\\geyser.los\r\nunit\\neutral\\geyshad.grp\r\nunit\\neutral\\gunship.grp\r\nunit\\neutral\\icritter.grp\r\nunit\\neutral\\ion.grp\r\nunit\\neutral\\jcritter.grp\r\nunit\\neutral\\kcritter.grp\r\nunit\\neutral\\kerrchry.grp\r\nunit\\neutral\\kerregg.grp\r\nunit\\neutral\\khalis.grp\r\nunit\\neutral\\khchunk.grp\r\nunit\\neutral\\khyad01.grp\r\nunit\\neutral\\maprev.grp\r\nunit\\neutral\\min01.grp\r\nunit\\neutral\\min01sha.grp\r\nunit\\neutral\\min02.grp\r\nunit\\neutral\\min02sha.grp\r\nunit\\neutral\\min03.grp\r\nunit\\neutral\\min03sha.grp\r\nunit\\neutral\\nacshad.grp\r\nunit\\neutral\\nbcshad.grp\r\nunit\\neutral\\ncicshad.grp\r\nunit\\neutral\\ncishad.grp\r\nunit\\neutral\\nckshad.grp\r\nunit\\neutral\\nddsha2.grp\r\nunit\\neutral\\nddshad.grp\r\nunit\\neutral\\nflsha2.grp\r\nunit\\neutral\\nflshad.grp\r\nunit\\neutral\\ngcshad.grp\r\nunit\\neutral\\ngoshad.grp\r\nunit\\neutral\\ngsshad.grp\r\nunit\\neutral\\njcshad.grp\r\nunit\\neutral\\nkesha2.grp\r\nunit\\neutral\\nkeshad.grp\r\nunit\\neutral\\nkhsha2.grp\r\nunit\\neutral\\nkhshad.grp\r\nunit\\neutral\\nkoshad.grp\r\nunit\\neutral\\norshad.grp\r\nunit\\neutral\\npssha2.grp\r\nunit\\neutral\\npsshad.grp\r\nunit\\neutral\\nrcdeath.grp\r\nunit\\neutral\\orechunk.grp\r\nunit\\neutral\\psidisr.grp\r\nunit\\neutral\\psiemit.grp\r\nunit\\neutral\\raider.grp\r\nunit\\neutral\\scritter.grp\r\nunit\\neutral\\starbase.grp\r\nunit\\neutral\\stasis.grp\r\nunit\\neutral\\temple.grp\r\nunit\\neutral\\tgnshad.grp\r\nunit\\neutral\\tpdshad.grp\r\nunit\\neutral\\uraj.grp\r\nunit\\protoss\\arbiter.grp\r\nunit\\protoss\\archives.grp\r\nunit\\protoss\\archives.lof\r\nunit\\protoss\\archon.grp\r\nunit\\protoss\\archon.lob\r\nunit\\protoss\\archont.grp\r\nunit\\protoss\\archont.lol\r\nunit\\protoss\\archont2.grp\r\nunit\\protoss\\assim.grp\r\nunit\\protoss\\assim.lof\r\nunit\\protoss\\assim.los\r\nunit\\protoss\\beacon.grp\r\nunit\\protoss\\beacon.lof\r\nunit\\protoss\\carrier.grp\r\nunit\\protoss\\citadel.grp\r\nunit\\protoss\\citadel.lof\r\nunit\\protoss\\corsair.grp\r\nunit\\protoss\\darchn.grp\r\nunit\\protoss\\darchn.lob\r\nunit\\protoss\\darchnt.grp\r\nunit\\protoss\\darchnt.lol\r\nunit\\protoss\\darchnt2.grp\r\nunit\\protoss\\dragoon.grp\r\nunit\\protoss\\dtemplar.grp\r\nunit\\protoss\\forge.grp\r\nunit\\protoss\\forge.lof\r\nunit\\protoss\\forget.grp\r\nunit\\protoss\\gateway.grp\r\nunit\\protoss\\gateway.lof\r\nunit\\protoss\\gencore.grp\r\nunit\\protoss\\gencore.lof\r\nunit\\protoss\\gencoret.grp\r\nunit\\protoss\\intercep.grp\r\nunit\\protoss\\lowm\\arbiter.grp\r\nunit\\protoss\\lowm\\scout.grp\r\nunit\\protoss\\lowm\\shuttle.grp\r\nunit\\protoss\\lowm\\texture.grp\r\nunit\\protoss\\lowm\\witness.grp\r\nunit\\protoss\\lshield.los\r\nunit\\protoss\\mshield.los\r\nunit\\protoss\\nexus.grp\r\nunit\\protoss\\nexus.lof\r\nunit\\protoss\\pacbuild.grp\r\nunit\\protoss\\pacshad.grp\r\nunit\\protoss\\pasbuild.grp\r\nunit\\protoss\\passhad.grp\r\nunit\\protoss\\paubuild.grp\r\nunit\\protoss\\paushad.grp\r\nunit\\protoss\\pb1glow.grp\r\nunit\\protoss\\pbabuild.grp\r\nunit\\protoss\\pbaglow.grp\r\nunit\\protoss\\pbashad.grp\r\nunit\\protoss\\pbebuild.grp\r\nunit\\protoss\\pbeshad.grp\r\nunit\\protoss\\pcibuild.grp\r\nunit\\protoss\\pcirglow.grp\r\nunit\\protoss\\pcishad.grp\r\nunit\\protoss\\pdadeath.grp\r\nunit\\protoss\\pdrdeath.grp\r\nunit\\protoss\\pdrshad.grp\r\nunit\\protoss\\pfobuild.grp\r\nunit\\protoss\\pfoshad.grp\r\nunit\\protoss\\pgabuild.grp\r\nunit\\protoss\\pgashad.grp\r\nunit\\protoss\\pgcbuild.grp\r\nunit\\protoss\\pgcshad.grp\r\nunit\\protoss\\photon.grp\r\nunit\\protoss\\photon.lof\r\nunit\\protoss\\pmarker.grp\r\nunit\\protoss\\pnebuild.grp\r\nunit\\protoss\\pneglow.grp\r\nunit\\protoss\\pneshad.grp\r\nunit\\protoss\\ppbbuild.grp\r\nunit\\protoss\\ppbshad.grp\r\nunit\\protoss\\ppybuild.grp\r\nunit\\protoss\\ppyshad.grp\r\nunit\\protoss\\prism.grp\r\nunit\\protoss\\prism.lof\r\nunit\\protoss\\probe.grp\r\nunit\\protoss\\probuild.grp\r\nunit\\protoss\\proshad.grp\r\nunit\\protoss\\psgbuild.grp\r\nunit\\protoss\\psgglow.grp\r\nunit\\protoss\\psgshad.grp\r\nunit\\protoss\\pstbuild.grp\r\nunit\\protoss\\pstshad.grp\r\nunit\\protoss\\pteshad.grp\r\nunit\\protoss\\ptrshad.grp\r\nunit\\protoss\\pwabuild.grp\r\nunit\\protoss\\pwashad.grp\r\nunit\\protoss\\pwgshad.grp\r\nunit\\protoss\\pxtshad.grp\r\nunit\\protoss\\pylon.grp\r\nunit\\protoss\\pylon.lof\r\nunit\\protoss\\pzeshad.grp\r\nunit\\protoss\\robotic.grp\r\nunit\\protoss\\robotic.lof\r\nunit\\protoss\\sapper.grp\r\nunit\\protoss\\sbattery.grp\r\nunit\\protoss\\sbattery.lof\r\nunit\\protoss\\scout.grp\r\nunit\\protoss\\shuttle.grp\r\nunit\\protoss\\sshield.los\r\nunit\\protoss\\stargate.grp\r\nunit\\protoss\\stargate.lof\r\nunit\\protoss\\stasis.grp\r\nunit\\protoss\\stasis.lof\r\nunit\\protoss\\templar.grp\r\nunit\\protoss\\texture.grp\r\nunit\\protoss\\trilob.grp\r\nunit\\protoss\\warp.grp\r\nunit\\protoss\\warp.lof\r\nunit\\protoss\\witness.grp\r\nunit\\protoss\\xeltempl.grp\r\nunit\\protoss\\xwarpfir.grp\r\nunit\\protoss\\xwarpgat.grp\r\nunit\\protoss\\zealot.grp\r\nunit\\temp.txt\r\nunit\\terran\\academy.grp\r\nunit\\terran\\academy.lof\r\nunit\\terran\\academyt.grp\r\nunit\\terran\\battlecr.grp\r\nunit\\terran\\battlecr.lol\r\nunit\\terran\\battlecr.lox\r\nunit\\terran\\bomber.grp\r\nunit\\terran\\chemlab.grp\r\nunit\\terran\\chemlab.lof\r\nunit\\terran\\chemlabt.grp\r\nunit\\terran\\comsat.grp\r\nunit\\terran\\comsat.lof\r\nunit\\terran\\comsatc.grp\r\nunit\\terran\\comsatt.grp\r\nunit\\terran\\control.grp\r\nunit\\terran\\control.lod\r\nunit\\terran\\control.lof\r\nunit\\terran\\control.lou\r\nunit\\terran\\controlt.grp\r\nunit\\terran\\depot.grp\r\nunit\\terran\\depot.lof\r\nunit\\terran\\depott.grp\r\nunit\\terran\\dropship.grp\r\nunit\\terran\\dropship.lod\r\nunit\\terran\\dropship.lou\r\nunit\\terran\\drydockc.grp\r\nunit\\terran\\drydocks.grp\r\nunit\\terran\\drydocks.lof\r\nunit\\terran\\drydockt.grp\r\nunit\\terran\\factory.grp\r\nunit\\terran\\factory.lod\r\nunit\\terran\\factory.lof\r\nunit\\terran\\factory.lou\r\nunit\\terran\\factoryt.grp\r\nunit\\terran\\firebat.grp\r\nunit\\terran\\genelab.grp\r\nunit\\terran\\genelab.lof\r\nunit\\terran\\genelabc.grp\r\nunit\\terran\\genelabt.grp\r\nunit\\terran\\ghost.grp\r\nunit\\terran\\goliath.grp\r\nunit\\terran\\goliath.lol\r\nunit\\terran\\goliatht.grp\r\nunit\\terran\\lowm\\dropship.grp\r\nunit\\terran\\lowm\\phoenix.grp\r\nunit\\terran\\machinec.grp\r\nunit\\terran\\machines.grp\r\nunit\\terran\\machines.lof\r\nunit\\terran\\marine.grp\r\nunit\\terran\\medic.grp\r\nunit\\terran\\missile.grp\r\nunit\\terran\\missile.lof\r\nunit\\terran\\missilet.grp\r\nunit\\terran\\nukemiss.grp\r\nunit\\terran\\nukesilc.grp\r\nunit\\terran\\nukesilo.grp\r\nunit\\terran\\nukesilo.lof\r\nunit\\terran\\nukesilt.grp\r\nunit\\terran\\phoenix.grp\r\nunit\\terran\\phoenix.lol\r\nunit\\terran\\physics.grp\r\nunit\\terran\\physics.lof\r\nunit\\terran\\physicsc.grp\r\nunit\\terran\\pillbox.grp\r\nunit\\terran\\pillbox.loa\r\nunit\\terran\\pillbox.lof\r\nunit\\terran\\pillboxt.grp\r\nunit\\terran\\power.grp\r\nunit\\terran\\power.lof\r\nunit\\terran\\refinery.grp\r\nunit\\terran\\refinery.lof\r\nunit\\terran\\refinery.los\r\nunit\\terran\\research.grp\r\nunit\\terran\\research.lod\r\nunit\\terran\\research.lof\r\nunit\\terran\\research.lou\r\nunit\\terran\\researct.grp\r\nunit\\terran\\scv.grp\r\nunit\\terran\\scv.loo\r\nunit\\terran\\spider.grp\r\nunit\\terran\\stank.grp\r\nunit\\terran\\stank.lol\r\nunit\\terran\\stankt.grp\r\nunit\\terran\\stankt.loa\r\nunit\\terran\\starport.grp\r\nunit\\terran\\starport.lod\r\nunit\\terran\\starport.lof\r\nunit\\terran\\starport.lou\r\nunit\\terran\\starpot.grp\r\nunit\\terran\\tacshad.grp\r\nunit\\terran\\tank.grp\r\nunit\\terran\\tank.lol\r\nunit\\terran\\tankt.grp\r\nunit\\terran\\tb1shad.grp\r\nunit\\terran\\tb2shad.grp\r\nunit\\terran\\tb3shad.grp\r\nunit\\terran\\tbarrack.grp\r\nunit\\terran\\tbarrack.lod\r\nunit\\terran\\tbarrack.lof\r\nunit\\terran\\tbarrack.lou\r\nunit\\terran\\tbldlrg.grp\r\nunit\\terran\\tbldmed.grp\r\nunit\\terran\\tbldsml.grp\r\nunit\\terran\\tbrshad.grp\r\nunit\\terran\\tccshad.grp\r\nunit\\terran\\tcirglow.grp\r\nunit\\terran\\tclshad.grp\r\nunit\\terran\\tcsshad.grp\r\nunit\\terran\\tddshad.grp\r\nunit\\terran\\tdeshad.grp\r\nunit\\terran\\tfashad.grp\r\nunit\\terran\\tfbshad.grp\r\nunit\\terran\\tghdeath.grp\r\nunit\\terran\\tghshad.grp\r\nunit\\terran\\tglshad.grp\r\nunit\\terran\\tgoshad.grp\r\nunit\\terran\\tmadeath.grp\r\nunit\\terran\\tmarker.grp\r\nunit\\terran\\tmashad.grp\r\nunit\\terran\\tmedeath.grp\r\nunit\\terran\\tmeshad.grp\r\nunit\\terran\\tmishad.grp\r\nunit\\terran\\tmsshad.grp\r\nunit\\terran\\tnsshad.grp\r\nunit\\terran\\tpbshad.grp\r\nunit\\terran\\tpgshad.grp\r\nunit\\terran\\tphcloak.grp\r\nunit\\terran\\tplshad.grp\r\nunit\\terran\\treshad.grp\r\nunit\\terran\\trlshad.grp\r\nunit\\terran\\tsmshad.grp\r\nunit\\terran\\tspshad.grp\r\nunit\\terran\\tstshad.grp\r\nunit\\terran\\ttashad.grp\r\nunit\\terran\\tveshad.grp\r\nunit\\terran\\twpshad.grp\r\nunit\\terran\\ughost.grp\r\nunit\\terran\\ughshad.grp\r\nunit\\terran\\vulture.grp\r\nunit\\terran\\weaponpl.grp\r\nunit\\terran\\weaponpl.lod\r\nunit\\terran\\weaponpl.lof\r\nunit\\terran\\weaponpl.lou\r\nunit\\terran\\weaponpt.grp\r\nunit\\terran\\wessel.grp\r\nunit\\terran\\wessel.lod\r\nunit\\terran\\wessel.lol\r\nunit\\terran\\wessel.lou\r\nunit\\terran\\wesselt.grp\r\nunit\\thingy\\bblood01.grp\r\nunit\\thingy\\bblood02.grp\r\nunit\\thingy\\bblood03.grp\r\nunit\\thingy\\bblood04.grp\r\nunit\\thingy\\bdust.grp\r\nunit\\thingy\\bfirec.grp\r\nunit\\thingy\\bfiref.grp\r\nunit\\thingy\\bfirev.grp\r\nunit\\thingy\\blackx.grp\r\nunit\\thingy\\blood01.grp\r\nunit\\thingy\\blood02.grp\r\nunit\\thingy\\bsmoke.grp\r\nunit\\thingy\\circleb.grp\r\nunit\\thingy\\circleg.grp\r\nunit\\thingy\\circleo.grp\r\nunit\\thingy\\circlew.grp\r\nunit\\thingy\\consume.grp\r\nunit\\thingy\\dbl_exp.grp\r\nunit\\thingy\\disrupt.grp\r\nunit\\thingy\\dswarm.grp\r\nunit\\thingy\\dust01.grp\r\nunit\\thingy\\dust02.grp\r\nunit\\thingy\\dust03.grp\r\nunit\\thingy\\dust04.grp\r\nunit\\thingy\\dust05.grp\r\nunit\\thingy\\dust06.grp\r\nunit\\thingy\\dust07.grp\r\nunit\\thingy\\dust08.grp\r\nunit\\thingy\\dust09.grp\r\nunit\\thingy\\ebbcloud.grp\r\nunit\\thingy\\ebbhitl.grp\r\nunit\\thingy\\ebbhitm.grp\r\nunit\\thingy\\ebbhits.grp\r\nunit\\thingy\\ecahit.grp\r\nunit\\thingy\\edmbackl.grp\r\nunit\\thingy\\edmbackm.grp\r\nunit\\thingy\\edmbacks.grp\r\nunit\\thingy\\edmfronl.grp\r\nunit\\thingy\\edmfronm.grp\r\nunit\\thingy\\edmfrons.grp\r\nunit\\thingy\\edmhitl.grp\r\nunit\\thingy\\edmhitm.grp\r\nunit\\thingy\\edmhits.grp\r\nunit\\thingy\\efghit.grp\r\nunit\\thingy\\ehalarge.grp\r\nunit\\thingy\\ehamed.grp\r\nunit\\thingy\\ehasmall.grp\r\nunit\\thingy\\elbbat.grp\r\nunit\\thingy\\elbfire.grp\r\nunit\\thingy\\elbfirec.grp\r\nunit\\thingy\\elbfirew.grp\r\nunit\\thingy\\elbhit.grp\r\nunit\\thingy\\elbmuzz.grp\r\nunit\\thingy\\eldfire.grp\r\nunit\\thingy\\eldlarge.grp\r\nunit\\thingy\\eldmed.grp\r\nunit\\thingy\\eldsmall.grp\r\nunit\\thingy\\elect02.grp\r\nunit\\thingy\\elect02a.grp\r\nunit\\thingy\\emp.grp\r\nunit\\thingy\\empl.grp\r\nunit\\thingy\\emsbeam.grp\r\nunit\\thingy\\emshit.grp\r\nunit\\thingy\\ensgool.grp\r\nunit\\thingy\\ensgoom.grp\r\nunit\\thingy\\ensgoos.grp\r\nunit\\thingy\\ensnare.grp\r\nunit\\thingy\\ep2fire.grp\r\nunit\\thingy\\ep3burst.grp\r\nunit\\thingy\\ep3shot.grp\r\nunit\\thingy\\epgfire.grp\r\nunit\\thingy\\eplmuzz.grp\r\nunit\\thingy\\eradlrg.grp\r\nunit\\thingy\\eradmed.grp\r\nunit\\thingy\\eradsml.grp\r\nunit\\thingy\\esfhit.grp\r\nunit\\thingy\\esflarge.grp\r\nunit\\thingy\\esfmed.grp\r\nunit\\thingy\\esfsmall.grp\r\nunit\\thingy\\esifire.grp\r\nunit\\thingy\\etghit.grp\r\nunit\\thingy\\ettflash.grp\r\nunit\\thingy\\evecast.grp\r\nunit\\thingy\\explo2.grp\r\nunit\\thingy\\explode.grp\r\nunit\\thingy\\explodlt.grp\r\nunit\\thingy\\eycblast.grp\r\nunit\\thingy\\eychit.grp\r\nunit\\thingy\\flamer.grp\r\nunit\\thingy\\geysmok1.grp\r\nunit\\thingy\\geysmok2.grp\r\nunit\\thingy\\geysmok3.grp\r\nunit\\thingy\\geysmok4.grp\r\nunit\\thingy\\geysmok5.grp\r\nunit\\thingy\\geysmos1.grp\r\nunit\\thingy\\geysmos2.grp\r\nunit\\thingy\\geysmos3.grp\r\nunit\\thingy\\geysmos4.grp\r\nunit\\thingy\\geysmos5.grp\r\nunit\\thingy\\gresmoke.grp\r\nunit\\thingy\\gsmoke.grp\r\nunit\\thingy\\halmind.grp\r\nunit\\thingy\\hkexplod.grp\r\nunit\\thingy\\hktrail.grp\r\nunit\\thingy\\juice01.grp\r\nunit\\thingy\\juice02.grp\r\nunit\\thingy\\large.grp\r\nunit\\thingy\\largex.lox\r\nunit\\thingy\\lowm\\bblood01.grp\r\nunit\\thingy\\lowm\\bblood02.grp\r\nunit\\thingy\\lowm\\bblood03.grp\r\nunit\\thingy\\lowm\\bblood04.grp\r\nunit\\thingy\\lowm\\consume.grp\r\nunit\\thingy\\lowm\\disrupt.grp\r\nunit\\thingy\\lowm\\dswarm.grp\r\nunit\\thingy\\lowm\\dust01.grp\r\nunit\\thingy\\lowm\\dust02.grp\r\nunit\\thingy\\lowm\\dust03.grp\r\nunit\\thingy\\lowm\\dust04.grp\r\nunit\\thingy\\lowm\\dust05.grp\r\nunit\\thingy\\lowm\\dust06.grp\r\nunit\\thingy\\lowm\\dust07.grp\r\nunit\\thingy\\lowm\\dust08.grp\r\nunit\\thingy\\lowm\\dust09.grp\r\nunit\\thingy\\lowm\\ebbcloud.grp\r\nunit\\thingy\\lowm\\ecahit.grp\r\nunit\\thingy\\lowm\\efghit.grp\r\nunit\\thingy\\lowm\\ehamed.grp\r\nunit\\thingy\\lowm\\elbbat.grp\r\nunit\\thingy\\lowm\\elbmuzz.grp\r\nunit\\thingy\\lowm\\eldlarge.grp\r\nunit\\thingy\\lowm\\eldmed.grp\r\nunit\\thingy\\lowm\\eldsmall.grp\r\nunit\\thingy\\lowm\\emsbeam.grp\r\nunit\\thingy\\lowm\\emshit.grp\r\nunit\\thingy\\lowm\\ensnare.grp\r\nunit\\thingy\\lowm\\ep3burst.grp\r\nunit\\thingy\\lowm\\eplmuzz.grp\r\nunit\\thingy\\lowm\\esfhit.grp\r\nunit\\thingy\\lowm\\esflarge.grp\r\nunit\\thingy\\lowm\\esfsmall.grp\r\nunit\\thingy\\lowm\\esifire.grp\r\nunit\\thingy\\lowm\\etghit.grp\r\nunit\\thingy\\lowm\\eycblast.grp\r\nunit\\thingy\\lowm\\eychit.grp\r\nunit\\thingy\\lowm\\hkexplod.grp\r\nunit\\thingy\\lowm\\nukehit.grp\r\nunit\\thingy\\lowm\\ofirec.grp\r\nunit\\thingy\\lowm\\ofiref.grp\r\nunit\\thingy\\lowm\\ofirev.grp\r\nunit\\thingy\\lowm\\pabglow.grp\r\nunit\\thingy\\lowm\\pscglow.grp\r\nunit\\thingy\\lowm\\pshglow.grp\r\nunit\\thingy\\lowm\\recall.grp\r\nunit\\thingy\\lowm\\tbangl.grp\r\nunit\\thingy\\lowm\\tbangs.grp\r\nunit\\thingy\\lowm\\tbangx.grp\r\nunit\\thingy\\lowm\\tdrglow.grp\r\nunit\\thingy\\lowm\\temp.txt\r\nunit\\thingy\\lowm\\tphglow.grp\r\nunit\\thingy\\lowm\\zblddths.grp\r\nunit\\thingy\\maelhit.grp\r\nunit\\thingy\\med1.grp\r\nunit\\thingy\\med2.grp\r\nunit\\thingy\\mediumx.lox\r\nunit\\thingy\\mushroom.grp\r\nunit\\thingy\\nukebeam.grp\r\nunit\\thingy\\nukehit.grp\r\nunit\\thingy\\nuketarg.grp\r\nunit\\thingy\\o022.grp\r\nunit\\thingy\\o032.grp\r\nunit\\thingy\\o048.grp\r\nunit\\thingy\\o062.grp\r\nunit\\thingy\\o072.grp\r\nunit\\thingy\\o094.grp\r\nunit\\thingy\\o110.grp\r\nunit\\thingy\\o122.grp\r\nunit\\thingy\\o146.grp\r\nunit\\thingy\\o224.grp\r\nunit\\thingy\\od022.grp\r\nunit\\thingy\\od032.grp\r\nunit\\thingy\\od048.grp\r\nunit\\thingy\\od062.grp\r\nunit\\thingy\\od072.grp\r\nunit\\thingy\\od094.grp\r\nunit\\thingy\\od110.grp\r\nunit\\thingy\\od122.grp\r\nunit\\thingy\\od146.grp\r\nunit\\thingy\\od224.grp\r\nunit\\thingy\\ofirec.grp\r\nunit\\thingy\\ofiref.grp\r\nunit\\thingy\\ofirev.grp\r\nunit\\thingy\\pabglow.grp\r\nunit\\thingy\\pbangl.grp\r\nunit\\thingy\\pbangs.grp\r\nunit\\thingy\\pbangx.grp\r\nunit\\thingy\\pcaglow.grp\r\nunit\\thingy\\pcsglow.grp\r\nunit\\thingy\\pcssplsh.grp\r\nunit\\thingy\\pdamndlg.grp\r\nunit\\thingy\\pdamndmd.grp\r\nunit\\thingy\\pdamndsm.grp\r\nunit\\thingy\\pdamyolg.grp\r\nunit\\thingy\\pdamyomd.grp\r\nunit\\thingy\\pdamyosm.grp\r\nunit\\thingy\\pdaparlg.grp\r\nunit\\thingy\\pdaparmd.grp\r\nunit\\thingy\\pdaparsm.grp\r\nunit\\thingy\\pdapsylg.grp\r\nunit\\thingy\\pdapsymd.grp\r\nunit\\thingy\\pdapsysm.grp\r\nunit\\thingy\\pexplode.grp\r\nunit\\thingy\\phohit.grp\r\nunit\\thingy\\plasdrip.grp\r\nunit\\thingy\\plasma.grp\r\nunit\\thingy\\prubblel.grp\r\nunit\\thingy\\prubbles.grp\r\nunit\\thingy\\psaexplo.grp\r\nunit\\thingy\\pscglow.grp\r\nunit\\thingy\\pshglow.grp\r\nunit\\thingy\\pshield.grp\r\nunit\\thingy\\psiimpac.grp\r\nunit\\thingy\\psistorm.grp\r\nunit\\thingy\\pteglow.grp\r\nunit\\thingy\\recall.grp\r\nunit\\thingy\\rubblel.grp\r\nunit\\thingy\\rubbles.grp\r\nunit\\thingy\\sbalarge.grp\r\nunit\\thingy\\sbasmall.grp\r\nunit\\thingy\\small.grp\r\nunit\\thingy\\smallx.lox\r\nunit\\thingy\\smoke.grp\r\nunit\\thingy\\spooge.grp\r\nunit\\thingy\\sporehit.grp\r\nunit\\thingy\\spotrail.grp\r\nunit\\thingy\\startloc.grp\r\nunit\\thingy\\tbaglow.grp\r\nunit\\thingy\\tbangl.grp\r\nunit\\thingy\\tbangs.grp\r\nunit\\thingy\\tbangx.grp\r\nunit\\thingy\\tbmafter.grp\r\nunit\\thingy\\tbmglow.grp\r\nunit\\thingy\\tcurelrg.grp\r\nunit\\thingy\\tcuremed.grp\r\nunit\\thingy\\tcuresml.grp\r\nunit\\thingy\\tdrglow.grp\r\nunit\\thingy\\temp.yxy\r\nunit\\thingy\\tileset\\ashworld\\hasroc01.grp\r\nunit\\thingy\\tileset\\ashworld\\hasroc02.grp\r\nunit\\thingy\\tileset\\ashworld\\hasroc03.grp\r\nunit\\thingy\\tileset\\ashworld\\hasroc04.grp\r\nunit\\thingy\\tileset\\ashworld\\hasroc05.grp\r\nunit\\thingy\\tileset\\ashworld\\hasroc06.grp\r\nunit\\thingy\\tileset\\ashworld\\lalroc01.grp\r\nunit\\thingy\\tileset\\ashworld\\lalroc02.grp\r\nunit\\thingy\\tileset\\ashworld\\rock01.grp\r\nunit\\thingy\\tileset\\ashworld\\rock02.grp\r\nunit\\thingy\\tileset\\ashworld\\rock03.grp\r\nunit\\thingy\\tileset\\ashworld\\rock04.grp\r\nunit\\thingy\\tileset\\ashworld\\rock05.grp\r\nunit\\thingy\\tileset\\ashworld\\rock1sha.grp\r\nunit\\thingy\\tileset\\ashworld\\rock2sha.grp\r\nunit\\thingy\\tileset\\ashworld\\rock3sha.grp\r\nunit\\thingy\\tileset\\ashworld\\rock4sha.grp\r\nunit\\thingy\\tileset\\ashworld\\rock5sha.grp\r\nunit\\thingy\\tileset\\ashworld\\rorock01.grp\r\nunit\\thingy\\tileset\\ashworld\\rorock02.grp\r\nunit\\thingy\\tileset\\ashworld\\rorock03.grp\r\nunit\\thingy\\tileset\\badlands\\cbattle.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock01.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock02.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock03.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock04.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock05.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock06.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock07.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock08.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock1s.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock2s.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock3s.grp\r\nunit\\thingy\\tileset\\badlands\\hdrock4s.grp\r\nunit\\thingy\\tileset\\badlands\\hdtree01.grp\r\nunit\\thingy\\tileset\\badlands\\hdtree02.grp\r\nunit\\thingy\\tileset\\badlands\\hdtree03.grp\r\nunit\\thingy\\tileset\\badlands\\hdtree04.grp\r\nunit\\thingy\\tileset\\badlands\\hdvent01.grp\r\nunit\\thingy\\tileset\\badlands\\hgtree01.grp\r\nunit\\thingy\\tileset\\badlands\\khyad01.grp\r\nunit\\thingy\\tileset\\badlands\\khyad02.grp\r\nunit\\thingy\\tileset\\badlands\\khyad03.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop01.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop02.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop03.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop04.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop05.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop06.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop07.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop08.grp\r\nunit\\thingy\\tileset\\badlands\\lcshop09.grp\r\nunit\\thingy\\tileset\\badlands\\lcshopaa.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign01.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign02.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign03.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign04.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign05.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign06.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign07.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign08.grp\r\nunit\\thingy\\tileset\\badlands\\lcsign09.grp\r\nunit\\thingy\\tileset\\badlands\\lcsignaa.grp\r\nunit\\thingy\\tileset\\badlands\\lcsignbb.grp\r\nunit\\thingy\\tileset\\badlands\\lcsigncc.grp\r\nunit\\thingy\\tileset\\badlands\\ldtree1s.grp\r\nunit\\thingy\\tileset\\badlands\\ldtree2s.grp\r\nunit\\thingy\\tileset\\badlands\\ldtree3s.grp\r\nunit\\thingy\\tileset\\badlands\\ldtree4s.grp\r\nunit\\thingy\\tileset\\badlands\\stasis.grp\r\nunit\\thingy\\tileset\\badlands\\temple.grp\r\nunit\\thingy\\tileset\\desert\\hdbant.grp\r\nunit\\thingy\\tileset\\desert\\hdbbroke.grp\r\nunit\\thingy\\tileset\\desert\\hdbgas.grp\r\nunit\\thingy\\tileset\\desert\\hdbmed.grp\r\nunit\\thingy\\tileset\\desert\\hdbmoss.grp\r\nunit\\thingy\\tileset\\desert\\hdbtent.grp\r\nunit\\thingy\\tileset\\desert\\hdlbox01.grp\r\nunit\\thingy\\tileset\\desert\\hdmachn2.grp\r\nunit\\thingy\\tileset\\desert\\hdplnt03.grp\r\nunit\\thingy\\tileset\\desert\\jgbcomm.grp\r\nunit\\thingy\\tileset\\desert\\jgbfact.grp\r\nunit\\thingy\\tileset\\desert\\jgbgas.grp\r\nunit\\thingy\\tileset\\desert\\jgbgen.grp\r\nunit\\thingy\\tileset\\desert\\jgbred.grp\r\nunit\\thingy\\tileset\\desert\\jgbroke.grp\r\nunit\\thingy\\tileset\\desert\\jgbsgn.grp\r\nunit\\thingy\\tileset\\desert\\jgbtent.grp\r\nunit\\thingy\\tileset\\desert\\jgplnt01.grp\r\nunit\\thingy\\tileset\\desert\\jgplnt02.grp\r\nunit\\thingy\\tileset\\desert\\ldbaz.grp\r\nunit\\thingy\\tileset\\desert\\ldbgas.grp\r\nunit\\thingy\\tileset\\desert\\ldbgren.grp\r\nunit\\thingy\\tileset\\desert\\ldbneon.grp\r\nunit\\thingy\\tileset\\desert\\ldbsuky.grp\r\nunit\\thingy\\tileset\\desert\\ldbtent.grp\r\nunit\\thingy\\tileset\\desert\\ldlbox01.grp\r\nunit\\thingy\\tileset\\desert\\ldmachn1.grp\r\nunit\\thingy\\tileset\\desert\\ldneon.grp\r\nunit\\thingy\\tileset\\desert\\ldplnt04.grp\r\nunit\\thingy\\tileset\\desert\\sarlacc.grp\r\nunit\\thingy\\tileset\\desert\\shdbbrke.grp\r\nunit\\thingy\\tileset\\desert\\shdbgas.grp\r\nunit\\thingy\\tileset\\desert\\shdbmed.grp\r\nunit\\thingy\\tileset\\desert\\shdbmoss.grp\r\nunit\\thingy\\tileset\\desert\\shdbtent.grp\r\nunit\\thingy\\tileset\\desert\\shdlbox1.grp\r\nunit\\thingy\\tileset\\desert\\shdplnt3.grp\r\nunit\\thingy\\tileset\\desert\\sjgbcomm.grp\r\nunit\\thingy\\tileset\\desert\\sjgbfact.grp\r\nunit\\thingy\\tileset\\desert\\sjgbgas.grp\r\nunit\\thingy\\tileset\\desert\\sjgbgen.grp\r\nunit\\thingy\\tileset\\desert\\sjgbred.grp\r\nunit\\thingy\\tileset\\desert\\sjgbroke.grp\r\nunit\\thingy\\tileset\\desert\\sjgbsgn.grp\r\nunit\\thingy\\tileset\\desert\\sjgbtent.grp\r\nunit\\thingy\\tileset\\desert\\sjgplnt2.grp\r\nunit\\thingy\\tileset\\desert\\sldbaz.grp\r\nunit\\thingy\\tileset\\desert\\sldbgas.grp\r\nunit\\thingy\\tileset\\desert\\sldbgren.grp\r\nunit\\thingy\\tileset\\desert\\sldbsuky.grp\r\nunit\\thingy\\tileset\\desert\\sldbtent.grp\r\nunit\\thingy\\tileset\\desert\\sldlbox1.grp\r\nunit\\thingy\\tileset\\desert\\sldmchn1.grp\r\nunit\\thingy\\tileset\\desert\\sldplnt4.grp\r\nunit\\thingy\\tileset\\desert\\tgas.grp\r\nunit\\thingy\\tileset\\ice\\hdbld01.grp\r\nunit\\thingy\\tileset\\ice\\hdbld02.grp\r\nunit\\thingy\\tileset\\ice\\hdbld03.grp\r\nunit\\thingy\\tileset\\ice\\hdbld04.grp\r\nunit\\thingy\\tileset\\ice\\hdpipes.grp\r\nunit\\thingy\\tileset\\ice\\hdradarl.grp\r\nunit\\thingy\\tileset\\ice\\hdradarr.grp\r\nunit\\thingy\\tileset\\ice\\hdradr02.grp\r\nunit\\thingy\\tileset\\ice\\hdrock01.grp\r\nunit\\thingy\\tileset\\ice\\hdrock02.grp\r\nunit\\thingy\\tileset\\ice\\hdspire.grp\r\nunit\\thingy\\tileset\\ice\\hdstre01.grp\r\nunit\\thingy\\tileset\\ice\\hdstre02.grp\r\nunit\\thingy\\tileset\\ice\\hdstre03.grp\r\nunit\\thingy\\tileset\\ice\\hdstre04.grp\r\nunit\\thingy\\tileset\\ice\\hdtwr01.grp\r\nunit\\thingy\\tileset\\ice\\hdtwr02.grp\r\nunit\\thingy\\tileset\\ice\\jgant1.grp\r\nunit\\thingy\\tileset\\ice\\ldbld01.grp\r\nunit\\thingy\\tileset\\ice\\ldbld02.grp\r\nunit\\thingy\\tileset\\ice\\ldbtre01.grp\r\nunit\\thingy\\tileset\\ice\\ldbtre02.grp\r\nunit\\thingy\\tileset\\ice\\ldbtre03.grp\r\nunit\\thingy\\tileset\\ice\\ldbtre04.grp\r\nunit\\thingy\\tileset\\ice\\ldcomm.grp\r\nunit\\thingy\\tileset\\ice\\lddish.grp\r\nunit\\thingy\\tileset\\ice\\lddtre01.grp\r\nunit\\thingy\\tileset\\ice\\lddtre02.grp\r\nunit\\thingy\\tileset\\ice\\ldrck01.grp\r\nunit\\thingy\\tileset\\ice\\ldrck02.grp\r\nunit\\thingy\\tileset\\ice\\ldrdr01.grp\r\nunit\\thingy\\tileset\\ice\\ldrdr02.grp\r\nunit\\thingy\\tileset\\ice\\ldrdr03.grp\r\nunit\\thingy\\tileset\\ice\\ldsmrock.grp\r\nunit\\thingy\\tileset\\ice\\ldthing.grp\r\nunit\\thingy\\tileset\\ice\\rjbtree1.grp\r\nunit\\thingy\\tileset\\ice\\rjbtree2.grp\r\nunit\\thingy\\tileset\\ice\\rjbtree3.grp\r\nunit\\thingy\\tileset\\ice\\rjbtree4.grp\r\nunit\\thingy\\tileset\\ice\\shdbld01.grp\r\nunit\\thingy\\tileset\\ice\\shdbld02.grp\r\nunit\\thingy\\tileset\\ice\\shdbld03.grp\r\nunit\\thingy\\tileset\\ice\\shdbld04.grp\r\nunit\\thingy\\tileset\\ice\\shdpipes.grp\r\nunit\\thingy\\tileset\\ice\\shdradr2.grp\r\nunit\\thingy\\tileset\\ice\\shdradrl.grp\r\nunit\\thingy\\tileset\\ice\\shdradrr.grp\r\nunit\\thingy\\tileset\\ice\\shdrck01.grp\r\nunit\\thingy\\tileset\\ice\\shdrck02.grp\r\nunit\\thingy\\tileset\\ice\\shdspire.grp\r\nunit\\thingy\\tileset\\ice\\shdtwr01.grp\r\nunit\\thingy\\tileset\\ice\\shdtwr02.grp\r\nunit\\thingy\\tileset\\ice\\sldbld01.grp\r\nunit\\thingy\\tileset\\ice\\sldbld02.grp\r\nunit\\thingy\\tileset\\ice\\sldbtre1.grp\r\nunit\\thingy\\tileset\\ice\\sldbtre2.grp\r\nunit\\thingy\\tileset\\ice\\sldbtre3.grp\r\nunit\\thingy\\tileset\\ice\\sldbtre4.grp\r\nunit\\thingy\\tileset\\ice\\sldcomm.grp\r\nunit\\thingy\\tileset\\ice\\slddish.grp\r\nunit\\thingy\\tileset\\ice\\slddtre1.grp\r\nunit\\thingy\\tileset\\ice\\slddtre2.grp\r\nunit\\thingy\\tileset\\ice\\sldrck01.grp\r\nunit\\thingy\\tileset\\ice\\sldrck02.grp\r\nunit\\thingy\\tileset\\ice\\sldrdr01.grp\r\nunit\\thingy\\tileset\\ice\\sldrdr02.grp\r\nunit\\thingy\\tileset\\ice\\sldrdr03.grp\r\nunit\\thingy\\tileset\\ice\\sldsmrck.grp\r\nunit\\thingy\\tileset\\ice\\sldthing.grp\r\nunit\\thingy\\tileset\\ice\\srjbtre1.grp\r\nunit\\thingy\\tileset\\ice\\srjbtre2.grp\r\nunit\\thingy\\tileset\\ice\\srjbtre3.grp\r\nunit\\thingy\\tileset\\ice\\srjbtre4.grp\r\nunit\\thingy\\tileset\\install\\clplat1t.grp\r\nunit\\thingy\\tileset\\install\\clplate1.grp\r\nunit\\thingy\\tileset\\install\\clplate2.grp\r\nunit\\thingy\\tileset\\install\\crdoor1.grp\r\nunit\\thingy\\tileset\\install\\dcfan1.grp\r\nunit\\thingy\\tileset\\install\\dcfan2.grp\r\nunit\\thingy\\tileset\\install\\dcgun1.grp\r\nunit\\thingy\\tileset\\install\\dcgun2.grp\r\nunit\\thingy\\tileset\\install\\dcgun2.loa\r\nunit\\thingy\\tileset\\install\\dicran1.grp\r\nunit\\thingy\\tileset\\install\\dicran2.grp\r\nunit\\thingy\\tileset\\install\\dicran3.grp\r\nunit\\thingy\\tileset\\install\\dicran4.grp\r\nunit\\thingy\\tileset\\install\\didoor1.grp\r\nunit\\thingy\\tileset\\install\\digear1.grp\r\nunit\\thingy\\tileset\\install\\digear2.grp\r\nunit\\thingy\\tileset\\install\\dihatc1.grp\r\nunit\\thingy\\tileset\\jungle\\dd025.grp\r\nunit\\thingy\\tileset\\jungle\\dd026.grp\r\nunit\\thingy\\tileset\\jungle\\dd027.grp\r\nunit\\thingy\\tileset\\jungle\\dd028.grp\r\nunit\\thingy\\tileset\\jungle\\dd029.grp\r\nunit\\thingy\\tileset\\jungle\\dd030.grp\r\nunit\\thingy\\tileset\\jungle\\dd031.grp\r\nunit\\thingy\\tileset\\jungle\\dd055.grp\r\nunit\\thingy\\tileset\\jungle\\dd056.grp\r\nunit\\thingy\\tileset\\jungle\\dd075.grp\r\nunit\\thingy\\tileset\\jungle\\dd076.grp\r\nunit\\thingy\\tileset\\jungle\\dd077.grp\r\nunit\\thingy\\tileset\\jungle\\dd078.grp\r\nunit\\thingy\\tileset\\jungle\\dd079.grp\r\nunit\\thingy\\tileset\\jungle\\dd080.grp\r\nunit\\thingy\\tileset\\jungle\\dd081.grp\r\nunit\\thingy\\tileset\\jungle\\dd091.grp\r\nunit\\thingy\\tileset\\jungle\\dd203.grp\r\nunit\\thingy\\tileset\\jungle\\dd204.grp\r\nunit\\thingy\\tileset\\jungle\\dd205.grp\r\nunit\\thingy\\tileset\\jungle\\dd206.grp\r\nunit\\thingy\\tileset\\jungle\\dd207.grp\r\nunit\\thingy\\tileset\\jungle\\dd209.grp\r\nunit\\thingy\\tileset\\jungle\\dd210.grp\r\nunit\\thingy\\tileset\\jungle\\dd211.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock01.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock02.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock03.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock04.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock1s.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock2s.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock3s.grp\r\nunit\\thingy\\tileset\\jungle\\hdrock4s.grp\r\nunit\\thingy\\tileset\\jungle\\jubush01.grp\r\nunit\\thingy\\tileset\\jungle\\jubush03.grp\r\nunit\\thingy\\tileset\\jungle\\jubush05.grp\r\nunit\\thingy\\tileset\\jungle\\jubush1s.grp\r\nunit\\thingy\\tileset\\jungle\\jubush3s.grp\r\nunit\\thingy\\tileset\\jungle\\jubush5s.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree01.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree02.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree03.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree04.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree1s.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree2s.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree3s.grp\r\nunit\\thingy\\tileset\\jungle\\ldtree4s.grp\r\nunit\\thingy\\tileset\\jungle\\tree01.grp\r\nunit\\thingy\\tileset\\jungle\\tree02.grp\r\nunit\\thingy\\tileset\\jungle\\tree03.grp\r\nunit\\thingy\\tileset\\jungle\\tree04.grp\r\nunit\\thingy\\tileset\\jungle\\tree1sha.grp\r\nunit\\thingy\\tileset\\jungle\\tree2sha.grp\r\nunit\\thingy\\tileset\\jungle\\tree3sha.grp\r\nunit\\thingy\\tileset\\jungle\\tree4sha.grp\r\nunit\\thingy\\tileset\\platform\\dish01.grp\r\nunit\\thingy\\tileset\\platform\\dish02.grp\r\nunit\\thingy\\tileset\\platform\\dish03.grp\r\nunit\\thingy\\tileset\\platform\\dish1sha.grp\r\nunit\\thingy\\tileset\\platform\\dish2sha.grp\r\nunit\\thingy\\tileset\\platform\\dish3sha.grp\r\nunit\\thingy\\tileset\\platform\\glob01.grp\r\nunit\\thingy\\tileset\\platform\\glob02.grp\r\nunit\\thingy\\tileset\\platform\\glob03.grp\r\nunit\\thingy\\tileset\\platform\\glob1sha.grp\r\nunit\\thingy\\tileset\\platform\\glob2sha.grp\r\nunit\\thingy\\tileset\\platform\\glob3sha.grp\r\nunit\\thingy\\tileset\\platform\\lbsign01.grp\r\nunit\\thingy\\tileset\\platform\\lbsign02.grp\r\nunit\\thingy\\tileset\\platform\\lbsign03.grp\r\nunit\\thingy\\tileset\\platform\\lbsign04.grp\r\nunit\\thingy\\tileset\\platform\\lbsign05.grp\r\nunit\\thingy\\tileset\\platform\\lbsign06.grp\r\nunit\\thingy\\tileset\\platform\\lbsign07.grp\r\nunit\\thingy\\tileset\\platform\\lbsign08.grp\r\nunit\\thingy\\tileset\\platform\\refinery.grp\r\nunit\\thingy\\tileset\\platform\\spthin01.grp\r\nunit\\thingy\\tileset\\platform\\towr01.grp\r\nunit\\thingy\\tileset\\platform\\towr02.grp\r\nunit\\thingy\\tileset\\platform\\tree01.grp\r\nunit\\thingy\\tileset\\platform\\tree02.grp\r\nunit\\thingy\\tileset\\twilight\\jtree01.grp\r\nunit\\thingy\\tileset\\twilight\\jtree02.grp\r\nunit\\thingy\\tileset\\twilight\\jtree03.grp\r\nunit\\thingy\\tileset\\twilight\\jtree04.grp\r\nunit\\thingy\\tileset\\twilight\\jtree05.grp\r\nunit\\thingy\\tileset\\twilight\\ldarch.grp\r\nunit\\thingy\\tileset\\twilight\\lddrill.grp\r\nunit\\thingy\\tileset\\twilight\\ldxel01.grp\r\nunit\\thingy\\tileset\\twilight\\ldxel02.grp\r\nunit\\thingy\\tileset\\twilight\\ldxel03.grp\r\nunit\\thingy\\tileset\\twilight\\ldxel04.grp\r\nunit\\thingy\\tileset\\twilight\\ldxel05.grp\r\nunit\\thingy\\tileset\\twilight\\ldxel06.grp\r\nunit\\thingy\\tileset\\twilight\\ldxeltur.grp\r\nunit\\thingy\\tileset\\twilight\\rstatue.grp\r\nunit\\thingy\\tmeflshl.grp\r\nunit\\thingy\\tmeflshm.grp\r\nunit\\thingy\\tmeflshs.grp\r\nunit\\thingy\\tmeheall.grp\r\nunit\\thingy\\tmehealm.grp\r\nunit\\thingy\\tmeheals.grp\r\nunit\\thingy\\tmnexplo.grp\r\nunit\\thingy\\tphglow.grp\r\nunit\\thingy\\tscglow.grp\r\nunit\\thingy\\tveglowb.grp\r\nunit\\thingy\\tveglowo.grp\r\nunit\\thingy\\tvegloww.grp\r\nunit\\thingy\\zairdthl.grp\r\nunit\\thingy\\zairdths.grp\r\nunit\\thingy\\zbgexplo.grp\r\nunit\\thingy\\zblddthl.grp\r\nunit\\thingy\\zblddths.grp\r\nunit\\thingy\\zdvbirth.grp\r\nunit\\thingy\\zdvgool.grp\r\nunit\\thingy\\zdvgoom.grp\r\nunit\\thingy\\zdvgoos.grp\r\nunit\\thingy\\zdvhit.grp\r\nunit\\thingy\\zdvpuke.grp\r\nunit\\thingy\\zrubblel.grp\r\nunit\\thingy\\zrubbles.grp\r\nunit\\unit\\thingy\\PRubbleL.grp\r\nunit\\unit\\thingy\\PRubbleS.grp\r\nunit\\unit\\thingy\\tBangL.grp\r\nunit\\unit\\thingy\\tBangS.grp\r\nunit\\unit\\thingy\\tBangX.grp\r\nunit\\wirefram\\grpwire.grp\r\nunit\\wirefram\\tranwire.grp\r\nunit\\wirefram\\wirefram.grp\r\nunit\\zerg\\avenger.grp\r\nunit\\zerg\\brood.grp\r\nunit\\zerg\\bugguy.grp\r\nunit\\zerg\\cerebrat.grp\r\nunit\\zerg\\cerebrat.lof\r\nunit\\zerg\\chrysal.grp\r\nunit\\zerg\\chrysal.lof\r\nunit\\zerg\\cocoon.grp\r\nunit\\zerg\\cocoon.lob\r\nunit\\zerg\\defiler.grp\r\nunit\\zerg\\defiler.log\r\nunit\\zerg\\devour.grp\r\nunit\\zerg\\drone.grp\r\nunit\\zerg\\drone.log\r\nunit\\zerg\\drone.loo\r\nunit\\zerg\\egg.grp\r\nunit\\zerg\\extract.grp\r\nunit\\zerg\\extract.lof\r\nunit\\zerg\\extract.los\r\nunit\\zerg\\fcolony.grp\r\nunit\\zerg\\fcolony.lof\r\nunit\\zerg\\guardian.grp\r\nunit\\zerg\\guardian.log\r\nunit\\zerg\\hatchery.grp\r\nunit\\zerg\\hatchery.lof\r\nunit\\zerg\\hive.grp\r\nunit\\zerg\\hive.lof\r\nunit\\zerg\\hydra.grp\r\nunit\\zerg\\hydra.log\r\nunit\\zerg\\infest01.grp\r\nunit\\zerg\\infest02.grp\r\nunit\\zerg\\infest03.grp\r\nunit\\zerg\\lair.grp\r\nunit\\zerg\\lair.lof\r\nunit\\zerg\\larva.grp\r\nunit\\zerg\\lowm\\overlord.grp\r\nunit\\zerg\\lurkburr.grp\r\nunit\\zerg\\lurkegg.grp\r\nunit\\zerg\\lurker.grp\r\nunit\\zerg\\lurker.lof\r\nunit\\zerg\\lurknorm.grp\r\nunit\\zerg\\mutacham.grp\r\nunit\\zerg\\mutacham.lof\r\nunit\\zerg\\mutalid.grp\r\nunit\\zerg\\mutalid.log\r\nunit\\zerg\\mutapit.grp\r\nunit\\zerg\\mutapit.lof\r\nunit\\zerg\\mutate.grp\r\nunit\\zerg\\nest.grp\r\nunit\\zerg\\nest.lof\r\nunit\\zerg\\nyduspit.grp\r\nunit\\zerg\\nyduspit.lof\r\nunit\\zerg\\over1.grp\r\nunit\\zerg\\over1.lof\r\nunit\\zerg\\over2.grp\r\nunit\\zerg\\over2.lof\r\nunit\\zerg\\overlord.grp\r\nunit\\zerg\\queen.grp\r\nunit\\zerg\\rcluster.grp\r\nunit\\zerg\\rcluster.lof\r\nunit\\zerg\\scolony.grp\r\nunit\\zerg\\scolony.lof\r\nunit\\zerg\\snakey.grp\r\nunit\\zerg\\snakey.lof\r\nunit\\zerg\\spire.grp\r\nunit\\zerg\\spire.lof\r\nunit\\zerg\\ucereb.grp\r\nunit\\zerg\\ucereb.lof\r\nunit\\zerg\\uikerr.grp\r\nunit\\zerg\\uikshad.grp\r\nunit\\zerg\\ultra.grp\r\nunit\\zerg\\xovermnd.grp\r\nunit\\zerg\\zavbirth.grp\r\nunit\\zerg\\zavbirth.lob\r\nunit\\zerg\\zavdeath.grp\r\nunit\\zerg\\zavexplo.grp\r\nunit\\zerg\\zbgshad.grp\r\nunit\\zerg\\zbrdeath.grp\r\nunit\\zerg\\zbrshad.grp\r\nunit\\zerg\\zbshad.grp\r\nunit\\zerg\\zbuild.grp\r\nunit\\zerg\\zceshad.grp\r\nunit\\zerg\\zchshad.grp\r\nunit\\zerg\\zcirglow.grp\r\nunit\\zerg\\zdebirth.grp\r\nunit\\zerg\\zdedeath.grp\r\nunit\\zerg\\zdrbirth.grp\r\nunit\\zerg\\zdrdeath.grp\r\nunit\\zerg\\zDvbirth.grp\r\nunit\\zerg\\zdvdeath.grp\r\nunit\\zerg\\zegdeath.grp\r\nunit\\zerg\\zegshad.grp\r\nunit\\zerg\\zegspawn.grp\r\nunit\\zerg\\zergling.grp\r\nunit\\zerg\\zfcshad.grp\r\nunit\\zerg\\zgudeath.grp\r\nunit\\zerg\\zhashad.grp\r\nunit\\zerg\\zhishad.grp\r\nunit\\zerg\\zhybirth.grp\r\nunit\\zerg\\zhydeath.grp\r\nunit\\zerg\\zhyshad.grp\r\nunit\\zerg\\zladeath.grp\r\nunit\\zerg\\zlrshad.grp\r\nunit\\zerg\\zlubirth.grp\r\nunit\\zerg\\zlubshad.grp\r\nunit\\zerg\\zludeath.grp\r\nunit\\zerg\\zlurker.grp\r\nunit\\zerg\\zlurshad.grp\r\nunit\\zerg\\zlushad.grp\r\nunit\\zerg\\zmarker.grp\r\nunit\\zerg\\zmcshad.grp\r\nunit\\zerg\\zmhshad.grp\r\nunit\\zerg\\zmubirth.grp\r\nunit\\zerg\\zmudeath.grp\r\nunit\\zerg\\zneshad.grp\r\nunit\\zerg\\znyshad.grp\r\nunit\\zerg\\zo1shad.grp\r\nunit\\zerg\\zo2shad.grp\r\nunit\\zerg\\zovbirth.grp\r\nunit\\zerg\\zovdeath.grp\r\nunit\\zerg\\zovshad.grp\r\nunit\\zerg\\zqubirth.grp\r\nunit\\zerg\\zqudeath.grp\r\nunit\\zerg\\zrcshad.grp\r\nunit\\zerg\\zreshad.grp\r\nunit\\zerg\\zsbshad.grp\r\nunit\\zerg\\zscshad.grp\r\nunit\\zerg\\zspawn01.grp\r\nunit\\zerg\\zspawn02.grp\r\nunit\\zerg\\zspawn03.grp\r\nunit\\zerg\\zspshad.grp\r\nunit\\zerg\\zucshad.grp\r\nunit\\zerg\\zulbirth.grp\r\nunit\\zerg\\zuldeath.grp\r\nunit\\zerg\\zulshad.grp\r\nunit\\zerg\\zzebirth.grp\r\nunit\\zerg\\zzebirth.lob\r\nunit\\zerg\\zzedeath.grp\r\nunit\\zerg\\zzeshad.grp\r\nunit\\zerg\\zzlushad.grp\r\nunits.dat\r\nupdate.txt\r\nupgrades.dat\r\nv105\\battle.snp\r\nv105\\bnupdate.exe\r\nv105\\bw\\patch_rt.mpq\r\nv105\\bw\\starcraft.exe\r\nv105\\patch.txt\r\nv105\\patch_rt.mpq\r\nv105\\seditdeu.loc\r\nv105\\seditenu.loc\r\nv105\\seditesp.loc\r\nv105\\seditfra.loc\r\nv105\\seditita.loc\r\nv105\\seditptb.loc\r\nv105\\standard.snp\r\nv105\\starcraft.exe\r\nv105\\staredit.exe\r\nv105\\storm.dll\r\nvidsize.exe\r\nweapons.dat\r\nzerg.grp\r\n"
  },
  {
    "path": "release.py",
    "content": "#!/usr/bin/env ruby\n\nimport atexit\nimport os\nimport pprint\nimport sys\n\n\nSTRINGS = {\n  \"version\": \"3.3.0\",\n  \"homepage\": \"https://github.com/wargus/stargus\",\n  \"license\": \"GPL v2\",\n  \"copyright\": \"(c) 2002-2022 by the Stratagus Project\",\n}\n\n\nFILES = [\n    \"src/startool.h\",\n    \"stargus.rc\",\n    \"stargus.nsi\",\n    \"mac/Info.plist\",\n    \"scripts/stratagus.lua\",\n    \"debian/copyright\",\n    __file__\n]\n\n\nupdates = []\n\n\nfor arg in sys.argv[1:]:\n    if arg.startswith(\"--\"):\n      updates.append(arg.replace(\"--\", \"\"))\n    else:\n      updates[-1] = (updates[-1], arg)\n\n\nupdates = dict(updates)\n\n\nif not updates:\n  print('You can update the following STRINGS by passing --key \"new-value\"')\n  pprint.pprint(STRINGS)\n  exit()\n\n\nif updates.get(\"version\"):\n  STRINGS[\"viversion\"] = STRINGS[\"version\"].replace(\".\", \",\")\n  updates[\"viversion\"] = updates[\"version\"].replace(\".\", \",\")\n\n\nfor filename in FILES:\n    with open(filename, \"r\") as f:\n        content = f.read()\n    for k,v in updates.items():\n        content = content.replace(STRINGS[k], v)\n    with open(filename, \"w\") as f:\n        f.write(content)\n\n\nif updates.get(\"version\"):\n    cmds = [\n        f'dch -v{updates[\"version\"]}-1',\n        \"gbp dch\",\n        \"dch -r\",\n        \"git add --patch\",\n        f'git commit -m \"Release {updates[\"version\"]}\"',\n        f'git tag v{updates[\"version\"]}'\n    ]\n    idx = 0\n\n    @atexit.register\n    def atexit_func():\n        if idx < len(cmds):\n            print(\"Not running the following commands:\", \"\\n\".join(cmds[idx:]))\n\n    for cmd in cmds:\n        print(f\"Running {cmd} (abort by interrupting the process)\")\n        input()\n        os.system(cmd)\n        idx += 1\n"
  },
  {
    "path": "scripts/RapidStratagusIDE/RSI_Functions.lua",
    "content": "function RSI_MapStarter()\n  mapname = \"maps/\\(2\\)Space Madness.smp\"\n  Load(mapname)\n  RunMap(mapname)\nend\n\nfunction RSI_MapConfiguration()\n  init_x = 40\n  init_y = 40\n  initPos = {init_x, init_y}\n  \n  SetStartView(0, init_x, init_y)\n  \n  Load(\"rsi_testscenario/rsi_configuration.lua\")\n  \n  if (_G[\"RSI_tc_run\"] ~= nil) then\n    RSI_tc_run(initPos)\n  else\n    print(\"RapidStratagusIDE->RSI_tc_run() not available\") \n  end\n\n  -- on screen\n  SetFogOfWar(false)\n  RevealMap(\"explored\")\nend\n\n"
  },
  {
    "path": "scripts/ai/terran.lua",
    "content": "InitFuncs:add(function()\n  ai_terran_func = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}\nend)\n\nlocal terran_funcs = {\n  function() return AiSleep(AiGetSleepCycles()) end,\n  \n--cheat a little\n  function() return SetPlayerData(GetThisPlayer(), \"Resources\", \"minerals\", 50000) end,\n  function() return SetPlayerData(GetThisPlayer(), \"Resources\", \"gas\", 50000) end,\n  \n--start of game/building stage\n  function() return AiNeed(\"unit-terran-command-center\") end,\n  function() return AiWait(\"unit-terran-command-center\") end,\n\n  function() return AiSet(\"unit-terran-scv\", 7) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n  function() return AiNeed(\"unit-terran-barracks\") end,\n  function() return AiWait(\"unit-terran-barracks\") end,\n\n  function() return AiSet(\"unit-terran-scv\", 8) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n  function() return AiWait(\"unit-terran-supply-depot\") end,\n\n\n--rush\n--rush force is #4\n  function() return AiForce(4, {\"unit-terran-marine\", 4}) end,\n  function() return AiWaitForce(4) end,\n  function() return AiAttackWithForce(4) end,\n\n  function() return AiNeed(\"unit-terran-refinery\") end,\n  function() return AiWait(\"unit-terran-refinery\") end,\n\n  function() return AiSet(\"unit-terran-scv\", 10) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n--base defence force is #1\n  function() return AiForce(1, {\"unit-terran-marine\", 2}) end,\n  function() return AiWaitForce(1) end,\n\n  function() return AiSet(\"unit-terran-scv\", 11) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n  function() return AiForce(1, {\"unit-terran-marine\", 3}) end,\n  function() return AiWaitForce(1) end,\n\n  function() return AiSet(\"unit-terran-scv\", 12) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n  function() return AiWait(\"unit-terran-supply-depot\") end,\n\n  function() return AiForce(1, {\"unit-terran-marine\", 4}) end,\n  function() return AiWaitForce(1) end,\n\n  function() return AiSet(\"unit-terran-scv\", 13) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n  function() return AiForce(1, {\"unit-terran-marine\", 5}) end,\n  function() return AiWaitForce(1) end,\n\n  function() return AiSet(\"unit-terran-scv\", 14) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n  function() return AiNeed(\"unit-terran-bunker\") end,\n  function() return AiWait(\"unit-terran-bunker\") end,\n\n  function() return AiSet(\"unit-terran-scv\", 15) end,\n  function() return AiWait(\"unit-terran-scv\") end,\n\n  function() return AiNeed(\"unit-terran-barracks\") end,\n  function() return AiWait(\"unit-terran-barracks\") end,\n\n  function() return AiForce(1, {\"unit-terran-marine\", 6}) end,\n  function() return AiWaitForce(1) end,\n\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n  function() return AiWait(\"unit-terran-supply-depot\") end,\n\n  function() return AiForce(1, {\"unit-terran-marine\", 7}) end,\n  function() return AiWaitForce(1) end,\n\n  function() return AiNeed(\"unit-terran-refinery\") end,\n  function() return AiWait(\"unit-terran-refinery\") end,\n\n  function() return AiForce(1, {\"unit-terran-marine\", 8}) end,\n  function() return AiWaitForce(1) end,\n\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n  function() return AiWait(\"unit-terran-supply-depot\") end,\n\n  function() return AiNeed(\"unit-terran-academy\") end,\n  function() return AiWait(\"unit-terran-academy\") end,\n  \n  function() return AiForce(1, {\"unit-terran-firebat\", 2}) end,\n  function() return AiForceRole(1, \"defend\") end,\n\n  function() return AiNeed(\"unit-terran-factory\") end,\n  function() return AiWait(\"unit-terran-factory\") end,\n\n  function() return AiNeed(\"unit-terran-barracks\") end,\n  function() return AiWait(\"unit-terran-barracks\") end,\n\n--end of building stage\n--war stage\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n  function() return AiWait(\"unit-terran-supply-depot\") end,\n\n--first attack force is #2\n  function() return AiForce(2, {\"unit-terran-marine\", 10}) end,\n\n  function() return AiForce(2, {\"unit-terran-vulture\", 3}) end,\n\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n  function() return AiWait(\"unit-terran-supply-depot\") end,\n\n  function() return AiForce(2, {\"unit-terran-siege-tank\", 2}) end,\n\n  function() return AiForce(2, {\"unit-terran-firebat\", 5}) end,\n\n  function() return AiForce(2, {\"unit-terran-goliath\", 5}) end,\n  function() return AiWait(\"unit-terran-goliath\") end,\n  function() return AiWaitForce(2) end,\n\n--ATTACK!!!!!\n  function() return AiAttackWithForce(2) end,\n\n-- start new base\n  function() return AiNeed(\"unit-terran-command-center\") end,\n  function() return AiWait(\"unit-terran-command-center\") end,\n\n  function() return AiNeed(\"unit-terran-refinery\") end,\n  function() return AiWait(\"unit-terran-refinery\") end,\n\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n  function() return AiWait(\"unit-terran-supply-depot\") end,\n  \n  function() return AiNeed(\"unit-terran-starport\") end,\n  function() return AiWait(\"unit-terran-starport\") end,\n\n--next attack force #5 (bigger) \n-- :)\n  function() return AiForce(5, {\"unit-terran-wraith\", 3}) end,\n\n  function() return AiForce(5, {\"unit-terran-marine\", 12}) end,\n\n  function() return AiForce(5, {\"unit-terran-vulture\", 5}) end,\n\n  function() return AiNeed(\"unit-terran-supply-depot\") end,\n\n  function() return AiForce(5, {\"unit-terran-siege-tank\", 4}) end,\n\n  function() return AiForce(5, {\"unit-terran-firebat\", 7}) end,\n\n  function() return AiForce(5, {\"unit-terran-goliath\", 7}) end,\n\n  function() return AiWaitForce(5) end,\n  \n--attack with #5\n  function() return AiAttackWithForce(5) end,\n\n  function() return true end,\n}\n\nfunction AiTerran()\n  local ret\n  local player\n\n  player = AiPlayer() + 1\n\n  while (true) do\n    ret = terran_funcs[ai_terran_func[player]]()\n    if (ret) then\n      break\n    end\n    ai_terran_func[player] = ai_terran_func[player] + 1\n  end\nend\n\n\nDefineAi(\"terran-ai\", \"*\", \"terran-ai\", AiTerran)\n\n"
  },
  {
    "path": "scripts/ai/zerg.lua",
    "content": " \nInitFuncs:add(function()\n  ai_zerg_func = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}\nend)\n\nlocal zerg_funcs = {\n  function() return AiSleep(AiGetSleepCycles()) end,\n  \n--cheat a little\n  function() return SetPlayerData(GetThisPlayer(), \"Resources\", \"minerals\", 50000) end,\n  function() return SetPlayerData(GetThisPlayer(), \"Resources\", \"gas\", 50000) end,\n  \n--get started\n  function() return AiNeed(\"unit-zerg-hatchery\") end,\n  function() return AiWait(\"unit-zerg-hatchery\") end,\n\n  function() return AiSet(\"unit-zerg-overlord\", 1) end,\n  function() return AiWait(\"unit-zerg-overlord\") end,\n\n  function() return AiSet(\"unit-zerg-drone\", 7) end,\n  function() return AiWait(\"unit-zerg-drone\") end,\n \n  function() return AiNeed(\"unit-zerg-spawning-pool\") end,\n  function() return AiWait(\"unit-zerg-spawning-pool\") end,\n  \n-- Rush with 4 zerglings\n  function() return AiForce(4, {\"unit-zerg-zergling\", 4}) end,\n  function() return AiWaitForce(4) end,\n  function() return AiAttackWithForce(4) end,\n  \n--Get the basics of a common zerg base\n  function() return AiNeed(\"unit-zerg-extractor\") end,\n  function() return AiWait(\"unit-zerg-extractor\") end,\n  \n\n  function() return AiNeed(\"unit-zerg-hydralisk-den\") end,\n  function() return AiWait(\"unit-zerg-hydralisk-den\") end,\n  \n  function() return AiSet(\"unit-zerg-overlord\", 2) end,\n  function() return AiWait(\"unit-zerg-overlord\") end,\n  \n  function() return AiSet(\"unit-zerg-drone\", 15) end,\n  function() return AiWait(\"unit-zerg-drone\") end,\n  \n  function() return AiSet(\"unit-zerg-overlord\", 4) end,\n  function() return AiWait(\"unit-zerg-overlord\") end,\n  \n--Mid game rush (hydralisk + zerglings)\n  function() return AiForce(5, {\"unit-zerg-hydralisk\", 4}) end,\n\n  function() return AiForce(5, {\"unit-zerg-zergling\", 4}) end,\n  function() return AiWaitForce(5) end,\n  function() return AiAttackWithForce(5) end,\n  \n--Prepare for massing + setting up a defence\n  function() return AiSet(\"unit-zerg-overlord\", 5) end,\n  function() return AiWait(\"unit-zerg-overlord\") end,\n\n  function() return AiNeed(\"unit-zerg-hatchery\") end,\n  function() return AiNeed(\"unit-zerg-evolution-chamber\") end,\n  function() return AiWait(\"unit-zerg-evolution-chamber\") end,\n  \n--Build a defence (sunkens + spore colonies)\n  function() return AiSet(\"unit-zerg-creep-colony\", 4) end,\n  function() return AiWait(\"unit-zerg-creep-colony\") end,\n  function() return AiUpgradeTo(\"unit-zerg-sunken-colony\") end,\n  function() return AiUpgradeTo(\"unit-zerg-spore-colony\") end,\n  \n--Upgrade Hatchery to lair\n  function() return AiUpgradeTo(\"unit-zerg-lair\") end,\n\n--Build a mobile defence\n  function() return AiForce(6, {\"unit-zerg-hydralisk\", 4}) end,\n  function() return AiForceRole(6, {\"defend\"}) end,\n\n--Build an army\n  function() return AiForce(7, {\"unit-zerg-hydralisk\", 4}) end,\n  function() return AiForce(7, {\"unit-zerg-zergling\", 4}) end,\n  function() return AiForce(7, {\"unit-zerg-ultralisk\", 4}) end,\n  function() return AiForce(7, {\"unit-zerg-mutalisk\", 4}) end,\n  function() return AiForce(7, {\"unit-zerg-overlord\", 2}) end, --Need to detect cloaked enemy units + for transporting\n  function() return AiWaitForce(7) end,\n  \n--Attack with force\n  function() return AiAttackWithForce(7) end,\n\n--Morph Lair to hive\n  function() return AiUpgradeTo(\"unit-zerg-hive\") end,\n  \n  function() return AiNeed(\"unit-zerg-ultralisk-cavern\") end,\n  function() return AiWait(\"unit-zerg-ultralisk-cavern\") end,\n  \n  function() return true end,\n}\n\nfunction AiZerg()\n  local ret\n  local player\n\n  player = AiPlayer() + 1\n\n  while (true) do\n    ret = zerg_funcs[ai_zerg_func[player]]()\n    if (ret) then\n      break\n    end\n    ai_zerg_func[player] = ai_zerg_func[player] + 1\n  end\nend\n\n\nDefineAi(\"zerg-ai\", \"*\", \"zerg-ai\", AiZerg)\n\n"
  },
  {
    "path": "scripts/ai.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      ai.lua - Define the AI.\n--\n--      (c) Copyright 2007-2013 by Jimmy Salmon, and Joris Dauphin\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nrace1 = \"terran\"\nrace2 = \"zerg\"\nrace3 = \"neutral\"\nrace4 = \"protoss\"\n\n--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n--  * Race terran.\n--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\nDefineAiHelper()\n\n--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n--  * Race Zerg.\n--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\nDefineAiHelper()\n\nLoad(\"scripts/ai/terran.lua\")\nLoad(\"scripts/ai/zerg.lua\")\n\nfunction AiPassive()\nend\n\nDefineAi(\"ai-passive\", \"*\", \"ai-passive\", AiPassive)\n"
  },
  {
    "path": "scripts/anim.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      anim.lua - The unit animation definitions.\n--\n--      (c) Copyright 2000-2005 by Josh Cogliati, Lutz Sammer,\n--                                 and Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nUnitStill = {\"frame 0\", \"wait 4\", \"random-goto 99 no-rotate\", \"random-rotate 1\", \"label no-rotate\", \"wait 1\",}\nBuildingStill = {\"frame 0\", \"wait 4\", \"frame 0\", \"wait 1\",}\n\nLoad(\"scripts/terran/anim.lua\")\nLoad(\"scripts/zerg/anim.lua\")\nLoad(\"scripts/neutral/anim.lua\")\n\nDefineAnimations(\"animations-daemon\", {\n  Still = {\"frame 0\", \"wait 4\", \"frame 5\", \"wait 4\", \"frame 10\", \"wait 4\",\n    \"frame 15\", \"wait 4\",},\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 5\", \"move 2\", \"wait 1\", \"frame 5\", \"move 3\", \"wait 1\",\n    \"frame 10\", \"move 2\", \"wait 1\", \"frame 10\", \"move 3\", \"wait 1\",\n    \"frame 10\", \"move 3\", \"wait 1\", \"frame 15\", \"move 2\", \"wait 1\",\n    \"frame 15\", \"move 3\", \"wait 1\", \"frame 20\", \"move 3\", \"wait 1\",\n    \"frame 20\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"frame 0\", \"wait 4\", \"frame 5\", \"wait 4\",\n    \"frame 10\", \"wait 4\", \"frame 15\", \"wait 4\", \"frame 20\", \"wait 4\",\n    \"frame 20\", \"wait 1\", \"frame 25\", \"wait 4\", \"frame 30\", \"wait 4\",\n    \"frame 35\", \"wait 4\", \"frame 40\", \"attack\", \"wait 4\",\n    \"frame 45\", \"wait 4\", \"frame 0\", \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"frame 50\", \"wait 5\", \"frame 55\", \"wait 5\", \"frame 60\", \"wait 5\",\n    \"frame 65\", \"wait 5\", \"frame 65\", \"unbreakable end\", \"wait 1\",},\n})\n\n\nDefineAnimations(\"animations-critter\", {\n  Still = {\"frame 0\", \"wait 4\", \"frame 0\", \"wait 1\",},\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 2\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"move 2\", \"wait 3\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"move 2\", \"wait 3\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"move 2\", \"wait 3\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"move 2\", \"wait 3\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"move 2\", \"wait 3\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"move 2\", \"wait 3\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"move 2\", \"wait 3\", \"frame 0\", \"move 2\", \"wait 3\",\n    \"frame 0\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"frame 0\", \"attack\", \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"frame 5\", \"wait 200\", \"frame 5\", \"unbreakable end\", \"wait 1\",},\n})\n\n\nDefineAnimations(\"animations-building\", {\n  Still = BuildingStill,\n  Research = BuildingStill,\n  Train = BuildingStill,\n  Upgrade = BuildingStill,\n})\n\n\nDefineAnimations(\"animations-dead-body\", {\n  Death = {\"unbreakable begin\", \"frame 5\", \"wait 200\", \"frame 10\", \"wait 200\", \"frame 15\", \"wait 200\",\n    \"frame 20\", \"wait 200\", \"frame 25\", \"wait 200\", \"frame 25\", \"unbreakable end\", \"wait 1\",},\n})\n\n\nDefineAnimations(\"animations-destroyed-place\", {\n  Death = {\"unbreakable begin\", \"frame 0\", \"wait 200\", \"frame 1\", \"wait 200\", \"frame 1\", \"unbreakable end\", \"wait 1\", },\n})\n\n"
  },
  {
    "path": "scripts/buttons.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      buttons.lua - Define the general unit-buttons.\n--\n--      (c) Copyright 2001-2004 by Vladi Belperchinov-Shabanski, Lutz Sammer,\n--                                 and Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\n-- Load the buttons of all races\n\n--Load(\"scripts/terran/buttons.lua\")\n\n------------------------------------------------------------------------------\n--  Define unit-button.\n--\n--  DefineButton( { Pos = n, Level = n, Icon = ident,\n--    Action = name, [Value = value,]\n--    [Allowed = check, [values,]]\n--    Key = key, Hint = hint, ForUnit = units)\n--\n\n-- general cancel button ------------------------------------------------------\n\nDefineButton( { Pos = 9, Level = 9, Icon = \"icon-cancel\",\n  Action = \"cancel\",\n  Key = \"\\27\", Hint = \"~<ESC~> CANCEL\",\n  ForUnit = {\"*\"} } )\n\nDefineButton( { Pos = 9, Level = 0, Icon = \"icon-cancel\",\n  Action = \"cancel-upgrade\",\n  Key = \"\\27\", Hint = \"~<ESC~> CANCEL UPGRADE\",\n  ForUnit = {\"cancel-upgrade\"} } )\n\nDefineButton( { Pos = 9, Level = 0, Icon = \"icon-cancel\",\n  Action = \"cancel-train-unit\",\n  Key = \"\\27\", Hint = \"~<ESC~> CANCEL UNIT TRAINING\",\n  ForUnit = {\"*\"} } )\n\nDefineButton( { Pos = 9, Level = 0, Icon = \"icon-cancel\",\n  Action = \"cancel-build\",\n  Key = \"\\27\", Hint = \"~<ESC~> CANCEL CONSTRUCTION\",\n  ForUnit = {\"cancel-build\"} } )\n"
  },
  {
    "path": "scripts/campaigns.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      campaigns.lua - Define the used campaigns.\n--\n--      (c) Copyright 2002-2004 by Lutz Sammer and Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\n--=============================================================================\n--  Define all campaigns.\n\nDefineCampaign(\"human\", \"name\", \"~!Human campaign\",\n  \"file\", \"scripts/human/campaign1.lua\")\nDefineCampaign(\"orc\", \"name\", \"~!Orc campaign\",\n  \"file\", \"scripts/orc/campaign1.lua\")\nif (expansion) then\n  DefineCampaign(\"human-exp\", \"name\", \"H~!uman expansion levels\",\n    \"file\", \"scripts/human/campaign2.lua\")\n  DefineCampaign(\"orc-exp\", \"name\", \"O~!rc expansion levels\",\n    \"file\", \"scripts/orc/campaign2.lua\")\nend\n"
  },
  {
    "path": "scripts/cheats.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      cheats.lua - Cheats\n--\n--      (c) Copyright 2001-2007 by Lutz Sammer and Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nspeedcheat = false\ngodcheat = false\n\nfunction HandleCheats(str)\n  local resources = { \"minerals\", \"gas\" }\n\n  if (str == \"show me the money\") then\n    AddMessage(\"Cheat Enabled\")\n    SetPlayerData(GetThisPlayer(), \"Resources\", \"minerals\",\n      GetPlayerData(GetThisPlayer(), \"Resources\", \"minerals\") + 10000)\n    SetPlayerData(GetThisPlayer(), \"Resources\", \"gas\",\n      GetPlayerData(GetThisPlayer(), \"Resources\", \"gas\") + 10000)\n\n  elseif (str == \"whats mine is mine\") then\n    AddMessage(\"Cheat Enabled\")\n    SetPlayerData(GetThisPlayer(), \"Resources\", \"minerals\",\n      GetPlayerData(GetThisPlayer(), \"Resources\", \"minerals\") + 10000)\n\n  elseif (str == \"breathe deep\") then\n    AddMessage(\"Cheat Enabled\")\n    SetPlayerData(GetThisPlayer(), \"Resources\", \"gas\",\n      GetPlayerData(GetThisPlayer(), \"Resources\", \"gas\") + 10000)\n\n  elseif (str == \"black sheep wall\") then\n    AddMessage(\"Cheat Enabled\")\n    SetFogOfWar(false)\n    RevealMap()\n\n  elseif (str == \"war aint what it used to be\") then\n    AddMessage(\"Cheat Enabled\")\n    SetFogOfWar(false)\n    \n  elseif (str == \"on screen\") then\n    SetFogOfWar(false)\n    RevealMap(\"explored\")\n\n  elseif (str == \"operation cwal\") then\n    if (speedcheat) then\n      speedcheat = false\n      AddMessage(\"Cheat Disabled\")\n      for i = 1,table.getn(resources) do\n        SetSpeedResourcesHarvest(resources[i], 1)\n        SetSpeedResourcesReturn(resources[i], 1)\n      end\n      SetSpeedBuild(1)\n      SetSpeedTrain(1)\n      SetSpeedUpgrade(1)\n      SetSpeedResearch(1)\n    else\n      speedcheat = true\n      AddMessage(\"Cheat Enabled\")\n      for i = 1,table.getn(resources) do\n        SetSpeedResourcesHarvest(resources[i], 10)\n        SetSpeedResourcesReturn(resources[i], 10)\n      end\n      SetSpeedBuild(10)\n      SetSpeedTrain(10)\n      SetSpeedUpgrade(10)\n      SetSpeedResearch(10)\n      for i = 1,table.getn(resources) do\n        SetPlayerData(GetThisPlayer(), \"Resources\", resources[i],\n          GetPlayerData(GetThisPlayer(), \"Resources\", resources[i]) + 32000)\n      end\n    end\n\n  elseif (str == \"there is no cow level\") then\n    AddMessage(\"Cheat Enabled\")\n    ActionVictory()\n\n  elseif (str == \"game over man\") then\n    AddMessage(\"Cheat Enabled\")\n    ActionDefeat()\n\n  elseif (str == \"power overwhelming\") then\n    if (godcheat) then\n      godcheat = false\n      SetGodMode(false)\n      AddMessage(\"Cheat Disabled\")\n    else\n      godcheat = true\n      SetGodMode(true)\n      AddMessage(\"Cheat Enabled\")\n    end\n  elseif (IsDebugEnabled) then\n    if (str == \"fast debug\") then\n      for i = 0,PlayerMax - 1 do\n        for j = 1,table.getn(resources) do\n        SetSpeedResourcesHarvest(i, resources[j], 1000)\n        SetSpeedResourcesReturn(i, resources[j], 1000)\n        end\n        SetSpeedBuild(i, 1000)\n        SetSpeedTrain(i, 1000)\n        SetSpeedUpgrade(i, 1000)\n        SetSpeedResearch(i, 1000)\n      end\n      AddMessage(\"FAST DEBUG SPEED\")\n\n    elseif (str == \"normal debug\") then\n      for i = 0,PlayerMax - 1 do\n        for j = 1,table.getn(resources) do\n        SetSpeedResourcesHarvest(i, resources[j], 100)\n        SetSpeedResourcesReturn(i, resources[j], 100)\n        end\n        SetSpeedBuild(i, 100)\n        SetSpeedTrain(i, 100)\n        SetSpeedUpgrade(i, 100)\n        SetSpeedResearch(i, 100)\n      end\n      AddMessage(\"NORMAL DEBUG SPEED\")\n\n    elseif (string.find(str, \".lua\")) then\n       if (string.find(str, \"watch \", 1, true) == 1) then\n          if GlobalWatches == nil then\n             GlobalWatches = {}\n             AddTrigger(\n                function()\n                   for fn,value in pairs(GlobalWatches) do\n                      local buf = LoadBuffer(\"scripts/\" .. fn)\n                      if value[1] ~= buf then\n                         -- file contents changed, load it\n                         AddMessage(fn .. \" contents changed, reloading\")\n                         value[1] = buf\n                         Load(\"scripts/\" .. fn, false)\n                         LoadDecorations();\n                         InitUserInterface();\n                         LoadUI(GetPlayerData(GetThisPlayer(), \"RaceName\"))\n                         return false\n                      end\n                   end\n                   return false\n                end,\n                function()\n                   return true\n                end\n             )\n          end\n          local filename = str:gsub(\"^watch \", \"\")\n          local buf = LoadBuffer(filename)\n          if buf then\n             AddMessage(\"Watching \" .. filename)\n             GlobalWatches[filename] = {buf}\n          else\n             AddMessage(\"Cannot read \" .. filename .. \", not watching\")\n          end\n       elseif (string.find(str, \"unwatch \", 1, true) == 1) then\n          if GlobalWatches then\n             local filename = str:gsub(\"^unwatch \", \"\")\n             AddMessage(\"Unwatching \" .. filename)\n             GlobalWatches[filename] = nil\n          end\n       else\n          AddMessage(\"Reloading \" .. str)\n          print(\"Force reloading by in-game console cmd \" .. str)\n          Load(\"scripts/\" .. str, false)\n          LoadDecorations();\n          InitUserInterface();\n          LoadUI(GetPlayerData(GetThisPlayer(), \"RaceName\"))\n       end\n    elseif (string.find(str, \"eval\") == 1) then\n      local code = str:gsub(\"^eval%s\", \"\")\n      AddMessage(\"Running: \" .. code)\n      print(\"Running by \\'eval\\' cmd: \" .. code)\n      local result = loadstring(\"return \" .. code)\n      result = result()\n      AddMessage(\" => \" .. tostring(result))\n      print(\" => \" .. tostring(result))\n    end\n  else\n    return false\n  end\n  return true\nend\n"
  },
  {
    "path": "scripts/commands.lua",
    "content": "function HandleIngameCommandKey(key, ctrl, alt, shift)\n  if ((key == \"h\" and (ctrl or alt)) or key == \"f1\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunHelpMenu()\n  elseif (key == \"f5\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunGameOptionsMenu()\n  elseif (key == \"f7\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunGameSoundOptionsMenu()\n  elseif (key == \"f8\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunPreferencesMenu()\n  elseif (key == \"f9\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunDiplomacyMenu()\n  elseif ((key == \"m\" and alt) or key == \"f10\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunGameMenu()\n  elseif ((key == \"s\" and alt) or key == \"f11\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunSaveMenu()\n  elseif ((key == \"l\" and alt) or key == \"f12\") then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunGameLoadGameMenu()\n  elseif (key == \"q\" and (ctrl or alt)) then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunQuitToMenuConfirmMenu()\n  elseif (key == \"r\" and (ctrl or alt)) then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunRestartConfirmMenu()\n  elseif (key == \"x\" and (ctrl or alt)) then\n    if (not IsNetworkGame()) then SetGamePaused(true) end\n    RunExitConfirmMenu()\n  else\n    return false\n  end\n  return true\nend\n\nHandleCommandKey = HandleIngameCommandKey\n"
  },
  {
    "path": "scripts/editor.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      editor.lua - Editor configuration and functions.\n--\n--      (c) Copyright 2005 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\n--\tSet which icons to display\nSetEditorSelectIcon(\"icon-stop\")\nSetEditorUnitsIcon(\"icon-terran-marine\")\n\n\n--\n--\teditor-unit-types a sorted list of unit-types for the editor.\n--\tFIXME: this is only a temporary hack, for better sorted units.\n--\nDefineEditorUnitTypes({\n  \"unit-resource-mineral-field\",\n  \"unit-resource-mineral-field-type-2\",\n  \"unit-resource-mineral-field-type-3\",\n  \"unit-resource-vespene-geyser\",\n\n  -- Terran\n  \"unit-terran-marine\",\n  \"unit-terran-ghost\",\n  \"unit-terran-vulture\",\n  \"unit-terran-goliath\",\n  \"unit-terran-siege-tank\",\n  \"unit-terran-scv\",\n  \"unit-terran-firebat\",\n  \"unit-terran-wraith\",\n  \"unit-terran-science-vessel\",\n  \"unit-terran-dropship\",\n  \"unit-terran-battlecruiser\",\n\n  \"unit-terran-command-center\",\n  \"unit-terran-supply-depot\",\n  \"unit-terran-refinery\",\n  \"unit-terran-barracks\",\n  \"unit-terran-academy\",\n  \"unit-terran-factory\",\n  \"unit-terran-starport\",\n  \"unit-terran-science-facility\",\n  \"unit-terran-engineering-bay\",\n  \"unit-terran-armory\",\n  \"unit-terran-missile-turret\",\n  \"unit-terran-bunker\",\n\n})\n"
  },
  {
    "path": "scripts/fonts.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\\n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/\n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      fonts.lua - Define the used fonts.\n--\n--      (c) Copyright 2004-2006 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--\n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--\n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nCFont:New(\"small\", CGraphic:New(\"ui/fonts/font8.png\", 8, 11))\nCFont:New(\"game\", CGraphic:New(\"ui/fonts/font10.png\",10, 13))\nCFont:New(\"large\", CGraphic:New(\"ui/fonts/font12.png\", 12, 12))\nCFont:New(\"small-title\", CGraphic:New(\"ui/fonts/font32.png\", 32, 35))\nCFont:New(\"large-title\", CGraphic:New(\"ui/fonts/font50.png\",52, 50))\n\nCFont:New(\"font8\", CGraphic:New(\"ui/fonts/font8.png\",8, 11))\nCFont:New(\"font10\", CGraphic:New(\"ui/fonts/font10.png\",10, 13))\nCFont:New(\"font12\", CGraphic:New(\"ui/fonts/font12.png\",12, 12))\nCFont:New(\"font14\", CGraphic:New(\"ui/fonts/font14.png\",15, 16))\nCFont:New(\"font16\", CGraphic:New(\"ui/fonts/font16.png\",17, 19))\nCFont:New(\"font16x\", CGraphic:New(\"ui/fonts/font16x.png\",25, 19))\nCFont:New(\"font32\", CGraphic:New(\"ui/fonts/font32.png\",32, 35))\nCFont:New(\"font50\", CGraphic:New(\"ui/fonts/font50.png\",52, 50))\n\n\n--\tFIXME: only yellow, white, and grey are correct.\n\nfunction DefineFontColor(id, t)\n  fc = CFontColor:New(id)\n  for i = 0,(table.getn(t) / 3 - 1) do\n    fc.Colors[i] = CColor(t[i * 3 + 1], t[i * 3 + 2], t[i * 3 + 3])\n  end\nend\n\n\nDefineFontColor(\"black\",\n  {    0,   0,   0,\t-- 0\n      40,  40,  60,\t-- 228\n      40,  40,  60,\t-- 228\n      40,  40,  60,\t-- 228\n      40,  40,  60,\t-- 228\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"red\",\n  {    0,   0,   0,\t-- 0\n     164,   0,   0,\t-- 208\n     124,   0,   0,\t-- 209\n      92,   4,   0,\t-- 210\n      68,   4,   0,\t-- 211\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"green\",\n  {    0,   0,   0,\t-- 0\n      44, 180, 148,\t-- 216\n      44, 180, 148,\t-- 216\n      44, 180, 148,\t-- 216\n      44, 180, 148,\t-- 216\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"yellow\",\n  {  252, 248, 240,\t-- 246\n     244, 224,  32,\t-- 200\n     208, 192,  28,\t-- 199\n     168, 140,  16,\t-- 197\n      92,  48,   0,\t-- 192\n       0,   0,   0,\t-- 239\n     108, 108, 108})\t-- 104\nDefineFontColor(\"blue\",\n  {    0,   0,   0,\t-- 0\n       0, 148, 252,\t-- 1\n       0, 148, 252,\t-- 1\n       0, 148, 252,\t-- 1\n       0, 148, 252,\t-- 1\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"magenta\",\n  {    0,   0,   0,\t-- 0\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"cyan\",\n  {    0,   0,   0,\t-- 0\n     248, 140, 140,\t-- 224\n     248, 140, 140,\t-- 224\n     248, 140, 140,\t-- 224\n     248, 140, 140,\t-- 224\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"white\",\n  {    0,   0,   0,\t-- 0\n     252, 248, 240,\t-- 246\n     252, 248, 240,\t-- 246\n     252, 248, 240,\t-- 246\n     108, 108, 108,\t-- 104\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"grey\",\n  {    0,   0,   0,\t-- 0\n     192, 192, 192,\t-- 111\n     180, 180, 180,\t-- 110\n     168, 168, 168,\t-- 109\n     108, 108, 108,\t-- 104\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"light-red\",\n  {    0,   0,   0,\t-- 0\n     164,   0,   0,\t-- 208\n     164,   0,   0,\t-- 208\n     164,   0,   0,\t-- 208\n     164,   0,   0,\t-- 208\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"light-green\",\n  {    0,   0,   0,\t-- 0\n      44, 250,  58,\t-- 216\n      44, 250,  58,\t-- 216\n      44, 250,  58,\t-- 216\n      44, 250,  58,\t-- 216\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"light-yellow\",\n  {  252, 248, 240,\t-- 246\n     244, 224,  32,\t-- 200\n     208, 192,  28,\t-- 199\n     168, 140,  16,\t-- 197\n      92,  48,   0,\t-- 192\n       0,   0,   0,\t-- 239\n     108, 108, 108})\t-- 104\nDefineFontColor(\"light-blue\",\n  {    0,   0,   0,\t-- 0\n       0, 148, 252,\t-- 1\n       0, 148, 252,\t-- 1\n       0, 148, 252,\t-- 1\n       0, 148, 252,\t-- 1\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"light-magenta\",\n  {    0,   0,   0,\t-- 0\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"light-cyan\",\n  {    0,   0,   0,\t-- 0\n     248, 140,  20,\t-- 224\n     248, 140,  20,\t-- 224\n     248, 140,  20,\t-- 224\n     248, 140,  20,\t-- 224\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"light-grey\",\n  {    0,   0,   0,\t-- 0\n     192, 192, 192,\t-- 111\n     180, 180, 180,\t-- 110\n     168, 168, 168,\t-- 109\n     108, 108, 108,\t-- 104\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\n\nDefineFontColor(\"violet\",\n  {    0,   0,   0,\t-- 0\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n     152,  72, 176,\t-- 220\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\nDefineFontColor(\"orange\",\n  {    0,   0,   0,\t-- 0\n     248, 140,  20,\t-- 224\n     248, 140,  20,\t-- 224\n     248, 140,  20,\t-- 224\n     248, 140,  20,\t-- 224\n       0,   0,   0,\t-- 239\n       0,   0,   0})\t-- 0\n"
  },
  {
    "path": "scripts/gameui.lua",
    "content": "--       _________ __                 __\n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\\n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/\n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      ui.lua - Define the terran user interface\n--\n--      (c) Copyright 2005-2007 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--\n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--\n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nfunction LoadUI(race)\n\n  local original_width = 640\n  local original_height = 480\n  local offx = 0\n  local offx_right = Video.Width - 235\n  local offy = Video.Height - original_height\n\n  UI.NormalFontColor = \"white\"\n  UI.ReverseFontColor = \"yellow\"\n\n  UI.Fillers:clear()\n\n  function AddFiller(file, x, y)\n    b = CFiller:new_local()\n    b.G = CGraphic:New(file)\n    b.X = x\n    b.Y = y\n    UI.Fillers:push_back(b)\n  end\n\n  if (race == \"terran\") then\n\n    local console_left = 275\n    local console_middle = 21\n    local console_right = 344\n\n    AddFiller(\"ui/tconsole_left.png\", 0, offy)\n\n    local middle_num = (Video.Width - console_left - console_right) / console_middle\n\n    for i=0,middle_num do\n      AddFiller(\"ui/tconsole_middle.png\", console_left + i*console_middle, offy)  \n    end\n    \n    AddFiller(\"ui/tconsole_right.png\", Video.Width - console_right, offy)\n\n    UI.DefaultUnitPortrait = \"unit-terran-command-center\"\n    \n  elseif (race == \"zerg\") then\n    \n    local console_left = 274\n    local console_middle = 7\n    local console_right = 359\n    \n    AddFiller(\"ui/zconsole_left.png\", 0, offy)\n\n    local middle_num = (Video.Width - console_left - console_right) / console_middle\n\n    for i=0,middle_num do\n      AddFiller(\"ui/zconsole_middle.png\", console_left + i*console_middle, offy)  \n    end\n    \n    AddFiller(\"ui/zconsole_right.png\", Video.Width - console_right, offy)\n    \n    UI.DefaultUnitPortrait = \"unit-zerg-hive\"\n    \n  else -- Protoss\n    local console_left = 227\n    local console_middle = 38\n    local console_right = 375\n    \n    AddFiller(\"ui/pconsole_left.png\", 0, offy)\n\n    local middle_num = (Video.Width - console_left - console_right) / console_middle\n\n    for i=0,middle_num do\n      AddFiller(\"ui/pconsole_middle.png\", console_left + i*console_middle, offy)  \n    end\n    \n    AddFiller(\"ui/pconsole_right.png\", Video.Width - console_right, offy)\n    \n    UI.DefaultUnitPortrait = \"unit-protoss-nexus\"\n    \n  end\n\n  UI.InfoPanel.X = offx + 168\n  UI.InfoPanel.Y = offy + 396\n\n  -- Units Portrait\n  b = CUIButton:new()\n  b.X = offx_right + 10\n  b.Y = offy + 411\n  b.Style = FindButtonStyle(\"icon\")\n  UI.SingleSelectedButton = b\n\n  UI.SelectedButtons:clear()\n\n  function AddSelectedButton(x, y)\n    b = CUIButton:new_local()\n    b.X = x\n    b.Y = y\n    b.Style = FindButtonStyle(\"icon\")\n    UI.SelectedButtons:push_back(b)\n  end\n\n  local selected_width = 36\n  local selected_height = 37\n  \n  -- offset for the action button group on the right side\n  local selected_offy = 396\n  local selected_offx = 168\n\n  local selected_box_num = (offx_right - selected_offx) / selected_width\n\n  -- those are the buttons for the selected units\n  for i=0,selected_box_num do\n    AddSelectedButton(offx + selected_offx + i*selected_width, offy + selected_offy + 0*selected_height)\n    AddSelectedButton(offx + selected_offx + i*selected_width, offy + selected_offy + 1*selected_height)\n  end\n  \n  -- the screen resolution influences number of selectable units\n  SetMaxSelectable(selected_box_num*2)\n\n  UI.MaxSelectedFont = Fonts[\"game\"]\n  UI.MaxSelectedTextX = offx + 10\n  UI.MaxSelectedTextY = offy + 160 + 10\n\n  b = CUIButton:new()\n  b.X = offx + 240\n  b.Y = offy + 396\n  b.Style = FindButtonStyle(\"icon\")\n  UI.SingleTrainingButton = b\n\n  UI.TrainingButtons:clear()\n\n  function AddTrainingButton(x, y)\n    b = CUIButton:new_local()\n    b.X = x\n    b.Y = y\n    b.Style = FindButtonStyle(\"training\")\n    UI.TrainingButtons:push_back(b)\n  end\n\n  AddTrainingButton(offx + 240, offy + 396)\n  AddTrainingButton(offx + 240, offy + 434)\n  AddTrainingButton(offx + 278, offy + 434)\n  AddTrainingButton(offx + 316, offy + 434)\n  AddTrainingButton(offx + 354, offy + 434)\n\n  b = CUIButton:new()\n  b.X = offx + 240\n  b.Y = offy + 396\n  b.Style = FindButtonStyle(\"icon\")\n  UI.UpgradingButton = b\n\n  b = CUIButton:new()\n  b.X = offx + 240\n  b.Y = offy + 396\n  b.Style = FindButtonStyle(\"icon\")\n  UI.ResearchingButton = b\n\n  UI.TransportingButtons:clear()\n\n  function AddTransportingButton(x, y)\n    b = CUIButton:new_local()\n    b.X = x\n    b.Y = y\n    b.Style = FindButtonStyle(\"icon\")\n    UI.TransportingButtons:push_back(b)\n  end\n\n  AddTransportingButton(offx + 240, offy + 396)\n  AddTransportingButton(offx + 240, offy + 433)\n  AddTransportingButton(offx + 276, offy + 396)\n  AddTransportingButton(offx + 276, offy + 433)\n  AddTransportingButton(offx + 312, offy + 396)\n  AddTransportingButton(offx + 312, offy + 433)\n  AddTransportingButton(offx + 348, offy + 396)\n  AddTransportingButton(offx + 348, offy + 433)\n\n  UI.CompletedBarColorRGB = CColor(48, 100, 4)\n  UI.CompletedBarShadow = true\n\n  UI.ButtonPanel.Buttons:clear()\n\n  function AddButtonPanelButton(x, y)\n    b = CUIButton:new_local()\n    b.X = x\n    b.Y = y\n    b.Style = FindButtonStyle(\"icon\")\n    UI.ButtonPanel.Buttons:push_back(b)\n  end\n  \n  local action_width = 46\n  local action_height = 40\n  \n  -- offset for the action button group on the right side\n  local action_offy = 360\n  local action_offx = 103\n  \n  -- those are the buttons for move, attack,...\n  AddButtonPanelButton(offx_right + action_offx + 0*action_width, offy + action_offy + 0*action_height)\n  AddButtonPanelButton(offx_right + action_offx + 1*action_width, offy + action_offy + 0*action_height)\n  AddButtonPanelButton(offx_right + action_offx + 2*action_width, offy + action_offy + 0*action_height)\n  \n  AddButtonPanelButton(offx_right + action_offx + 0*action_width, offy + action_offy + 1*action_height)\n  AddButtonPanelButton(offx_right + action_offx + 1*action_width, offy + action_offy + 1*action_height)\n  AddButtonPanelButton(offx_right + action_offx + 2*action_width, offy + action_offy + 1*action_height)\n  \n  AddButtonPanelButton(offx_right + action_offx + 0*action_width, offy + action_offy + 2*action_height)\n  AddButtonPanelButton(offx_right + action_offx + 1*action_width, offy + action_offy + 2*action_height)\n  AddButtonPanelButton(offx_right + action_offx + 2*action_width, offy + action_offy + 2*action_height)\n  AddButtonPanelButton(offx_right + action_offx + 3*action_width, offy + action_offy + 2*action_height)\n\n  UI.ButtonPanel.X = offx + 0\n  UI.ButtonPanel.Y = offy + 336\n  UI.ButtonPanel.AutoCastBorderColorRGB = CColor(0, 0, 252)\n\n  UI.MapArea.X = 0\n  UI.MapArea.Y = 0\n  UI.MapArea.EndX = Video.Width - 1\n  UI.MapArea.EndY = Video.Height - 107\n\n  UI.Minimap.X = offx + 6\n  UI.Minimap.Y = offy + 348\n  UI.Minimap.W = 128\n  UI.Minimap.H = 128\n\n  UI.StatusLine.TextX = offx + 172\n  UI.StatusLine.TextY = offy + 350\n  UI.StatusLine.Width = Video.Width - offx - 172\n  UI.StatusLine.Font = Fonts[\"game\"]\n\n  -- minerals\n  UI.Resources[1].G = CGraphic:New(\"ui/icons.png\", 54, 14)\n  UI.Resources[1].IconFrame = 0\n  UI.Resources[1].IconX = offx + 436\n  UI.Resources[1].IconY = 3\n  UI.Resources[1].TextX = offx + 452\n  UI.Resources[1].TextY = 3\n\n  -- gas\n  UI.Resources[2].G = CGraphic:New(\"ui/icons.png\", 54, 14)\n  UI.Resources[2].IconFrame = 2\n  UI.Resources[2].IconX = offx + 504\n  UI.Resources[2].IconY = 3\n  UI.Resources[2].TextX = offx + 520\n  UI.Resources[2].TextY = 3\n\n  -- food\n  UI.Resources[FoodCost].G = CGraphic:New(\"ui/icons.png\", 54, 14)\n  UI.Resources[FoodCost].IconFrame = 5\n  UI.Resources[FoodCost].IconX = offx + 572\n  UI.Resources[FoodCost].IconY = 3\n  UI.Resources[FoodCost].TextX = offx + 588\n  UI.Resources[FoodCost].TextY = 3\n\n  -- score\n  --[[\n  UI.Resources[ScoreCost].G = CGraphic:New(\"ui/score.png\", 14, 14)\n  UI.Resources[ScoreCost].IconFrame = 0\n  UI.Resources[ScoreCost].IconX = Video.Width - 16 - 68\n  UI.Resources[ScoreCost].IconY = 0\n  UI.Resources[ScoreCost].TextX = Video.Width - 16 - 68 + 18\n  UI.Resources[ScoreCost].TextY = 1\n  ]]\n\n  UI.MenuButton.X = offx_right + 10\n  UI.MenuButton.Y = offy + 388\n  UI.MenuButton.Text = \"MENU\"\n  UI.MenuButton.Style = FindButtonStyle(race .. \" menu button\")\n  UI.MenuButton:SetCallback(function() RunGameMenu() end)\n\n  UI.NetworkMenuButton.X = offx + 416\n  UI.NetworkMenuButton.Y = offy + 388\n  UI.NetworkMenuButton.Text = \"MENU\"\n  UI.NetworkMenuButton.Style = FindButtonStyle(race .. \" menu button\")\n  UI.NetworkMenuButton:SetCallback(function() RunGameMenu() end)\n\n  UI.NetworkDiplomacyButton.X = offx + 76\n  UI.NetworkDiplomacyButton.Y = offy + 320\n  --UI.NetworkDiplomacyButton.Text = \"Diplomacy\"\n  UI.NetworkDiplomacyButton.Style = FindButtonStyle(race .. \" diplomacy button\")\n  UI.NetworkDiplomacyButton:SetCallback(function() RunDiplomacyMenu() end)\n\n  local minimapButton = CUIUserButton:new_local()\n  minimapButton.Button = CUIButton:new_local()\n  minimapButton.Button.X = offx + 6\n  minimapButton.Button.Y = offy + 320\n  minimapButton.Button:SetCallback(function() UiToggleTerrain() end)\n  minimapButton.Button.Style = FindButtonStyle(race .. \" minimap terrain button\")\n  UI.UserButtons:push_back(minimapButton)\n\n  UI.LifeBarColorNames:clear()\n  UI.LifeBarColorNames:push_back(\"green\")\n  UI.LifeBarColorNames:push_back(\"yellow\")\n  UI.LifeBarColorNames:push_back(\"orange\")\n  UI.LifeBarColorNames:push_back(\"red\")\n  UI.LifeBarYOffset = -8\n  UI.LifeBarBorder = false\n  UI.LifeBarPadding = 4\n\n  -- minimap terrain at 3,320\n\nend -- function LoadUI\n\n"
  },
  {
    "path": "scripts/guichan.lua",
    "content": "SetPlayerData(GetThisPlayer(), \"RaceName\", \"terran\")\n\n-- Global useful objects for menus  ----------\ndark = Color(38, 38, 78)\nclear = Color(200, 200, 120)\nblack = Color(0, 0, 0)\n\nbckground = CGraphic:New(\"ui/Menu background without title.png\")\nbckground:Load()\nbckground:Resize(Video.Width, Video.Height)\nbackgroundWidget = ImageWidget(bckground)\n\n-- button large\ng_tbln = CGraphic:New(\"ui/terran/agg/button_large.png\")\ng_tbln:Load()\ng_tblp = CGraphic:New(\"ui/terran/agg/button_large_pressed.png\")\ng_tblp:Load()\ng_tblg = CGraphic:New(\"ui/terran/agg/button_large_disabled.png\")\ng_tblg:Load()\n\ng_zbln = CGraphic:New(\"ui/zerg/agg/button_large.png\")\ng_zbln:Load()\ng_zblp = CGraphic:New(\"ui/zerg/agg/button_large_pressed.png\")\ng_zblp:Load()\ng_zblg = CGraphic:New(\"ui/zerg/agg/button_large_disabled.png\")\ng_zblg:Load()\n\ng_pbln = CGraphic:New(\"ui/protoss/agg/button_large.png\")\ng_pbln:Load()\ng_pblp = CGraphic:New(\"ui/protoss/agg/button_large_pressed.png\")\ng_pblp:Load()\ng_pblg = CGraphic:New(\"ui/protoss/agg/button_large_disabled.png\")\ng_pblg:Load()\n\n-- button left large\ng_tblln = CGraphic:New(\"ui/terran/agg/button_left_large.png\")\ng_tblln:Load()\ng_tbllp = CGraphic:New(\"ui/terran/agg/button_left_large_pressed.png\")\ng_tbllp:Load()\ng_tbllg = CGraphic:New(\"ui/terran/agg/button_left_large_disabled.png\")\ng_tbllg:Load()\n\ng_zblln = CGraphic:New(\"ui/zerg/agg/button_left_large.png\")\ng_zblln:Load()\ng_zbllp = CGraphic:New(\"ui/zerg/agg/button_left_large_pressed.png\")\ng_zbllp:Load()\ng_zbllg = CGraphic:New(\"ui/zerg/agg/button_left_large_disabled.png\")\ng_zbllg:Load()\n\ng_pblln = CGraphic:New(\"ui/protoss/agg/button_left_large.png\")\ng_pblln:Load()\ng_pbllp = CGraphic:New(\"ui/protoss/agg/button_left_large_pressed.png\")\ng_pbllp:Load()\ng_pbllg = CGraphic:New(\"ui/protoss/agg/button_left_large_disabled.png\")\ng_pbllg:Load()\n\n-- button small\ng_tbhn = CGraphic:New(\"ui/terran/agg/button_small.png\")\ng_tbhn:Load()\ng_tbhp = CGraphic:New(\"ui/terran/agg/button_small_pressed.png\")\ng_tbhp:Load()\ng_tbhg = CGraphic:New(\"ui/terran/agg/button_small_disabled.png\")\ng_tbhg:Load()\n\ng_zbhn = CGraphic:New(\"ui/zerg/agg/button_small.png\")\ng_zbhn:Load()\ng_zbhp = CGraphic:New(\"ui/zerg/agg/button_small_pressed.png\")\ng_zbhp:Load()\ng_zbhg = CGraphic:New(\"ui/zerg/agg/button_small_disabled.png\")\ng_zbhg:Load()\n\ng_pbhn = CGraphic:New(\"ui/protoss/agg/button_small.png\")\ng_pbhn:Load()\ng_pbhp = CGraphic:New(\"ui/protoss/agg/button_small_pressed.png\")\ng_pbhp:Load()\ng_pbhg = CGraphic:New(\"ui/protoss/agg/button_small_disabled.png\")\ng_pbhg:Load()\n\n-- button left small\ng_tbhln = CGraphic:New(\"ui/terran/agg/button_left_small.png\")\ng_tbhln:Load()\ng_tbhlp = CGraphic:New(\"ui/terran/agg/button_left_small_pressed.png\")\ng_tbhlp:Load()\ng_tbhlg = CGraphic:New(\"ui/terran/agg/button_left_small_disabled.png\")\ng_tbhlg:Load()\n\ng_zbhln = CGraphic:New(\"ui/zerg/agg/button_left_small.png\")\ng_zbhln:Load()\ng_zbhlp = CGraphic:New(\"ui/zerg/agg/button_left_small_pressed.png\")\ng_zbhlp:Load()\ng_zbhlg = CGraphic:New(\"ui/zerg/agg/button_left_small_disabled.png\")\ng_zbhlg:Load()\n\ng_pbhln = CGraphic:New(\"ui/protoss/agg/button_left_small.png\")\ng_pbhln:Load()\ng_pbhlp = CGraphic:New(\"ui/protoss/agg/button_left_small_pressed.png\")\ng_pbhlp:Load()\ng_pbhlg = CGraphic:New(\"ui/protoss/agg/button_left_small_disabled.png\")\ng_pbhlg:Load()\n\n-- button right small\ng_tbhrn = CGraphic:New(\"ui/terran/agg/button_right_small.png\")\ng_tbhrn:Load()\ng_tbhrp = CGraphic:New(\"ui/terran/agg/button_right_small_pressed.png\")\ng_tbhrp:Load()\ng_tbhrg = CGraphic:New(\"ui/terran/agg/button_right_small_disabled.png\")\ng_tbhrg:Load()\n\ng_zbhrn = CGraphic:New(\"ui/zerg/agg/button_right_small.png\")\ng_zbhrn:Load()\ng_zbhrp = CGraphic:New(\"ui/zerg/agg/button_right_small_pressed.png\")\ng_zbhrp:Load()\ng_zbhrg = CGraphic:New(\"ui/zerg/agg/button_right_small_disabled.png\")\ng_zbhrg:Load()\n\ng_pbhrn = CGraphic:New(\"ui/protoss/agg/button_right_small.png\")\ng_pbhrn:Load()\ng_pbhrp = CGraphic:New(\"ui/protoss/agg/button_right_small_pressed.png\")\ng_pbhrp:Load()\ng_pbhrg = CGraphic:New(\"ui/protoss/agg/button_right_small_disabled.png\")\ng_pbhrg:Load()\n\nfunction panel(n)\n  return \"ui/panels/\" .. n .. \".png\"\nend\n\n\n\nfunction AddMenuHelpers(menu)\n  function menu:addCentered(widget, x, y)\n    self:add(widget, x - widget:getWidth() / 2, y)\n  end\n\n  function menu:addLabel(text, x, y, font, center)\n    local label = Label(text)\n    if (font == nil) then font = Fonts[\"large\"] end\n    label:setFont(font)\n    label:adjustSize()\n    if (center == nil or center == true) then -- center text by default\n      x = x - label:getWidth() / 2\n    end\n    self:add(label, x, y)\n\n    return label\n  end\n\n  function menu:writeText(text, x, y)\n    return self:addLabel(text, x, y, Fonts[\"game\"], false)\n  end\n\n  function menu:writeLargeText(text, x, y)\n    return self:addLabel(text, x, y, Fonts[\"large\"], false)\n  end\n\n  function menu:addButton(caption, hotkey, x, y, callback, size)\n    local b = ButtonWidget(caption)\n    b:setHotKey(hotkey)\n    b:setActionCallback(callback)\n    if (size == nil) then size = {200, 24} end\n    b:setSize(size[1], size[2])\n    b:setBackgroundColor(dark)\n    b:setBaseColor(dark)\n    self:add(b, x, y)\n    return b\n  end\n  \n  function menu:addTextButton(caption, hotkey, x, y, callback, size)\n    local b = ButtonWidget(caption)\n    b:setFont(Fonts[\"font16x\"])\n    b:setHotKey(hotkey)\n    b:setActionCallback(callback)\n    if size then\n      b:setSize(size[1], size[2])\n    else\n      b:adjustSize()\n    end\n    b:setBackgroundColor(Color(0, 0, 0, 0))\n    b:setBaseColor(Color(0, 0, 0, 0))\n    self:add(b, x, y)\n    return b\n  end\n\n  function menu:addImageButton(caption, hotkey, x, y, callback)\n    local b = ImageButton(caption)\n    b:setBorderSize(0)\n    b:setHotKey(hotkey)\n    b:setActionCallback(callback)\n    self:add(b, x, y)\n    return b\n  end\n\n  function menu:addFullLeftButton(caption, hotkey, x, y, callback)\n    local b = self:addImageButton(caption, hotkey, x, y, callback)\n    if (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"terran\") then\n      b:setNormalImage(g_tblln)\n      b:setPressedImage(g_tbllp)\n      b:setDisabledImage(g_tbllg)\n    elseif (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"zerg\") then\n      b:setNormalImage(g_zblln)\n      b:setPressedImage(g_zbllp)\n      b:setDisabledImage(g_zbllg)\n    else\n      b:setNormalImage(g_pblln)\n      b:setPressedImage(g_pbllp)\n      b:setDisabledImage(g_pbllg)\n    end\n    b:setSize(224, 28)\n    return b\n  end\n\n  function menu:addFullButton(caption, hotkey, x, y, callback)\n    local b = self:addImageButton(caption, hotkey, x, y, callback)\n    if (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"terran\") then\n      b:setNormalImage(g_tbln)\n      b:setPressedImage(g_tblp)\n      b:setDisabledImage(g_tblg)\n    elseif (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"zerg\") then\n      b:setNormalImage(g_zbln)\n      b:setPressedImage(g_zblp)\n      b:setDisabledImage(g_zblg)\n    else\n      b:setNormalImage(g_pbln)\n      b:setPressedImage(g_pblp)\n      b:setDisabledImage(g_pblg)\n    end\n    b:setSize(224, 28)\n    return b\n  end\n\n  function menu:addHalfLeftButton(caption, hotkey, x, y, callback)\n    local b = self:addImageButton(caption, hotkey, x, y, callback)\n    if (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"terran\") then\n      b:setNormalImage(g_tbhln)\n      b:setPressedImage(g_tbhlp)\n      b:setDisabledImage(g_tbhlg)\n    elseif (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"zerg\") then\n      b:setNormalImage(g_zbhln)\n      b:setPressedImage(g_zbhlp)\n      b:setDisabledImage(g_zbhlg)\n    else\n      b:setNormalImage(g_pbhln)\n      b:setPressedImage(g_pbhlp)\n      b:setDisabledImage(g_pbhlg)\n    end\n    b:setSize(104, 28)\n    return b\n  end\n\n  function menu:addHalfButton(caption, hotkey, x, y, callback)\n    local b = self:addImageButton(caption, hotkey, x, y, callback)\n    if (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"terran\") then\n      b:setNormalImage(g_tbhn)\n      b:setPressedImage(g_tbhp)\n      b:setDisabledImage(g_tbhg)\n    elseif (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"zerg\") then\n      b:setNormalImage(g_zbhn)\n      b:setPressedImage(g_zbhp)\n      b:setDisabledImage(g_zbhg)\n    else\n      b:setNormalImage(g_pbhn)\n      b:setPressedImage(g_pbhp)\n      b:setDisabledImage(g_pbhg)\n    end\n    b:setSize(104, 28)\n    return b\n  end\n\n  function menu:addHalfRightButton(caption, hotkey, x, y, callback)\n    local b = self:addImageButton(caption, hotkey, x, y, callback)\n    if (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"terran\") then\n      b:setNormalImage(g_tbhrn)\n      b:setPressedImage(g_tbhrp)\n      b:setDisabledImage(g_tbhrg)\n    elseif (GetPlayerData(GetThisPlayer(), \"RaceName\") == \"zerg\") then\n      b:setNormalImage(g_zbhrn)\n      b:setPressedImage(g_zbhrp)\n      b:setDisabledImage(g_zbhrg)\n    else\n      b:setNormalImage(g_pbhrn)\n      b:setPressedImage(g_pbhrp)\n      b:setDisabledImage(g_pbhrg)\n    end\n    b:setSize(104, 28)\n    return b\n  end\n\n  function menu:addSlider(min, max, w, h, x, y, callback)\n    local b = Slider(min, max)\n    b:setBaseColor(dark)\n    b:setForegroundColor(clear)\n    b:setBackgroundColor(clear)\n    b:setSize(w, h)\n    b:setActionCallback(function(s) callback(b, s) end)\n    self:add(b, x, y)\n    return b\n  end\n\n  function menu:addListBox(x, y, w, h, list)\n    local bq = ListBoxWidget(w, h)\n    bq:setList(list)\n    bq:setBaseColor(black)\n    bq:setForegroundColor(clear)\n    bq:setBackgroundColor(dark)\n    bq:setFont(Fonts[\"game\"])\n    self:add(bq, x, y)   \n    bq.itemslist = list\n    return bq\n  end\n\n  function menu:addBrowser(path, filter, x, y, w, h, default)\n    -- Create a list of all dirs and files in a directory\n    local function listfiles(path)\n      local dirlist = {}\n      local i\n      local f\n      local u = 1\n\n      local dirs = ListDirsInDirectory(path)\n      for i,f in ipairs(dirs) do\n        dirlist[u] = f .. \"/\"\n        u = u + 1\n      end\n\n      local fileslist = ListFilesInDirectory(path)\n      for i,f in ipairs(fileslist) do\n        if (string.find(f, filter)) then\n          dirlist[u] = f\n          u = u + 1\n        end\n      end\n\n      return dirlist\n    end\n\n    local bq = self:addListBox(x, y, w, h, {})\n    bq.origpath = path\n    bq.actioncb = nil\n\n    -- The directory changed, update the list\n    function bq:updateList()\n      self.itemslist = listfiles(self.path)\n      if (self.path ~= self.origpath) then\n        table.insert(self.itemslist, 1, \"../\")\n      end\n      self:setList(self.itemslist)\n    end\n\n    -- Change to the default directory and select the default file\n    if (default == nil) then\n      bq.path = path\n      bq:updateList()\n    else\n      local i\n      for i=string.len(default)-1,1,-1 do\n        if (string.sub(default, i, i) == \"/\") then\n          bq.path = string.sub(default, 1, i)\n          bq:updateList()\n\n          local f = string.sub(default, i + 1)\n          for i=1,table.getn(bq.itemslist) do\n            if (bq.itemslist[i] == f) then\n              bq:setSelected(i - 1)\n            end\n          end\n          break\n        end\n      end\n    end\n\n    function bq:getSelectedItem()\n      if (self:getSelected() < 0) then\n        return self.itemslist[1]\n      end\n      return self.itemslist[self:getSelected() + 1]\n    end\n\n    -- If a directory was clicked change dirs\n    -- Otherwise call the user's callback\n    local function cb(s)\n      local f = bq:getSelectedItem()\n      if (f == \"../\") then\n        local i\n        for i=string.len(bq.path)-1,1,-1 do\n          if (string.sub(bq.path, i, i) == \"/\") then\n            bq.path = string.sub(bq.path, 1, i)\n            bq:updateList()\n            break\n          end\n        end\n      elseif (string.sub(f, string.len(f)) == '/') then\n        bq.path = bq.path .. f\n        bq:updateList()\n      else\n        if (bq.actioncb ~= nil) then\n          bq:actioncb(s)\n        end\n      end\n    end\n    bq:setActionCallback(cb)\n\n    bq.oldSetActionCallback = bq.setActionCallback\n    function bq:setActionCallback(cb)\n      bq.actioncb = cb\n    end\n\n    return bq\n  end\n\n  function menu:addCheckBox(caption, x, y, callback)\n    local b = CheckBox(caption)\n    b:setBaseColor(clear)\n    b:setForegroundColor(clear)\n    b:setBackgroundColor(dark)\n    b:setActionCallback(function(s) callback(b, s) end)\n    b:setFont(Fonts[\"game\"])\n    self:add(b, x, y)\n    return b\n  end\n\n  function menu:addRadioButton(caption, group, x, y, callback)\n    local b = RadioButton(caption, group)\n    b:setBaseColor(dark)\n    b:setForegroundColor(clear)\n    b:setBackgroundColor(dark)\n    b:setActionCallback(callback)\n    self:add(b, x, y)\n    return b\n  end\n\n  function menu:addDropDown(list, x, y, callback)\n    local dd = DropDownWidget()\n    dd:setFont(Fonts[\"game\"])\n    dd:setList(list)\n    dd:setActionCallback(function(s) callback(dd, s) end)\n    dd:setBaseColor(dark)\n    dd:setForegroundColor(clear)\n    dd:setBackgroundColor(dark)\n    self:add(dd, x, y)\n    return dd\n  end\n\n  function menu:addTextInputField(text, x, y, w)\n    local b = TextField(text)\n    b:setActionCallback(function() end) --FIXME: remove this?\n    b:setFont(Fonts[\"game\"])\n    b:setBaseColor(clear)\n    b:setForegroundColor(clear)\n    b:setBackgroundColor(dark)\n    if (w == nil) then w = 100 end\n    b:setSize(w, 18)\n    self:add(b, x, y)\n    return b\n  end\n  \n  function menu:addAnimation(filename, x, y, center)\n    local mng1 = Mng:New(filename)\n    if mng1 then\n      mng1:Load()\n      mng1:Reset()\n      local im1 = ImageWidget(mng1)\n      \n      if center then\n        x = x - (im1:getWidth() / 2)\n      end\n      menu:add(im1, x, y)\n      \n      return im1\n    end\n  end\n\n  function menu:addAnimatedButton(filename, filenameOn, x, y, xOn, yOn, caption, hotkey, callback, animationIsBehind, center)\n    local mng1 = Mng:New(filename)\n    local im1\n    local mngOn\n    local imOn\n    if mng1 then\n      mng1:Load()\n      mng1:Reset()\n      im1 = ImageWidget(mng1)\n\n      if center then\n        x = x - (im1:getWidth() / 2)\n      end\n\n      if not animationIsBehind then\n        self:add(im1, x, y)\n      end\n\n      mngOn = Mng:New(filenameOn)\n      mngOn:Load()\n      imOn = ImageWidget(mngOn)\n      self:add(imOn, xOn, yOn)\n      imOn:setVisible(false)\n\n      if animationIsBehind then\n        self:add(im1, x, y)\n      end\n    end\n\n    local fnt = Fonts[\"font16x\"]\n    local label_max_width = fnt:Width(caption)\n    local label_max_height = fnt:Height()\n    local max_width = label_max_width\n    local max_height = label_max_height\n    if im1 then\n      max_width = math.max(im1:getWidth(), label_max_width)\n      max_height = math.max(im1:getHeight(), label_max_height) \n    end\n\n    local label = MultiLineLabel(caption)\n    label:setSize(max_width, max_height)\n    label:setAlignment(MultiLineLabel.RIGHT)\n    label:setVerticalAlignment(MultiLineLabel.BOTTOM)\n    label:setFont(fnt)\n    self:add(label, x, y)\n    \n    local button = self:addTextButton(\"\", hotkey, x, y, callback, {max_width, max_height})\n\n    if mngOn then\n      button:setMouseCallback(function(evt, btn, cnt)\n        if evt == \"mouseIn\" then\n          mngOn:Reset()\n          imOn:setVisible(true)\n        elseif evt == \"mouseOut\" then\n          imOn:setVisible(false)\n        end\n      end)\n    end\n  end\n\n  function menu:addBottomButton(caption, hotkey, x, row, callback)\n    local bckground = CGraphic:New(\"ui/readyt/butterr.png\")\n    bckground:Load()\n    local backgroundWidget = ImageWidget(bckground)\n    local h = backgroundWidget:getHeight()\n    local x = x - (backgroundWidget:getWidth() / 2)\n    local y = Video.Height - (h * 0.5 * row) - h\n    menu:add(backgroundWidget, x, y)\n    local btn = menu:addTextButton(caption, hotkey, x, y + 16, callback)\n    btn:setSize(backgroundWidget:getWidth(), btn:getHeight())\n    return btn\n  end\nend\n\nfunction WarMenu(title, background, resize)\n  local menu\n  local exitButton\n  local bg\n  local bgg\n\n  menu = MenuScreen()\n\n  if background == nil then\n    menu:add(backgroundWidget, 0, 0)\n  elseif type(background) == \"string\" then\n    bgg = CGraphic:New(background)\n    bgg:Load()\n    if (resize == nil or resize == true) then\n      bgg:Resize(Video.Width, Video.Height)\n    end\n    menu:add(ImageWidget(bgg), 0, 0)\n  else\n    menu:setOpaque(true)\n    menu:setBaseColor(Color(0, 0, 0, 255))\n  end\n\n  AddMenuHelpers(menu)\n\n  if title then\n    menu:addLabel(title, Video.Width / 2, Video.Height / 20, Fonts[\"large\"])\n  end\n\n  return menu\nend\n\n-- Default configurations -------\nWidget:setGlobalFont(Fonts[\"large\"])\n\n\nDefaultObjectives = {\"-Destroy the enemy\"}\nObjectives = DefaultObjectives\n\n\n-- Define the different menus ----------\n\nfunction InitGameSettings()\n  GameSettings.NetGameType = 1\n  for i=0,PlayerMax-1 do\n    GameSettings.Presets[i].Race = -1\n    GameSettings.Presets[i].Team = -1\n    GameSettings.Presets[i].Type = -1\n  end\n  GameSettings.Resources = -1\n  GameSettings.NumUnits = -1\n  GameSettings.Opponents = -1\n  GameSettings.Terrain = -1\n  GameSettings.GameType = -1\n  GameSettings.NoFogOfWar = false\n  GameSettings.RevealMap = 0\nend\nInitGameSettings()\n\nfunction RunMap(map, objective, fow, revealmap)\n  SetMusic(GetPlayerData(GetThisPlayer(), \"RaceName\"))\n  if objective == nil then\n    Objectives = DefaultObjectives\n  else\n    Objectives = objective\n  end\n  loop = true\n  while (loop) do\n    InitGameVariables()\n    if fow ~= nil then\n      SetFogOfWar(fow)\n    end\n    if revealmap == true then\n       RevealMap()\n    end\n    \n    if (preferences.RapidStratagusIDE == true) then\n  Load(\"RapidStratagusIDE/RSI_Functions.lua\")\n  --RSI_MapConfiguration()\n  --CreateUnit(\"unit-terran-command-center\", 0, {0, 0})\nend\n\n    \n    StartMap(map)\n    if GameResult ~= GameRestart then\n      loop = false\n    end\n  end\n  RunResultsMenu(s)\n\n  InitGameSettings()\n  SetPlayerData(GetThisPlayer(), \"RaceName\", \"terran\")\n  SetMusic(\"menu\")\nend\n\nmapname = \"maps/\\(2\\)Space Madness.smp\"\nlocal mapinfo = {\n  playertypes = {nil, nil, nil, nil, nil, nil, nil, nil},\n  description = \"\",\n  nplayers = 1,\n  w = 32,\n  h = 32,\n  id = 0\n}\n\nfunction GetMapInfo(mapname)\n  local OldDefinePlayerTypes = DefinePlayerTypes\n  local OldPresentMap = PresentMap\n\n  function DefinePlayerTypes(p1, p2, p3, p4, p5, p6, p7, p8)\n    mapinfo.playertypes[1] = p1\n    mapinfo.playertypes[2] = p2\n    mapinfo.playertypes[3] = p3\n    mapinfo.playertypes[4] = p4\n    mapinfo.playertypes[5] = p5\n    mapinfo.playertypes[6] = p6\n    mapinfo.playertypes[7] = p7\n    mapinfo.playertypes[8] = p8\n\n    mapinfo.nplayers = 0\n    for i=0,8 do\n      local t = mapinfo.playertypes[i]\n      if (t == \"person\" or t == \"computer\") then\n        mapinfo.nplayers = mapinfo.nplayers + 1\n      end\n    end\n  end\n\n  function PresentMap(description, nplayers, w, h, id)\n    mapinfo.description = description\n    -- nplayers includes rescue-passive and rescue-active\n    -- calculate the real nplayers in DefinePlayerTypes\n    --mapinfo.nplayers = nplayers\n    mapinfo.w = w\n    mapinfo.h = h\n    mapinfo.id = id\n  end\n\n  Load(mapname)\n\n  DefinePlayerTypes = OldDefinePlayerTypes\n  PresentMap = OldPresentMap\nend\n\nfunction RunSelectScenarioMenu()\n  local menu = WarMenu(nil, panel(\"384x256\"), false)\n  menu:setSize(384, 256)\n  menu:setPosition((Video.Width - 384) / 2, (Video.Height - 256) / 2)\n\n  menu:addLabel(\"Select scenario\", 384/2, 8)\n\n  local browser = menu:addBrowser(\"maps/\", \"^.*%.smp%.?g?z?$\",\n    32, 44, 320, 160, mapname)\n\n  menu:addFullLeftButton(\"~!OK\", \"o\", 20, 216,\n    function()\n      if (browser:getSelected() < 0) then\n        return\n      end\n\n      mapname = browser.path .. browser:getSelectedItem()\n      menu:stop()\n    end)\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 260, 216,\n    function() menu:stop() end)\n\n  menu:run()\nend\n\nfunction RunInfoMenu()\n  local menu = WarMenu()\n  local offx = (Video.Width - 640) / 2\n  local offy = (Video.Height - 480) / 2\n  \n  menu:addLabel(\"~<Game Information~>\", offx + 640/2 + 12, offy + 192)\n  \n  menu:addFullButton(\"~!Back\", \"b\", offx + 640 - 224 - 16, offy + 360 + 36*2, function() menu:stop() end)\n  \n  menu:addLabel(stargus.Name .. \" V\" .. stargus.Version .. \"  \" .. stargus.Homepage, offx + 320, offy + 226 + 18*0) \n  menu:addLabel(\"Stratagus V\" .. GetStratagusVersion() .. \"  \" .. GetStratagusHomepage(), offx + 320, offy + 226 + 18*1)\n  menu:addLabel(Copyright, offx + 320, offy + 290 + 18*4)\n  \n  menu:run()\nend\n\nfunction RunSinglePlayerGameMenu()\n  local menu = WarMenu()\n  local offx = (Video.Width - 640) / 2\n  local offy = (Video.Height - 480) / 2\n  local d\n  local race\n  local resources\n  local opponents\n  local numunits\n  local gametype\n  local mapl\n  local descriptionl\n\n  menu:addLabel(\"Scenario:\", offx + 16, offy + 360, Fonts[\"game\"], false)\n  mapl = menu:addLabel(string.sub(mapname, 6), offx + 16, offy + 360 + 24, Fonts[\"game\"], false)\n  descriptionl = menu:addLabel(\"descriptionl\", offx + 16 + 70, offy + 360, Fonts[\"game\"], false)\n\n  menu:addLabel(\"~<Single Player Game Setup~>\", offx + 640/2 + 12, offy + 192)\n  menu:addFullButton(\"S~!elect Scenario\", \"e\", offx + 640 - 224 - 16, offy + 360 + 36*0,\n    function()\n      local oldmapname = mapname\n      RunSelectScenarioMenu()\n      if (mapname ~= oldmapname) then\n        GetMapInfo(mapname)\n        MapChanged()\n      end\n    end)\n  menu:addFullButton(\"~!Start Game\", \"s\", offx + 640 - 224 - 16, offy + 360 + 36*1,\n    function()\n      GameSettings.Presets[0].Race = race:getSelected()\n      GameSettings.Resources = resources:getSelected()\n      GameSettings.Opponents = opponents:getSelected()\n      GameSettings.NumUnits = numunits:getSelected()\n      GameSettings.GameType = gametype:getSelected() - 1\n      RunMap(mapname)\n      menu:stop()\n    end)\n  menu:addFullButton(\"~!Cancel Game\", \"c\", offx + 640 - 224 - 16, offy + 360 + 36*2, function() menu:stop() end)\n\n  menu:addLabel(\"~<Your Race:~>\", offx + 40, offy + (10 + 240) - 20, Fonts[\"game\"], false)\n  race = menu:addDropDown({\"Map Default\", \"Terran\", \"Zerg\", \"Protoss\"}, offx + 40, offy + 10 + 240,\n    function(dd) end)\n  race:setSize(152, 20)\n\n  menu:addLabel(\"~<Resources:~>\", offx + 220, offy + (10 + 240) - 20, Fonts[\"game\"], false)\n  resources = menu:addDropDown({\"Map Default\", \"Low\", \"Medium\", \"High\"}, offx + 220, offy + 10 + 240,\n    function(dd) end)\n  resources:setSize(152, 20)\n\n  menu:addLabel(\"~<Units:~>\", offx + 640 - 224 - 16, offy + (10 + 240) - 20, Fonts[\"game\"], false)\n  numunits = menu:addDropDown({\"Map Default\", \"One Peasant Only\"}, offx + 640 - 224 - 16, offy + 10 + 240,\n    function(dd) end)\n  numunits:setSize(190, 20)\n\n  local opponents_list = {\"Map Default\", \"1 Opponent\", \"2 Opponents\",\n    \"3 Opponents\", \"4 Opponents\", \"5 Opponents\", \"6 Opponents\", \"7 Opponents\"}\n\n  menu:addLabel(\"~<Opponents:~>\", offx + 40, offy + (10 + 300) - 20, Fonts[\"game\"], false)\n  opponents = menu:addDropDown(opponents_list, offx + 40, offy + 10 + 300,\n    function(dd) end)\n  opponents:setSize(152, 20)\n\n  menu:addLabel(\"~<Game Type:~>\", offx + 220, offy + (10 + 300) - 20, Fonts[\"game\"], false)\n  gametype = menu:addDropDown({\"Use map settings\", \"Melee\", \"Free for all\", \"Top vs bottom\", \"Left vs right\", \"Man vs Machine\"}, offx + 220, offy + 10 + 300,\n    function(dd) end)\n  gametype:setSize(152, 20)\n\n  function MapChanged()\n    mapl:setCaption(string.sub(mapname, 6))\n    mapl:adjustSize()\n\n    descriptionl:setCaption(mapinfo.description ..\n      \" (\" .. mapinfo.w .. \" x \" .. mapinfo.h .. \")\")\n    descriptionl:adjustSize()\n \n    local o = {}\n    for i=1,mapinfo.nplayers do\n      table.insert(o, opponents_list[i])\n    end\n    opponents:setList(o)\n  end\n\n  GetMapInfo(mapname)\n  MapChanged()\n\n  menu:run()\nend\n\n\n\nfunction BuildProgramStartMenu()\n  \n  local menu = WarMenu()\n  local offx = (Video.Width - 640) / 2\n  local offy = (Video.Height - 480) / 2\n\n  menu:addLabel(\"~white~\" .. stargus.Name .. \" V\" .. stargus.Version, Video.Width - 60, Video.Height - 18*1) \n  \n  menu:addAnimatedButton(\n    \"videos/mainmenu/single.mng\",\n    \"videos/mainmenu/singleon.mng\",\n    100, 50,\n    143, 115,\n    \"~light-green~S~!ingle Player\",\n    \"s\",\n    function() RunCampaignGameMenu(); menu:stop(1) end,\n    true\n  )\n  \n  menu:addAnimatedButton(\n    \"videos/mainmenu/multi.mng\",\n    \"videos/mainmenu/multion.mng\",\n    80, 250,\n    99, 261,\n    \"~light-green~M~!ultiplayer\",\n    \"m\",\n    function() RunMultiPlayerGameMenu(); menu:stop(1) end\n  )\n  \n  menu:addAnimatedButton(\n    \"videos/mainmenu/exit.mng\",\n    \"videos/mainmenu/exiton.mng\",\n    Video.Width - 300, Video.Height - 200,\n    Video.Width - 285, Video.Height - 200,\n    \"~light-green~E~!xit Program\",\n    \"x\",\n    function() menu:stop() end\n  )\n\n  --menu:addFullButton(\"~!Single Player Game\", \"s\", offx + 208, offy + 104 + 36*0,\n    --function() RunSinglePlayerGameMenu(); menu:stop(1) end)\n\n  --menu:addFullButton(\"~!Multi Player Game\", \"m\", offx + 208, offy + 104 + 36*1,\n    --function() RunMultiPlayerGameMenu(); menu:stop(1) end)\n\n  --menu:addFullButton(\"~!Campaign Game\", \"c\", offx + 208, offy + 104 + 36*2,\n    --function() RunCampaignGameMenu(); menu:stop(1) end)\n\n  --menu:addFullButton(\"~!Load Game\", \"l\", offx + 208, offy + 104 + 36*3,\n    --function() RunLoadGameMenu(); menu:stop(1) end)\n    \n  --menu:addFullButton(\"~!Replay Game\", \"r\", offx + 208, offy + 104 + 36*4,\n    --function() RunReplayGameMenu(); menu:stop(1) end)\n    \n  --menu:addFullButton(\"~!Options\", \"o\", offx + 208, offy + 104 + 36*5,\n  --  function() RunOptionsMenu(); menu:stop(1) end)\n  \n    --menu:addFullButton(\"E~!xit Program\", \"x\", offx + 208, offy + 104 + 36*8,\n    --function() menu:stop() end)\n  \n  -- menu:addTextButton(\"~light-green~C~white~ampaign Game\", \"c\", 100, Video.Height-120, function() RunCampaignGameMenu(); menu:stop(1) end)\n  \n  -- menu:addTextButton(\"~light-green~L~white~oad Game\", \"l\", 100, Video.Height-100, function() RunReplayGameMenu(); menu:stop(1) end)\n    \n  -- menu:addTextButton(\"~light-green~R~white~eplay Game\", \"r\", 100, Video.Height-80, function() RunReplayGameMenu(); menu:stop(1) end)\n    \n  -- TODO: merge video options and all needed widgets from wargus\n  --menu:addTextButton(\"~light-green~V~white~ideo Options\", \"o\", 100, Video.Height-80, function() BuildVideoOptionsMenu(); menu:stop(1) end)\n  \n  menu:addTextButton(\"~light-green~O~white~ptions\", \"o\", 100, Video.Height-60, function() RunOptionsMenu(); menu:stop(1) end)\n  \n  menu:addTextButton(\"~white~Show ~light-green~I~white~nfo\", \"i\", 100, Video.Height-40, function() RunInfoMenu(); menu:stop(1) end)\n  \n  menu:addTextButton(\"~white~Show Cre~light-green~d~white~its\", \"d\", 100, Video.Height-20, RunShowCreditsMenu)\n\n  return menu:run()\nend\n\n\n\nLoadGameFile = nil\n\nfunction RunProgramStartMenu()\n  local continue = 1\n\n  while continue == 1 do\n    if (LoadGameFile ~= nil) then\n      LoadGame(LoadGameFile)\n    else\n      continue = BuildProgramStartMenu(menu)\n    end\n  end\nend\n\n\nLoad(\"scripts/menus/campaign.lua\")\nLoad(\"scripts/menus/load.lua\")\nLoad(\"scripts/menus/save.lua\")\nLoad(\"scripts/menus/replay.lua\")\nLoad(\"scripts/menus/options.lua\")\nLoad(\"scripts/menus/credits.lua\")\nLoad(\"scripts/menus/game.lua\")\nLoad(\"scripts/menus/help.lua\")\nLoad(\"scripts/menus/objectives.lua\")\nLoad(\"scripts/menus/endscenario.lua\")\nLoad(\"scripts/menus/diplomacy.lua\")\nLoad(\"scripts/menus/results.lua\")\nLoad(\"scripts/menus/network.lua\")\n\nif SetShader then\n  SetShader(\"none\")\nend\n\nif (preferences.RapidStratagusIDE == true) then\n  Load(\"RapidStratagusIDE/RSI_Functions.lua\")\n  RSI_MapStarter()\nend\n  \nRunProgramStartMenu()\n\n"
  },
  {
    "path": "scripts/icons.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      icons.lua - Define the icons.\n--\n--      (c) Copyright 2005 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nicons = {\n  {\"icon-minerals1\", 176},\n  {\"icon-minerals2\", 177},\n  {\"icon-minerals3\", 178},\n  {\"icon-vespene-geyser\", 188},\n  {\"icon-bengalaas-jungle-critter\", 90},\n  {\"icon-rhynadon-badlands-critter\", 89},\n  {\"icon-ragnasaur-ashworld-critter\", 95},\n  \n  {\"icon-move\", 228},\n  {\"icon-stop\", 229},\n  {\"icon-attack\", 230},\n  {\"icon-gather\", 231},\n  {\"icon-repair\", 232},\n  {\"icon-build\", 234},\n  {\"icon-advanced-build\", 235},\n  {\"icon-cancel\", 236},\n  {\"icon-patrol\", 254},\n  {\"icon-hold-position\", 255},\n  {\"icon-rally-point\", 286},\n  {\"icon-zerg-build\", 257},\n  {\"icon-zerg-advanced-build\", 258},\n}\n\nLoad(\"scripts/terran/icons.lua\")\nLoad(\"scripts/zerg/icons.lua\")\nLoad(\"scripts/protoss/icons.lua\")\n\nlocal wireframe_red = {200, 24, 24}\nlocal wireframe_yellow = {252, 252, 56}\nlocal wireframe_green = {16, 252, 24}\n\nlocal terranPaletteSwap = {\n  \"HitPoints\", {\n    208, -- health colors for terran/protoss starts at 208\n    { -- # health steps\n      { -- # of alternatives for step\n        {wireframe_red, wireframe_red, wireframe_red, wireframe_yellow}, -- 4 colors\n        {wireframe_red, wireframe_red, wireframe_yellow, wireframe_red},\n        {wireframe_red, wireframe_yellow, wireframe_red, wireframe_red},\n        {wireframe_yellow, wireframe_red, wireframe_red, wireframe_red},\n      },\n      {\n        {wireframe_yellow, wireframe_red, wireframe_red, wireframe_yellow},\n        {wireframe_red, wireframe_yellow, wireframe_yellow, wireframe_red},\n        {wireframe_red, wireframe_yellow, wireframe_red, wireframe_yellow},\n        {wireframe_yellow, wireframe_red, wireframe_yellow, wireframe_red},\n      },\n      {\n        {wireframe_yellow, wireframe_yellow, wireframe_yellow, wireframe_yellow},\n        {wireframe_yellow, wireframe_yellow, wireframe_yellow, wireframe_yellow},\n        {wireframe_yellow, wireframe_yellow, wireframe_yellow, wireframe_yellow},\n        {wireframe_yellow, wireframe_yellow, wireframe_yellow, wireframe_yellow},\n      },\n      {\n        {wireframe_yellow, wireframe_green, wireframe_yellow, wireframe_green},\n        {wireframe_green, wireframe_yellow, wireframe_green, wireframe_yellow},\n        {wireframe_green, wireframe_green, wireframe_yellow, wireframe_green},\n        {wireframe_yellow, wireframe_yellow, wireframe_green, wireframe_yellow},\n      },\n      {\n        {wireframe_yellow, wireframe_green, wireframe_green, wireframe_green},\n        {wireframe_green, wireframe_yellow, wireframe_green, wireframe_green},\n        {wireframe_green, wireframe_green, wireframe_yellow, wireframe_green},\n        {wireframe_green, wireframe_green, wireframe_green, wireframe_yellow},\n      },\n      {\n        {wireframe_green, wireframe_green, wireframe_green, wireframe_green},\n        {wireframe_green, wireframe_green, wireframe_green, wireframe_green},\n        {wireframe_green, wireframe_green, wireframe_green, wireframe_green},\n        {wireframe_green, wireframe_green, wireframe_green, wireframe_green},\n      },\n    },\n  },\n}\n\nlocal zergPaletteSwap = {\n  \"HitPoints\", {\n    216, -- health colors for zerg starts at 216\n    { -- # health steps\n      { -- # of alternatives for step\n        {{136, 64, 156}, {8, 52, 152}, {4, 32, 100}, {4, 32, 100}},\n      },\n      {\n        {{232, 80, 20}, {168, 8, 8}, {132, 4, 4}, {8, 52, 152}},\n      },\n      {\n        {{232, 80, 20}, {168, 8, 8}, {200, 24, 24}, {104, 48, 120}},\n      },\n      {\n        {{16, 252, 24}, {248, 140, 20}, {160, 84, 28}, {104, 48, 120}},\n      },\n      {\n        {{16, 252, 24}, {248, 140, 20}, {160, 84, 28}, {168, 8, 8}},\n      },\n      {\n        {{252, 252, 56}, {16, 252, 24}, {248, 140, 20}, {200, 24, 24}},\n      },\n    },\n  },\n}\n\nlocal protossPaletteSwap = {\n  \"HitPoints\", terranPaletteSwap[2],\n  \"ShieldPoints\", {\n    192, -- shields are at 192 + 193\n    { -- # shield steps\n      {\n        {{8, 8, 8}, {8, 8, 8}},\n      },\n      {\n        {{0, 16, 52}, {8, 8, 8}}\n      },\n      {\n        {{4, 32, 100}, {0, 16, 52}},\n      },\n      {\n        {{4, 32, 100}, {4, 32, 100}},\n      },\n      {\n        {{8, 52, 152}, {4, 32, 100}},\n      },\n      {\n        {{8, 52, 152}, {8, 52, 152}},\n      },\n      {\n        {{12, 72, 204}, {8, 52, 152}},\n      },\n      {\n        {{12, 72, 204}, {12, 72, 204}},\n      },\n    }\n  }\n}\n\nfor i = 1,table.getn(icons) do\n  icon = CIcon:New(icons[i][1])\n  icon.G = CPlayerColorGraphic:New(\"cmdicons.png\", 36, 34)\n  icon.Frame = icons[i][2]\n\n  if string.find(icons[i][1], \"icon-terran-\", 1, true) then\n    DefinePaletteSwap(icons[i][1], terranPaletteSwap)\n  elseif string.find(icons[i][1], \"icon-zerg-\", 1, true) then\n    DefinePaletteSwap(icons[i][1], zergPaletteSwap)\n  elseif string.find(icons[i][1], \"icon-protoss-\", 1, true) then\n    DefinePaletteSwap(icons[i][1], protossPaletteSwap)\n  end\n\n  icon:ClearExtraGraphics()\n  icon:AddSingleSelectionGraphic(CPlayerColorGraphic:New(\"wirefram.png\", 64, 64))\n  icon:AddGroupSelectionGraphic(CPlayerColorGraphic:New(\"grpwire.png\", 32, 32))\n  icon:AddContainedGraphic(CPlayerColorGraphic:New(\"tranwire.png\", 64, 64))\nend\n"
  },
  {
    "path": "scripts/maps.lua",
    "content": "--       _________ __                 __\n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      maps.lua - Define map helper functions.\n--\n--      (c) Copyright 2005 by Francois Beerten\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--\n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--\n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nfunction DefineImageTilemodels(terrain, imgx, imgy)\n   local til = {}\n\n   for i = 0, imgx * imgy - 1 do\n      til[i + 1] = i\n   end\n\n   DefineTileset(\n     \"name\",  \"Image terrain\",\n     \"image\", terrain,\n     -- Slots descriptions\n     \"slots\", {\n       \"solid\", { \"light-grass\", \"land\",\n      til}\n     }\n   )\nDefineTileset(\n     \"name\",  \"Image terrain\",\n     \"image\", terrain,\n     -- Slots descriptions\n     \"slots\", {\n       \"solid\", { \"high-platform\", \"land\",\n      til}\n     }\n   )\nDefineTileset(\n     \"name\",  \"Image terrain\",\n     \"image\", terrain,\n     -- Slots descriptions\n     \"slots\", {\n       \"solid\", { \"low-installation\", \"land\",\n      til}\n     }\n   )\nDefineTileset(\n     \"name\",  \"Image terrain\",\n     \"image\", terrain,\n     -- Slots descriptions\n     \"slots\", {\n       \"solid\", { \"high-wall\", \"land\",\n      til}\n     }\n   )\nDefineTileset(\n     \"name\",  \"Image terrain\",\n     \"image\", terrain,\n     -- Slots descriptions\n     \"slots\", {\n       \"solid\", { \"high-cliff\", \"land\",\n      til}\n     }\n   )\nDefineTileset(\n     \"name\",  \"Image terrain\",\n     \"image\", terrain,\n     -- Slots descriptions\n     \"slots\", {\n       \"solid\", { \"low-water\", \"land\",\n      til}\n     }\n   )\nend\n\nfunction RepeatMap(mapx, mapy, imgx, imgy)\n  -- Tile map\n  for y = 0, mapy - 1 do\n    for x = 0, mapx - 1 do\n      SetTile(math.mod(x, imgx) + math.mod(y, imgy) * imgx, x, y)\n    end\n  end\n\n  -- The terrain of image based maps shouldnt be editable by the stratagus \n  -- builtin editor and the editor shouldn't try to write the tiles map\n  Editor.TerrainEditable = false\nend\n\n\n\nfunction DefineImageTerrain(terrain, mapx, mapy, imgx, imgy)\n   DefineImageTilemodels(terrain, imgx, imgy)\n   RepeatMap(mapx, mapy, imgx, imgy)\nend\n\n"
  },
  {
    "path": "scripts/menus/campaign.lua",
    "content": "function Briefing(title, objs, bg, text, voices)\n  local menu = WarMenu(nil, bg)\n\n  Objectives = objs\n\n  menu:addLabel(title, (70 + 340) / 2 * Video.Width / 640, 28 * Video.Height / 480,\n    Fonts[\"large\"], true)\n\n  local t = LoadBuffer(text)\n  t = \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\" .. t .. \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\"\n  local sw = ScrollingWidget(320, 170 * Video.Height / 480)\n  sw:setBackgroundColor(Color(0,0,0,0))\n  sw:setSpeed(0.38)\n  local l = MultiLineLabel(t)\n  l:setFont(Fonts[\"large\"])\n  l:setAlignment(MultiLineLabel.LEFT)\n  l:setLineWidth(320)\n  l:adjustSize()\n  sw:add(l, 0, 0)\n  menu:add(sw, 70 * Video.Width / 640, 80 * Video.Height / 480)\n\n  menu:addLabel(\"Objectives:\", 372 * Video.Width / 640, 306 * Video.Height / 480, Fonts[\"large\"], false)\n\n  local objectives = \"\"\n  table.foreachi(objs, function(k,v) objectives = objectives .. v .. \"\\n\" end)\n\n  local l = MultiLineLabel(objectives)\n  l:setFont(Fonts[\"large\"])\n  l:setAlignment(MultiLineLabel.LEFT)\n  l:setLineWidth(250 * Video.Width / 640)\n  l:adjustSize()\n  menu:add(l, 372 * Video.Width / 640, (306 * Video.Height / 480) + 30)\n\n  local voice = 0\n  local channel = -1\n\n  menu:addHalfButton(\"~!Continue\", \"c\", 455 * Video.Width / 640, 440 * Video.Height / 480,\n    function()\n      if (channel ~= -1) then\n        voice = table.getn(voices)\n        StopChannel(channel)\n      end\n      menu:stop()\n    end)\n\n\n  function PlayNextVoice()\n    voice = voice + 1\n    if (voice <= table.getn(voices)) then\n      channel = PlaySoundFile(voices[voice], PlayNextVoice);\n    else\n      channel = -1\n    end\n  end\n  PlayNextVoice()\n\n  local speed = GetGameSpeed()\n  SetGameSpeed(30)\n\n  menu:run()\n\n  SetGameSpeed(speed)\nend\n\nfunction CreatePictureStep(bg, title, text)\n  return function()\n    local menu = WarMenu(nil, bg)\n    local offx = (Video.Width - 640) / 2\n    local offy  = (Video.Height - 480) / 2\n    menu:addLabel(title, offx + 320, offy + 240 - 67, Fonts[\"large-title\"], true)\n    menu:addLabel(text, offx + 320, offy + 240 - 25, Fonts[\"small-title\"], true)\n    menu:addHalfButton(\"~!Continue\", \"c\", 455 * Video.Width / 640, 440 * Video.Height / 480,\n      function() menu:stop() end)\n    menu:run()\n    GameResult = GameVictory\n  end\nend\n\nfunction CreateMapStep(map)\n  return function()\n    Load(map)\n    RunMap(map)\n  end\nend\n\nfunction RunImageStep(filename, pagenum)\n  local txt = LoadBuffer(filename)\n\n  local fadespeed = 100\n  local displaytime = 5000\n  local bg = false\n  local verticalAlignment = MultiLineLabel.TOP\n  local menu\n  local label\n  if pagenum == nil then\n    pagenum = 1\n  end\n  local current_page = 1\n  local text = \"\"\n\n  for s in txt:gmatch(\"[^\\r\\n]*\") do\n    if s:find(\"</FADESPEED \", 1, true) then\n      s = s:gsub(\"[^0-9]+\", \"\")\n      fadespeed = tonumber(s)\n    elseif s:find(\"</DISPLAYTIME \", 1, true) then\n      s = s:gsub(\"[^0-9]+\", \"\")\n      displaytime = tonumber(s)\n    elseif s:find(\"</BACKGROUND \", 1, true) then\n      bg = s:sub(string.len(\"</BACKGROUND \") + 1):gsub(\"[\\\\]\", \"/\"):gsub(\"%.pcx>\", \".png\")\n      if CanAccessFile(bg) then\n        menu = WarMenu(nil, bg)\n      else\n        print(\"Missing background: \" .. bg)\n        menu = WarMenu(nil, false)\n      end\n    elseif s:find(\"</SCREENLOWERLEFT>\", 1, true) then\n      text = \"\"\n      verticalAlignment = MultiLineLabel.BOTTOM\n      label = MultiLineLabel(\"...\")\n      label:setForegroundColor(Color(128, 128, 128, 255))\n      label:setAlignment(MultiLineLabel.LEFT)\n      label:setVerticalAlignment(verticalAlignment)\n      label:setFont(Fonts[\"font16x\"])\n    elseif s:find(\"</SCREENLEFT>\", 1, true) then\n      text = \"\"\n      verticalAlignment = MultiLineLabel.TOP\n      label = MultiLineLabel(\"...\")\n      label:setForegroundColor(Color(128, 128, 128, 255))\n      label:setAlignment(MultiLineLabel.LEFT)\n      label:setVerticalAlignment(verticalAlignment)\n      label:setFont(Fonts[\"font16x\"])\n    elseif s:find(\"</PAGE>\", 1, true) then\n      if pagenum == current_page then\n        label:setCaption(text)\n        label:setSize(Video.Width - 30, Video.Height - 30)\n        label:setLineWidth(Video.Width - 40)\n        menu:add(label, 15, 15)\n\n        local blackScreen = Container()\n        blackScreen:setSize(Video.Width, Video.Height)\n        blackScreen:setBaseColor(Color(0, 0, 0, 255))\n        blackScreen:setOpaque(true)\n        menu:add(blackScreen, 0, 0)\n\n        local time = 0\n        local alpha = 255\n        local function listen()\n          if time <= fadespeed then\n            alpha = math.max(0, alpha - 255 / fadespeed)\n            blackScreen:setBaseColor(Color(0, 0, 0, math.floor(alpha)))\n          else\n            blackScreen:setVisible(false)\n          end\n          if time >= displaytime then\n            menu:stop()\n            RunImageStep(filename, current_page + 1)\n            GameResult = GameVictory\n          end\n          time = time + (1000 / (GetGameSpeed() + 1))\n        end\n        local listener = LuaActionListener(listen)\n        menu:addLogicCallback(listener)\n\n        label:setMouseCallback(function (evt, btn, cnt)\n          if evt == \"mouseClick\" then\n            time = displaytime\n          end\n        end)\n\n        menu:run()\n      end\n      current_page = current_page + 1\n    elseif not s:find(\"</\", 1, true) then\n      if label then\n        text = text .. \"\\n\" .. s\n      end\n    else\n      print(\"Unsupported tag: \" .. s)\n    end\n  end\nend\n\nfunction RunCampaignSubmenu(campaign)\n  Load(campaign)\n\n  if not preferences.Progress then\n    preferences.Progress = {}\n    SavePreferences()\n  end\n  local campaign_key = string.gsub(campaign, \"[/.]\", \"_\")\n  if not preferences.Progress[campaign_key] then\n    preferences.Progress[campaign_key] = #campaign_steps\n    SavePreferences()\n  end\n  campaign_position = preferences.Progress[campaign_key]\n\n  local menu = WarMenu(nil, false)\n\n  local function RunMission(number)\n    campaign_position = number\n    while (campaign_position <= #campaign_steps) do\n      campaign_steps[campaign_position]()\n      if (GameResult == GameVictory) then\n        campaign_position = campaign_position + 1\n        preferences.Progress[campaign_key] = math.max(preferences.Progress[campaign_key], campaign_position)\n        SavePreferences()\n      else\n        menu:stop() -- quit to menu\n        break\n      end\n    end\n  end\n\n  for i=1,#campaign_menu do\n    menu:addTextButton(\"Mission \" .. i, nil, Video.Width / 2 - (Fonts[\"large\"]:Width(\"Mission 10\") / 2), 20 + i * Fonts[\"large\"]:Height() * 2,\n      function() RunMission(campaign_menu[i]) end)\n  end\n\n  menu:addBottomButton(\"Cancel\", \"c\", Video.Width / 2, 0, function()\n    menu:stop()\n  end)\n\n  menu:run()\nend\n\nfunction RunCampaignGameMenu()\n  local menu = WarMenu(nil, false)\n  local offx = (Video.Width - 640) / 2\n  local offy = (Video.Height - 480) / 2\n  local center = Video.Width / 2\n  \n  local t_x = Video.Width / 6 * 3\n  local t_y = 50 + offy\n  local p_x = Video.Width / 6 * 5\n  local p_y = 100 + offy\n  local z_x = Video.Width / 6 * 1\n  local z_y = 100 + offy\n\n  menu:addAnimation(\"videos/campaign/disk.mng\", t_x, t_y + 160, true)\n  menu:addAnimation(\"videos/campaign/disk.mng\", p_x, p_y + 160, true)\n  menu:addAnimation(\"videos/campaign/disk.mng\", z_x, z_y + 160, true)\n\n  menu:addAnimatedButton(\n    \"videos/campaign/terr.mng\",\n    \"videos/campaign/terron.mng\",\n    t_x - 35, t_y,\n    t_x - 140, t_y - 50,\n    \"~light-green~T~!erran\",\n    \"t\",\n    function() RunCampaignSubmenu(\"scripts/terran/campaign1.lua\"); menu:stop() end,\n    false,\n    true\n  )\n\n  menu:addAnimatedButton(\n    \"videos/campaign/prot.mng\",\n    \"videos/campaign/proton.mng\",\n    p_x, p_y,\n    p_x - 140, p_y - 90,\n    \"~light-green~P~!rotoss\",\n    \"p\",\n    function() RunCampaignSubmenu(\"scripts/protoss/campaign1.lua\"); menu:stop() end,\n    false,\n    true\n  )\n  \n  menu:addAnimatedButton(\n    \"videos/campaign/zerg.mng\",\n    \"videos/campaign/zergon.mng\",\n    z_x + 5, z_y - 15,\n    z_x - 105, z_y - 50,\n    \"~light-green~Z~!erg\",\n    \"z\",\n    function() RunCampaignSubmenu(\"scripts/zerg/campaign1.lua\"); menu:stop() end,\n    false,\n    true\n  )\n  \n  --menu:addFullButton(\"~!Terran Campaign\", \"t\", offx + 208, offy + 212 + (36 * 0),\n    --function() RunCampaign(\"scripts/terran/campaign1.lua\"); menu:stop() end)\n  --menu:addFullButton(\"~!Zerg Campaign\", \"z\", offx + 208, offy + 212 + (36 * 1),\n    --function() RunCampaign(\"scripts/zerg/campaign1.lua\"); menu:stop() end):setEnabled(false)\n  --menu:addFullButton(\"~!Protoss Campaign\", \"p\", offx + 208, offy + 212 + (36 * 2),\n    --function() RunCampaign(\"scripts/protoss/campaign1.lua\"); menu:stop() end):setEnabled(false)\n\n  menu:addBottomButton(\"~!Skirmish\", \"s\", center, 1.9, RunSinglePlayerGameMenu)\n  menu:addBottomButton(\"~!Load\", \"l\", center, 0.7, RunReplayGameMenu)\n  menu:addBottomButton(\"~!Replay\", \"r\", center, -0.5, RunReplayGameMenu)\n  menu:addBottomButton(\"~!Cancel\", \"c\", center + Video.Width / 3, 0, function() menu:stop() end)\n\n  menu:run()\nend\n\n"
  },
  {
    "path": "scripts/menus/credits.lua",
    "content": "function RunShowCreditsMenu()\n  local menu = WarMenu(nil, \"ui/Menu background without title.png\")\n  local offx = (Video.Width - 640) / 2\n  local offy = (Video.Height - 480) / 2\n\n  local credits = {\n\t\"Programmers\",\n\t\"  Jimmy Salmon\",\n    \"  Francois Beerten\",\n\t\"  Nehal Mistry\",\n\t\"  Joris Dauphin\",\n\t\"  Russell Smith\",\n\t\"  Bradley Clemetson\",\n\t\"Patches\",\n\t\"  Martin Renold\",\n\t\"  Carlos Perello Marin\",\n\t\"  Pludov\",\n\t\"Past Programmers\",\n\t\"  Andreas 'Ari' Arens\",\n\t\"  Lutz 'Johns' Sammer\",\n\t\"  Edgar 'Froese' Toernig\",\n\t\"  Crestez Leonard\",\n\t\"  Mark Pazolli\",\n\t\"  Valery Shchedrin\",\n\t\"  Iftikhar Rathore\",\n\t\"  Charles K Hardin\",\n\t\"  Fabrice Rossi\",\n\t\"  DigiCat\",\n\t\"  Josh Cogliati\",\n\t\"  Patrick Mullen\",\n\t\"  Vladi Belperchinov-Shabanski\",\n\t\"  Cris Daniluk\",\n\t\"  Patrice Fortier\",\n\t\"  FT Rathore\",\n\t\"  Trent Piepho\",\n\t\"  Jon Gabrielson\",\n\t\"  Lukas Hejtmanek\",\n\t\"  Steinar Hamre\",\n\t\"  Ian Farmer\",\n\t\"  Sebastian Drews\",\n\t\"  Jarek Sobieszek\",\n\t\"  Anthony Towns\",\n\t\"  Stefan Dirsch\",\n\t\"  Al Koskelin\",\n\t\"  George J. Carrette\",\n\t\"  Dirk 'Guardian' Richartz\",\n\t\"  Michael O'Reilly\",\n\t\"  Dan Hensley\",\n\t\"  Sean McMillian\",\n\t\"  Mike Earl\",\n\t\"  Ian Turner\",\n\t\"  David Slimp\",\n\t\"  Iuri Fiedoruk\",\n\t\"  Luke Mauldin\",\n\t\"  Nathan Adams\",\n\t\"  Stephan Rasenberger\",\n\t\"  Dave Reed\",\n\t\"  Josef Spillner\",\n\t\"  James Dessart\",\n\t\"  Jan Uerpmann\",\n\t\"  Aaron Berger\",\n\t\"  Latimerius\",\n\t\"  Antonis Chaniotis\",\n\t\"  Samuel Hays\",\n\t\"  David Martinez Moreno\",\n\t\"  Flavio Silvestrow\",\n\t\"  Daniel Burrows\",\n\t\"  Dave Turner\",\n\t\"  Ben Hines\",\n\t\"  Kachalov Anton\",\n\t\"Past Patch Contributors\",\n\t\"  Martin Hajduch\",\n\t\"  Jeff Binder\",\n\t\"  Ludovic\",\n\t\"  Juan Pablo\",\n\t\"  Phil Hannent\",\n\t\"  Alexander MacLean\",\n\t\"\",\n\t\"Code used:\",\n\t\"  SDL Copyright by Sam Lantinga\",\n\t\"  ZLIB Copyright by Jean-loup Gailly and Mark Adler\",\n\t\"  BZ2LIB Copyright by Julian Seward\",\n\t\"  PNG Copyright by Glenn Randers-Pehrson\",\n\t\"  libmodplug Copyright by Kenton Varda & Olivier Lapique\",\n\t\"  OGG/Vorbis Copyright by Xiph.org Foundation\",\n\t\"  VP3 codec Copyright by On2 Technologies Inc.\",\n\t\"  Guichan Copyright by Per Larsson and Olof Naessen\",\n\t\"  tolua++ Copyright by Codenix\",\n\t\"\",\n\t\"\",\n\t\"The Stratagus Team thanks all the people who have contributed\",\n\t\"patches, bug reports, and ideas.\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"\",\n  }\n\n  local sw = ScrollingWidget(320, 275)\n  menu:add(sw, offx + 140, offy + 80)\n  sw:setBackgroundColor(Color(0,0,0,0))\n  sw:setActionCallback(function() sw:restart() end)\n  for i,f in ipairs(credits) do\n    sw:add(Label(f), 0, 24 * (i - 1) + 275)\n  end\n\n  menu:addHalfButton(\"~!Continue\", \"c\", offx + 455, offy + 440,\n    function() menu:stop() end)\n\n  local speed = GetGameSpeed()\n  SetGameSpeed(30)\n\n  menu:run()\n\n  SetGameSpeed(speed)\nend\n\n"
  },
  {
    "path": "scripts/menus/diplomacy.lua",
    "content": "function RunDiplomacyMenu()\n  local menu = WarGameMenu(panel(\"296x336\"))\n  menu:resize(296, 336)\n\n  menu:addLabel(\"Alliances\", 11, 13, Fonts[\"font16\"], false)\n  menu:addLabel(\"Allies\", 179, 21, Fonts[\"game\"])\n  menu:addLabel(\"Shared\", 246, 5, Fonts[\"game\"])\n  menu:addLabel(\"Vision\", 246, 21, Fonts[\"game\"])\n\n--  menu:addCheckBox(\"Allied Victory\", 11, 274)\n\n  local allied = {}\n  local enemy = {}\n  local sharedvision = {}\n  local j = 0\n\n  for i=0,11 do\n    if (Players[i].Type ~= PlayerNobody and ThisPlayer.Index ~= i) then\n      local l = Label(Players[i].Name)\n      l:setFont(Fonts[\"font16\"])\n      l:adjustSize()\n      menu:add(l, 31, (17 * j) + 41)\n      -- player color is at x=11, name is at x=31\n\n      -- FIXME: disable checkboxes in replays or if on the same team\n\n      local alliedcb = {}\n      local sharedvisioncb = {}\n\n      alliedcb = menu:addCheckBox(\"\", 227, (17 * j) + 41,\n        function() end)\n      alliedcb:setMarked(ThisPlayer:IsAllied(Players[i]))\n      allied[j] = alliedcb\n      allied[j].index = i\n\n      sharedvisioncb = menu:addCheckBox(\"\", 269, (17 * j) + 41,\n        function() end)\n      -- FIXME: IsSharedVision() produces a LUA stacktrace\n      --sharedvisioncb:setMarked(ThisPlayer:IsSharedVision(Players[i]))\n      sharedvision[j] = sharedvisioncb\n\n      j = j + 1\n    end\n  end\n\n  menu:addHalfLeftButton(\"Accept\", nil, 11, 299,\n    function()\n      for j=1,table.getn(allied) do\n        local i = allied[j].index\n\n        -- allies\n        if (allied[j]:isMarked()) then\n          if (ThisPlayer:IsAllied(Players[i]) == false or\n             ThisPlayer:IsEnemy(Players[i])) then\n            SetDiplomacy(ThisPlayer.Index, \"allied\", i)\n          end\n        end\n\n        -- enemies\n        if (allied[j]:isMarked() == false) then\n          if (ThisPlayer:IsAllied(Players[i]) or\n             ThisPlayer:IsEnemy(Players[i]) == false) then\n            SetDiplomacy(ThisPlayer.Index, \"enemy\", i)\n          end\n        end\n\n        -- shared vision\n        if (sharedvision[j]:isMarked()) then\n          if (ThisPlayer:IsSharedVision(Players[i]) == false) then\n            SetSharedVision(ThisPlayer.Index, true, i)\n          end\n        else\n          if (ThisPlayer:IsSharedVision(Players[i])) then\n            SetSharedVision(ThisPlayer.Index, false, i)\n          end\n        end\n      end\n      menu:stop()\n    end)\n  menu:addHalfRightButton(\"Cancel\", nil, 165, 299, function() menu:stop() end)\n\n  menu:run(false)\nend\n\n"
  },
  {
    "path": "scripts/menus/endscenario.lua",
    "content": "function RunEndScenarioMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  menu:addLabel(\"End Mission\", 264/2, 8)\n\n  local b = menu:addFullButton(\"~!Restart Mission\", \"r\", 20, 70,\n    function() RunRestartConfirmMenu() end)\n  if (IsNetworkGame()) then\n    b:setEnabled(false)\n  end\n  menu:addFullButton(\"~!Quit Mission\", \"q\", 20, 104,\n    function() RunQuitToMenuConfirmMenu() end)\n  menu:addFullButton(\"E~!xit Program\", \"x\", 20, 138,\n    function() RunExitConfirmMenu() end)\n  menu:addFullButton(\"Previous (~<Esc~>)\", \"escape\", 20, 252,\n    function() menu:stop() end)\n\n--  menu:addFullButton(\"~!Surrender\", \"s\", 20, 172,\n--    function() RunSurrenderConfirmMenu() end)\n\n  menu:run(false)\nend\n\nfunction RunRestartConfirmMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  menu:addLabel(\"Are you sure you\", 264/2, 8)\n  menu:addLabel(\"want to restart\", 264/2, 32)\n  menu:addLabel(\"the scenario?\", 264/2, 56)\n  menu:addFullButton(\"~!Restart Mission\", \"r\", 20, 104,\n    function() StopGame(GameRestart); menu:stopAll() end)\n  menu:addFullButton(\"Cancel (~<Esc~>)\", \"escape\", 20, 252,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\nfunction RunSurrenderConfirmMenu()\n  local menu = WarGameMenu(panel(1))\n\n  menu:addLabel(\"Are you sure you\", 128, 11)\n  menu:addLabel(\"want to surrender\", 128, 11 + (24 * 1))\n  menu:addLabel(\"to your enemies?\", 128, 11 + (24 * 2))\n  menu:addFullButton(\"~!Surrender\", \"s\", 16, 11 + (24 * 3) + 29,\n    function() StopGame(GameDefeat); menu:stopAll() end)\n  menu:addFullButton(\"Cancel (~<Esc~>)\", \"escape\", 16, 248,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\nfunction RunQuitToMenuConfirmMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  menu:addLabel(\"Are you sure you\", 264/2, 8)\n  menu:addLabel(\"want to quit\", 264/2, 32)\n  menu:addLabel(\"the mission?\", 264/2, 56)\n  menu:addFullButton(\"~!Quit Mission\", \"q\", 20, 104,\n    function() StopGame(GameQuitToMenu); menu:stopAll() end)\n--  menu:addFullButton(\"Become O~!bserver\", \"b\", 20, 138,\n--    function() end)\n  menu:addFullButton(\"Cancel (~<Esc~>)\", \"escape\", 20, 252,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\nfunction RunExitConfirmMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  menu:addLabel(\"Are you sure you\", 264/2, 8)\n  menu:addLabel(\"want to exit\", 264/2, 32)\n  menu:addLabel(\"Stargus?\", 264/2, 56)\n  menu:addFullButton(\"E~!xit Program\", \"x\", 20, 104,\n    function() Exit(0) end)\n  menu:addFullButton(\"Cancel (~<Esc~>)\", \"escape\", 20, 252,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\n"
  },
  {
    "path": "scripts/menus/game.lua",
    "content": "function WarGameMenu(background)\n  local menu = MenuScreen()\n\n  if (background == nil) then\n    menu:setOpaque(true)\n    menu:setBaseColor(dark)\n  else\n    local bgg = CGraphic:New(background)\n    bgg:Load()\n    local bg = ImageWidget(bgg)\n    menu:add(bg, 0, 0)\n  end\n\n  function menu:resize(w, h)\n    menu:setSize(w, h)\n    menu:setPosition((Video.Width - menu:getWidth()) / 2,\n      (Video.Height - 128 - menu:getHeight()) / 2)\n  end\n\n  menu:resize(256, 288)\n  menu:setBorderSize(0)\n\n  AddMenuHelpers(menu)\n\n  return menu\nend\n\n\n\nfunction RunGameMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  menu:addLabel(\"Game Menu\", 264/2, 8)\n\n  menu:addFullButton(\"~!Save Game\", \"s\", 20, 36,\n    function() RunSaveMenu() end)\n  menu:addFullButton(\"~!Load Game\", \"l\", 20, 70,\n    function() RunGameLoadGameMenu() end)\n--[[\n  menu:addFullButton(\"~!Pause Game\", \"p\", 20, 70,\n    function() end)\n  menu:addFullButton(\"~!Resume Game\", \"r\", 20, 70,\n    function() end)\n]]\n  menu:addFullButton(\"~!Options\", \"o\", 20, 104,\n    function() RunGameOptionsMenu() end)  \n  menu:addFullButton(\"~!Help\", \"h\", 20, 138,\n    function() RunHelpMenu() end)\n  menu:addFullButton(\"Mission Ob~!jectives\", \"j\", 20, 172,\n    function() RunObjectivesMenu() end)\n  menu:addFullButton(\"~!End Mission\", \"e\", 20, 206,\n    function() RunEndScenarioMenu() end)\n  menu:addFullButton(\"Return to Game (~<Esc~>)\", \"escape\", 20, 252,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\n"
  },
  {
    "path": "scripts/menus/help.lua",
    "content": "function RunHelpMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  menu:addLabel(\"Help Menu\", 264/2, 8)\n  menu:addFullButton(\"Keystroke ~!Help\", \"h\", 20, 36,\n    function() RunKeystrokeHelpMenu() end)\n  menu:addFullButton(\"Stargus ~!Tips\", \"t\", 20, 70,\n    function() RunTipsMenu() end)\n  menu:addFullButton(\"Previous (~<Esc~>)\", \"escape\", 20, 252,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\nlocal keystrokes = {\n  {\"Alt-F\", \"- toggle full screen\"},\n  {\"Alt-G\", \"- toggle grab mouse\"},\n  {\"Ctrl-S\", \"- mute sound\"},\n  {\"Ctrl-M\", \"- mute music\"},\n  {\"+\", \"- increase game speed\"},\n  {\"-\", \"- decrease game speed\"},\n  {\"Ctrl-P\", \"- pause game\"},\n  {\"PAUSE\", \"- pause game\"},\n  {\"PRINT\", \"- make screen shot\"},\n  {\"Alt-H\", \"- help menu\"},\n  {\"Alt-R\", \"- restart scenario\"},\n  {\"Alt-Q\", \"- quit to main menu\"},\n  {\"Alt-X\", \"- quit game\"},\n  {\"Alt-B\", \"- toggle expand map\"},\n  {\"Alt-M\", \"- game menu\"},\n  {\"ENTER\", \"- write a message\"},\n  {\"SPACE\", \"- goto last event\"},\n  {\"TAB\", \"- hide/unhide terrain\"},\n  {\"Ctrl-T\", \"- track unit\"},\n  {\"Alt-I\", \"- find idle peon\"},\n  {\"Alt-C\", \"- center on selected unit\"},\n  {\"Alt-V\", \"- next view port\"},\n  {\"Ctrl-V\", \"- previous view port\"},\n  {\"^\", \"- select nothing\"},\n  {\"#\", \"- select group\"},\n  {\"##\", \"- center on group\"},\n  {\"Ctrl-#\", \"- define group\"},\n  {\"Shift-#\", \"- add to group\"},\n  {\"Alt-#\", \"- add to alternate group\"},\n  {\"F2-F4\", \"- recall map position\"},\n  {\"Shift F2-F4\", \"- save map postition\"},\n  {\"F5\", \"- game options\"},\n  {\"F7\", \"- sound options\"},\n  {\"F8\", \"- speed options\"},\n  {\"F9\", \"- preferences\"},\n  {\"F10\", \"- game menu\"},\n  {\"F11\", \"- save game\"},\n  {\"F12\", \"- load game\"},\n}\n\nfunction RunKeystrokeHelpMenu()\n  local menu = WarGameMenu(panel(\"312x312\"))\n  menu:resize(312, 312)\n\n  local c = Container()\n  c:setOpaque(false)\n\n  for i=1,table.getn(keystrokes) do\n    local l = Label(keystrokes[i][1])\n    l:setFont(Fonts[\"game\"])\n    l:adjustSize()\n    c:add(l, 0, 20 * (i - 1))\n    local l = Label(keystrokes[i][2])\n    l:setFont(Fonts[\"game\"])\n    l:adjustSize()\n    c:add(l, 80, 20 * (i - 1))\n  end\n\n  local s = ScrollArea()\n  c:setSize(280 - s:getScrollbarWidth(), 20 * table.getn(keystrokes))\n  s:setBaseColor(dark)\n  s:setBackgroundColor(dark)\n  s:setForegroundColor(clear)\n  s:setSize(280, 220)\n  s:setContent(c)\n  menu:add(s, 16, 40)\n\n  menu:addLabel(\"Stargus Help\", 312/2, 8)\n  menu:addHalfButton(\"~!OK\", \"o\", 100, 276,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\nlocal tips = {\n  \"Click on NEXT TIP to cycle through all available tips. You can activate this help menu at any time by clicking on the MENU button and choosing HELP. \",\n  \"Units can be ordered to move, attack, gather resources, or repair other units and buildings automatically. With a unit selected, right-click on the area or target where the action will be performed.\",\n  \"To toggle subtitles on or off, go to MENU. Under OPTIONS, select SOUND and click on the box marked TOGGLE SUBTITLES.\",\n  \"The Terran Refinery, Zerg Extractor and Protoss Assimilator must be constructed on top of a Vespene Geyser before any gas can be collected.\",\n  \"Most commands in the game have hot keys.  These keys are denoted by the highlighted letter in the text of the command button.\",\n  \"To restart a mission, choose END MISSION from the menu.\",\n  \"Mission objectives may be viewed at any time by choosing MISSION OBJECTIVES from the menu.\",\n  \"Any Terran Infantry units may be placed inside a Bunker. While inside a Bunker, units are shielded from attacks, but are free to return fire. To load a unit into a Bunker, select the unit and right-click on the Bunker.\",\n  \"Terran Vultures can lay Spider Mines: select a Vulture unit, then select the MINE button and designate an area of ground as the target. \",\n  \"Queue up to five units at the same time by selecting a building, then clicking on the button of the unit you wish to queue.\",\n  \"Terran Marines and Firebats have \\\"Stimpack\\\" upgrades. Stimpacks increase a unit's attack rate and movement rate, at a cost of 10 hit points per \\\"stim.\\\"\",\n  \"In some missions, you must return specific units to a particular location, designated by a glowing Command Point Marker, called a \\\"Beacon.\\\"\",\n  \"When building a Terran Command Center, Protoss Nexus, or Zerg Hatchery, try to place it as close to resources as possible.\",\n  \"Both the Terran Wraith and Ghost have the ability to \\\"Cloak.\\\" While cloaked, they are safe from attack, unless spotted by enemy detection units.\",\n  \"Cancel any unit in a queue by clicking on its icon in the construction \\\"pipeline\\\" display.\",\n  \"Toggle the terrain information on and off in the Mini Map by pressing ~<TAB~>.\",\n  \"Terran Dropships ferry units quickly between areas. Load Dropships by selecting one or more units, then right-clicking on the Dropship. Dropships are built at the Starport.\",\n  \"Toggle the Mini Map between Team Color Identification and Friend-or-Foe recognition modes by pressing ~<SHIFT+TAB~>.\",\n  \"When using the MOVE command, your units will ignore enemy units as they travel to their destination.  In this way, you can also use the MOVE command to retreat.\",\n  \"Most Terran buildings can fly. Select the building and click the LIFTOFF button to fly; press the button again to select a location to land.\",\n  \"Move your units with the ATTACK command when you wish them to engage enemy forces along the way.\",\n  \"You can adjust the sound, music, and speech in the SOUND menu.\",\n  \"Take over abandoned Terran add-ons (Machine Shops, Control Towers, etc.) by landing your own buildings next to them. \",\n  \"You can adjust the game speed, mouse speed, and other speed settings in the SPEED menu.\",\n  \"In single player games, you can speed up or slow down the game by pressing the ~<+~> or ~<-~> keys.\",\n  \"The Terran Nuclear Silo is an add-on to the Command Center. To launch a nuclear attack, build a nuclear missile at the silo, then use a Ghost unit to designate a target.\",\n  \"Deselect an individual unit from a group by holding down the ~<SHIFT~> key while selecting that unit.\",\n  \"To single out a unit from within a group, either select the individual unit, or select that unit's wireframe from the status display. \",\n  \"Missile Turrets and Science vessels reveal hidden units within their range. The Comsat station briefly reveals hidden units anywhere on the map with its Sensor Sweep.\",\n  \"Load units into a transport using the MOVE command. The transport will automatically move to meet the units.\",\n  \"Unload units from a transport by clicking the UNLOAD ALL button and selecting an unloading area. Unload an individual unit by clicking on its wireframe.\",\n  \"All Zerg buildings, except the Hatchery and Extractor, must be constructed on creep. Creep can be created by building a Hatchery or a creep colony.\",\n  \"You can designate targets for your commands (MOVE, ATTACK, GATHER, etc.) using the Mini Map.  In this way, you can send units to distant locations without having to scroll the Main Screen.\",\n  \"Click and drag in the Mini Map to rapidly scroll your view in the main screen.\",\n  \"The Zerg Hatchery can be upgraded to a Lair and eventually a Hive.  Each upgrade allows you to build additional Zerg structures.\",\n  \"To select a unit's previous group, hold down the ~<ALT~> key while selecting that unit.\",\n  \"SAVE your game frequently. If you find yourself in a desperate situation, you can go back and LOAD your game before you got into this whole mess. \",\n  \"Zerg Overlords can be upgraded to carry units at the Lair or Hive. Once upgraded, you can use them as transports by selecting a group of units and right-clicking on an Overlord.\",\n  \"Use the Campaign Editor, found on the Main Menu, to build your own maps and edit unit variables.\",\n  \"You can turn off unit responses in the SOUND menu.\",\n  \"Zerg Queens have the ability to \\\"Infest\\\" a severely damaged Terran Command Center. Once infested, the Command Center is now a Zerg structure capable of building Infested Terrans that explode when attacking.\",\n  \"The ~<SHIFT~> key allows you to chain together multiple commands. Hold down the SHIFT key while issuing commands; the unit will finish each task before proceeding to the next.\",\n  \"You can use the PATROL command to setup a patrol route for your units.  While in patrol mode your units will attack any enemy units that they see.\",\n  \"Most Zerg ground units have the ability to Burrow. When Burrowed, they cannot attack or be attacked unless detected. \",\n  \"Stationary combat units are assumed to be on guard: if they see an enemy unit they will automatically engage it.\",\n  \"Using the HOLD POSITION command, units will remain stationary, even if attacked, and attack enemy units within their range.\",\n  \"Zerg Mutalisks can be transformed into a unit called the Guardian. Once a Spire is upgraded into a Greater Spire, all Mutalisks automatically gain the ability to transform into Guardians.\",\n  \"You can setup convoys by selecting your escorts and telling them to MOVE onto the unit you want escorted.  They will then follow the designated unit.\",\n  \"To send messages to your opponent during multiplayer games, press ~<Enter~>, type in your message and press ~<Enter~> again.\",\n  \"Zerg Defilers have the ability to CONSUME their own units. Every unit consumed restores 50 energy points to the Defiler.\",\n  \"You can form alliances during a multiplayer game using the DIPLOMACY button on the Command Console.\",\n  \"During multiplayer games, allies achieve a shared victory only if all surviving allies have selected ALLIED VICTORY from the DIPLOMACY MENU.\",\n  \"Use the PLAGUE spell to severely damage any unit or building. It will cause up to 300 points of damage to its target, but will not kill a target.\",\n  \"In a multiplayer game, allies can share their fog of war information once all members of the alliance select SHARE VISION from the DIPLOMACY MENU.\",\n  \"Pressing ~<CTRL-S~> will toggle the sound on or off.  ~<CTRL-M~> will toggle the music on or off.\",\n  \"Zerg Scourge can be set on Patrol to automatically attack all air units that come near. \",\n  \"To surrender during a campaign or multiplayer game, use the SURRENDER button in the OPTIONS menu.\",\n  \"The Zerg Queen's ENSNARE spell and The Defiler's PLAGUE spell can be cast on cloaked units to allow other units to target them.\",\n  \"Keep the path between the Command Center and available resources clear.  Obstacles slow the rate at which resources can be returned.\",\n  \"All Protoss buildings, except the Nexus, must be built within the energy field of a Pylon. \",\n  \"To save your current position on the map, press ~<Shift-F2~>. To recall that position at any time, press ~<F2~>. You can save up to three views using keys F2-F4 in this manner.\",\n  \"Protoss Reavers attack by firing explosive \\\"Scarabs\\\" at their targets. To build Scarabs, select the Reaver and press the BUILD SCARABS button.\",\n  \"Different units are designed to work together and support each other. Combinations are more effective than a force composed of a single unit type.\",\n  \"Protoss Probes can build multiple buildings at one time. Once a building warp has been started, the Probe can move onto a new task.\",\n  \"Hold down ~<CTRL~> while selecting a unit to select all units of the same type within your view.\",\n  \"Use PSIONIC STORM to damage all units in the spell's area of effect. It is devastating against a tight formation of enemy units.\",\n  \"Double-click a unit to select all units of the same type within your view.\",\n  \"Protoss Templars have the ability to transform into a powerful fighting unit called an Archon. Select two Templars and press the ARCHON WARP button to create an Archon.\",\n  \"Pressing the space bar will center the screen on the location of your last transmission.\",\n  \"Use HALLUCINATION to make multiple holograms of a single unit. Use them to scout and draw enemy fire as decoys. \",\n  \"To save your currently selected group of units, press ~<CTRL-1~>. To recall that group at any time, press ~<1~>. You can save up to ten groups using keys 1 through 0 in this manner. This also works for buildings.\",\n  \"Protoss Observers are great for scouting: they remain permanently cloaked, and can detect hidden units.\",\n  \"In a multiplayer game, pressing ~<SHIFT-ENTER~> sends your message to all players.\",\n  \"Protoss Carriers attack by launching small interceptors that swarm their target. To build Interceptors, select the Carrier and press the BUILD INTERCEPTORS button.\",\n  \"In a multiplayer game, pressing ~<CTRL-ENTER~> sends a message that is exclusive to your allies.\",\n  \"The Protoss Arbiter cloaks all nearby units, although the Arbiter itself remains visible. Arbiters cannot cloak each other.\",\n  \"Units caught in an Arbiter's Stasis Field can neither attack nor be attacked for the duration of the spell.\",\n  \"Protoss Arbiters can use Recall to instantly teleport units to their location. \",\n  \"In Greed and Slaughter Mutiplayer games, a leaderboard displays the current leader. Press ~<CTRL-R~> to toggle between displaying the leader, and displaying all players.\",\n  \"Tell everyone you know to buy Starcraft.\",}\n\nfunction RunTipsMenu()\n  local menu = WarGameMenu(panel(\"384x256\"))\n  menu:resize(384, 256)\n\n  menu:addLabel(\"Stargus Tips\", 384/2, 8)\n\n  local l = MultiLineLabel()\n  l:setFont(Fonts[\"game\"])\n  l:setSize(372, 148)\n  l:setLineWidth(372)\n  menu:add(l, 6, 32)\n\n  function l:prevTip()\n    preferences.TipNumber = preferences.TipNumber - 1\n    if (preferences.TipNumber < 1) then\n      preferences.TipNumber = table.getn(tips)\n    end\n    SavePreferences()\n  end\n  function l:nextTip()\n    preferences.TipNumber = preferences.TipNumber + 1\n    if (preferences.TipNumber > table.getn(tips)) then\n      preferences.TipNumber = 1\n    end\n    SavePreferences()\n  end\n  function l:updateCaption()\n    self:setCaption(tips[preferences.TipNumber])\n  end\n\n  if (preferences.TipNumber == 0) then\n    l:nextTip()\n  end\n  l:updateCaption()\n\n  local showtips = {}\n  showtips = menu:addCheckBox(\"~!Show Tips at Startup\", 20, 188,\n    function()\n      preferences.ShowTips = showtips:isMarked()\n      SavePreferences()\n    end)\n  showtips:setMarked(preferences.ShowTips)\n\n  menu:addHalfLeftButton(\"~!OK\", \"o\", 20, 216,\n    function() l:nextTip(); menu:stop() end)\n  menu:addHalfButton(\"~!Previous Tip\", \"p\", 140, 216,\n    function() l:prevTip(); l:updateCaption() end)\n  menu:addHalfRightButton(\"~!Next Tip\", \"n\", 260, 216,\n    function() l:nextTip(); l:updateCaption() end)\n\n  menu:run(false)\nend\n\n\n"
  },
  {
    "path": "scripts/menus/load.lua",
    "content": "function LoadGame(s)\n  LoadGameFile = nil\n  currentCampaign = nil\n  loop = true\n\n  while (loop) do\n    InitGameVariables()\n    StartSavedGame(s)\n    if (GameResult ~= GameRestart) then\n      loop = false\n    end\n  end\n\n  RunResultsMenu()\n\n  InitGameSettings()\n  SetPlayerData(GetThisPlayer(), \"RaceName\", \"orc\")\n\n  if currentCampaign ~= nil then\n    if GameResult == GameVictory then\n      position = position + 1\n    elseif (GameResult == GameDefeat) then\n    elseif (GameResult == GameDraw) then\n    else\n      currentCampaign = nil -- quit to menu\n      return\n    end\n    RunCampaign(currentCampaign)\n  end\nend\n\nfunction AddLoadGameItems(menu)\n  menu:addLabel(\"Load Game\", 384/2, 8)\n  local browser = menu:addBrowser(\"~save\", \"^.*%.sav%.?g?z?$\",\n    32, 44, 320, 160)\n\n  menu:addFullLeftButton(\"~!Load\", \"l\", 20, 216,\n    function()\n      if (browser:getSelected() < 0) then\n        return\n      end\n      LoadGameFile = \"~save/\" .. browser:getSelectedItem()\n      if (menu.ingame) then\n        StopGame(GameNoResult)\n        menu:stopAll()\n      else\n        menu:stop()\n      end\n    end)\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 260, 216,\n    function() menu:stop() end)\nend\n\nfunction RunLoadGameMenu()\n  local menu = WarMenu(nil, panel(\"384x256\"), false)\n  menu:setSize(384, 256)\n  menu:setPosition((Video.Width - 384) / 2, (Video.Height - 256) / 2)\n\n  AddLoadGameItems(menu)\n\n  menu.ingame = false\n  menu:run()\nend\n\nfunction RunGameLoadGameMenu()\n  local menu = WarGameMenu(panel(\"384x256\"))\n  menu:resize(384, 256)\n\n  AddLoadGameItems(menu)\n\n  menu.ingame = true\n  menu:run(false)\nend\n\n"
  },
  {
    "path": "scripts/menus/network.lua",
    "content": "--  (c) Copyright 2005-2006 by François Beerten and Jimmy Salmon\n\nfunction bool2int(boolvalue)\n  if boolvalue == true then\n    return 1\n  else\n    return 0\n  end\nend\n\nfunction int2bool(int)\n  if int == 0 then\n    return false\n  else\n    return true\n  end\nend\n\nfunction ErrorMenu(errmsg)\n  local menu = WarMenu(nil, panel(\"288x128\"), false)\n  menu:setSize(288, 128)\n  menu:setPosition((Video.Width - 288) / 2, (Video.Height - 128) / 2)\n\n  local l = MultiLineLabel(errmsg)\n  l:setFont(Fonts[\"large\"])\n  l:setAlignment(MultiLineLabel.CENTER)\n  l:setVerticalAlignment(MultiLineLabel.CENTER)\n  l:setLineWidth(270)\n  l:setWidth(264)\n  l:setHeight(80)\n  l:setBackgroundColor(dark)\n  menu:add(l, 12, 8)\n\n  menu:addHalfButton(\"~!OK\", \"o\", 92, 92, function() menu:stop() end)\n\n  menu:run()\nend\n\nfunction addPlayersList(menu, numplayers)\n  local i\n  local players_name = {}\n  local players_state = {}\n  local sx = Video.Width / 20\n  local sy = Video.Height / 20\n  local numplayers_text\n\n  menu:writeLargeText(\"Players\", sx * 11, sy*3)\n  for i=1,8 do\n    players_name[i] = menu:writeText(\"Player\"..i, sx * 11, sy*4 + i*18)\n    players_state[i] = menu:writeText(\"Preparing\", sx * 11 + 80, sy*4 + i*18)\n  end\n  numplayers_text = menu:writeText(\"Open slots : \" .. numplayers - 1, sx *11, sy*4 + 144)\n\n  local function updatePlayers()\n    local connected_players = 0\n    local ready_players = 0\n    players_state[1]:setCaption(\"Creator\")\n    players_name[1]:setCaption(Hosts[0].PlyName)\n    for i=2,8 do\n      if Hosts[i-1].PlyName == \"\" then\n        players_name[i]:setCaption(\"\")\n        players_state[i]:setCaption(\"\")\n      else\n        connected_players = connected_players + 1\n        if ServerSetupState.Ready[i-1] == 1 then\n          ready_players = ready_players + 1\n          players_state[i]:setCaption(\"Ready\")    \n        else\n          players_state[i]:setCaption(\"Preparing\")\n        end\n        players_name[i]:setCaption(Hosts[i-1].PlyName)\n     end\n    end\n    numplayers_text:setCaption(\"Open slots : \" .. numplayers - 1 - connected_players)\n    numplayers_text:adjustSize()\n    return (connected_players > 0 and ready_players == connected_players)\n  end\n\n  return updatePlayers\nend\n\n\njoincounter = 0\n\nfunction RunJoiningMapMenu(s)\n  local menu\n  local listener  \n  local sx = Video.Width / 20\n  local sy = Video.Height / 20\n  local numplayers = 3\n  local state\n  local d\n\n  menu = WarMenu(\"Joining game: Map\")\n\n  menu:writeLargeText(\"Map\", sx, sy*3)\n  menu:writeText(\"File:\", sx, sy*3+30)\n  maptext = menu:writeText(NetworkMapName, sx+50, sy*3+30)\n  menu:writeText(\"Players:\", sx, sy*3+50)\n  players = menu:writeText(numplayers, sx+70, sy*3+50)\n  menu:writeText(\"Description:\", sx, sy*3+70)\n  descr = menu:writeText(description, sx+20, sy*3+90)\n\n  local fow = menu:addCheckBox(\"Fog of war\", sx, sy*3+120, function() end)\n  fow:setMarked(true)\n  ServerSetupState.FogOfWar = 1\n  fow:setEnabled(false)\n  local revealmap = menu:addCheckBox(\"Reveal map\", sx, sy*3+150, function() end)\n  revealmap:setEnabled(false)\n  \n  menu:writeText(\"Units:\", sx, sy*11)\n  local units = menu:addDropDown({\"Map Default\", \"One Peasant Only\"}, sx + 100, sy*11,\n    function(dd) end)\n  units:setSize(190, 20)\n  units:setEnabled(false)\n\n  menu:writeText(\"Resources:\", sx, sy*11+25)\n  local resources = menu:addDropDown({\"Map Default\", \"Low\", \"Medium\", \"High\"}, sx + 100, sy*11+25,\n    function(dd) end)\n  resources:setSize(190, 20)\n  resources:setEnabled(false)\n\n  local OldPresentMap = PresentMap\n  PresentMap = function(desc, nplayers, w, h, id)\n    numplayers = nplayers\n    players:setCaption(\"\"..nplayers)\n    players:adjustSize()\n    descr:setCaption(desc)\n    descr:adjustSize()\n    OldPresentMap(desc, nplayers, w, h, id)\n  end\n\n  -- Security: The map name is checked by the stratagus engine.\n  Load(NetworkMapName)\n  local function readycb(dd)\n     LocalSetupState.Ready[NetLocalHostsSlot] = bool2int(dd:isMarked())\n  end\n  menu:addCheckBox(\"~!Ready\", sx*11,  sy*14, readycb)\n\n  local updatePlayersList = addPlayersList(menu, numplayers)\n\n  joincounter = 0\n  local function listen()\n    NetworkProcessClientRequest()\n    fow:setMarked(int2bool(ServerSetupState.FogOfWar))\n    GameSettings.NoFogOfWar = not int2bool(ServerSetupState.FogOfWar)\n    revealmap:setMarked(int2bool(ServerSetupState.RevealMap))\n    GameSettings.RevealMap = ServerSetupState.RevealMap\n    units:setSelected(ServerSetupState.UnitsOption)\n    GameSettings.NumUnits = ServerSetupState.UnitsOption\n    resources:setSelected(ServerSetupState.ResourcesOption)\n    GameSettings.Resources = ServerSetupState.ResourcesOption\n    updatePlayersList()\n    state = GetNetworkState()\n    -- FIXME: don't use numbers\n    if (state == 15) then -- ccs_started, server started the game\n      SetThisPlayer(1)\n      joincounter = joincounter + 1\n      if (joincounter == 30) then\n        SetFogOfWar(fow:isMarked())\n        if revealmap:isMarked() == true then\n          RevealMap()\n        end\n        NetworkGamePrepareGameSettings()\n        RunMap(NetworkMapName)\n        PresentMap = OldPresentMap\n        menu:stop()\n      end\n    elseif (state == 10) then -- ccs_unreachable\n      ErrorMenu(\"Cannot reach server\")\n      menu:stop()\n    end\n  end\n  listener = LuaActionListener(listen)\n  menu:addLogicCallback(listener)\n\n  menu:addFullButton(\"~!Cancel\", \"c\", Video.Width / 2 - 100, Video.Height - 100,\n    function() NetworkDetachFromServer(); menu:stop() end)\n\n  menu:run()\nend\n\nfunction RunJoiningGameMenu(s)\n  local menu = WarMenu(nil, panel(\"288x128\"), false)\n  menu:setSize(288, 128)\n  menu:setPosition((Video.Width - 288) / 2, (Video.Height - 128) / 2)\n\n  menu:addLabel(\"Connecting to server\", 144, 8)\n\n  local percent = 0\n\n  local sb = StatBoxWidget(258, 30)\n  sb:setCaption(\"Connecting...\")\n  sb:setPercent(percent)\n  menu:add(sb, 15, 38)\n  sb:setBackgroundColor(dark)\n\n  local function checkconnection() \n    NetworkProcessClientRequest()\n    percent = percent + 100 / (24 * GetGameSpeed()) -- 24 seconds * fps\n    sb:setPercent(percent)\n    local state = GetNetworkState()\n    -- FIXME: do not use numbers\n    if (state == 3) then -- ccs_mapinfo\n      -- got ICMMap => load map\n      RunJoiningMapMenu()\n      menu:stop(0)\n    elseif (state == 4) then -- ccs_badmap\n      ErrorMenu(\"Map not available\")\n      menu:stop(1)\n    elseif (state == 10) then -- ccs_unreachable\n      ErrorMenu(\"Cannot reach server\")\n      menu:stop(1)\n    elseif (state == 12) then -- ccs_nofreeslots\n      ErrorMenu(\"Server is full\")\n      menu:stop(1)\n    elseif (state == 13) then -- ccs_serverquits\n      ErrorMenu(\"Server gone\")\n      menu:stop(1)\n    elseif (state == 16) then -- ccs_incompatibleengine\n      ErrorMenu(\"Incompatible engine version\")\n      menu:stop(1)\n    elseif (state == 17) then -- ccs_incompatiblenetwork\n      ErrorMenu(\"Incompatible netowrk version\")\n      menu:stop(1)\n    end\n  end\n  local listener = LuaActionListener(checkconnection)\n  menu:addLogicCallback(listener)\n\n  menu:addHalfButton(\"~!Cancel\", \"c\", 92, 92,\n    function() menu:stop(1) end)\n\n  menu:run()\nend\n\nfunction RunJoinIpMenu()\n  local menu = WarMenu(nil, panel(\"288x128\"), false)\n  menu:setSize(288, 128)\n  menu:setPosition((Video.Width - 288) / 2, (Video.Height - 128) / 2)\n\n  menu:addLabel(\"Enter server IP-address:\", 144, 8)\n  local server = menu:addTextInputField(\"localhost\", 40, 38, 212)\n\n  menu:addHalfLeftButton(\"~!OK\", \"o\", 24, 92,\n    function(s) \n      -- FIXME: allow port (\"localhost:1234\")\n      if (NetworkSetupServerAddress(server:getText()) ~= 0) then\n        ErrorMenu(\"Invalid server name\")\n        return\n      end\n      NetworkInitClientConnect() \n      if (RunJoiningGameMenu() ~= 0) then\n        -- connect failed, don't leave this menu\n        return\n      end\n      menu:stop() \n    end\n  )\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 160, 92,\n    function() menu:stop() end)\n\n  menu:run()\nend\n\nfunction RunServerMultiGameMenu(map, description, numplayers)\n  local menu\n  local sx = Video.Width / 20\n  local sy = Video.Height / 20\n  local startgame\n  local d\n\n  menu = WarMenu(\"Create MultiPlayer game\")\n\n  menu:writeLargeText(\"Map\", sx, sy*3)\n  menu:writeText(\"File:\", sx, sy*3+30)\n  maptext = menu:writeText(map, sx+50, sy*3+30)\n  menu:writeText(\"Players:\", sx, sy*3+50)\n  players = menu:writeText(numplayers, sx+70, sy*3+50)\n  menu:writeText(\"Description:\", sx, sy*3+70)\n  descr = menu:writeText(\"Unknown map\", sx+20, sy*3+90)\n\n  local function fowCb(dd)\n    ServerSetupState.FogOfWar = bool2int(dd:isMarked()) \n    NetworkServerResyncClients()\n    GameSettings.NoFogOfWar = not dd:isMarked()\n  end\n  local fow = menu:addCheckBox(\"Fog of war\", sx, sy*3+120, fowCb)\n  fow:setMarked(true)\n  local function revealMapCb(dd)\n    ServerSetupState.RevealMap = bool2int(dd:isMarked()) \n    NetworkServerResyncClients()\n    GameSettings.RevealMap = bool2int(dd:isMarked())\n  end\n  local revealmap = menu:addCheckBox(\"Reveal map\", sx, sy*3+150, revealMapCb)\n  \n  menu:writeText(\"Units:\", sx, sy*11)\n  d = menu:addDropDown({\"Map Default\", \"One Peasant Only\"}, sx + 100, sy*11,\n    function(dd)\n      GameSettings.NumUnits = dd:getSelected()\n      ServerSetupState.UnitsOption = GameSettings.NumUnits\n      NetworkServerResyncClients()\n    end)\n  d:setSize(190, 20)\n\n  menu:writeText(\"Resources:\", sx, sy*11+25)\n  d = menu:addDropDown({\"Map Default\", \"Low\", \"Medium\", \"High\"}, sx + 100, sy*11+25,\n    function(dd)\n      GameSettings.Resources = dd:getSelected()\n      ServerSetupState.ResourcesOption = GameSettings.Resources\n      NetworkServerResyncClients()\n    end)\n  d:setSize(190, 20)\n\n  local updatePlayers = addPlayersList(menu, numplayers)\n\n  NetworkMapName = map\n  NetworkInitServerConnect(numplayers)\n  ServerSetupState.FogOfWar = 1\n  startgame = menu:addFullButton(\"~!Start Game\", \"s\", sx * 11,  sy*14, \n    function(s)    \n      SetFogOfWar(fow:isMarked())\n      if revealmap:isMarked() == true then\n        RevealMap()\n      end\n      NetworkServerStartGame() \n      NetworkGamePrepareGameSettings()\n      RunMap(map)\n      menu:stop()\n    end\n  )\n  startgame:setVisible(false)\n  local waitingtext = menu:writeText(\"Waiting for players\", sx*11, sy*14)\n  local function updateStartButton(ready) \n    startgame:setVisible(ready)\n    waitingtext:setVisible(not ready)\n  end\n\n  local listener = LuaActionListener(function(s) updateStartButton(updatePlayers()) end)\n  menu:addLogicCallback(listener)\n\n  menu:addFullButton(\"~!Cancel\", \"c\", Video.Width / 2 - 100, Video.Height - 100,\n    function() menu:stop() end)\n\n  menu:run()\nend\n\nfunction RunCreateMultiGameMenu(s)\n  local menu\n  local map = \"No Map\"\n  local description = \"No map\"\n  local mapfile = \"maps/default.smp\"\n  local numplayers = 3\n  local sx = Video.Width / 20\n  local sy = Video.Height / 20\n\n  menu = WarMenu(\"Create MultiPlayer game\")\n\n  menu:writeText(\"File:\", sx, sy*3+30)\n  maptext = menu:writeText(mapfile, sx+50, sy*3+30)\n  menu:writeText(\"Players:\", sx, sy*3+50)\n  players = menu:writeText(numplayers, sx+70, sy*3+50)\n  menu:writeText(\"Description:\", sx, sy*3+70)\n  descr = menu:writeText(description, sx+20, sy*3+90)\n\n  local OldPresentMap = PresentMap\n  PresentMap = function(desc, nplayers, w, h, id)\n    numplayers = nplayers\n    players:setCaption(\"\"..numplayers)\n    players:adjustSize()\n    description = desc\n    descr:setCaption(desc)\n    descr:adjustSize()\n    OldPresentMap(desc, nplayers, w, h, id)\n  end\n\n  Load(mapfile)\n  local browser = menu:addBrowser(\"maps/\", \"^.*%.smp%.?g?z?$\", sx*10, sy*2+20, sx*8, sy*11)\n  local function cb(s)\n    mapfile = browser.path .. browser:getSelectedItem()\n    Load(mapfile)\n    maptext:setCaption(mapfile)\n    maptext:adjustSize()\n  end\n  browser:setActionCallback(cb)\n  \n  menu:addFullButton(\"~!Create Game\", \"c\", sx,  sy*11, \n    function(s)    \n      if (browser:getSelected() < 0) then\n        return\n      end\n      RunServerMultiGameMenu(mapfile, description, numplayers)\n      menu:stop()\n    end\n  )\n  menu:run()\n  PresentMap = OldPresentMap\nend\n\nfunction RunCreateJoinMenu()\n  local menu = WarMenu()\n  local offx = (Video.Width - 640) / 2\n  local offy = (Video.Height - 480) / 2\n\n  InitGameSettings()\n  InitNetwork1()\n\n  menu:addFullButton(\"~!Join Game\", \"j\", 208 + offx, 320 + (36 * 0) + offy,\n    function()\n      RunJoinIpMenu()\n      menu:stop()\n    end)\n  menu:addFullButton(\"~!Create Game\", \"c\", 208 + offx, 320 + (36 * 1) + offy,\n    function()\n      RunCreateMultiGameMenu()\n      menu:stop()\n    end)\n\n  menu:addFullButton(\"~!Previous Menu\", \"p\", 208 + offx, 320 + (36 * 2) + offy,\n    function() menu:stop() end)\n\n  menu:run()\n\n  ExitNetwork1()\nend\n\nfunction RunMultiPlayerGameMenu(s)\n  local menu = WarMenu(nil, panel(\"288x128\"), false)\n  menu:setSize(288, 128)\n  menu:setPosition((Video.Width - 288) / 2, (Video.Height - 128) / 2)\n\n  menu:addLabel(\"Enter your name:\", 288/2, 8)\n\n  local nick = menu:addTextInputField(GetLocalPlayerName(), 40, 38, 212)\n\n  menu:addHalfLeftButton(\"~!OK\", \"o\", 24, 92,\n    function()\n      if nick:getText() ~= GetLocalPlayerName() then\n        SetLocalPlayerName(nick:getText())\n        preferences.PlayerName = nick:getText()\n        SavePreferences()\n      end\n      RunCreateJoinMenu()\n      menu:stop()\n    end)\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 160, 92,\n    function() menu:stop() end)\n\n  menu:run()\nend\n\n"
  },
  {
    "path": "scripts/menus/objectives.lua",
    "content": "function RunObjectivesMenu()\n  local menu = WarGameMenu(panel(\"384x256\"))\n  menu:resize(384, 256)\n\n  menu:addLabel(\"Mission Objectives\", 384/2, 8, Fonts[\"large\"], true)\n\n  local objectives = \"\"\n  table.foreachi(Objectives, function(k,v) objectives = objectives .. v .. \"\\n\" end)\n\n  local l = MultiLineLabel(objectives)\n  l:setFont(Fonts[\"large\"])\n  l:setAlignment(MultiLineLabel.LEFT)\n  l:setLineWidth(228)\n  l:adjustSize()\n  menu:add(l, 6, 32)\n\n  menu:addFullButton(\"Previous (~<Esc~>)\", \"escape\", 80, 216, function() menu:stop() end)\n\n  menu:run()\nend\n\n"
  },
  {
    "path": "scripts/menus/options.lua",
    "content": "function AddSoundOptions(menu, offx, offy, centerx, bottom)\n  local b\n\n  b = menu:addLabel(\"Sound Options\", 264/2, 8)\n\n  b = Label(\"Effects Volume\")\n  b:setFont(CFont:Get(\"game\"))\n  b:adjustSize();\n  menu:add(b, offx + 16, offy + 36 * 1)\n\n  -- FIXME: disable if effects turned off\n  local soundslider = Slider(0, 255)\n  soundslider:setValue(GetEffectsVolume())\n  soundslider:setActionCallback(function() SetEffectsVolume(soundslider:getValue()) end)\n  soundslider:setWidth(198)\n  soundslider:setHeight(18)\n  soundslider:setBaseColor(dark)\n  soundslider:setForegroundColor(clear)\n  soundslider:setBackgroundColor(clear)\n  menu:add(soundslider, offx + 32, offy + 36 * 1.5)\n\n  b = Label(\"min\")\n  b:setFont(CFont:Get(\"game\"))\n  b:adjustSize();\n  menu:addCentered(b, offx + 44, offy + 36 * 2 + 6)\n\n  b = Label(\"max\")\n  b:setFont(CFont:Get(\"game\"))\n  b:adjustSize();\n  menu:addCentered(b, offx + 218, offy + 36 * 2 + 6)\n\n  local effectscheckbox = {}\n  effectscheckbox = menu:addCheckBox(\"Enabled\", offx + 240, offy + 36 * 1.5,\n    function() SetEffectsEnabled(effectscheckbox:isMarked()) end)\n  effectscheckbox:setMarked(IsEffectsEnabled())\n  effectscheckbox:adjustSize()\n\n  b = Label(\"Music Volume\")\n  b:setFont(CFont:Get(\"game\"))\n  b:adjustSize();\n  menu:add(b, offx + 16, offy + 36 * 3)\n\n  -- FIXME: disable if music turned off\n  local musicslider = Slider(0, 255)\n  musicslider:setValue(GetMusicVolume())\n  musicslider:setActionCallback(function() SetMusicVolume(musicslider:getValue()) end)\n  musicslider:setWidth(198)\n  musicslider:setHeight(18)\n  musicslider:setBaseColor(dark)\n  musicslider:setForegroundColor(clear)\n  musicslider:setBackgroundColor(clear)\n  menu:add(musicslider, offx + 32, offy + 36 * 3.5)\n\n  b = Label(\"min\")\n  b:setFont(CFont:Get(\"game\"))\n  b:adjustSize();\n  menu:addCentered(b, offx + 44, offy + 36 * 4 + 6)\n\n  b = Label(\"max\")\n  b:setFont(CFont:Get(\"game\"))\n  b:adjustSize();\n  menu:addCentered(b, offx + 218, offy + 36 * 4 + 6)\n\n  local musiccheckbox = {}\n  musiccheckbox = menu:addCheckBox(\"Enabled\", offx + 240, offy + 36 * 3.5,\n    function() SetMusicEnabled(musiccheckbox:isMarked()); MusicStopped() end)\n  musiccheckbox:setMarked(IsMusicEnabled())\n  musiccheckbox:adjustSize();\n\n  b = menu:addHalfLeftButton(\"~!OK\", \"o\", offx + 20, 252,\n    function()\n      preferences.EffectsVolume = GetEffectsVolume()\n      preferences.EffectsEnabled = IsEffectsEnabled()\n      preferences.MusicVolume = GetMusicVolume()\n      preferences.MusicEnabled = IsMusicEnabled()\n      SavePreferences()\n      menu:stop()\n    end)\n  b = menu:addHalfRightButton(\"~!Cancel\", \"c\", offx + 140, 252,\n    function() menu:stop() end)\nend\n\nfunction RunGameSoundOptionsMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  AddSoundOptions(menu, 0, 0, 264/2 - 224/2, 288)\n\n  menu:run(false)\nend\n\nfunction RunPreferencesMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n\n  menu:addLabel(\"Preferences\", 264/2, 8)\n\n  local fog = {}\n  fog = menu:addCheckBox(\"Fog of War\", 16, 40 + 36 * 0,\n    function() SetFogOfWar(fog:isMarked()) end)\n  fog:setMarked(GetFogOfWar())\n  if (IsReplayGame() or IsNetworkGame()) then\n    fog:setEnabled(false)\n  end\n\n  local ckey = {}\n  ckey = menu:addCheckBox(\"Show command key\", 16, 40 + 36 * 1,\n    function() UI.ButtonPanel.ShowCommandKey = ckey:isMarked() end)\n  ckey:setMarked(UI.ButtonPanel.ShowCommandKey)\n\n  menu:addLabel(\"Game Speed\", 16, 40 + 36 * 2, Fonts[\"game\"], false)\n\n  local gamespeed = {}\n  gamespeed = menu:addSlider(15, 75, 198, 18, 32, 40 + 36 * 2.5,\n    function() SetGameSpeed(gamespeed:getValue()) end)\n  gamespeed:setValue(GetGameSpeed())\n\n  menu:addLabel(\"slow\", 34, 40 + (36 * 3) + 6, Fonts[\"small\"], false)\n  local l = Label(\"fast\")\n  l:setFont(Fonts[\"small\"])\n  l:adjustSize()\n  menu:add(l, 230 - l:getWidth(), 40 + (36 * 3) + 6)\n  \n  local grabMouse = menu:addCheckBox(\"Grab Mouse\", 16, 40 + 36 * 4, function()end)\n  grabMouse:setMarked(GetGrabMouse())\n  grabMouse:setActionCallback(\n    function()\n      SetGrabMouse(grabMouse:isMarked())\n    end)\n\n  menu:addHalfLeftButton(\"~!OK\", \"o\", 20, 252,\n    function()\n      preferences.FogOfWar = GetFogOfWar()\n      preferences.ShowCommandKey = UI.ButtonPanel.ShowCommandKey\n      preferences.GameSpeed = GetGameSpeed()\n      SavePreferences()\n      menu:stop()\n    end)\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 140, 252,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\nfunction SetVideoSize(width, height)\n  if (Video:ResizeScreen(width, height) == false) then\n    return\n  end\n  bckground:Resize(Video.Width, Video.Height)\n  backgroundWidget = ImageWidget(bckground)\n  Load(\"scripts/ui.lua\")\n  preferences.VideoWidth = Video.Width\n  preferences.VideoHeight = Video.Height\n  SavePreferences()\nend\n\nfunction BuildOptionsMenu()\n  local menu = WarMenu()\n  local offx = (Video.Width - 352) / 2\n  local offy = (Video.Height - 352) / 2\n  local checkTexture\n  local b\n\n  menu:addLabel(\"Global Options\", offx + 176, offy + 11)\n  menu:addLabel(\"Video Resolution\", offx + 16, offy + 44, Fonts[\"game\"], false)\n\n  b = menu:addCheckBox(\"640 x 480\", offx + 16, offy + 65 + 26*0,\n    function() SetVideoSize(640, 480) menu:stop(1) end)\n  if (Video.Width == 640) then b:setMarked(true) end\n  b = menu:addCheckBox(\"800 x 480\", offx + 16, offy + 65 + 26*1,\n    function() SetVideoSize(800, 480) menu:stop(1) end)\n  if (Video.Width == 800 and Video.Height == 480) then b:setMarked(true) end\n  b = menu:addCheckBox(\"800 x 600\", offx + 16, offy + 65 + 26*2,\n    function() SetVideoSize(800, 600) menu:stop(1) end)\n  if (Video.Width == 800 and Video.Height == 600) then b:setMarked(true) end\n  b = menu:addCheckBox(\"1024 x 768\", offx + 16, offy + 65 + 26*3,\n    function() SetVideoSize(1024, 768) menu:stop(1) end)\n  if (Video.Width == 1024) then b:setMarked(true) end\n  b = menu:addCheckBox(\"1280 x 800\", offx + 16, offy + 65 + 26*4,\n    function() SetVideoSize(1280, 800) menu:stop(1) end)\n  if (Video.Height == 800) then b:setMarked(true) end \n  b = menu:addCheckBox(\"1280 x 960\", offx + 16, offy + 65 + 26*5,\n    function() SetVideoSize(1280, 960) menu:stop(1) end)\n  if (Video.Height == 960) then b:setMarked(true) end \n  b = menu:addCheckBox(\"1280 x 1024\", offx + 16, offy + 65 + 26*6,\n    function() SetVideoSize(1280, 1024) menu:stop(1) end)\n  if (Video.Height == 1024) then b:setMarked(true) end \n  b = menu:addCheckBox(\"1400 x 1050\", offx + 16, offy + 65 + 26*7,\n    function() SetVideoSize(1400, 1050) menu:stop(1) end)\n  if (Video.Width == 1400) then b:setMarked(true) end \n  b = menu:addCheckBox(\"1600 x 1200\", offx + 16, offy + 65 + 26*8,\n    function() SetVideoSize(1600, 1200) menu:stop(1) end)\n  if (Video.Width == 1600) then b:setMarked(true) end \n  b = menu:addCheckBox(\"1680 x 1050\", offx + 16, offy + 65 + 26*9,\n    function() SetVideoSize(1680, 1050) menu:stop(1) end)\n  if (Video.Width == 1680) then b:setMarked(true) end\n\n  b = menu:addCheckBox(\"Full Screen\", offx + 17, offy + 65 + 26*10,\n    function()\n      ToggleFullScreen()\n      preferences.VideoFullScreen = Video.FullScreen\n      SavePreferences()\n      menu:stop(1)\n    end)\n  b:setMarked(Video.FullScreen)\n\n  local grabMouse = menu:addCheckBox(\"Grab Mouse\", offx + 16, offy + 65 + 26*11, function()end)\n  grabMouse:setMarked(GetGrabMouse())\n  grabMouse:setActionCallback(\n    function()\n      SetGrabMouse(grabMouse:isMarked())\n    end)\n\n   local hwCursor = menu:addCheckBox(\"Hardware cursor\", offx + 16, offy + 65 + 26*12, function()end)\n   hwCursor:setMarked(preferences.HardwareCursor)\n   hwCursor:setActionCallback(\n    function()\n      preferences.HardwareCursor = hwCursor:isMarked()\n      Preference.HardwareCursor = hwCursor:isMarked()\n      SavePreferences()\n    end)\n\n  menu:addHalfButton(\"~!OK\", \"o\", offx + 123, offy + 309, function() menu:stop() end)\n\n  return menu:run()\nend\n\nfunction RunOptionsMenu()\n  local continue = 1\n  while (continue == 1) do\n    continue = BuildOptionsMenu()\n  end\nend\n\nfunction RunGameOptionsMenu()\n  local menu = WarGameMenu(panel(\"264x288\"))\n  menu:resize(264, 288)\n\n  menu:addLabel(\"Game Options\", 264/2, 8)\n  menu:addFullButton(\"~!Sound\", \"s\", 20, 36,\n    function() RunGameSoundOptionsMenu() end)\n  menu:addFullButton(\"~!Preferences\", \"p\", 20, 70,\n    function() RunPreferencesMenu() end)\n  menu:addFullButton(\"~!Diplomacy\", \"d\", 20, 104,\n    function() RunDiplomacyMenu() end)\n  menu:addFullButton(\"Previous (~<Esc~>\", \"escape\", 20, 252,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\n"
  },
  {
    "path": "scripts/menus/replay.lua",
    "content": "function RunReplayGameMenu()\n  local menu = WarMenu(nil, panel(\"384x256\"), false)\n  menu:setSize(384, 256)\n  menu:setPosition((Video.Width - 384) / 2, (Video.Height - 256) / 2)\n\n  menu:addLabel(\"Select Game\", 384/2, 8)\n\n  local browser = menu:addBrowser(\"~logs/\", \"%.log%.?g?z?$\",\n    32, 44, 320, 146)\n\n  local reveal = menu:addCheckBox(\"Reveal Map\", 32, 196, function() end)\n\n  menu:addFullLeftButton(\"~!OK\", \"o\", 20, 216,\n    function()\n      if (browser:getSelected() < 0) then\n        return\n      end\n      InitGameVariables()\n      StartReplay(\"~logs/\" .. browser:getSelectedItem(), reveal:isMarked())\n      InitGameSettings()\n      SetPlayerData(GetThisPlayer(), \"RaceName\", \"orc\")\n      menu:stop()\n    end)\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 260, 216,\n    function() menu:stop() end)\n\n  menu:run()\nend\n\nfunction RunSaveReplayMenu()\n  local menu = WarGameMenu(panel(\"384x256\"))\n  menu:setSize(384, 256)\n  menu:setPosition((Video.Width - 384) / 2, (Video.Height - 256) / 2)\n\n  menu:addLabel(\"Save Replay\", 384/2, 8)\n\n  local t = menu:addTextInputField(\"game.log\",\n    32, 22, 320)\n\n  local browser = menu:addBrowser(\"~logs\", \".log$\",\n    32, 44, 320, 146)\n  local function cb(s)\n    t:setText(browser:getSelectedItem())\n  end\n  browser:setActionCallback(cb)\n\n  menu:addFullLeftButton(\"~!Save\", \"s\", 20, 216,\n    -- FIXME: use a confirm menu if the file exists already\n    function()\n      local name = t:getText()\n      -- check for an empty string\n      if (string.len(name) == 0) then\n        return\n      end\n      -- append .log\n      if (string.find(name, \".log$\") == nil) then\n        name = name .. \".log\"\n      end\n      -- replace invalid chars with underscore\n      local t = {\"\\\\\", \"/\", \":\", \"*\", \"?\", \"\\\"\", \"<\", \">\", \"|\"}\n      table.foreachi(t, function(k,v) name = string.gsub(name, v, \"_\") end)\n\n      SaveReplay(name)\n      menu:stop()\n    end)\n\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 260, 216,\n    function() menu:stop() end)\n\n  menu:run()\nend\n"
  },
  {
    "path": "scripts/menus/results.lua",
    "content": "local tvictory = \"terran/victory screen.png\"\nlocal tdefeat =  \"terran/defeat screen.png\"\nlocal zvictory = \"zerg/victory screen.png\"\nlocal zdefeat =  \"zerg/defeat screen.png\"\nlocal pvictory = \"protoss/victory screen.png\"\nlocal pdefeat =  \"protoss/defeat screen.png\"\n\nfunction RunResultsMenu()\n  local background\n  local result\n  local race = GetPlayerData(GetThisPlayer(), \"RaceName\")\n\n  if (GameResult == GameVictory) then\n    result = \"Victory!\"\n    if (race == \"terran\") then\n      background = tvictory\n    elseif (race == \"zerg\") then\n      background = zvictory\n    else\n      background = pvictory\n    end\n  elseif (GameResult == GameDefeat) then\n    result = \"Defeat!\"\n    if (race == \"terran\") then\n      background = tdefeat\n    elseif (race == \"zerg\") then\n      background = zdefeat\n    else\n      background = pdefeat\n    end\n  elseif (GameResult == GameDraw) then\n    result = \"Draw!\"\n    if (race == \"terran\") then\n      background = tdefeat\n    elseif (race == \"zerg\") then\n      background = zdefeat\n    else\n      background = pdefeat\n    end\n  else\n    return -- quit to menu\n  end\n\n  local menu = WarMenu(nil, background)\n  local offx = (Video.Width - 640) / 2\n  local offy = (Video.Height - 480) / 2\n\n  local names_font = Fonts[\"small-title\"]\n  local top_offset = 57\n  local bottom_offset = 178\n  local description_offset = 30\n\n  local c = 0\n  for i=0,7 do\n    if (GetPlayerData(i, \"TotalUnits\") > 0 ) then\n      c = c + 1\n    end\n  end\n\n  local line_spacing = (432 - bottom_offset - description_offset) / c\n\n  menu:addLabel(\"Outcome\", offx + 106, offy + top_offset)\n  menu:addLabel(result, offx + 106, offy + top_offset + 21, Fonts[\"large-title\"])\n\n  menu:addLabel(\"Units\", offx + 50, offy + bottom_offset, Fonts[\"large\"], true)\n  menu:addLabel(\"Buildings\", offx + 140, offy + bottom_offset, Fonts[\"large\"], true)\n  menu:addLabel(\"Minerals\", offx + 230, offy + bottom_offset, Fonts[\"large\"], true)\n  menu:addLabel(\"Gas\", offx + 320, offy + bottom_offset, Fonts[\"large\"], true)\n  menu:addLabel(\"Kills\", offx + 500, offy + bottom_offset, Fonts[\"large\"], true)\n  menu:addLabel(\"Razings\", offx + 590, offy + bottom_offset, Fonts[\"large\"], true)\n\n  c = 0\n  for i=0,7 do\n    if (GetPlayerData(i, \"TotalUnits\") > 0 ) then\n      local name = GetPlayerData(i, \"Name\")\n      if (ThisPlayer.Index == i) then\n        name = name .. \" - You\"\n      elseif (ThisPlayer:IsAllied(Players[i])) then\n        name = name .. \" - Ally\"\n      elseif (ThisPlayer:IsEnemy(Players[i])) then\n        name = name .. \" - Enemy\"\n      else\n        name = name .. \" - Neutral\"\n      end\n      menu:addLabel(name, offx + 320,\n        offy + bottom_offset + description_offset + 26 + line_spacing * c + 5,\n        names_font, true)\n      menu:addLabel(GetPlayerData(i, \"TotalUnits\"), offx + 10 + 40,\n        offy + bottom_offset + description_offset + line_spacing * c + 5,\n        Fonts[\"large\"], true)\n      menu:addLabel(GetPlayerData(i, \"TotalBuildings\"), offx + 100 + 40,\n        offy + bottom_offset + description_offset + line_spacing * c + 5,\n        Fonts[\"large\"], true)\n      menu:addLabel(GetPlayerData(i, \"TotalResources\", \"minerals\"), offx + 190 + 40,\n        offy + bottom_offset + description_offset + line_spacing * c + 5,\n        Fonts[\"large\"], true)\n      menu:addLabel(GetPlayerData(i, \"TotalResources\", \"gas\"), offx + 280 + 40,\n        offy + bottom_offset + description_offset + line_spacing * c + 5,\n        Fonts[\"large\"], true)\n      menu:addLabel(GetPlayerData(i, \"TotalKills\"), offx + 460 + 40,\n        offy + bottom_offset + description_offset + line_spacing * c + 5,\n        Fonts[\"large\"], true)\n      menu:addLabel(GetPlayerData(i, \"TotalRazings\"), offx + 550 + 40,\n        offy + bottom_offset + description_offset + line_spacing * c + 5,\n        Fonts[\"large\"], true)\n\n      c = c + 1\n    end\n  end\n\n  menu:addFullButton(\"~!Save Replay\", \"s\", offx + 200, offy + 480,\n    function() RunSaveReplayMenu() end)\n\n  menu:addFullButton(\"~!Continue\", \"c\", offx + 450, offy + 480,\n    function() menu:stop() end)\n\n  menu:run()\nend\n\n"
  },
  {
    "path": "scripts/menus/save.lua",
    "content": "function RunSaveMenu()\n  local menu = WarGameMenu(panel(\"384x256\"))\n  menu:resize(384, 256)\n\n  menu:addLabel(\"Save Game\", 384/2, 8)\n\n  local t = menu:addTextInputField(\"game.sav\", 32, 44, 320)\n\n  local browser = menu:addBrowser(\"~save\", \".sav.gz$\",\n    32, 70, 320, 134)\n  local function cb(s)\n    t:setText(browser:getSelectedItem())\n  end\n  browser:setActionCallback(cb)\n\n  menu:addHalfLeftButton(\"~!Save\", \"s\", 20, 216,\n    -- FIXME: use a confirm menu if the file exists already\n    function()\n      local name = t:getText()\n      -- check for an empty string\n      if (string.len(name) == 0) then\n        return\n      end\n      -- strip .gz\n      if (string.find(name, \".gz$\") ~= nil) then\n        name = string.sub(name, 1, string.len(name) - 3)\n      end\n      -- append .sav\n      if (string.find(name, \".sav$\") == nil) then\n        name = name .. \".sav\"\n      end\n      -- replace invalid chars with underscore\n      local t = {\"\\\\\", \"/\", \":\", \"*\", \"?\", \"\\\"\", \"<\", \">\", \"|\"}\n      table.foreachi(t, function(k,v) name = string.gsub(name, v, \"_\") end)\n\n      SaveGame(name)\n      UI.StatusLine:Set(\"Saved game to: \" .. name)\n      menu:stop()\n    end)\n\n  menu:addHalfButton(\"~!Delete\", \"d\", 140, 216,\n    function()\n      if (browser:getSelected() >= 0) then\n        DeleteSaveGame(browser:getSelectedItem())\n        browser:updateList()\n      end\n    end)\n\n  menu:addHalfRightButton(\"~!Cancel\", \"c\", 260, 216,\n    function() menu:stop() end)\n\n  menu:run(false)\nend\n\n"
  },
  {
    "path": "scripts/missiles.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      missiles.lua - Define the used missiles.\n--\n--      (c) Copyright 1998-2004 by Lutz Sammer, Fabrice Rossi,\n--                                 Jimmy Salmon and Crestez Leonard\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nLoad(\"luagen/images/luagen-images.lua\")\nLoad(\"scripts/terran/missiles.lua\")\nLoad(\"scripts/zerg/missiles.lua\")\n\nDefineMissileType(\"missile-small-fire\",\n  { File = image_450_thingy_ofirec_file, Size = image_450_thingy_ofirec_size, Frames = 6, NumDirections = 1,\n  DrawLevel = 200, Class = \"missile-class-fire\", Sleep = 8, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-big-fire\",\n  { File = image_451_thingy_ofiref_file, Size = image_451_thingy_ofiref_size, Frames = 10, NumDirections = 1,\n  DrawLevel = 200, Class = \"missile-class-fire\", Sleep = 8, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-impact\",\n  { File = image_522_bullet_blastcan_file, Size = image_522_bullet_blastcan_size, Frames = 17, NumDirections = 1,\n  DrawLevel = 50, Class = \"missile-class-stay\", Sleep = 1, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-explosion\",\n  { File = image_215_thingy_tbangx_file, Size = image_215_thingy_tbangx_size, Frames = 10, NumDirections = 1,\n  DrawLevel = 50, Class = \"missile-class-stay\", Sleep = 1, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-small-cannon\",\n  { File = image_522_bullet_blastcan_file, Size = image_522_bullet_blastcan_size, Frames = 17, NumDirections = 5,\n  DrawLevel = 50, ImpactSound = \"explosion\",\n  Class = \"missile-class-parabolic\", Sleep = 1, Speed = 16, Range = 1,\n  ImpactMissile = \"missile-cannon-explosion\" } )\n\nDefineMissileType(\"missile-cannon-explosion\",\n  { File = image_522_bullet_blastcan_file, Size = image_522_bullet_blastcan_size, Frames = 17, NumDirections = 1,\n  DrawLevel = 50, Class = \"missile-class-stay\", Sleep = 1, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-green-cross\",\n  { File = \"ui/cursors/targg.png\", Size = {128, 128}, Frames = 2, NumDirections = 1,\n  DrawLevel = 150, Class = \"missile-class-cycle-once\", Sleep = 1, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-red-cross\",\n  { File = \"ui/cursors/targr.png\", Size = {128, 128}, Frames = 2, NumDirections = 1,\n  DrawLevel = 150, Class = \"missile-class-cycle-once\", Sleep = 1, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-none\",\n  { Size = {32, 32}, DrawLevel = 50,\n  Class = \"missile-class-none\", Sleep = 1, Speed = 16, Range = 1 } )\n\nDefineMissileType(\"missile-hit\",\n  { Size = {15, 15}, DrawLevel = 150,\n  Class = \"missile-class-hit\", Sleep = 1, Speed = 1, Range = 16 } )\n\nDefineBurningBuilding(\n  {\"percent\", 0, \"missile\", \"missile-big-fire\"},\n  {\"percent\", 50, \"missile\", \"missile-small-fire\"},\n  {\"percent\", 75 } -- no missile\n)\n"
  },
  {
    "path": "scripts/mobdebug.lua",
    "content": "--\n-- MobDebug -- Lua remote debugger\n-- Copyright 2011-20 Paul Kulchenko\n-- Based on RemDebug 1.0 Copyright Kepler Project 2005\n--\n\n-- use loaded modules or load explicitly on those systems that require that\nlocal require = require\nlocal io = io or require \"io\"\nlocal table = table or require \"table\"\nlocal string = string or require \"string\"\nlocal coroutine = coroutine or require \"coroutine\"\nlocal debug = require \"debug\"\n-- protect require \"os\" as it may fail on embedded systems without os module\nlocal os = os or (function(module)\n  local ok, res = pcall(require, module)\n  return ok and res or nil\nend)(\"os\")\n\nlocal mobdebug = {\n  _NAME = \"mobdebug\",\n  _VERSION = \"0.801\",\n  _COPYRIGHT = \"Paul Kulchenko\",\n  _DESCRIPTION = \"Mobile Remote Debugger for the Lua programming language\",\n  port = os and os.getenv and tonumber((os.getenv(\"MOBDEBUG_PORT\"))) or 8172,\n  checkcount = 200,\n  yieldtimeout = 0.02, -- yield timeout (s)\n  connecttimeout = 2, -- connect timeout (s)\n}\n\nlocal HOOKMASK = \"lcr\"\nlocal error = error\nlocal getfenv = getfenv\nlocal setfenv = setfenv\nlocal loadstring = loadstring or load -- \"load\" replaced \"loadstring\" in Lua 5.2\nlocal pairs = pairs\nlocal setmetatable = setmetatable\nlocal tonumber = tonumber\nlocal unpack = table.unpack or unpack\nlocal rawget = rawget\nlocal gsub, sub, find = string.gsub, string.sub, string.find\n\n-- if strict.lua is used, then need to avoid referencing some global\n-- variables, as they can be undefined;\n-- use rawget to avoid complaints from strict.lua at run-time.\n-- it's safe to do the initialization here as all these variables\n-- should get defined values (if any) before the debugging starts.\n-- there is also global 'wx' variable, which is checked as part of\n-- the debug loop as 'wx' can be loaded at any time during debugging.\nlocal genv = _G or _ENV\nlocal jit = rawget(genv, \"jit\")\nlocal MOAICoroutine = rawget(genv, \"MOAICoroutine\")\n\n-- ngx_lua/Openresty requires special handling as its coroutine.*\n-- methods use a different mechanism that doesn't allow resume calls\n-- from debug hook handlers.\n-- Instead, the \"original\" coroutine.* methods are used.\nlocal ngx = rawget(genv, \"ngx\")\nlocal corocreate = ngx and coroutine._create or coroutine.create\nlocal cororesume = ngx and coroutine._resume or coroutine.resume\nlocal coroyield = ngx and coroutine._yield or coroutine.yield\nlocal corostatus = ngx and coroutine._status or coroutine.status\nlocal corowrap = coroutine.wrap\n\nif not setfenv then -- Lua 5.2+\n  -- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html\n  -- this assumes f is a function\n  local function findenv(f)\n    local level = 1\n    repeat\n      local name, value = debug.getupvalue(f, level)\n      if name == '_ENV' then return level, value end\n      level = level + 1\n    until name == nil\n    return nil end\n  getfenv = function (f) return(select(2, findenv(f)) or _G) end\n  setfenv = function (f, t)\n    local level = findenv(f)\n    if level then debug.setupvalue(f, level, t) end\n    return f end\nend\n\n-- check for OS and convert file names to lower case on windows\n-- (its file system is case insensitive, but case preserving), as setting a\n-- breakpoint on x:\\Foo.lua will not work if the file was loaded as X:\\foo.lua.\n-- OSX and Windows behave the same way (case insensitive, but case preserving).\n-- OSX can be configured to be case-sensitive, so check for that. This doesn't\n-- handle the case of different partitions having different case-sensitivity.\nlocal win = os and os.getenv and (os.getenv('WINDIR') or (os.getenv('OS') or ''):match('[Ww]indows')) and true or false\nlocal mac = not win and (os and os.getenv and os.getenv('DYLD_LIBRARY_PATH') or not io.open(\"/proc\")) and true or false\nlocal iscasepreserving = win or (mac and io.open('/library') ~= nil)\n\n-- turn jit off based on Mike Pall's comment in this discussion:\n-- http://www.freelists.org/post/luajit/Debug-hooks-and-JIT,2\n-- \"You need to turn it off at the start if you plan to receive\n-- reliable hook calls at any later point in time.\"\nif jit and jit.off then jit.off() end\n\nlocal socket = require \"socket\"\nlocal coro_debugger\nlocal coro_debugee\nlocal coroutines = {}; setmetatable(coroutines, {__mode = \"k\"}) -- \"weak\" keys\nlocal events = { BREAK = 1, WATCH = 2, RESTART = 3, STACK = 4 }\nlocal breakpoints = {}\nlocal watches = {}\nlocal lastsource\nlocal lastfile\nlocal watchescnt = 0\nlocal abort -- default value is nil; this is used in start/loop distinction\nlocal seen_hook = false\nlocal checkcount = 0\nlocal step_into = false\nlocal step_over = false\nlocal step_level = 0\nlocal stack_level = 0\nlocal server\nlocal buf\nlocal outputs = {}\nlocal iobase = {print = print}\nlocal basedir = \"\"\nlocal deferror = \"execution aborted at default debugee\"\nlocal debugee = function ()\n  local a = 1\n  for _ = 1, 10 do a = a + 1 end\n  error(deferror)\nend\nlocal function q(s) return string.gsub(s, '([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end\n\nlocal serpent = (function() ---- include Serpent module for serialization\nlocal n, v = \"serpent\", \"0.302\" -- (C) 2012-18 Paul Kulchenko; MIT License\nlocal c, d = \"Paul Kulchenko\", \"Lua serializer and pretty printer\"\nlocal snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}\nlocal badtype = {thread = true, userdata = true, cdata = true}\nlocal getmetatable = debug and debug.getmetatable or getmetatable\nlocal pairs = function(t) return next, t end -- avoid using __pairs in Lua 5.2+\nlocal keyword, globals, G = {}, {}, (_G or _ENV)\nfor _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false',\n  'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',\n  'return', 'then', 'true', 'until', 'while'}) do keyword[k] = true end\nfor k,v in pairs(G) do globals[v] = k end -- build func to name mapping\nfor _,g in ipairs({'coroutine', 'debug', 'io', 'math', 'string', 'table', 'os'}) do\n  for k,v in pairs(type(G[g]) == 'table' and G[g] or {}) do globals[v] = g..'.'..k end end\n\nlocal function s(t, opts)\n  local name, indent, fatal, maxnum = opts.name, opts.indent, opts.fatal, opts.maxnum\n  local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge\n  local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge)\n  local maxlen, metatostring = tonumber(opts.maxlength), opts.metatostring\n  local iname, comm = '_'..(name or ''), opts.comment and (tonumber(opts.comment) or math.huge)\n  local numformat = opts.numformat or \"%.17g\"\n  local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0\n  local function gensym(val) return '_'..(tostring(tostring(val)):gsub(\"[^%w]\",\"\"):gsub(\"(%d%w+)\",\n    -- tostring(val) is needed because __tostring may return a non-string value\n    function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return tostring(syms[s]) end)) end\n  local function safestr(s) return type(s) == \"number\" and tostring(huge and snum[tostring(s)] or numformat:format(s))\n    or type(s) ~= \"string\" and tostring(s) -- escape NEWLINE/010 and EOF/026\n    or (\"%q\"):format(s):gsub(\"\\010\",\"n\"):gsub(\"\\026\",\"\\\\026\") end\n  local function comment(s,l) return comm and (l or 0) < comm and ' --[['..select(2, pcall(tostring, s))..']]' or '' end\n  local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal\n    and safestr(select(2, pcall(tostring, s))) or error(\"Can't serialize \"..tostring(s)) end\n  local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r']\n    local n = name == nil and '' or name\n    local plain = type(n) == \"string\" and n:match(\"^[%l%u_][%w_]*$\") and not keyword[n]\n    local safe = plain and n or '['..safestr(n)..']'\n    return (path or '')..(plain and path and '.' or '')..safe, safe end\n  local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding\n    local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}\n    local function padnum(d) return (\"%0\"..tostring(maxn)..\"d\"):format(tonumber(d)) end\n    table.sort(k, function(a,b)\n      -- sort numeric keys first: k[key] is not nil for numerical keys\n      return (k[a] ~= nil and 0 or to[type(a)] or 'z')..(tostring(a):gsub(\"%d+\",padnum))\n           < (k[b] ~= nil and 0 or to[type(b)] or 'z')..(tostring(b):gsub(\"%d+\",padnum)) end) end\n  local function val2str(t, name, indent, insref, path, plainindex, level)\n    local ttype, level, mt = type(t), (level or 0), getmetatable(t)\n    local spath, sname = safename(path, name)\n    local tag = plainindex and\n      ((type(name) == \"number\") and '' or name..space..'='..space) or\n      (name ~= nil and sname..space..'='..space or '')\n    if seen[t] then -- already seen this element\n      sref[#sref+1] = spath..space..'='..space..seen[t]\n      return tag..'nil'..comment('ref', level) end\n    -- protect from those cases where __tostring may fail\n    if type(mt) == 'table' and metatostring ~= false then\n      local to, tr = pcall(function() return mt.__tostring(t) end)\n      local so, sr = pcall(function() return mt.__serialize(t) end)\n      if (to or so) then -- knows how to serialize itself\n        seen[t] = insref or spath\n        t = so and sr or tr\n        ttype = type(t)\n      end -- new value falls through to be serialized\n    end\n    if ttype == \"table\" then\n      if level >= maxl then return tag..'{}'..comment('maxlvl', level) end\n      seen[t] = insref or spath\n      if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty\n      if maxlen and maxlen < 0 then return tag..'{}'..comment('maxlen', level) end\n      local maxn, o, out = math.min(#t, maxnum or #t), {}, {}\n      for key = 1, maxn do o[key] = key end\n      if not maxnum or #o < maxnum then\n        local n = #o -- n = n + 1; o[n] is much faster than o[#o+1] on large tables\n        for key in pairs(t) do if o[key] ~= key then n = n + 1; o[n] = key end end end\n      if maxnum and #o > maxnum then o[maxnum+1] = nil end\n      if opts.sortkeys and #o > maxn then alphanumsort(o, t, opts.sortkeys) end\n      local sparse = sparse and #o > maxn -- disable sparsness if only numeric keys (shorter output)\n      for n, key in ipairs(o) do\n        local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse\n        if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing\n        or opts.keyallow and not opts.keyallow[key]\n        or opts.keyignore and opts.keyignore[key]\n        or opts.valtypeignore and opts.valtypeignore[type(value)] -- skipping ignored value types\n        or sparse and value == nil then -- skipping nils; do nothing\n        elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then\n          if not seen[key] and not globals[key] then\n            sref[#sref+1] = 'placeholder'\n            local sname = safename(iname, gensym(key)) -- iname is table for local variables\n            sref[#sref] = val2str(key,sname,indent,sname,iname,true) end\n          sref[#sref+1] = 'placeholder'\n          local path = seen[t]..'['..tostring(seen[key] or globals[key] or gensym(key))..']'\n          sref[#sref] = path..space..'='..space..tostring(seen[value] or val2str(value,nil,indent,path))\n        else\n          out[#out+1] = val2str(value,key,indent,nil,seen[t],plainindex,level+1)\n          if maxlen then\n            maxlen = maxlen - #out[#out]\n            if maxlen < 0 then break end\n          end\n        end\n      end\n      local prefix = string.rep(indent or '', level)\n      local head = indent and '{\\n'..prefix..indent or '{'\n      local body = table.concat(out, ','..(indent and '\\n'..prefix..indent or space))\n      local tail = indent and \"\\n\"..prefix..'}' or '}'\n      return (custom and custom(tag,head,body,tail,level) or tag..head..body..tail)..comment(t, level)\n    elseif badtype[ttype] then\n      seen[t] = insref or spath\n      return tag..globerr(t, level)\n    elseif ttype == 'function' then\n      seen[t] = insref or spath\n      if opts.nocode then return tag..\"function() --[[..skipped..]] end\"..comment(t, level) end\n      local ok, res = pcall(string.dump, t)\n      local func = ok and \"((loadstring or load)(\"..safestr(res)..\",'@serialized'))\"..comment(t, level)\n      return tag..(func or globerr(t, level))\n    else return tag..safestr(t) end -- handle all other types\n  end\n  local sepr = indent and \"\\n\" or \";\"..space\n  local body = val2str(t, name, indent) -- this call also populates sref\n  local tail = #sref>1 and table.concat(sref, sepr)..sepr or ''\n  local warn = opts.comment and #sref>1 and space..\"--[[incomplete output with shared/self-references skipped]]\" or ''\n  return not name and body..warn or \"do local \"..body..sepr..tail..\"return \"..name..sepr..\"end\"\nend\n\nlocal function deserialize(data, opts)\n  local env = (opts and opts.safe == false) and G\n    or setmetatable({}, {\n        __index = function(t,k) return t end,\n        __call = function(t,...) error(\"cannot call functions\") end\n      })\n  local f, res = (loadstring or load)('return '..data, nil, nil, env)\n  if not f then f, res = (loadstring or load)(data, nil, nil, env) end\n  if not f then return f, res end\n  if setfenv then setfenv(f, env) end\n  return pcall(f)\nend\n\nlocal function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end\nreturn { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize = s,\n  load = deserialize,\n  dump = function(a, opts) return s(a, merge({name = '_', compact = true, sparse = true}, opts)) end,\n  line = function(a, opts) return s(a, merge({sortkeys = true, comment = true}, opts)) end,\n  block = function(a, opts) return s(a, merge({indent = '  ', sortkeys = true, comment = true}, opts)) end }\nend)() ---- end of Serpent module\n\nmobdebug.line = serpent.line\nmobdebug.dump = serpent.dump\nmobdebug.linemap = nil\nmobdebug.loadstring = loadstring\n\nlocal function removebasedir(path, basedir)\n  if iscasepreserving then\n    -- check if the lowercased path matches the basedir\n    -- if so, return substring of the original path (to not lowercase it)\n    return path:lower():find('^'..q(basedir:lower()))\n      and path:sub(#basedir+1) or path\n  else\n    return string.gsub(path, '^'..q(basedir), '')\n  end\nend\n\nlocal function stack(start)\n  local function vars(f)\n    local func = debug.getinfo(f, \"f\").func\n    local i = 1\n    local locals = {}\n    -- get locals\n    while true do\n      local name, value = debug.getlocal(f, i)\n      if not name then break end\n      if string.sub(name, 1, 1) ~= '(' then\n        locals[name] = {value, select(2,pcall(tostring,value))}\n      end\n      i = i + 1\n    end\n    -- get varargs (these use negative indices)\n    i = 1\n    while true do\n      local name, value = debug.getlocal(f, -i)\n      if not name then break end\n      locals[name:gsub(\"%)$\",\" \"..i..\")\")] = {value, select(2,pcall(tostring,value))}\n      i = i + 1\n    end\n    -- get upvalues\n    i = 1\n    local ups = {}\n    while func do -- check for func as it may be nil for tail calls\n      local name, value = debug.getupvalue(func, i)\n      if not name then break end\n      ups[name] = {value, select(2,pcall(tostring,value))}\n      i = i + 1\n    end\n    return locals, ups\n  end\n\n  local stack = {}\n  local linemap = mobdebug.linemap\n  for i = (start or 0), 100 do\n    local source = debug.getinfo(i, \"Snl\")\n    if not source then break end\n\n    local src = source.source\n    if src:find(\"@\") == 1 then\n      src = src:sub(2):gsub(\"\\\\\", \"/\")\n      if src:find(\"%./\") == 1 then src = src:sub(3) end\n    end\n\n    table.insert(stack, { -- remove basedir from source\n      {source.name, removebasedir(src, basedir),\n       linemap and linemap(source.linedefined, source.source) or source.linedefined,\n       linemap and linemap(source.currentline, source.source) or source.currentline,\n       source.what, source.namewhat, source.short_src},\n      vars(i+1)})\n  end\n  return stack\nend\n\nlocal function set_breakpoint(file, line)\n  if file == '-' and lastfile then file = lastfile\n  elseif iscasepreserving then file = string.lower(file) end\n  if not breakpoints[line] then breakpoints[line] = {} end\n  breakpoints[line][file] = true\nend\n\nlocal function remove_breakpoint(file, line)\n  if file == '-' and lastfile then file = lastfile\n  elseif file == '*' and line == 0 then breakpoints = {}\n  elseif iscasepreserving then file = string.lower(file) end\n  if breakpoints[line] then breakpoints[line][file] = nil end\nend\n\nlocal function has_breakpoint(file, line)\n  return breakpoints[line]\n     and breakpoints[line][iscasepreserving and string.lower(file) or file]\nend\n\nlocal function restore_vars(vars)\n  if type(vars) ~= 'table' then return end\n\n  -- locals need to be processed in the reverse order, starting from\n  -- the inner block out, to make sure that the localized variables\n  -- are correctly updated with only the closest variable with\n  -- the same name being changed\n  -- first loop find how many local variables there is, while\n  -- the second loop processes them from i to 1\n  local i = 1\n  while true do\n    local name = debug.getlocal(3, i)\n    if not name then break end\n    i = i + 1\n  end\n  i = i - 1\n  local written_vars = {}\n  while i > 0 do\n    local name = debug.getlocal(3, i)\n    if not written_vars[name] then\n      if string.sub(name, 1, 1) ~= '(' then\n        debug.setlocal(3, i, rawget(vars, name))\n      end\n      written_vars[name] = true\n    end\n    i = i - 1\n  end\n\n  i = 1\n  local func = debug.getinfo(3, \"f\").func\n  while true do\n    local name = debug.getupvalue(func, i)\n    if not name then break end\n    if not written_vars[name] then\n      if string.sub(name, 1, 1) ~= '(' then\n        debug.setupvalue(func, i, rawget(vars, name))\n      end\n      written_vars[name] = true\n    end\n    i = i + 1\n  end\nend\n\nlocal function capture_vars(level, thread)\n  level = (level or 0)+2 -- add two levels for this and debug calls\n  local func = (thread and debug.getinfo(thread, level, \"f\") or debug.getinfo(level, \"f\") or {}).func\n  if not func then return {} end\n\n  local vars = {['...'] = {}}\n  local i = 1\n  while true do\n    local name, value = debug.getupvalue(func, i)\n    if not name then break end\n    if string.sub(name, 1, 1) ~= '(' then vars[name] = value end\n    i = i + 1\n  end\n  i = 1\n  while true do\n    local name, value\n    if thread then\n      name, value = debug.getlocal(thread, level, i)\n    else\n      name, value = debug.getlocal(level, i)\n    end\n    if not name then break end\n    if string.sub(name, 1, 1) ~= '(' then vars[name] = value end\n    i = i + 1\n  end\n  -- get varargs (these use negative indices)\n  i = 1\n  while true do\n    local name, value\n    if thread then\n      name, value = debug.getlocal(thread, level, -i)\n    else\n      name, value = debug.getlocal(level, -i)\n    end\n    if not name then break end\n    vars['...'][i] = value\n    i = i + 1\n  end\n  -- returned 'vars' table plays a dual role: (1) it captures local values\n  -- and upvalues to be restored later (in case they are modified in \"eval\"),\n  -- and (2) it provides an environment for evaluated chunks.\n  -- getfenv(func) is needed to provide proper environment for functions,\n  -- including access to globals, but this causes vars[name] to fail in\n  -- restore_vars on local variables or upvalues with `nil` values when\n  -- 'strict' is in effect. To avoid this `rawget` is used in restore_vars.\n  setmetatable(vars, { __index = getfenv(func), __newindex = getfenv(func), __mode = \"v\" })\n  return vars\nend\n\nlocal function stack_depth(start_depth)\n  for i = start_depth, 0, -1 do\n    if debug.getinfo(i, \"l\") then return i+1 end\n  end\n  return start_depth\nend\n\nlocal function is_safe(stack_level)\n  -- the stack grows up: 0 is getinfo, 1 is is_safe, 2 is debug_hook, 3 is user function\n  if stack_level == 3 then return true end\n  for i = 3, stack_level do\n    -- return if it is not safe to abort\n    local info = debug.getinfo(i, \"S\")\n    if not info then return true end\n    if info.what == \"C\" then return false end\n  end\n  return true\nend\n\nlocal function in_debugger()\n  local this = debug.getinfo(1, \"S\").source\n  -- only need to check few frames as mobdebug frames should be close\n  for i = 3, 7 do\n    local info = debug.getinfo(i, \"S\")\n    if not info then return false end\n    if info.source == this then return true end\n  end\n  return false\nend\n\nlocal function is_pending(peer)\n  -- if there is something already in the buffer, skip check\n  if not buf and checkcount >= mobdebug.checkcount then\n    peer:settimeout(0) -- non-blocking\n    buf = peer:receive(1)\n    peer:settimeout() -- back to blocking\n    checkcount = 0\n  end\n  return buf\nend\n\nlocal function readnext(peer, num)\n  peer:settimeout(0) -- non-blocking\n  local res, err, partial = peer:receive(num)\n  peer:settimeout() -- back to blocking\n  return res or partial or '', err\nend\n\nlocal function handle_breakpoint(peer)\n  -- check if the buffer has the beginning of SETB/DELB command;\n  -- this is to avoid reading the entire line for commands that\n  -- don't need to be handled here.\n  if not buf or not (buf:sub(1,1) == 'S' or buf:sub(1,1) == 'D') then return end\n\n  -- check second character to avoid reading STEP or other S* and D* commands\n  if #buf == 1 then buf = buf .. readnext(peer, 1) end\n  if buf:sub(2,2) ~= 'E' then return end\n\n  -- need to read few more characters\n  buf = buf .. readnext(peer, 5-#buf)\n  if buf ~= 'SETB ' and buf ~= 'DELB ' then return end\n\n  local res, _, partial = peer:receive(\"*l\") -- get the rest of the line; blocking\n  if not res then\n    if partial then buf = buf .. partial end\n    return\n  end\n\n  local _, _, cmd, file, line = (buf..res):find(\"^([A-Z]+)%s+(.-)%s+(%d+)%s*$\")\n  if cmd == 'SETB' then set_breakpoint(file, tonumber(line))\n  elseif cmd == 'DELB' then remove_breakpoint(file, tonumber(line))\n  else\n    -- this looks like a breakpoint command, but something went wrong;\n    -- return here to let the \"normal\" processing to handle,\n    -- although this is likely to not go well.\n    return\n  end\n\n  buf = nil\nend\n\nlocal function normalize_path(file)\n  local n\n  repeat\n    file, n = file:gsub(\"/+%.?/+\",\"/\") -- remove all `//` and `/./` references\n  until n == 0\n  -- collapse all up-dir references: this will clobber UNC prefix (\\\\?\\)\n  -- and disk on Windows when there are too many up-dir references: `D:\\foo\\..\\..\\bar`;\n  -- handle the case of multiple up-dir references: `foo/bar/baz/../../../more`;\n  -- only remove one at a time as otherwise `../../` could be removed;\n  repeat\n    file, n = file:gsub(\"[^/]+/%.%./\", \"\", 1)\n  until n == 0\n  -- there may still be a leading up-dir reference left (as `/../` or `../`); remove it\n  return (file:gsub(\"^(/?)%.%./\", \"%1\"))\nend\n\nlocal function debug_hook(event, line)\n  -- (1) LuaJIT needs special treatment. Because debug_hook is set for\n  -- *all* coroutines, and not just the one being debugged as in regular Lua\n  -- (http://lua-users.org/lists/lua-l/2011-06/msg00513.html),\n  -- need to avoid debugging mobdebug's own code as LuaJIT doesn't\n  -- always correctly generate call/return hook events (there are more\n  -- calls than returns, which breaks stack depth calculation and\n  -- 'step' and 'step over' commands stop working; possibly because\n  -- 'tail return' events are not generated by LuaJIT).\n  -- the next line checks if the debugger is run under LuaJIT and if\n  -- one of debugger methods is present in the stack, it simply returns.\n  -- ngx_lua/Openresty requires a slightly different handling, as it\n  -- creates a coroutine wrapper, so this processing needs to be skipped.\n  if jit and not (ngx and type(ngx) == \"table\" and ngx.say) then\n    -- when luajit is compiled with LUAJIT_ENABLE_LUA52COMPAT,\n    -- coroutine.running() returns non-nil for the main thread.\n    local coro, main = coroutine.running()\n    if not coro or main then coro = 'main' end\n    local disabled = coroutines[coro] == false\n      or coroutines[coro] == nil and coro ~= (coro_debugee or 'main')\n    if coro_debugee and disabled or not coro_debugee and (disabled or in_debugger()) then\n      return\n    end\n  end\n\n  -- (2) check if abort has been requested and it's safe to abort\n  if abort and is_safe(stack_level) then error(abort) end\n\n  -- (3) also check if this debug hook has not been visited for any reason.\n  -- this check is needed to avoid stepping in too early\n  -- (for example, when coroutine.resume() is executed inside start()).\n  if not seen_hook and in_debugger() then return end\n\n  if event == \"call\" then\n    stack_level = stack_level + 1\n  elseif event == \"return\" or event == \"tail return\" then\n    stack_level = stack_level - 1\n  elseif event == \"line\" then\n    if mobdebug.linemap then\n      local ok, mappedline = pcall(mobdebug.linemap, line, debug.getinfo(2, \"S\").source)\n      if ok then line = mappedline end\n      if not line then return end\n    end\n\n    -- may need to fall through because of the following:\n    -- (1) step_into\n    -- (2) step_over and stack_level <= step_level (need stack_level)\n    -- (3) breakpoint; check for line first as it's known; then for file\n    -- (4) socket call (only do every Xth check)\n    -- (5) at least one watch is registered\n    if not (\n      step_into or step_over or breakpoints[line] or watchescnt > 0\n      or is_pending(server)\n    ) then checkcount = checkcount + 1; return end\n\n    checkcount = mobdebug.checkcount -- force check on the next command\n\n    -- this is needed to check if the stack got shorter or longer.\n    -- unfortunately counting call/return calls is not reliable.\n    -- the discrepancy may happen when \"pcall(load, '')\" call is made\n    -- or when \"error()\" is called in a function.\n    -- in either case there are more \"call\" than \"return\" events reported.\n    -- this validation is done for every \"line\" event, but should be \"cheap\"\n    -- as it checks for the stack to get shorter (or longer by one call).\n    -- start from one level higher just in case we need to grow the stack.\n    -- this may happen after coroutine.resume call to a function that doesn't\n    -- have any other instructions to execute. it triggers three returns:\n    -- \"return, tail return, return\", which needs to be accounted for.\n    stack_level = stack_depth(stack_level+1)\n\n    local caller = debug.getinfo(2, \"S\")\n\n    -- grab the filename and fix it if needed\n    local file = lastfile\n    if (lastsource ~= caller.source) then\n      file, lastsource = caller.source, caller.source\n      -- technically, users can supply names that may not use '@',\n      -- for example when they call loadstring('...', 'filename.lua').\n      -- Unfortunately, there is no reliable/quick way to figure out\n      -- what is the filename and what is the source code.\n      -- If the name doesn't start with `@`, assume it's a file name if it's all on one line.\n      if find(file, \"^@\") or not find(file, \"[\\r\\n]\") then\n        file = gsub(gsub(file, \"^@\", \"\"), \"\\\\\", \"/\")\n        -- normalize paths that may include up-dir or same-dir references\n        -- if the path starts from the up-dir or reference,\n        -- prepend `basedir` to generate absolute path to keep breakpoints working.\n        -- ignore qualified relative path (`D:../`) and UNC paths (`\\\\?\\`)\n        if find(file, \"^%.%./\") then file = basedir..file end\n        if find(file, \"/%.%.?/\") then file = normalize_path(file) end\n        -- need this conversion to be applied to relative and absolute\n        -- file names as you may write \"require 'Foo'\" to\n        -- load \"foo.lua\" (on a case insensitive file system) and breakpoints\n        -- set on foo.lua will not work if not converted to the same case.\n        if iscasepreserving then file = string.lower(file) end\n        if find(file, \"^%./\") then file = sub(file, 3) end\n        -- remove basedir, so that breakpoints are checked properly\n        file = gsub(file, \"^\"..q(basedir), \"\")\n        -- some file systems allow newlines in file names; remove these.\n        file = gsub(file, \"\\n\", ' ')\n      else\n        file = mobdebug.line(file)\n      end\n\n      -- set to true if we got here; this only needs to be done once per\n      -- session, so do it here to at least avoid setting it for every line.\n      seen_hook = true\n      lastfile = file\n    end\n\n    if is_pending(server) then handle_breakpoint(server) end\n\n    local vars, status, res\n    if (watchescnt > 0) then\n      vars = capture_vars(1)\n      for index, value in pairs(watches) do\n        setfenv(value, vars)\n        local ok, fired = pcall(value)\n        if ok and fired then\n          status, res = cororesume(coro_debugger, events.WATCH, vars, file, line, index)\n          break -- any one watch is enough; don't check multiple times\n        end\n      end\n    end\n\n    -- need to get into the \"regular\" debug handler, but only if there was\n    -- no watch that was fired. If there was a watch, handle its result.\n    local getin = (status == nil) and\n      (step_into\n      -- when coroutine.running() return `nil` (main thread in Lua 5.1),\n      -- step_over will equal 'main', so need to check for that explicitly.\n      or (step_over and step_over == (coroutine.running() or 'main') and stack_level <= step_level)\n      or has_breakpoint(file, line)\n      or is_pending(server))\n\n    if getin then\n      vars = vars or capture_vars(1)\n      step_into = false\n      step_over = false\n      status, res = cororesume(coro_debugger, events.BREAK, vars, file, line)\n    end\n\n    -- handle 'stack' command that provides stack() information to the debugger\n    while status and res == 'stack' do\n      -- resume with the stack trace and variables\n      if vars then restore_vars(vars) end -- restore vars so they are reflected in stack values\n      status, res = cororesume(coro_debugger, events.STACK, stack(3), file, line)\n    end\n\n    -- need to recheck once more as resume after 'stack' command may\n    -- return something else (for example, 'exit'), which needs to be handled\n    if status and res and res ~= 'stack' then\n      if not abort and res == \"exit\" then mobdebug.onexit(1, true); return end\n      if not abort and res == \"done\" then mobdebug.done(); return end\n      abort = res\n      -- only abort if safe; if not, there is another (earlier) check inside\n      -- debug_hook, which will abort execution at the first safe opportunity\n      if is_safe(stack_level) then error(abort) end\n    elseif not status and res then\n      error(res, 2) -- report any other (internal) errors back to the application\n    end\n\n    if vars then restore_vars(vars) end\n\n    -- last command requested Step Over/Out; store the current thread\n    if step_over == true then step_over = coroutine.running() or 'main' end\n  end\nend\n\nlocal function stringify_results(params, status, ...)\n  if not status then return status, ... end -- on error report as it\n\n  params = params or {}\n  if params.nocode == nil then params.nocode = true end\n  if params.comment == nil then params.comment = 1 end\n\n  local t = {...}\n  for i,v in pairs(t) do -- stringify each of the returned values\n    local ok, res = pcall(mobdebug.line, v, params)\n    t[i] = ok and res or (\"%q\"):format(res):gsub(\"\\010\",\"n\"):gsub(\"\\026\",\"\\\\026\")\n  end\n  -- stringify table with all returned values\n  -- this is done to allow each returned value to be used (serialized or not)\n  -- intependently and to preserve \"original\" comments\n  return pcall(mobdebug.dump, t, {sparse = false})\nend\n\nlocal function isrunning()\n  return coro_debugger and (corostatus(coro_debugger) == 'suspended' or corostatus(coro_debugger) == 'running')\nend\n\n-- this is a function that removes all hooks and closes the socket to\n-- report back to the controller that the debugging is done.\n-- the script that called `done` can still continue.\nlocal function done()\n  if not (isrunning() and server) then return end\n\n  if not jit then\n    for co, debugged in pairs(coroutines) do\n      if debugged then debug.sethook(co) end\n    end\n  end\n\n  debug.sethook()\n  server:close()\n\n  coro_debugger = nil -- to make sure isrunning() returns `false`\n  seen_hook = nil -- to make sure that the next start() call works\n  abort = nil -- to make sure that callback calls use proper \"abort\" value\n  basedir = \"\" -- to reset basedir in case the same module/state is reused\nend\n\nlocal function debugger_loop(sev, svars, sfile, sline)\n  local command\n  local eval_env = svars or {}\n  local function emptyWatch () return false end\n  local loaded = {}\n  for k in pairs(package.loaded) do loaded[k] = true end\n\n  while true do\n    local line, err\n    if mobdebug.yield and server.settimeout then server:settimeout(mobdebug.yieldtimeout) end\n    while true do\n      line, err = server:receive(\"*l\")\n      if not line then\n        if err == \"timeout\" then\n          if mobdebug.yield then mobdebug.yield() end\n        elseif err == \"closed\" then\n          error(\"Debugger connection closed\", 0)\n        else\n          error((\"Unexpected socket error: %s\"):format(err), 0)\n        end\n      else\n        -- if there is something in the pending buffer, prepend it to the line\n        if buf then line = buf .. line; buf = nil end\n        break\n      end\n    end\n    if server.settimeout then server:settimeout() end -- back to blocking\n    command = string.sub(line, string.find(line, \"^[A-Z]+\"))\n    if command == \"SETB\" then\n      local _, _, _, file, line = string.find(line, \"^([A-Z]+)%s+(.-)%s+(%d+)%s*$\")\n      if file and line then\n        set_breakpoint(file, tonumber(line))\n        server:send(\"200 OK\\n\")\n      else\n        server:send(\"400 Bad Request\\n\")\n      end\n    elseif command == \"DELB\" then\n      local _, _, _, file, line = string.find(line, \"^([A-Z]+)%s+(.-)%s+(%d+)%s*$\")\n      if file and line then\n        remove_breakpoint(file, tonumber(line))\n        server:send(\"200 OK\\n\")\n      else\n        server:send(\"400 Bad Request\\n\")\n      end\n    elseif command == \"EXEC\" then\n      -- extract any optional parameters\n      local params = string.match(line, \"--%s*(%b{})%s*$\")\n      local _, _, chunk = string.find(line, \"^[A-Z]+%s+(.+)$\")\n      if chunk then\n        local func, res = mobdebug.loadstring(chunk)\n        local status\n        if func then\n          local pfunc = params and loadstring(\"return \"..params) -- use internal function\n          params = pfunc and pfunc()\n          params = (type(params) == \"table\" and params or {})\n          local stack = tonumber(params.stack)\n          -- if the requested stack frame is not the current one, then use a new capture\n          -- with a specific stack frame: `capture_vars(0, coro_debugee)`\n          local env = stack and coro_debugee and capture_vars(stack-1, coro_debugee) or eval_env\n          setfenv(func, env)\n          status, res = stringify_results(params, pcall(func, unpack(rawget(env,'...') or {})))\n        end\n        if status then\n          if mobdebug.onscratch then mobdebug.onscratch(res) end\n          server:send(\"200 OK \" .. tostring(#res) .. \"\\n\")\n          server:send(res)\n        else\n          -- fix error if not set (for example, when loadstring is not present)\n          if not res then res = \"Unknown error\" end\n          server:send(\"401 Error in Expression \" .. tostring(#res) .. \"\\n\")\n          server:send(res)\n        end\n      else\n        server:send(\"400 Bad Request\\n\")\n      end\n    elseif command == \"LOAD\" then\n      local _, _, size, name = string.find(line, \"^[A-Z]+%s+(%d+)%s+(%S.-)%s*$\")\n      size = tonumber(size)\n\n      if abort == nil then -- no LOAD/RELOAD allowed inside start()\n        if size > 0 then server:receive(size) end\n        if sfile and sline then\n          server:send(\"201 Started \" .. sfile .. \" \" .. tostring(sline) .. \"\\n\")\n        else\n          server:send(\"200 OK 0\\n\")\n        end\n      else\n        -- reset environment to allow required modules to load again\n        -- remove those packages that weren't loaded when debugger started\n        for k in pairs(package.loaded) do\n          if not loaded[k] then package.loaded[k] = nil end\n        end\n\n        if size == 0 and name == '-' then -- RELOAD the current script being debugged\n          server:send(\"200 OK 0\\n\")\n          coroyield(\"load\")\n        else\n          -- receiving 0 bytes blocks (at least in luasocket 2.0.2), so skip reading\n          local chunk = size == 0 and \"\" or server:receive(size)\n          if chunk then -- LOAD a new script for debugging\n            local func, res = mobdebug.loadstring(chunk, \"@\"..name)\n            if func then\n              server:send(\"200 OK 0\\n\")\n              debugee = func\n              coroyield(\"load\")\n            else\n              server:send(\"401 Error in Expression \" .. tostring(#res) .. \"\\n\")\n              server:send(res)\n            end\n          else\n            server:send(\"400 Bad Request\\n\")\n          end\n        end\n      end\n    elseif command == \"SETW\" then\n      local _, _, exp = string.find(line, \"^[A-Z]+%s+(.+)%s*$\")\n      if exp then\n        local func, res = mobdebug.loadstring(\"return(\" .. exp .. \")\")\n        if func then\n          watchescnt = watchescnt + 1\n          local newidx = #watches + 1\n          watches[newidx] = func\n          server:send(\"200 OK \" .. tostring(newidx) .. \"\\n\")\n        else\n          server:send(\"401 Error in Expression \" .. tostring(#res) .. \"\\n\")\n          server:send(res)\n        end\n      else\n        server:send(\"400 Bad Request\\n\")\n      end\n    elseif command == \"DELW\" then\n      local _, _, index = string.find(line, \"^[A-Z]+%s+(%d+)%s*$\")\n      index = tonumber(index)\n      if index > 0 and index <= #watches then\n        watchescnt = watchescnt - (watches[index] ~= emptyWatch and 1 or 0)\n        watches[index] = emptyWatch\n        server:send(\"200 OK\\n\")\n      else\n        server:send(\"400 Bad Request\\n\")\n      end\n    elseif command == \"RUN\" then\n      server:send(\"200 OK\\n\")\n\n      local ev, vars, file, line, idx_watch = coroyield()\n      eval_env = vars\n      if ev == events.BREAK then\n        server:send(\"202 Paused \" .. file .. \" \" .. tostring(line) .. \"\\n\")\n      elseif ev == events.WATCH then\n        server:send(\"203 Paused \" .. file .. \" \" .. tostring(line) .. \" \" .. tostring(idx_watch) .. \"\\n\")\n      elseif ev == events.RESTART then\n        -- nothing to do\n      else\n        server:send(\"401 Error in Execution \" .. tostring(#file) .. \"\\n\")\n        server:send(file)\n      end\n    elseif command == \"STEP\" then\n      server:send(\"200 OK\\n\")\n      step_into = true\n\n      local ev, vars, file, line, idx_watch = coroyield()\n      eval_env = vars\n      if ev == events.BREAK then\n        server:send(\"202 Paused \" .. file .. \" \" .. tostring(line) .. \"\\n\")\n      elseif ev == events.WATCH then\n        server:send(\"203 Paused \" .. file .. \" \" .. tostring(line) .. \" \" .. tostring(idx_watch) .. \"\\n\")\n      elseif ev == events.RESTART then\n        -- nothing to do\n      else\n        server:send(\"401 Error in Execution \" .. tostring(#file) .. \"\\n\")\n        server:send(file)\n      end\n    elseif command == \"OVER\" or command == \"OUT\" then\n      server:send(\"200 OK\\n\")\n      step_over = true\n\n      -- OVER and OUT are very similar except for\n      -- the stack level value at which to stop\n      if command == \"OUT\" then step_level = stack_level - 1\n      else step_level = stack_level end\n\n      local ev, vars, file, line, idx_watch = coroyield()\n      eval_env = vars\n      if ev == events.BREAK then\n        server:send(\"202 Paused \" .. file .. \" \" .. tostring(line) .. \"\\n\")\n      elseif ev == events.WATCH then\n        server:send(\"203 Paused \" .. file .. \" \" .. tostring(line) .. \" \" .. tostring(idx_watch) .. \"\\n\")\n      elseif ev == events.RESTART then\n        -- nothing to do\n      else\n        server:send(\"401 Error in Execution \" .. tostring(#file) .. \"\\n\")\n        server:send(file)\n      end\n    elseif command == \"BASEDIR\" then\n      local _, _, dir = string.find(line, \"^[A-Z]+%s+(.+)%s*$\")\n      if dir then\n        basedir = iscasepreserving and string.lower(dir) or dir\n        -- reset cached source as it may change with basedir\n        lastsource = nil\n        server:send(\"200 OK\\n\")\n      else\n        server:send(\"400 Bad Request\\n\")\n      end\n    elseif command == \"SUSPEND\" then\n      -- do nothing; it already fulfilled its role\n    elseif command == \"DONE\" then\n      coroyield(\"done\")\n      return -- done with all the debugging\n    elseif command == \"STACK\" then\n      -- first check if we can execute the stack command\n      -- as it requires yielding back to debug_hook it cannot be executed\n      -- if we have not seen the hook yet as happens after start().\n      -- in this case we simply return an empty result\n      local vars, ev = {}\n      if seen_hook then\n        ev, vars = coroyield(\"stack\")\n      end\n      if ev and ev ~= events.STACK then\n        server:send(\"401 Error in Execution \" .. tostring(#vars) .. \"\\n\")\n        server:send(vars)\n      else\n        local params = string.match(line, \"--%s*(%b{})%s*$\")\n        local pfunc = params and loadstring(\"return \"..params) -- use internal function\n        params = pfunc and pfunc()\n        params = (type(params) == \"table\" and params or {})\n        if params.nocode == nil then params.nocode = true end\n        if params.sparse == nil then params.sparse = false end\n        -- take into account additional levels for the stack frames and data management\n        if tonumber(params.maxlevel) then params.maxlevel = tonumber(params.maxlevel)+4 end\n\n        local ok, res = pcall(mobdebug.dump, vars, params)\n        if ok then\n          server:send(\"200 OK \" .. tostring(res) .. \"\\n\")\n        else\n          server:send(\"401 Error in Execution \" .. tostring(#res) .. \"\\n\")\n          server:send(res)\n        end\n      end\n    elseif command == \"OUTPUT\" then\n      local _, _, stream, mode = string.find(line, \"^[A-Z]+%s+(%w+)%s+([dcr])%s*$\")\n      if stream and mode and stream == \"stdout\" then\n        -- assign \"print\" in the global environment\n        local default = mode == 'd'\n        genv.print = default and iobase.print or corowrap(function()\n          -- wrapping into coroutine.wrap protects this function from\n          -- being stepped through in the debugger.\n          -- don't use vararg (...) as it adds a reference for its values,\n          -- which may affect how they are garbage collected\n          while true do\n            local tbl = {coroutine.yield()}\n            if mode == 'c' then iobase.print(unpack(tbl)) end\n            for n = 1, #tbl do\n              tbl[n] = select(2, pcall(mobdebug.line, tbl[n], {nocode = true, comment = false})) end\n            local file = table.concat(tbl, \"\\t\")..\"\\n\"\n            server:send(\"204 Output \" .. stream .. \" \" .. tostring(#file) .. \"\\n\" .. file)\n          end\n        end)\n        if not default then genv.print() end -- \"fake\" print to start printing loop\n        server:send(\"200 OK\\n\")\n      else\n        server:send(\"400 Bad Request\\n\")\n      end\n    elseif command == \"EXIT\" then\n      server:send(\"200 OK\\n\")\n      coroyield(\"exit\")\n    else\n      server:send(\"400 Bad Request\\n\")\n    end\n  end\nend\n\nlocal function output(stream, data)\n  if server then return server:send(\"204 Output \"..stream..\" \"..tostring(#data)..\"\\n\"..data) end\nend\n\nlocal function connect(controller_host, controller_port)\n  local sock, err = socket.tcp()\n  if not sock then return nil, err end\n\n  if sock.settimeout then sock:settimeout(mobdebug.connecttimeout) end\n  local res, err = sock:connect(controller_host, tostring(controller_port))\n  if sock.settimeout then sock:settimeout() end\n\n  if not res then return nil, err end\n  return sock\nend\n\nlocal lasthost, lastport\n\n-- Starts a debug session by connecting to a controller\nlocal function start(controller_host, controller_port)\n  -- only one debugging session can be run (as there is only one debug hook)\n  if isrunning() then return end\n\n  lasthost = controller_host or lasthost\n  lastport = controller_port or lastport\n\n  controller_host = lasthost or \"localhost\"\n  controller_port = lastport or mobdebug.port\n\n  local err\n  server, err = mobdebug.connect(controller_host, controller_port)\n  if server then\n    -- correct stack depth which already has some calls on it\n    -- so it doesn't go into negative when those calls return\n    -- as this breaks subsequence checks in stack_depth().\n    -- start from 16th frame, which is sufficiently large for this check.\n    stack_level = stack_depth(16)\n\n    coro_debugger = corocreate(debugger_loop)\n    debug.sethook(debug_hook, HOOKMASK)\n    seen_hook = nil -- reset in case the last start() call was refused\n    step_into = true -- start with step command\n    return true\n  else\n    print((\"Could not connect to %s:%s: %s\")\n      :format(controller_host, controller_port, err or \"unknown error\"))\n  end\nend\n\nlocal function controller(controller_host, controller_port, scratchpad)\n  -- only one debugging session can be run (as there is only one debug hook)\n  if isrunning() then return end\n\n  lasthost = controller_host or lasthost\n  lastport = controller_port or lastport\n\n  controller_host = lasthost or \"localhost\"\n  controller_port = lastport or mobdebug.port\n\n  local exitonerror = not scratchpad\n  local err\n  server, err = mobdebug.connect(controller_host, controller_port)\n  if server then\n    local function report(trace, err)\n      local msg = err .. \"\\n\" .. trace\n      server:send(\"401 Error in Execution \" .. tostring(#msg) .. \"\\n\")\n      server:send(msg)\n      return err\n    end\n\n    seen_hook = true -- allow to accept all commands\n    coro_debugger = corocreate(debugger_loop)\n\n    while true do\n      step_into = true -- start with step command\n      abort = false -- reset abort flag from the previous loop\n      if scratchpad then checkcount = mobdebug.checkcount end -- force suspend right away\n\n      coro_debugee = corocreate(debugee)\n      debug.sethook(coro_debugee, debug_hook, HOOKMASK)\n      local status, err = cororesume(coro_debugee, unpack(arg or {}))\n\n      -- was there an error or is the script done?\n      -- 'abort' state is allowed here; ignore it\n      if abort then\n        if tostring(abort) == 'exit' then break end\n      else\n        if status then -- no errors\n          if corostatus(coro_debugee) == \"suspended\" then\n            -- the script called `coroutine.yield` in the \"main\" thread\n            error(\"attempt to yield from the main thread\", 3)\n          end\n          break -- normal execution is done\n        elseif err and not string.find(tostring(err), deferror) then\n          -- report the error back\n          -- err is not necessarily a string, so convert to string to report\n          report(debug.traceback(coro_debugee), tostring(err))\n          if exitonerror then break end\n          -- check if the debugging is done (coro_debugger is nil)\n          if not coro_debugger then break end\n          -- resume once more to clear the response the debugger wants to send\n          -- need to use capture_vars(0) to capture only two (default) levels,\n          -- as even though there is controller() call, because of the tail call,\n          -- the caller may not exist for it;\n          -- This is not entirely safe as the user may see the local\n          -- variable from console, but they will be reset anyway.\n          -- This functionality is used when scratchpad is paused to\n          -- gain access to remote console to modify global variables.\n          local status, err = cororesume(coro_debugger, events.RESTART, capture_vars(0))\n          if not status or status and err == \"exit\" then break end\n        end\n      end\n    end\n  else\n    print((\"Could not connect to %s:%s: %s\")\n      :format(controller_host, controller_port, err or \"unknown error\"))\n    return false\n  end\n  return true\nend\n\nlocal function scratchpad(controller_host, controller_port)\n  return controller(controller_host, controller_port, true)\nend\n\nlocal function loop(controller_host, controller_port)\n  return controller(controller_host, controller_port, false)\nend\n\nlocal function on()\n  if not (isrunning() and server) then return end\n\n  -- main is set to true under Lua5.2 for the \"main\" chunk.\n  -- Lua5.1 returns co as `nil` in that case.\n  local co, main = coroutine.running()\n  if main then co = nil end\n  if co then\n    coroutines[co] = true\n    debug.sethook(co, debug_hook, HOOKMASK)\n  else\n    if jit then coroutines.main = true end\n    debug.sethook(debug_hook, HOOKMASK)\n  end\nend\n\nlocal function off()\n  if not (isrunning() and server) then return end\n\n  -- main is set to true under Lua5.2 for the \"main\" chunk.\n  -- Lua5.1 returns co as `nil` in that case.\n  local co, main = coroutine.running()\n  if main then co = nil end\n\n  -- don't remove coroutine hook under LuaJIT as there is only one (global) hook\n  if co then\n    coroutines[co] = false\n    if not jit then debug.sethook(co) end\n  else\n    if jit then coroutines.main = false end\n    if not jit then debug.sethook() end\n  end\n\n  -- check if there is any thread that is still being debugged under LuaJIT;\n  -- if not, turn the debugging off\n  if jit then\n    local remove = true\n    for _, debugged in pairs(coroutines) do\n      if debugged then remove = false; break end\n    end\n    if remove then debug.sethook() end\n  end\nend\n\n-- Handles server debugging commands\nlocal function handle(params, client, options)\n  -- when `options.verbose` is not provided, use normal `print`; verbose output can be\n  -- disabled (`options.verbose == false`) or redirected (`options.verbose == function()...end`)\n  local verbose = not options or options.verbose ~= nil and options.verbose\n  local print = verbose and (type(verbose) == \"function\" and verbose or print) or function() end\n  local file, line, watch_idx\n  local _, _, command = string.find(params, \"^([a-z]+)\")\n  if command == \"run\" or command == \"step\" or command == \"out\"\n  or command == \"over\" or command == \"exit\" then\n    client:send(string.upper(command) .. \"\\n\")\n    client:receive(\"*l\") -- this should consume the first '200 OK' response\n    while true do\n      local done = true\n      local breakpoint = client:receive(\"*l\")\n      if not breakpoint then\n        print(\"Program finished\")\n        return nil, nil, false\n      end\n      local _, _, status = string.find(breakpoint, \"^(%d+)\")\n      if status == \"200\" then\n        -- don't need to do anything\n      elseif status == \"202\" then\n        _, _, file, line = string.find(breakpoint, \"^202 Paused%s+(.-)%s+(%d+)%s*$\")\n        if file and line then\n          print(\"Paused at file \" .. file .. \" line \" .. line)\n        end\n      elseif status == \"203\" then\n        _, _, file, line, watch_idx = string.find(breakpoint, \"^203 Paused%s+(.-)%s+(%d+)%s+(%d+)%s*$\")\n        if file and line and watch_idx then\n          print(\"Paused at file \" .. file .. \" line \" .. line .. \" (watch expression \" .. watch_idx .. \": [\" .. watches[watch_idx] .. \"])\")\n        end\n      elseif status == \"204\" then\n        local _, _, stream, size = string.find(breakpoint, \"^204 Output (%w+) (%d+)$\")\n        if stream and size then\n          local size = tonumber(size)\n          local msg = size > 0 and client:receive(size) or \"\"\n          print(msg)\n          if outputs[stream] then outputs[stream](msg) end\n          -- this was just the output, so go back reading the response\n          done = false\n        end\n      elseif status == \"401\" then\n        local _, _, size = string.find(breakpoint, \"^401 Error in Execution (%d+)$\")\n        if size then\n          local msg = client:receive(tonumber(size))\n          print(\"Error in remote application: \" .. msg)\n          return nil, nil, msg\n        end\n      else\n        print(\"Unknown error\")\n        return nil, nil, \"Debugger error: unexpected response '\" .. breakpoint .. \"'\"\n      end\n      if done then break end\n    end\n  elseif command == \"done\" then\n    client:send(string.upper(command) .. \"\\n\")\n    -- no response is expected\n  elseif command == \"setb\" or command == \"asetb\" then\n    _, _, _, file, line = string.find(params, \"^([a-z]+)%s+(.-)%s+(%d+)%s*$\")\n    if file and line then\n      -- if this is a file name, and not a file source\n      if not file:find('^\".*\"$') then\n        file = string.gsub(file, \"\\\\\", \"/\") -- convert slash\n        file = removebasedir(file, basedir)\n      end\n      client:send(\"SETB \" .. file .. \" \" .. line .. \"\\n\")\n      if command == \"asetb\" or client:receive(\"*l\") == \"200 OK\" then\n        set_breakpoint(file, line)\n      else\n        print(\"Error: breakpoint not inserted\")\n      end\n    else\n      print(\"Invalid command\")\n    end\n  elseif command == \"setw\" then\n    local _, _, exp = string.find(params, \"^[a-z]+%s+(.+)$\")\n    if exp then\n      client:send(\"SETW \" .. exp .. \"\\n\")\n      local answer = client:receive(\"*l\")\n      local _, _, watch_idx = string.find(answer, \"^200 OK (%d+)%s*$\")\n      if watch_idx then\n        watches[watch_idx] = exp\n        print(\"Inserted watch exp no. \" .. watch_idx)\n      else\n        local _, _, size = string.find(answer, \"^401 Error in Expression (%d+)$\")\n        if size then\n          local err = client:receive(tonumber(size)):gsub(\".-:%d+:%s*\",\"\")\n          print(\"Error: watch expression not set: \" .. err)\n        else\n          print(\"Error: watch expression not set\")\n        end\n      end\n    else\n      print(\"Invalid command\")\n    end\n  elseif command == \"delb\" or command == \"adelb\" then\n    _, _, _, file, line = string.find(params, \"^([a-z]+)%s+(.-)%s+(%d+)%s*$\")\n    if file and line then\n      -- if this is a file name, and not a file source\n      if not file:find('^\".*\"$') then\n        file = string.gsub(file, \"\\\\\", \"/\") -- convert slash\n        file = removebasedir(file, basedir)\n      end\n      client:send(\"DELB \" .. file .. \" \" .. line .. \"\\n\")\n      if command == \"adelb\" or client:receive(\"*l\") == \"200 OK\" then\n        remove_breakpoint(file, line)\n      else\n        print(\"Error: breakpoint not removed\")\n      end\n    else\n      print(\"Invalid command\")\n    end\n  elseif command == \"delallb\" then\n    local file, line = \"*\", 0\n    client:send(\"DELB \" .. file .. \" \" .. tostring(line) .. \"\\n\")\n    if client:receive(\"*l\") == \"200 OK\" then\n      remove_breakpoint(file, line)\n    else\n      print(\"Error: all breakpoints not removed\")\n    end\n  elseif command == \"delw\" then\n    local _, _, index = string.find(params, \"^[a-z]+%s+(%d+)%s*$\")\n    if index then\n      client:send(\"DELW \" .. index .. \"\\n\")\n      if client:receive(\"*l\") == \"200 OK\" then\n        watches[index] = nil\n      else\n        print(\"Error: watch expression not removed\")\n      end\n    else\n      print(\"Invalid command\")\n    end\n  elseif command == \"delallw\" then\n    for index, exp in pairs(watches) do\n      client:send(\"DELW \" .. index .. \"\\n\")\n      if client:receive(\"*l\") == \"200 OK\" then\n        watches[index] = nil\n      else\n        print(\"Error: watch expression at index \" .. index .. \" [\" .. exp .. \"] not removed\")\n      end\n    end\n  elseif command == \"eval\" or command == \"exec\"\n      or command == \"load\" or command == \"loadstring\"\n      or command == \"reload\" then\n    local _, _, exp = string.find(params, \"^[a-z]+%s+(.+)$\")\n    if exp or (command == \"reload\") then\n      if command == \"eval\" or command == \"exec\" then\n        exp = exp:gsub(\"\\n\", \"\\r\") -- convert new lines, so the fragment can be passed as one line\n        if command == \"eval\" then exp = \"return \" .. exp end\n        client:send(\"EXEC \" .. exp .. \"\\n\")\n      elseif command == \"reload\" then\n        client:send(\"LOAD 0 -\\n\")\n      elseif command == \"loadstring\" then\n        local _, _, _, file, lines = string.find(exp, \"^([\\\"'])(.-)%1%s(.+)\")\n        if not file then\n           _, _, file, lines = string.find(exp, \"^(%S+)%s(.+)\")\n        end\n        client:send(\"LOAD \" .. tostring(#lines) .. \" \" .. file .. \"\\n\")\n        client:send(lines)\n      else\n        local file = io.open(exp, \"r\")\n        if not file and pcall(require, \"winapi\") then\n          -- if file is not open and winapi is there, try with a short path;\n          -- this may be needed for unicode paths on windows\n          winapi.set_encoding(winapi.CP_UTF8)\n          local shortp = winapi.short_path(exp)\n          file = shortp and io.open(shortp, \"r\")\n        end\n        if not file then return nil, nil, \"Cannot open file \" .. exp end\n        -- read the file and remove the shebang line as it causes a compilation error\n        local lines = file:read(\"*all\"):gsub(\"^#!.-\\n\", \"\\n\")\n        file:close()\n\n        local fname = string.gsub(exp, \"\\\\\", \"/\") -- convert slash\n        fname = removebasedir(fname, basedir)\n        client:send(\"LOAD \" .. tostring(#lines) .. \" \" .. fname .. \"\\n\")\n        if #lines > 0 then client:send(lines) end\n      end\n      while true do\n        local params, err = client:receive(\"*l\")\n        if not params then\n          return nil, nil, \"Debugger connection \" .. (err or \"error\")\n        end\n        local done = true\n        local _, _, status, len = string.find(params, \"^(%d+).-%s+(%d+)%s*$\")\n        if status == \"200\" then\n          len = tonumber(len)\n          if len > 0 then\n            local status, res\n            local str = client:receive(len)\n            -- handle serialized table with results\n            local func, err = loadstring(str)\n            if func then\n              status, res = pcall(func)\n              if not status then err = res\n              elseif type(res) ~= \"table\" then\n                err = \"received \"..type(res)..\" instead of expected 'table'\"\n              end\n            end\n            if err then\n              print(\"Error in processing results: \" .. err)\n              return nil, nil, \"Error in processing results: \" .. err\n            end\n            print(unpack(res))\n            return res[1], res\n          end\n        elseif status == \"201\" then\n          _, _, file, line = string.find(params, \"^201 Started%s+(.-)%s+(%d+)%s*$\")\n        elseif status == \"202\" or params == \"200 OK\" then\n          -- do nothing; this only happens when RE/LOAD command gets the response\n          -- that was for the original command that was aborted\n        elseif status == \"204\" then\n          local _, _, stream, size = string.find(params, \"^204 Output (%w+) (%d+)$\")\n          if stream and size then\n            local size = tonumber(size)\n            local msg = size > 0 and client:receive(size) or \"\"\n            print(msg)\n            if outputs[stream] then outputs[stream](msg) end\n            -- this was just the output, so go back reading the response\n            done = false\n          end\n        elseif status == \"401\" then\n          len = tonumber(len)\n          local res = client:receive(len)\n          print(\"Error in expression: \" .. res)\n          return nil, nil, res\n        else\n          print(\"Unknown error\")\n          return nil, nil, \"Debugger error: unexpected response after EXEC/LOAD '\" .. params .. \"'\"\n        end\n        if done then break end\n      end\n    else\n      print(\"Invalid command\")\n    end\n  elseif command == \"listb\" then\n    for l, v in pairs(breakpoints) do\n      for f in pairs(v) do\n        print(f .. \": \" .. l)\n      end\n    end\n  elseif command == \"listw\" then\n    for i, v in pairs(watches) do\n      print(\"Watch exp. \" .. i .. \": \" .. v)\n    end\n  elseif command == \"suspend\" then\n    client:send(\"SUSPEND\\n\")\n  elseif command == \"stack\" then\n    local opts = string.match(params, \"^[a-z]+%s+(.+)$\")\n    client:send(\"STACK\" .. (opts and \" \"..opts or \"\") ..\"\\n\")\n    local resp = client:receive(\"*l\")\n    local _, _, status, res = string.find(resp, \"^(%d+)%s+%w+%s+(.+)%s*$\")\n    if status == \"200\" then\n      local func, err = loadstring(res)\n      if func == nil then\n        print(\"Error in stack information: \" .. err)\n        return nil, nil, err\n      end\n      local ok, stack = pcall(func)\n      if not ok then\n        print(\"Error in stack information: \" .. stack)\n        return nil, nil, stack\n      end\n      for _,frame in ipairs(stack) do\n        print(mobdebug.line(frame[1], {comment = false}))\n      end\n      return stack\n    elseif status == \"401\" then\n      local _, _, len = string.find(resp, \"%s+(%d+)%s*$\")\n      len = tonumber(len)\n      local res = len > 0 and client:receive(len) or \"Invalid stack information.\"\n      print(\"Error in expression: \" .. res)\n      return nil, nil, res\n    else\n      print(\"Unknown error\")\n      return nil, nil, \"Debugger error: unexpected response after STACK\"\n    end\n  elseif command == \"output\" then\n    local _, _, stream, mode = string.find(params, \"^[a-z]+%s+(%w+)%s+([dcr])%s*$\")\n    if stream and mode then\n      client:send(\"OUTPUT \"..stream..\" \"..mode..\"\\n\")\n      local resp, err = client:receive(\"*l\")\n      if not resp then\n        print(\"Unknown error: \"..err)\n        return nil, nil, \"Debugger connection error: \"..err\n      end\n      local _, _, status = string.find(resp, \"^(%d+)%s+%w+%s*$\")\n      if status == \"200\" then\n        print(\"Stream \"..stream..\" redirected\")\n        outputs[stream] = type(options) == 'table' and options.handler or nil\n      -- the client knows when she is doing, so install the handler\n      elseif type(options) == 'table' and options.handler then\n        outputs[stream] = options.handler\n      else\n        print(\"Unknown error\")\n        return nil, nil, \"Debugger error: can't redirect \"..stream\n      end\n    else\n      print(\"Invalid command\")\n    end\n  elseif command == \"basedir\" then\n    local _, _, dir = string.find(params, \"^[a-z]+%s+(.+)$\")\n    if dir then\n      dir = string.gsub(dir, \"\\\\\", \"/\") -- convert slash\n      if not string.find(dir, \"/$\") then dir = dir .. \"/\" end\n\n      local remdir = dir:match(\"\\t(.+)\")\n      if remdir then dir = dir:gsub(\"/?\\t.+\", \"/\") end\n      basedir = dir\n\n      client:send(\"BASEDIR \"..(remdir or dir)..\"\\n\")\n      local resp, err = client:receive(\"*l\")\n      if not resp then\n        print(\"Unknown error: \"..err)\n        return nil, nil, \"Debugger connection error: \"..err\n      end\n      local _, _, status = string.find(resp, \"^(%d+)%s+%w+%s*$\")\n      if status == \"200\" then\n        print(\"New base directory is \" .. basedir)\n      else\n        print(\"Unknown error\")\n        return nil, nil, \"Debugger error: unexpected response after BASEDIR\"\n      end\n    else\n      print(basedir)\n    end\n  elseif command == \"help\" then\n    print(\"setb <file> <line>    -- sets a breakpoint\")\n    print(\"delb <file> <line>    -- removes a breakpoint\")\n    print(\"delallb               -- removes all breakpoints\")\n    print(\"setw <exp>            -- adds a new watch expression\")\n    print(\"delw <index>          -- removes the watch expression at index\")\n    print(\"delallw               -- removes all watch expressions\")\n    print(\"run                   -- runs until next breakpoint\")\n    print(\"step                  -- runs until next line, stepping into function calls\")\n    print(\"over                  -- runs until next line, stepping over function calls\")\n    print(\"out                   -- runs until line after returning from current function\")\n    print(\"listb                 -- lists breakpoints\")\n    print(\"listw                 -- lists watch expressions\")\n    print(\"eval <exp>            -- evaluates expression on the current context and returns its value\")\n    print(\"exec <stmt>           -- executes statement on the current context\")\n    print(\"load <file>           -- loads a local file for debugging\")\n    print(\"reload                -- restarts the current debugging session\")\n    print(\"stack                 -- reports stack trace\")\n    print(\"output stdout <d|c|r> -- capture and redirect io stream (default|copy|redirect)\")\n    print(\"basedir [<path>]      -- sets the base path of the remote application, or shows the current one\")\n    print(\"done                  -- stops the debugger and continues application execution\")\n    print(\"exit                  -- exits debugger and the application\")\n  else\n    local _, _, spaces = string.find(params, \"^(%s*)$\")\n    if spaces then\n      return nil, nil, \"Empty command\"\n    else\n      print(\"Invalid command\")\n      return nil, nil, \"Invalid command\"\n    end\n  end\n  return file, line\nend\n\n-- Starts debugging server\nlocal function listen(host, port)\n  host = host or \"*\"\n  port = port or mobdebug.port\n\n  local socket = require \"socket\"\n\n  print(\"Lua Remote Debugger\")\n  print(\"Run the program you wish to debug\")\n\n  local server = socket.bind(host, port)\n  local client = server:accept()\n\n  client:send(\"STEP\\n\")\n  client:receive(\"*l\")\n\n  local breakpoint = client:receive(\"*l\")\n  local _, _, file, line = string.find(breakpoint, \"^202 Paused%s+(.-)%s+(%d+)%s*$\")\n  if file and line then\n    print(\"Paused at file \" .. file )\n    print(\"Type 'help' for commands\")\n  else\n    local _, _, size = string.find(breakpoint, \"^401 Error in Execution (%d+)%s*$\")\n    if size then\n      print(\"Error in remote application: \")\n      print(client:receive(size))\n    end\n  end\n\n  while true do\n    io.write(\"> \")\n    local file, _, err = handle(io.read(\"*line\"), client)\n    if not file and err == false then break end -- completed debugging\n  end\n\n  client:close()\nend\n\nlocal cocreate\nlocal function coro()\n  if cocreate then return end -- only set once\n  cocreate = cocreate or coroutine.create\n  coroutine.create = function(f, ...)\n    return cocreate(function(...)\n      mobdebug.on()\n      return f(...)\n    end, ...)\n  end\nend\n\nlocal moconew\nlocal function moai()\n  if moconew then return end -- only set once\n  moconew = moconew or (MOAICoroutine and MOAICoroutine.new)\n  if not moconew then return end\n  MOAICoroutine.new = function(...)\n    local thread = moconew(...)\n    -- need to support both thread.run and getmetatable(thread).run, which\n    -- was used in earlier MOAI versions\n    local mt = thread.run and thread or getmetatable(thread)\n    local patched = mt.run\n    mt.run = function(self, f, ...)\n      return patched(self,  function(...)\n        mobdebug.on()\n        return f(...)\n      end, ...)\n    end\n    return thread\n  end\nend\n\n-- make public functions available\nmobdebug.setbreakpoint = set_breakpoint\nmobdebug.removebreakpoint = remove_breakpoint\nmobdebug.listen = listen\nmobdebug.loop = loop\nmobdebug.scratchpad = scratchpad\nmobdebug.handle = handle\nmobdebug.connect = connect\nmobdebug.start = start\nmobdebug.on = on\nmobdebug.off = off\nmobdebug.moai = moai\nmobdebug.coro = coro\nmobdebug.done = done\nmobdebug.pause = function() step_into = true end\nmobdebug.yield = nil -- callback\nmobdebug.output = output\nmobdebug.onexit = os and os.exit or done\nmobdebug.onscratch = nil -- callback\nmobdebug.basedir = function(b) if b then basedir = b end return basedir end\n\nreturn mobdebug\n"
  },
  {
    "path": "scripts/neutral/unit-bengalaas-jungle-critter.lua",
    "content": "DefineAnimations(\"animations-bengalaas-jungle-critter\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineUnitType(\"unit-critter-bengalaas\", {\n  Animations = \"animations-bengalaas-jungle-critter\", Icon = \"icon-bengalaas-jungle-critter\",\n  NeutralMinimapColor = {0, 228, 252},\n  DrawLevel = 5,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n})\n"
  },
  {
    "path": "scripts/neutral/unit-minerals.lua",
    "content": "--\n-- unit-minerals*\n--\n\nDefineAnimations(\"animations-minerals\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineUnitType(\"unit-resource-mineral-field\", {\n  Animations = \"animations-minerals\", Icon = \"icon-minerals1\",\n  NeutralMinimapColor = {0, 228, 252},\n  Speed = 0,\n  DrawLevel = 5,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  VisibleUnderFog = true,\n  GivesResource = \"minerals\", CanHarvest = true,\n})\n\nDefineUnitType(\"unit-resource-mineral-field-type-2\", {\n  Animations = \"animations-minerals\", Icon = \"icon-minerals1\",\n  NeutralMinimapColor = {0, 228, 252},\n  Speed = 0,\n  HitPoints = 100000,\n  DrawLevel = 5,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  VisibleUnderFog = true,\n  GivesResource = \"minerals\", CanHarvest = true,\n})\n\nDefineUnitType(\"unit-resource-mineral-field-type-3\", {\n  Animations = \"animations-minerals\", Icon = \"icon-minerals1\",\n  NeutralMinimapColor = {0, 228, 252},\n  Speed = 0,\n  HitPoints = 100000,\n  DrawLevel = 5,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  VisibleUnderFog = true,\n  GivesResource = \"minerals\", CanHarvest = true,\n})\n\n"
  },
  {
    "path": "scripts/neutral/unit-ragnasaur-ashworld-critter.lua",
    "content": "DefineAnimations(\"animations-ragnasaur-ashworld-critter\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineUnitType(\"unit-critter-ragnasaur\", {\n  Animations = \"animations-ragnasaur-ashworld-critter\", Icon = \"icon-ragnasaur-ashworld-critter\",\n  NeutralMinimapColor = {0, 228, 252},\n  Speed = 0,\n  DrawLevel = 5,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n})\n"
  },
  {
    "path": "scripts/neutral/unit-rhynadon-badlands-critter.lua",
    "content": "DefineAnimations(\"animations-rhynadon-badlands-critter\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineUnitType(\"unit-critter-rhynadon\", {\n  Animations = \"animations-rhynadon-badlands-critter\", Icon = \"icon-rhynadon-badlands-critter\",\n  NeutralMinimapColor = {0, 228, 252},\n  Speed = 0,\n  DrawLevel = 5,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n})\n"
  },
  {
    "path": "scripts/neutral/unit-vespene-geyser.lua",
    "content": "--\n-- unit-vespene-geyser\n--\n\nDefineAnimations(\"animations-vespene-geyser\", {\n  Still = {--[[FIXME: frame depends on tileset]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\n\nDefineUnitType(\"unit-resource-vespene-geyser\", {\n  Animations = \"animations-vespene-geyser\", Icon = \"icon-vespene-geyser\",\n  NeutralMinimapColor = {0, 228, 252},\n  Speed = 0,\n  DrawLevel = 5,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  VisibleUnderFog = true,\n  GivesResource = \"gas\",\n})\n\n"
  },
  {
    "path": "scripts/neutral/units.lua",
    "content": "Load(\"scripts/neutral/unit-vespene-geyser.lua\")\nLoad(\"scripts/neutral/unit-minerals.lua\")\nLoad(\"scripts/neutral/unit-bengalaas-jungle-critter.lua\")\nLoad(\"scripts/neutral/unit-ragnasaur-ashworld-critter.lua\")\nLoad(\"scripts/neutral/unit-rhynadon-badlands-critter.lua\")\n\n--\n-- Allow\n--\nDefineAllow(\"unit-resource-vespene-geyser\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-resource-mineral-field\",      \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-resource-mineral-field-type-2\",      \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-resource-mineral-field-type-3\",      \"AAAAAAAAAAAAAAAA\")\n\n"
  },
  {
    "path": "scripts/protoss/campaign1.lua",
    "content": "campaign_steps = {}\ncampaign_menu = {}\n\ncampaign_steps[#campaign_steps + 1] = function() RunImageStep(\"campaigns/protoss/EstP0t.txt\", i) end\ncampaign_menu[#campaign_menu + 1] = #campaign_steps\ncampaign_steps[#campaign_steps + 1] = CreateMapStep(\"campaigns/protoss/tutorial/scenario.smp\")\n\nfor i=1,10 do\n  campaign_steps[#campaign_steps + 1] = function() RunImageStep(string.format(\"campaigns/protoss/EstP%02d.txt\", i)) end\n  campaign_menu[#campaign_menu + 1] = #campaign_steps\n  campaign_steps[#campaign_steps + 1] = CreateMapStep(string.format(\"campaigns/protoss/%02d/scenario.smp\", i))\nend\n"
  },
  {
    "path": "scripts/protoss/icons.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      icons.lua - Define the icons.\n--\n--      (c) Copyright 2005 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nlocal protoss_icons = {\n  {\"icon-protoss-corsair\", 60},\n  {\"icon-protoss-dark-templar\", 61},\n  {\"icon-protoss-dark-archon\", 63},\n  {\"icon-protoss-probe\", 64},\n  {\"icon-protoss-zealot\", 65},\n  {\"icon-protoss-dragoon\", 66},\n  {\"icon-protoss-high-templar\", 67},\n  {\"icon-protoss-archon\", 68},\n  {\"icon-protoss-shuttle\", 69},\n  {\"icon-protoss-scout\", 70},\n  {\"icon-protoss-arbiter\", 71},\n  {\"icon-protoss-carrier\", 72},\n  {\"icon-protoss-interceptor\", 73},\n  {\"icon-protoss-dark-templar-hero\", 74},\n  {\"icon-protoss-zeratul-dark-templar\", 75},\n  {\"icon-protoss-tassadar-zeratul-archon\", 76},\n  {\"icon-protoss-fenix-zealot\", 77},\n  {\"icon-protoss-fenix-dragoon\", 78},\n  {\"icon-protoss-tassadar-templar\", 79},\n  {\"icon-protoss-reaver\", 83},\n  {\"icon-protoss-observer\", 84},\n  {\"icon-protoss-scarab\", 85},\n  {\"icon-protoss-nexus\", 154},\n  {\"icon-protoss-robotics-facility\", 155},\n  {\"icon-protoss-pylon\", 156},\n  {\"icon-protoss-assimilator\", 157},\n  {\"icon-protoss-observatory\", 159},\n  {\"icon-protoss-gateway\", 160},\n  {\"icon-protoss-photon-cannon\", 162},\n  {\"icon-protoss-citadel-of-adun\", 163},\n  {\"icon-protoss-cybernetics-core\", 164},\n  {\"icon-protoss-templar-archives\", 165},\n  {\"icon-protoss-forge\", 166},\n  {\"icon-protoss-stargate\", 167},\n  {\"icon-protoss-fleet-beacon\", 169},\n  {\"icon-protoss-arbiter-tribunal\", 170},\n  {\"icon-protoss-robotics-support-bay\", 171},\n  {\"icon-protoss-shield-battery\", 172},\n  {\"icon-protoss-temple\", 174},\n}\n\nlocal pos = table.getn(icons) + 1\n\nfor i = 1,table.getn(protoss_icons) do\n  icons[pos] = protoss_icons[i]\n  pos = pos + 1\nend\n\n\n"
  },
  {
    "path": "scripts/protoss/missiles.lua",
    "content": "--\n--  Missiles\n--\n--[[\nDefineMissileType(\"missile-terran-explosion-small\", {\n  File = \"terran/explosion small.png\", Size = {128, 128},\n  Frames = 9, NumDirections = 1, DrawLevel = 50,\n  Class = \"missile-class-stay\", Sleep = 2,\n})\n\nDefineMissileType(\"missile-terran-explosion-medium\", {\n  File = \"terran/explosion medium.png\", Size = {200, 200},\n  Frames = 10, NumDirections = 1, DrawLevel = 50,\n  Class = \"missile-class-stay\", Sleep = 2,\n})\n\nDefineMissileType(\"missile-terran-explosion-large\", {\n  File = \"terran/explosion large.png\", Size = {252, 200},\n  Frames = 14, NumDirections = 1, DrawLevel = 50,\n  Class = \"missile-class-stay\", Sleep = 2,\n})\n\nDefineMissileType(\"missile-terran-firebat-flame\", {\n  File = \"neutral/flamer.png\", Size = {224, 224},\n  Frames = 221, NumDirections = 32, DrawLevel = 50,\n  Class = \"missile-class-point-to-point\", Sleep = 1, Speed = 4, Range = 0,\n})\n--]]\n"
  },
  {
    "path": "scripts/protoss/nuetral.lua",
    "content": ""
  },
  {
    "path": "scripts/protoss/sound.lua",
    "content": "-- protoss unit advisor sounds (names in sync with startool)\nMakeSound(\"protoss-base-attacked\", \"protoss/units/advisor/upd00.ogg\")\nMakeSound(\"protoss-units-attacked\", \"protoss/units/advisor/upd01.ogg\")\nMakeSound(\"protoss-research-complete\", \"protoss/units/advisor/upd02.ogg\")\nMakeSound(\"protoss-nuclear-launch\", \"protoss/units/advisor/upd04.ogg\")\nMakeSound(\"protoss-upgrade-complete\", \"protoss/units/advisor/upd06.ogg\")\n\n\nMakeSound(\"protoss-nexuz-selected\", \"protoss/units/nexus.ogg\")\nMakeSound(\"protoss-pylon-selected\", \"protoss/units/pylon.ogg\")\nMakeSound(\"protoss-assimilator-selected\", \"protoss/units/assimilator.ogg\")\nMakeSound(\"protoss-citadel-selected\", \"protoss/units/citadel.ogg\")\nMakeSound(\"protoss-cybernetics-core-selected\", \"protoss/units/cybernetics core.ogg\")\nMakeSound(\"protoss-fleet-beacon-selected\", \"protoss/units/fleet beacon.ogg\")\nMakeSound(\"protoss-forge-selected\", \"protoss/units/forge.ogg\")\nMakeSound(\"protoss-gateway-selected\", \"protoss/units/gateway.ogg\")\n--MakeSound(\"protoss-observatory-selected\", \"protoss/units/observatory.ogg\")\n--MakeSound(\"protoss-assimilator-selected\", \"protoss/units/assimilator.ogg\")\n--MakeSound(\"protoss-assimilator-selected\", \"protoss/units/assimilator.ogg\")\nMakeSound(\"protoss-probe-mine\", \"protoss/units/probe/min00.ogg\")\nMakeSound(\"protoss-probe-ready\", \"protoss/units/probe/ready.ogg\")\nMakeSound(\"protoss-zealot-hit\", \"protoss/units/zealot/hit00.ogg\")\nMakeSound(\"protoss-zealot-attack\", \"protoss/units/zealot/att00.ogg\")\nMakeSound(\"protoss-zealot-death\", \"protoss/units/zealot/death/1.ogg\")\nMakeSound(\"protoss-zealot-ready\", \"protoss/units/zealot/ready.ogg\")\nMakeSound(\"protoss-dragoon-ready\", \"protoss/units/dragoon/ready.ogg\")\nMakeSound(\"protoss-high-templar-ready\", \"protoss/units/templar/ready.ogg\")\nMakeSound(\"protoss-high-templar-death\", \"protoss/units/templar/death/1.ogg\")\nMakeSound(\"protoss-high-templar-attacked\", \"protoss/units/advisor/upd01.ogg\")\n--FIXME SHOULD BE A DARK TEMPLAR READ SOUND HERE!!!\nMakeSound(\"protoss-dark-templar\", \"protoss/units/dark templar/death/1.ogg\")\nMakeSound(\"protoss-observer-ready\", \"protoss/units/observer/ready.ogg\")\nMakeSound(\"protoss-reaver-ready\", \"protoss/units/reaver/ready.ogg\")\nMakeSound(\"protoss-reaver-death\", \"protoss/units/reaver/death/1.ogg\")\nMakeSound(\"protoss-shuttle-ready\", \"protoss/units/shuttle/ready.ogg\")\nMakeSound(\"protoss-shuttle-death\", \"protoss/units/shuttle/death/1.ogg\")\nMakeSound(\"protoss-scout-ready\", \"protoss/units/scout/ready.ogg\")\nMakeSound(\"protoss-scout-death\", \"protoss/units/scout/death/1.ogg\")\n\nMakeSound(\"protoss-probe-acknowledge\",\n  {\"protoss/units/probe/acknowledgement/1.ogg\",\n  \"protoss/units/probe/acknowledgement/2.ogg\",\n  \"protoss/units/probe/acknowledgement/3.ogg\",\n  \"protoss/units/probe/acknowledgement/4.ogg\"})\n\nMakeSound(\"protoss-probe-pissed\",\n  {\"protoss/units/probe/pissed/1.ogg\",\n  \"protoss/units/probe/pissed/2.ogg\",\n  \"protoss/units/probe/pissed/3.ogg\",\n  \"protoss/units/probe/pissed/4.ogg\"})\n\nMakeSound(\"protoss-probe-selected\",\n  {\"protoss/units/probe/selected/1.ogg\",\n  \"protoss/units/probe/selected/2.ogg\",\n  \"protoss/units/probe/selected/3.ogg\",\n  \"protoss/units/probe/selected/4.ogg\"})\n  \nMakeSound(\"protoss-zealot-acknowledge\",\n  {\"protoss/units/zealot/acknowledgement/1.ogg\",\n  \"protoss/units/zealot/acknowledgement/2.ogg\",\n  \"protoss/units/zealot/acknowledgement/3.ogg\",\n  \"protoss/units/zealot/acknowledgement/4.ogg\"})\n\nMakeSound(\"protoss-zealot-pissed\",\n  {\"protoss/units/zealot/pissed/1.ogg\",\n  \"protoss/units/zealot/pissed/2.ogg\",\n  \"protoss/units/zealot/pissed/3.ogg\"})\n\nMakeSound(\"protoss-zealot-selected\",\n  {\"protoss/units/zealot/selected/1.ogg\",\n  \"protoss/units/zealot/selected/2.ogg\",\n  \"protoss/units/zealot/selected/3.ogg\",\n  \"protoss/units/zealot/selected/4.ogg\"})\n  \n  MakeSound(\"protoss-probe-selected\",\n  {\"protoss/units/probe/selected/1.ogg\",\n  \"protoss/units/probe/selected/2.ogg\",\n  \"protoss/units/probe/selected/3.ogg\",\n  \"protoss/units/probe/selected/4.ogg\"})\n  \nMakeSound(\"protoss-dragoon-acknowledge\",\n  {\"protoss/units/dragoon/acknowledgement/1.ogg\",\n  \"protoss/units/dragoon/acknowledgement/2.ogg\",\n  \"protoss/units/dragoon/acknowledgement/3.ogg\",\n  \"protoss/units/dragoon/acknowledgement/4.ogg\",\n  \"protoss/units/dragoon/acknowledgement/5.ogg\",\n  \"protoss/units/dragoon/acknowledgement/6.ogg\",\n  \"protoss/units/dragoon/acknowledgement/7.ogg\"})\n\nMakeSound(\"protoss-dragoon-pissed\",\n  {\"protoss/units/dragoon/pissed/1.ogg\",\n  \"protoss/units/dragoon/pissed/2.ogg\",\n  \"protoss/units/dragoon/pissed/3.ogg\",\n  \"protoss/units/dragoon/pissed/4.ogg\"})\n\nMakeSound(\"protoss-dragoon-selected\",\n  {\"protoss/units/dragoon/selected/1.ogg\",\n  \"protoss/units/dragoon/selected/2.ogg\",\n  \"protoss/units/dragoon/selected/3.ogg\",\n  \"protoss/units/dragoon/selected/4.ogg\",\n  \"protoss/units/dragoon/selected/5.ogg\",\n  \"protoss/units/dragoon/selected/6.ogg\",\n  \"protoss/units/dragoon/selected/7.ogg\",\n  \"protoss/units/dragoon/selected/8.ogg\"})\n  \nMakeSound(\"protoss-high-templar-selected\",\n  {\"protoss/units/templar/selected/1.ogg\",\n  \"protoss/units/templar/selected/2.ogg\",\n  \"protoss/units/templar/selected/3.ogg\",\n  \"protoss/units/templar/selected/4.ogg\"})\n \n MakeSound(\"protoss-high-templar-acknowledge\",\n  {\"protoss/units/templar/acknowledgement/1.ogg\",\n  \"protoss/units/templar/acknowledgement/2.ogg\",\n  \"protoss/units/templar/acknowledgement/3.ogg\",\n  \"protoss/units/templar/acknowledgement/4.ogg\"})\n  \nMakeSound(\"protoss-high-templar-pissed\",\n  {\"protoss/units/templar/pissed/1.ogg\",\n  \"protoss/units/templar/pissed/2.ogg\",\n  \"protoss/units/templar/pissed/3.ogg\",\n  \"protoss/units/templar/pissed/4.ogg\"})\n  \n  MakeSound(\"protoss-dark-templar-selected\",\n  {\"protoss/units/dark templar/selected/1.ogg\",\n  \"protoss/units/dark templar/selected/2.ogg\",\n  \"protoss/units/dark templar/selected/3.ogg\",\n  \"protoss/units/dark templar/selected/4.ogg\"})\n \n MakeSound(\"protoss-dark-templar-acknowledge\",\n  {\"protoss/units/dark templar/acknowledgement/1.ogg\",\n  \"protoss/units/dark templar/acknowledgement/2.ogg\",\n  \"protoss/units/dark templar/acknowledgement/3.ogg\",\n  \"protoss/units/dark templar/acknowledgement/4.ogg\"})\n  \nMakeSound(\"protoss-dark-templar-pissed\",\n  {\"protoss/units/dark templar/pissed/1.ogg\",\n  \"protoss/units/dark templar/pissed/2.ogg\",\n  \"protoss/units/dark templar/pissed/3.ogg\",\n  \"protoss/units/dark templar/pissed/4.ogg\"})\n\nMakeSound(\"protoss-observer-selected\",\n  {\"protoss/units/observer/selected/1.ogg\",\n  \"protoss/units/observer/selected/2.ogg\"})\n \nMakeSound(\"protoss-observer-acknowledge\",\n  {\"protoss/units/observer/acknowledgement/1.ogg\",\n  \"protoss/units/observer/acknowledgement/2.ogg\"})\n  \nMakeSound(\"protoss-observer-pissed\",\n  {\"protoss/units/observer/pissed/1.ogg\",\n  \"protoss/units/observer/pissed/2.ogg\",\n  \"protoss/units/observer/pissed/3.ogg\",\n  \"protoss/units/observer/pissed/4.ogg\",\n  \"protoss/units/observer/pissed/5.ogg\"})\n\nMakeSound(\"protoss-observer-death\",\n\t{\"protoss/units/observer/death/1.ogg\",\n\t\"protoss/units/observer/death/2.ogg\"})\n\t\nMakeSound(\"protoss-reaver-selected\",\n  {\"protoss/units/reaver/selected/1.ogg\",\n   \"protoss/units/reaver/selected/2.ogg\",\n   \"protoss/units/reaver/selected/3.ogg\",\n   \"protoss/units/reaver/selected/4.ogg\"})\n \nMakeSound(\"protoss-reaver-acknowledge\",\n  {\"protoss/units/reaver/acknowledgement/1.ogg\",\n  \"protoss/units/reaver/acknowledgement/2.ogg\",\n  \"protoss/units/reaver/acknowledgement/3.ogg\",\n  \"protoss/units/reaver/acknowledgement/4.ogg\"})\n  \nMakeSound(\"protoss-reaver-pissed\",\n  {\"protoss/units/reaver/pissed/1.ogg\",\n  \"protoss/units/reaver/pissed/2.ogg\",\n  \"protoss/units/reaver/pissed/3.ogg\"})\n  \nMakeSound(\"protoss-shuttle-selected\",\n  {\"protoss/units/shuttle/selected/1.ogg\",\n   \"protoss/units/shuttle/selected/2.ogg\",\n   \"protoss/units/shuttle/selected/3.ogg\",\n   \"protoss/units/shuttle/selected/4.ogg\"})\n \nMakeSound(\"protoss-shuttle-acknowledge\",\n  {\"protoss/units/shuttle/acknowledgement/1.ogg\",\n  \"protoss/units/shuttle/acknowledgement/2.ogg\",\n  \"protoss/units/shuttle/acknowledgement/3.ogg\",\n  \"protoss/units/shuttle/acknowledgement/4.ogg\"})\n  \nMakeSound(\"protoss-shuttle-pissed\",\n  {\"protoss/units/shuttle/pissed/1.ogg\",\n  \"protoss/units/shuttle/pissed/2.ogg\",\n  \"protoss/units/shuttle/pissed/3.ogg\",\n  \"protoss/units/shuttle/pissed/4.ogg\",\n  \"protoss/units/shuttle/pissed/5.ogg\"})\n  \nMakeSound(\"protoss-scout-selected\",\n  {\"protoss/units/scout/selected/1.ogg\",\n   \"protoss/units/scout/selected/2.ogg\",\n   \"protoss/units/scout/selected/3.ogg\",\n   \"protoss/units/scout/selected/4.ogg\"})\n \nMakeSound(\"protoss-scout-acknowledge\",\n  {\"protoss/units/scout/acknowledgement/1.ogg\",\n  \"protoss/units/scout/acknowledgement/2.ogg\",\n  \"protoss/units/scout/acknowledgement/3.ogg\",\n  \"protoss/units/scout/acknowledgement/4.ogg\"})\n  \nMakeSound(\"protoss-scout-pissed\",\n  {\"protoss/units/scout/pissed/1.ogg\",\n  \"protoss/units/scout/pissed/2.ogg\",\n  \"protoss/units/scout/pissed/3.ogg\",\n  \"protoss/units/scout/pissed/4.ogg\",\n  \"protoss/units/scout/pissed/5.ogg\"})\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-arbiter-tribunal.lua",
    "content": "--\n-- -- unit-protoss-arbiter-tribunal\n--\nDefineAnimations(\"animations-protoss-arbiter-tribunal\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-arbiter-tribunal\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-arbiter-tribunal\", {\n  Animations = \"animations-protoss-arbiter-tribunal\", Icon = \"icon-protoss-arbiter-tribunal\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-arbiter-tribunal\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-assimulator.lua",
    "content": "--\n--\n\nDefineAnimations(\"animations-protoss-assimulator\", {\n  Still = {\n    \"frame 0\", \"wait 5\", \"frame 1\", \"wait 5\", \"frame 2\", \"wait 5\", \"frame 3\", \"wait 5\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-assimulator\", {\n  Files = image_102_zerg_zbuild_var,\n  ShadowFiles = image_102_zerg_zbuild_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = .5,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 2,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 1.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 2,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 2.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 3,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 3.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 4,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 4.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 5.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 6,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 6.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 7,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 7.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 8,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 8.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 9,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 9.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 10,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 10.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 11,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 11.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 12,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 13.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 14,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 14.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 15,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 15.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 16,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 16.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 17.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 18.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 19.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 20.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 21,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 21.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 22,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 22.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 23,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 23.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 24,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 24.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 25,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 25.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 26,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 26.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 27,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 27.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 28,\n    File = \"construction\",\n    Frame = 8},\n\n\n   {Percent = 28.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 29,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 29.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 30,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 30.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 31,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 31.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 32,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 32.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 33,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 33.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 34,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 34.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 35,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 35.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 36,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 36.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 37,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 37.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 38,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 38.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 39,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 39.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 40.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 41,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 41.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 42,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 42.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 43,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 43.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 44,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 44.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 45,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 45.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 46,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 46.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 47,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 47.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 48,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 48.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 49,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 49.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 50,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 50.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 51,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 51.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 52,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 52.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 53,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 53.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 54,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 54.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 55,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 55.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 56,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 56.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 57,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 58.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 59,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 59.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 60,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 60.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 61,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 61.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 62,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 62.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 63,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 63.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 64,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 64.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 65,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 65.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 66,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 66.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 67,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 67.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 68,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 68.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 69,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 69.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 67,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 67.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 68,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 68.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 69,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 69.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 70,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 70.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 71,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 71.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 72,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 72.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 73,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 73.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 74,\n    File = \"construction\",\n    Frame = 8},\n\n\n   {Percent = 74.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 75,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 75.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 76,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 76.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 77,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 77.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 78,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 78.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 79,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 79.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 80,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 80.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 81,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 81.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 82,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 82.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 83,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 83.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 84,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 84.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 85,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 85.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 86,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 86.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 87,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 87.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 88,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 88.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 89,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 89.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 90,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 90.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 91,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 91.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 92,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 92.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 93,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 93.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 94,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 94.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 95,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 95.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 96,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 96.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 97,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 97.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 98,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 98.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 99,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 99.5,\n    File = \"construction\",\n    Frame = 8},\n}\n})\n\nDefineUnitType(\"unit-protoss-assimulator\", {\n  Animations = \"animations-protoss-assimulator\", Icon = \"icon-zerg-extractor\",\n  Construction = \"construction-protoss-assimulator\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 20,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-explosion\",\n  VisibleUnderFog = true, \n  BuildingRules = { { \"ontop\", { Type = \"unit-resource-vespene-geyser\", ReplaceOnDie = true, ReplaceOnBuild = true} } },\n  GivesResource = \"gas\", CanHarvest = true,\n  Sounds = {\n    \"selected\", \"zerg-extractor-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-citadel-of-adun.lua",
    "content": "--\n-- -- unit-protoss-citadel-of-adun\n--\nDefineAnimations(\"animations-protoss-citadel-of-adun\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-citadel-of-adun\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-citadel-of-adun\", {\n  Animations = \"animations-protoss-citadel-of-adun\", Icon = \"icon-protoss-citadel-of-adun\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-citadel-of-adun\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-cybernetics-core.lua",
    "content": "--\r\n-- -- unit-protoss-cybernetics-core\r\n--\r\n\r\nDefineAnimations(\"animations-protoss-cybernetics-core\", {\r\n  Still = {\r\n    \"frame 0\", \"wait 125\",\r\n  },\r\n  Train = {\r\n    \"frame 0\", \"wait 125\",\r\n  },\r\n})\r\n\r\nDefineConstruction(\"construction-protoss-cybernetics-core\", {\r\n  Files = image_325_terran_tbldlrg_var,\r\n  ShadowFiles = image_325_terran_tbldlrg_var,\r\n  Constructions = {\r\n   {Percent = 0,\r\n    File = \"construction\",\r\n    Frame = 0},\r\n   {Percent = 20,\r\n    File = \"construction\",\r\n    Frame = 1},\r\n   {Percent = 40,\r\n    File = \"construction\",\r\n    Frame = 2},\r\n   {Percent = 60,\r\n    File = \"main\",\r\n    Frame = 1}}\r\n})\r\n\r\nDefineUnitType(\"unit-protoss-cybernetics-core\", {\r\n  Animations = \"animations-protoss-cybernetics-core\", Icon = \"icon-protoss-cybernetics-core\",\r\n  RepairHp = 4,\r\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\r\n  Construction = \"construction-protoss-cybernetics-core\",\r\n  Speed = 0,\r\n  DrawLevel = 50,\r\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\r\n  Priority = 30, AnnoyComputerFactor = 35,\r\n  Points = 160,\r\n  BuilderOutside = true,\r\n  AutoBuildRate = 2,\r\n  VisibleUnderFog = true, \r\n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\r\n  Sounds = {\r\n    \"selected\", \"protoss-cybernetics-core-selected\",\r\n    \"ready\", \"protoss-building-done\",\r\n    \"help\", \"protoss-base-attacked\",\r\n    \"dead\", \"protoss-explosion-large\"} } )\r\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-dark-templar.lua",
    "content": "--\n-- unit-protoss-dark-templar\n--\n\nDefineAnimations(\"animations-protoss-dark-templar\", {\n  Still = {\n\t\"frame 85\", \"wait 125\",\n  },\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"frame 85\", \"move 4\", \"wait 1\", \"frame 102\",\n    \"move 4\", \"wait 1\", \"frame 119\", \"move 4\", \"wait 1\", \"frame 136\",\n    \"move 4\", \"wait 1\", \"frame 153\", \"move 4\", \"wait 1\", \"frame 170\",\n    \"move 4\", \"wait 1\", \"frame 187\",\n    --FIXME: subtile movement not supported\n    --[[\"move 4\", \"wait 1\", \"frame 204\",]]\n    \"move 4\", \"unbreakable end\", \"wait 1\", \"frame 119\",\n  },\n--  StartAttack = {\"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",},\n  Attack = {\n    \"wait 1\", \"unbreakable begin\", \"attack\", \"sound protoss-zealot-attack\",\n    \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 51\", \"wait 1\",\n    \"frame 68\", \"sound protoss-zealot-hit\", \"wait 1\", \"frame 51\", \"wait 1\", \"frame 34\", \"sound protoss-zealot-hit\",\n    \"unbreakable end\", \"wait 10\", \"frame 17\",\n  },\n--  EndAttack = {\"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", --[[goto 70FD]]},\n  Death = {\n    \"unbreakable begin\",\n    \"sound protoss-zealot-death\", \"exact-frame 221\", \"wait 2\",\n    \"exact-frame 222\", \"wait 2\", \"exact-frame 223\", \"wait 2\",\n    \"exact-frame 239\", \"wait 2\", \"exact-frame 225\", \"wait 2\",\n    \"exact-frame 226\", \"wait 2\", \"exact-frame 227\", \"wait 2\",\n    \"exact-frame 228\", \"wait 2\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-protoss-dark-templar\", {\n  Animations = \"animations-protoss-dark-templar\", Icon = \"icon-protoss-dark-templar\",\n  Speed = 10,\n  DrawLevel = 40,\n  Armor = 4, BasicDamage = 10, PiercingDamage = 3, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"protoss-dark-templar-selected\",\n    \"acknowledge\", \"protoss-dark-templar-acknowledge\",\n    --FIXME NO READY SOUND!!\n    \"ready\", \"protoss-high-templar-ready\",\n    \"help\", \"protoss-dark-templar-attacked\",} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-dragoon.lua",
    "content": "--\n-- unit-protoss-dragoon\n--\n\nDefineAnimations(\"animations-protoss-dragoon-death\", {\n  Death = {\"unbreakable begin\", \"frame 0\", \"wait 50\", \"frame 1\", \"wait 50\",\n    \"frame 2\", \"wait 50\", \"frame 3\", \"wait 50\", \"frame 4\", \"wait 50\", \"unbreakable end\", \"wait 1\", },\n})\n\nDefineUnitType(\"unit-protoss-dragoon-death\", { Name = \"Dead dragoon\",\n  Image = image_124_protoss_pdrdeath,\n  Animations = \"animations-terran-marine-death\", Icon = \"icon-terran-marine\",\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  Vanishes = true,\n  Sounds = {} } )\n\nDefineAnimations(\"animations-protoss-dragoon\", {\n   Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Move = {\n  \"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"frame 136\",\n    \"move 4\", \"wait 1\", \"frame 153\",\n    \"move 4\", \"wait 1\", \"frame 170\",\n    \"move 4\", \"wait 1\", \"frame 187\",\n    \"move 4\", \"wait 1\", \"frame 204\",\n    \"move 4\", \"wait 1\", \"frame 221\",\n    \"move 4\", \"wait 1\", \"frame 238\", \n\t\"move 4\", \"wait 1\", \"frame 255\", \n    \"unbreakable end\", \"wait 1\",\n  },\n  Attack = {\n    \"unbreakable begin\", \"frame 272\", \"wait 2\", \"frame 289\", \"wait 2\", \"frame 306\", \"wait 2\", \"frame 323\",\n    \"wait 2\", \"frame 340\", \"wait 2\", \"frame 357\", \"attack\",\n    \"unbreakable end\", \"wait 2\",\n  },\n  Death = {\n    \"unbreakable begin\",\n    \"frame 408\", \"wait 1\", \"frame 409\", \"wait 1\", \"frame 410\", \"wait 1\", \"frame 411\", \"wait 1\", \"frame 412\",\n    \"wait 1\", \"frame 413\", \"wait 1\", \"frame 414\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-protoss-dragoon\", {\n  Animations = \"animations-protoss-dragoon\", Icon = \"icon-protoss-dragoon\",\n  Speed = 10,\n  ShieldPoints = 200,\n  DrawLevel = 40,\n  Armor = 2, BasicDamage = 10, PiercingDamage = 3, Missile = \"missile-none\",\n  MaxAttackRange = 2,\n  Priority = 60,\n  Points = 50,\n  Demand = 2,\n  RightMouseAction = \"attack\",\n  Corpse = \"unit-protoss-dragoon-death\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetAir = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"protoss-dragoon-selected\",\n    \"acknowledge\", \"protoss-dragoon-acknowledge\",\n    \"ready\", \"protoss-dragoon-ready\",\n    \"help\", \"protoss-units-attacked\",} } )\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-fleet-beacon.lua",
    "content": "\n--\n-- -- unit-protoss-fleet-beacon\n--\nDefineAnimations(\"animations-protoss-fleet-beacon\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-fleet-beacon\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-fleet-beacon\", {\n  Animations = \"animations-protoss-stargate\", Icon = \"icon-protoss-fleet-beacon\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-fleet-beacon\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-forge.lua",
    "content": "--\n-- -- unit-protoss-forge\n--\n\nDefineAnimations(\"animations-protoss-forge\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-forge\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-forge\", {\n  Animations = \"animations-protoss-forge\", Icon = \"icon-protoss-forge\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-forge\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-forge-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-gateway.lua",
    "content": "--\n-- unit-protoss-gateway\n--\n\nDefineAnimations(\"animations-protoss-gateway\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-gateway\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-gateway\", {\n  Animations = \"animations-protoss-gateway\", Icon = \"icon-protoss-gateway\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-gateway\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  --ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  BuilderOutside = true,  \n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-gateway-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n\n\nDefineUnitType(\"unit-protoss-zealot\", {})\nDefineUnitType(\"unit-protoss-dragoon\", {})\nDefineUnitType(\"unit-protoss-high-templar\", {})\nDefineUnitType(\"unit-protoss-dark-templar\", {})\n\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-protoss-zealot\",\n  Action = \"train-unit\", Value = \"unit-protoss-zealot\",\n  Key = \"z\", Hint = \"Warp in Zealot\",\n  ForUnit = {\"unit-protoss-gateway\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-protoss-dragoon\",\n  Action = \"train-unit\", Value = \"unit-protoss-dragoon\",\n  Key = \"d\", Hint = \"Warp in Dragoon\",\n  ForUnit = {\"unit-protoss-gateway\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-protoss-high-templar\",\n  Action = \"train-unit\", Value = \"unit-protoss-high-templar\",\n  Key = \"d\", Hint = \"Warp in High Templar\",\n  ForUnit = {\"unit-protoss-gateway\"} } )\n  \n  DefineButton( { Pos = 4, Level = 0, Icon = \"icon-protoss-dark-templar\",\n  Action = \"train-unit\", Value = \"unit-protoss-dark-templar\",\n  Key = \"d\", Hint = \"Warp in Dark Templar\",\n  ForUnit = {\"unit-protoss-gateway\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-high-templar.lua",
    "content": "--\n-- unit-protoss-high-templar\n--\n\nDefineAnimations(\"animations-protoss-high-templar\", {\n  Still = {\n\t\"frame 85\", \"wait 125\",\n  },\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"frame 85\", \"move 4\", \"wait 1\", \"frame 102\",\n    \"move 4\", \"wait 1\", \"frame 119\", \"move 4\", \"wait 1\", \"frame 136\",\n    \"move 4\", \"wait 1\", \"frame 153\", \"move 4\", \"wait 1\", \"frame 170\",\n    \"move 4\", \"wait 1\", \"frame 187\",\n    --FIXME: subtile movement not supported\n    --[[\"move 4\", \"wait 1\", \"frame 204\",]]\n    \"move 4\", \"unbreakable end\", \"wait 1\", \"frame 119\",\n  },\n--  StartAttack = {\"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",},\n  Attack = {\n    \"wait 1\", \"unbreakable begin\", \"attack\", \"sound protoss-zealot-attack\",\n    \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 51\", \"wait 1\",\n    \"frame 68\", \"sound protoss-zealot-hit\", \"wait 1\", \"frame 51\", \"wait 1\", \"frame 34\", \"sound protoss-zealot-hit\",\n    \"unbreakable end\", \"wait 10\", \"frame 17\",\n  },\n--  EndAttack = {\"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", --[[goto 70FD]]},\n  Death = {\n    \"unbreakable begin\",\n    \"sound protoss-zealot-death\", \"exact-frame 221\", \"wait 2\",\n    \"exact-frame 222\", \"wait 2\", \"exact-frame 223\", \"wait 2\",\n    \"exact-frame 239\", \"wait 2\", \"exact-frame 225\", \"wait 2\",\n    \"exact-frame 226\", \"wait 2\", \"exact-frame 227\", \"wait 2\",\n    \"exact-frame 228\", \"wait 2\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-protoss-high-templar\", {\n  Animations = \"animations-protoss-high-templar\", Icon = \"icon-protoss-high-templar\",\n  Speed = 10,\n  DrawLevel = 40,\n  Armor = 4, BasicDamage = 10, PiercingDamage = 3, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"protoss-high-templar-selected\",\n    \"acknowledge\", \"protoss-high-templar-acknowledge\",\n    \"ready\", \"protoss-high-templar-ready\",\n    \"help\", \"protoss-high-templar-attacked\",} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-nexus.lua",
    "content": "DefineAnimations(\"animations-protoss-nexus\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-nexus\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\n--[[\nDefineConstruction(\"construction-zerg-hatchery\", {\n  Files = {\n    File = \"protoss/units/pb1glow.png\",\n    Size = {152, 2128}},\n  ShadowFiles = {\n    File = \"protoss/units/pneglow.png\",\n    Size = {192, 1120}},\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = .5,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 2,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 1.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 2,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 2.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 3,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 3.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 4,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 4.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 5.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 6,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 6.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 7,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 7.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 8,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 8.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 9,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 9.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 10,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 10.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 11,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 11.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 12,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 13.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 14,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 14.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 15,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 15.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 16,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 16.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 17.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 18.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 19.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 20.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 21,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 21.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 22,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 22.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 23,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 23.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 24,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 24.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 25,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 25.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 26,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 26.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 27,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 27.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 28,\n    File = \"construction\",\n    Frame = 8},\n\n\n   {Percent = 28.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 29,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 29.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 30,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 30.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 31,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 31.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 32,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 32.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 33,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 33.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 34,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 34.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 35,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 35.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 36,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 36.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 37,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 37.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 38,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 38.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 39,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 39.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 40.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 41,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 41.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 42,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 42.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 43,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 43.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 44,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 44.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 45,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 45.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 46,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 46.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 47,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 47.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 48,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 48.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 49,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 49.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 50,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 50.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 51,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 51.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 52,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 52.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 53,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 53.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 54,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 54.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 55,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 55.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 56,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 56.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 57,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 58.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 59,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 59.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 60,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 60.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 61,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 61.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 62,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 62.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 63,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 63.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 64,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 64.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 65,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 65.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 66,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 66.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 67,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 67.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 68,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 68.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 69,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 69.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 67,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 67.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 68,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 68.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 69,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 69.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 70,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 70.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 71,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 71.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 72,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 72.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 73,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 73.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 74,\n    File = \"construction\",\n    Frame = 8},\n\n\n   {Percent = 74.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 75,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 75.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 76,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 76.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 77,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 77.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 78,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 78.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 79,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 79.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 80,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 80.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 81,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 81.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 82,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 82.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 83,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 83.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 84,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 84.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 85,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 85.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 86,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 86.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 87,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 87.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 88,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 88.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 89,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 89.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 90,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 90.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 91,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 91.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 92,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 92.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 93,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 93.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 94,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 94.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 95,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 95.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 96,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 96.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 97,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 97.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 98,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 98.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 99,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 99.5,\n    File = \"construction\",\n    Frame = 8},\n}\n}) --]]\n\nDefineUnitType(\"unit-protoss-nexus\", {\n  Animations = \"animations-protoss-nexus\", Icon = \"icon-protoss-nexus\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 0},\n  Construction = \"construction-protoss-nexus\",\n  Speed = 0,\n  DrawLevel = 50,\n  BuilderOutside = true, \n  AutoBuildRate = 30,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 35, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 10,  \n  --Corpse = \"unit-destroyed-4x4-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \">\", Type = \"unit-resource-mineral-field\"} } },\n  CanStore = {\"gas\", \"minerals\"},\n  Sounds = {\n    \"selected\", \"protoss-nexus-selected\",\n--    \"ready\", \"town-hall-ready\",\n    \"help\", \"protoss-nexus-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n\n\nDefineUnitType(\"unit-protoss-probe\", {})\n\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-protoss-probe\",\n  Action = \"train-unit\", Value = \"unit-protoss-probe\",\n  Key = \"d\", Hint = \"Build Probe\",\n  ForUnit = {\"unit-protoss-nexus\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-observatory.lua",
    "content": "--\n-- -- unit-protoss-observatory\n--\nDefineAnimations(\"animations-protoss-observatory\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-observatory\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-observatory\", {\n  Animations = \"animations-protoss-observatory\", Icon = \"icon-protoss-observatory\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-observatory\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-observer.lua",
    "content": "--\n-- unit-protoss-observer\n--\n\n\nDefineAnimations(\"animations-protoss-observer-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 2\", --[[ active overlay 58 ]]\n    \"wait 1\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-protoss-observer-death\", { Name = \"Dead Overlord\",\n  Image = image_45_zerg_zovdeath,\n  Animations = \"animations-zerg-overlord-death\", Icon = \"icon-zerg-overlord\",\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {63, 63},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-protoss-observer\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"unbreakable end\", \"wait 1\",},\n  Death = {\n    --\"sound zerg-overlord-death\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-protoss-observer\", {\n  Animations = \"animations-protoss-observer\", Icon = \"icon-protoss-observer\",\n  RepairHp = 4,\n  Speed = 20, \n  DrawLevel = 45,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 0,\n  DetectCloak = true,\n  --CanTransport = {},\n  --MaxOnBoard = 6,\n  --Corpse = \"unit-zerg-overlord-death\",\n  SelectableByRectangle = true,\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  Sounds = {\n    \"selected\", \"protoss-observer-selected\",\n    \"acknowledge\", \"protoss-observer-acknowledge\",\n    \"ready\", \"protoss-observer-ready\",\n    \"help\", \"protoss-observer-attacked\",\n    \"dead\", \"protoss-observer-death\"} } )\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-photon-cannon.lua",
    "content": "DefineAnimations(\"animations-protoss-photon-cannon\", {\n   Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Attack = {\n    \"unbreakable begin\", \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 3\", \"wait 2\", \"sound protoss-photon-cannon-attack\", \"attack\",\n    \"unbreakable end\", \"wait 5\",\n  },  \n})\n\nDefineConstruction(\"construction-protoss-photon-cannon\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = .5,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 2,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 1.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 2,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 2.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 3,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 3.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 4,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 4.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 5.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 6,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 6.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 7,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 7.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 8,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 8.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 9,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 9.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 10,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 10.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 11,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 11.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 12,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 13.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 14,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 14.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 15,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 15.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 16,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 16.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 17.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 18.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 19.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 20.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 21,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 21.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 22,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 22.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 23,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 23.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 24,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 24.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 25,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 25.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 26,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 26.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 27,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 27.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 28,\n    File = \"construction\",\n    Frame = 8},\n\n\n   {Percent = 28.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 29,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 29.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 30,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 30.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 31,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 31.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 32,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 32.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 33,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 33.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 34,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 34.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 35,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 35.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 36,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 36.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 37,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 37.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 38,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 38.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 39,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 39.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 40.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 41,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 41.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 42,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 42.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 43,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 43.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 44,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 44.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 45,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 45.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 46,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 46.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 47,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 47.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 48,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 48.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 49,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 49.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 50,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 50.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 51,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 51.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 52,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 52.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 53,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 53.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 54,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 54.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 55,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 55.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 56,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 56.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 57,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 58.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 59,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 59.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 60,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 60.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 61,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 61.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 62,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 62.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 63,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 63.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 64,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 64.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 65,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 65.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 66,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 66.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 67,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 67.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 68,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 68.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 69,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 69.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 67,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 67.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 68,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 68.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 69,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 69.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 70,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 70.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 71,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 71.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 72,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 72.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 73,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 73.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 74,\n    File = \"construction\",\n    Frame = 8},\n\n\n   {Percent = 74.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 75,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 75.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 76,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 76.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 77,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 77.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 78,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 78.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 79,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 79.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 80,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 80.5,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 81,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 81.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 82,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 82.5,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 83,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 83.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 84,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 84.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 85,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 85.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 86,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 86.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 87,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 87.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 88,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 88.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 89,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 89.5,\n    File = \"construction\",\n    Frame = 8},\n\n   {Percent = 90,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 90.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 91,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 91.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 92,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 92.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 93,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 93.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 94,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 94.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 95,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 95.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 96,\n    File = \"construction\",\n    Frame = 9},\n   {Percent = 96.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 97,\n    File = \"construction\",\n    Frame = 7},\n   {Percent = 97.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 98,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 98.5,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 99,\n    File = \"construction\",\n    Frame = 8},\n   {Percent = 99.5,\n    File = \"construction\",\n    Frame = 8},\n}\n})\n\nDefineUnitType(\"unit-protoss-photon-cannon\", {\n  Animations = \"animations-protoss-photon-cannon\", Icon = \"icon-terran-bunker\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-photon-cannon\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  MaxAttackRange = 7,\n  Points = 170,\n  --[[Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",--]]\n  RightMouseAction = \"attack\",\n  BuilderOutside = true,\n  AutoBuildRate = 30,\n  CanAttack = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-photon-cannon-selected\",\n    \"ready\", \"protoss-building-ready\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-probe.lua",
    "content": "--\n-- unit-protoss-probe\n--\n\nDefineAnimations(\"animations-protoss-probe\", {\nStill = {\"frame 0\", \"wait 125\",},\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",},\n  Harvest_minerals = {\"unbreakable begin\", \"sound protoss-probe-mine\", \"wait 75\",\"sound protoss-probe-mine\", \"unbreakable end\", \"wait 1\",},\n  Repair = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",},\n  Build = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"frame 50\", \"wait 3\", \"frame 55\", \"wait 3\", \"frame 60\", \"wait 100\",\n    \"frame 60\", \"unbreakable end\", \"wait 1\",},\n})\n\n\nDefineUnitType(\"unit-protoss-probe\", {\n  DrawLevel = 19,\n  Animations = \"animations-protoss-probe\", Icon = \"icon-protoss-probe\",\n  Speed = 10,\n  DrawLevel = 40,\n  BasicDamage = 3, PiercingDamage = 2, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 50,\n  Points = 30,\n  Demand = 1,\n  --ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"harvest\",\n  CanAttack = true, RepairRange = 1,\n  CanTargetLand = true,\n  Coward = true,\n  CanGatherResources = {\n   {\"file-when-loaded\", \"graphics/unit/protoss/probe.png\",\n    \"resource-id\", \"minerals\",\n    \"harvest-from-outside\",\n    \"resource-capacity\", 8,\n    \"wait-at-resource\", 150,\n    \"wait-at-depot\", 50},\n   {\"file-when-loaded\", \"graphics/unit/protoss/probe.png\",\n    \"resource-id\", \"gas\",\n    \"resource-capacity\", 8,\n    \"wait-at-resource\", 50,\n    \"wait-at-depot\", 50,}},\n  organic = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"protoss-probe-selected\",\n    \"acknowledge\", \"protoss-probe-acknowledge\",\n    \"ready\", \"protoss-probe-ready\",\n    \"help\", \"protoss-units-attacked\",\n    \"dead\", \"protoss-probe-death\"} } )\n\nDefineUnitType(\"unit-protoss-pylon\", {})\nDefineUnitType(\"unit-protoss-nexus\", {})\nDefineUnitType(\"unit-protoss-gateway\", {})\nDefineUnitType(\"unit-protoss-photon-cannon\", {})\nDefineUnitType(\"unit-protoss-assimulator\", {})\nDefineUnitType(\"unit-protoss-forge\", {})\nDefineUnitType(\"unit-protoss-cybernetics-core\", {})\nDefineUnitType(\"unit-protoss-robotics-support-bay\", {})\nDefineUnitType(\"unit-protoss-stargate\", {})\nDefineUnitType(\"unit-protoss-citadel-of-adun\", {})\nDefineUnitType(\"unit-protoss-fleet-beacon\", {})\nDefineUnitType(\"unit-protoss-templar-archives\", {})\nDefineUnitType(\"unit-protoss-observatory\", {})\nDefineUnitType(\"unit-protoss-arbiter-tribunal\", {})\nDefineUnitType(\"unit-protoss-robotics-facility\", {})\n\n--\n-- Default\n--\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-move\",\n  Action = \"move\",\n  Key = \"m\", Hint = \"~!Move\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-stop\",\n  Action = \"stop\",\n  Key = \"s\", Hint = \"~!Stop\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-attack\",\n  Action = \"attack\",\n  Key = \"a\", Hint = \"~!Attack\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 4, Level = 0, Icon = \"icon-repair\",\n  Action = \"repair\",\n  Key = \"r\", Hint = \"~!Repair\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 5, Level = 0, Icon = \"icon-gather\",\n  Action = \"harvest\",\n  Key = \"g\", Hint = \"~!Gather\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-build\",\n  Action = \"button\", Value = 1,\n  Key = \"b\", Hint = \"~!Build Structure\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 8, Level = 0, Icon = \"icon-advanced-build\",\n  Action = \"button\", Value = 2,\n  Key = \"v\", Hint = \"Build Ad~!vanced Structure\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\n\n--\n-- Build\n--\nDefineButton( { Pos = 1, Level = 1, Icon = \"icon-protoss-nexus\",\n  Action = \"build\", Value = \"unit-protoss-nexus\",\n  Key = \"x\", Hint = \"~!Nexus\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 2, Level = 1, Icon = \"icon-protoss-pylon\",\n  Action = \"build\", Value = \"unit-protoss-pylon\",\n  Key = \"p\", Hint = \"~!Pylon\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \n DefineButton( { Pos = 3, Level = 1, Icon = \"icon-protoss-assimilator\",\n  Action = \"build\", Value = \"unit-protoss-assimulator\",\n  Key = \"a\", Hint = \"~!Assimulator\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \n  \nDefineButton( { Pos = 4, Level = 1, Icon = \"icon-protoss-gateway\",\n  Action = \"build\", Value = \"unit-protoss-gateway\",\n  Key = \"g\", Hint = \"~!Gateway\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 5, Level = 1, Icon = \"icon-protoss-forge\",\n  Action = \"build\", Value = \"unit-protoss-forge\",\n  Key = \"f\", Hint = \"~!Forge\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 6, Level = 1, Icon = \"icon-protoss-photon-cannon\",\n  Action = \"build\", Value = \"unit-protoss-photon-cannon\",\n  Key = \"c\", Hint = \"Photon ~!Cannon\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \nDefineButton( { Pos = 7, Level = 1, Icon = \"icon-protoss-cybernetics-core\",\n  Action = \"build\", Value = \"unit-protoss-cybernetics-core\",\n  Key = \"c\", Hint = \"C~!ybernetics Core\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \nDefineButton( { Pos = 8, Level = 1, Icon = \"icon-protoss-shield-battery\",\n  Action = \"build\", Value = \"unit-protoss-shield-battery\",\n  Key = \"c\", Hint = \"~!Shield Battery\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 9, Level = 1, Icon = \"icon-cancel\",\n  Action = \"button\", Value = 0,\n  Key = \"\\27\", Hint = \"~<ESC~> - Cancel\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\n--\n-- Advanced Build\n--\nDefineButton( { Pos = 1, Level = 2, Icon = \"icon-protoss-robotics-facility\",\n  Action = \"build\", Value = \"unit-protoss-robotics-facility\",\n  Key = \"c\", Hint = \"Robotics Facility\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \nDefineButton( { Pos = 2, Level = 2, Icon = \"icon-protoss-stargate\",\n  Action = \"build\", Value = \"unit-protoss-stargate\",\n  Key = \"c\", Hint = \"~!Stargate\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 3, Level = 2, Icon = \"icon-protoss-citadel-of-adun\",\n  Action = \"build\", Value = \"unit-protoss-citadel-of-adun\",\n  Key = \"c\", Hint = \"~!\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n\nDefineButton( { Pos = 4, Level = 2, Icon = \"icon-protoss-robotics-support-bay\",\n  Action = \"build\", Value = \"unit-protoss-robotics-support-bay\",\n  Key = \"c\", Hint = \"~!Robotics Support Bay\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \nDefineButton( { Pos = 5, Level = 2, Icon = \"icon-protoss-fleet-beacon\",\n  Action = \"build\", Value = \"unit-protoss-fleet-beacon\",\n  Key = \"c\", Hint = \"Fleet Beacon\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \n DefineButton( { Pos = 6, Level = 2, Icon = \"icon-protoss-templar-archives\",\n  Action = \"build\", Value = \"unit-protoss-templar-archives\",\n  Key = \"c\", Hint = \"Templar Archives\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \nDefineButton( { Pos = 7, Level = 2, Icon = \"icon-protoss-observatory\",\n  Action = \"build\", Value = \"unit-protoss-observatory\",\n  Key = \"c\", Hint = \"Observatory\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \nDefineButton( { Pos = 8, Level = 2, Icon = \"icon-protoss-arbiter-tribunal\",\n  Action = \"build\", Value = \"unit-protoss-arbiter-tribunal\",\n  Key = \"c\", Hint = \"Arbiter Tribunal\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n  \n  \nDefineButton( { Pos = 9, Level = 2, Icon = \"icon-cancel\",\n  Action = \"button\", Value = 0,\n  Key = \"\\27\", Hint = \"~<ESC~> - Cancel\",\n  ForUnit = {\"unit-protoss-probe\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-pylon.lua",
    "content": "--\n-- unit-protoss-pylon\n--\n\nDefineAnimations(\"animations-protoss-pylon\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-pylon\", {\n  Files = image_327_terran_tbldmed_var,\n  ShadowFiles = image_327_terran_tbldmed_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-pylon\", {\n  Animations = \"animations-protoss-pylon\", Icon = \"icon-protoss-pylon\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-pylon\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 45,\n  Points = 100,\n  BuilderOutside = true,\n  AutoBuildRate = 30,\n  Supply = 8,\n  --Corpse = \"unit-destroyed-2x2-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"protoss-pylon-selected\",\n--    \"acknowledge\", \"farm-acknowledge\",\n   \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"explosion-protoss-large\"} } )\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-reaver.lua",
    "content": "--\n-- unit-protoss-reaver\n--\n\nDefineAnimations(\"animations-protoss-reaver\", {\n  Still = {\n\t\"frame 85\", \"wait 125\",\n  },\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"frame 85\", \"move 4\", \"wait 1\", \"frame 102\",\n    \"move 4\", \"wait 1\", \"frame 119\", \"move 4\", \"wait 1\", \"frame 136\",\n    \"move 4\", \"wait 1\", \"frame 153\", \"move 4\", \"wait 1\", \"frame 170\",\n    \"move 4\", \"wait 1\", \"frame 187\",\n    --FIXME: subtile movement not supported\n    --[[\"move 4\", \"wait 1\", \"frame 204\",]]\n    \"move 4\", \"unbreakable end\", \"wait 1\", \"frame 119\",\n  },\n--  StartAttack = {\"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",},\n  Attack = {\n    \"wait 1\", \"unbreakable begin\", \"attack\", \"sound protoss-zealot-attack\",\n    \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 51\", \"wait 1\",\n    \"frame 68\", \"sound protoss-zealot-hit\", \"wait 1\", \"frame 51\", \"wait 1\", \"frame 34\", \"sound protoss-zealot-hit\",\n    \"unbreakable end\", \"wait 10\", \"frame 17\",\n  },\n--  EndAttack = {\"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", --[[goto 70FD]]},\n  Death = {\n    \"unbreakable begin\",\n    \"sound protoss-zealot-death\", \"exact-frame 221\", \"wait 2\",\n    \"exact-frame 222\", \"wait 2\", \"exact-frame 223\", \"wait 2\",\n    \"exact-frame 239\", \"wait 2\", \"exact-frame 225\", \"wait 2\",\n    \"exact-frame 226\", \"wait 2\", \"exact-frame 227\", \"wait 2\",\n    \"exact-frame 228\", \"wait 2\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-protoss-reaver\", {\n  Animations = \"animations-protoss-reaver\", Icon = \"icon-protoss-reaver\",\n  Speed = 10,\n  DrawLevel = 40,\n  Armor = 4, BasicDamage = 10, PiercingDamage = 3, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"protoss-reaver-selected\",\n    \"acknowledge\", \"protoss-reaver-acknowledge\",\n    \"ready\", \"protoss-reaver-ready\",\n    \"help\", \"protoss-reaver-attacked\",} } )\n\n\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-robotics-facility.lua",
    "content": "--\n-- -- unit-protoss-robotics-facility\n--\nDefineAnimations(\"animations-protoss-robotics-facility\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-robotics-facility\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-robotics-facility\", {\n  Animations = \"animations-protoss-robotics-facility\", Icon = \"icon-protoss-robotics-facility\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-robotics-facility\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n\n\nDefineUnitType(\"unit-protoss-shuttle\", {})\nDefineUnitType(\"unit-protoss-reaver\", {})\nDefineUnitType(\"unit-protoss-observer\", {})\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-protoss-shuttle\",\n  Action = \"train-unit\", Value = \"unit-protoss-shuttle\",\n  Key = \"z\", Hint = \"Warp in Shuttle\",\n  ForUnit = {\"unit-protoss-robotics-facility\"} } )\n  \nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-protoss-reaver\",\n  Action = \"train-unit\", Value = \"unit-protoss-reaver\",\n  Key = \"z\", Hint = \"Warp in Reaver\",\n  ForUnit = {\"unit-protoss-robotics-facility\"} } )\n  \nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-protoss-observer\",\n  Action = \"train-unit\", Value = \"unit-protoss-observer\",\n  Key = \"z\", Hint = \"Warp in Observer\",\n  ForUnit = {\"unit-protoss-robotics-facility\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-robotics-support-bay.lua",
    "content": "--\n-- -- unit-protoss-robotics-support-bay\n--\nDefineAnimations(\"animations-protoss-robotics-support-bay\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-robotics-support-bay\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-robotics-support-bay\", {\n  Animations = \"animations-protoss-robotics-support-bay\", Icon = \"icon-protoss-robotics-support-bay\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-robotics-support-bay\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-scout.lua",
    "content": "--\n-- unit-protoss-scout\n--\n\nDefineAnimations(\"animations-protoss-scout\", {\n  Still = {\"frame 0\", \"wait 125\",--[[FIXME: shift down 79A2]]},\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"attack\", \"sound protoss-scout-attack\",\n    \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"sound protoss-scout-death\",\n    --[[active overlay 332,0]] \"wait 3\", \"unbreakable end\", \"wait 1\",},\n})\n\nDefineUnitType(\"unit-protoss-scout\", {\n  DrawLevel = 45,\n  Animations = \"animations-protoss-scout\", Icon = \"icon-protoss-scout\",\n  Speed = 14,\n  DrawLevel = 60,\n  Armor = 5, BasicDamage = 0, PiercingDamage = 16, Missile = \"missile-none\",\n  AnnoyComputerFactor = 55,\n  MaxAttackRange = 4,\n  Priority = 65,\n  Points = 150,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetSea = true, CanTargetAir = true,\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"protoss-scout-selected\",\n    \"acknowledge\", \"protoss-scout-acknowledge\",\n    \"ready\", \"protoss-scout-ready\",\n    \"help\", \"protoss-unit-attacked\",\n    \"dead\", \"protoss-scout-death\"} } )\n\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-shield-battery.lua",
    "content": "--\n-- -- unit-protoss-shield-battery\n--\nDefineAnimations(\"animations-protoss-shield-battery\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-shield-battery\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-shield-battery\", {\n  Animations = \"animations-protoss-shield-battery\", Icon = \"icon-protoss-shield-battery\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-shield-battery\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-shuttle.lua",
    "content": "--\n-- unit-protoss-shuttle\n--\n\n\nDefineAnimations(\"animations-protoss-shuttle-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 2\", --[[ active overlay 58 ]]\n    \"wait 1\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-protoss-shuttle-death\", { Name = \"Dead Shuttle\",\n  Image = image_45_zerg_zovdeath,\n  Animations = \"animations-zerg-overlord-death\", Icon = \"icon-zerg-overlord\",\n  NumDirections = 1,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {63, 63},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-protoss-shuttle\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"unbreakable end\", \"wait 1\",},\n  Death = {\n    \"sound zerg-overlord-death\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-protoss-shuttle\", {\n  Animations = \"animations-protoss-shuttle\", Icon = \"icon-protoss-shuttle\",\n  RepairHp = 4,\n  Speed = 10,\n  DrawLevel = 45,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 9,\n  DetectCloak = true,\n  CanTransport = {},\n  MaxOnBoard = 6,\n  --Corpse = \"unit-zerg-overlord-death\",\n  SelectableByRectangle = true,\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  Sounds = {\n    \"selected\", \"protoss-shuttle-selected\",\n    \"acknowledge\", \"protoss-shuttle-acknowledge\",\n    \"ready\", \"protoss-shuttle-ready\",\n    \"help\", \"protoss-units-attacked\",\n    \"dead\", \"protoss-shuttle-death\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-stargate.lua",
    "content": "--\n-- -- unit-protoss-stargate\n--\nDefineAnimations(\"animations-protoss-stargate\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-stargate\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-stargate\", {\n  Animations = \"animations-protoss-stargate\", Icon = \"icon-protoss-stargate\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-stargate\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n\n--DefineUnitType(\"unit-protoss-scout\", {})\n\n--DefineButton( { Pos = 1, Level = 0, Icon = \"icon-protoss-scout\",\n--  Action = \"train-unit\", Value = \"unit-protoss-scout\",\n--  Key = \"z\", Hint = \"Warp in Scout\",\n--  ForUnit = {\"unit-protoss-stargate\"} } )\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-templar-archives.lua",
    "content": "\n--\n-- -- unit-protoss-templar-archives\n--\nDefineAnimations(\"animations-protoss-templar-archives\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-protoss-templar-archives\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-protoss-templar-archives\", {\n  Animations = \"animations-protoss-stargate\", Icon = \"icon-protoss-templar-archives\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-protoss-templar-archives\",\n  Speed = 0,\n  DrawLevel = 50,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  BuilderOutside = true,\n  AutoBuildRate = 2,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \"<\", Type = \"unit-protoss-pylon\"} } },\n  Sounds = {\n    \"selected\", \"protoss-cybernetics-core-selected\",\n    \"ready\", \"protoss-building-done\",\n    \"help\", \"protoss-base-attacked\",\n    \"dead\", \"protoss-explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/protoss/unit-protoss-zealot.lua",
    "content": "--\n-- unit-protoss-zealot\n--\n\nDefineAnimations(\"animations-protoss-zealot\", {\n  Still = {\n\t\"frame 85\", \"wait 125\",\n  },\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"frame 85\", \"move 4\", \"wait 1\", \"frame 102\",\n    \"move 4\", \"wait 1\", \"frame 119\", \"move 4\", \"wait 1\", \"frame 136\",\n    \"move 4\", \"wait 1\", \"frame 153\", \"move 4\", \"wait 1\", \"frame 170\",\n    \"move 4\", \"wait 1\", \"frame 187\",\n    --FIXME: subtile movement not supported\n    --[[\"move 4\", \"wait 1\", \"frame 204\",]]\n    \"move 4\", \"unbreakable end\", \"wait 1\", \"frame 119\",\n  },\n--  StartAttack = {\"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",},\n  Attack = {\n    \"wait 1\", \"unbreakable begin\", \"attack\", \"sound protoss-zealot-attack\",\n    \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 51\", \"wait 1\",\n    \"frame 68\", \"sound protoss-zealot-hit\", \"wait 1\", \"frame 51\", \"wait 1\", \"frame 34\", \"sound protoss-zealot-hit\",\n    \"unbreakable end\", \"wait 10\", \"frame 17\",\n  },\n--  EndAttack = {\"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", --[[goto 70FD]]},\n  Death = {\n    \"unbreakable begin\",\n    \"sound protoss-zealot-death\", \"exact-frame 221\", \"wait 2\",\n    \"exact-frame 222\", \"wait 2\", \"exact-frame 223\", \"wait 2\",\n    \"exact-frame 239\", \"wait 2\", \"exact-frame 225\", \"wait 2\",\n    \"exact-frame 226\", \"wait 2\", \"exact-frame 227\", \"wait 2\",\n    \"exact-frame 228\", \"wait 2\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-protoss-zealot\", {\n  Animations = \"animations-protoss-zealot\", Icon = \"icon-protoss-zealot\",\n  Speed = 10,\n  DrawLevel = 40,\n  Armor = 4, BasicDamage = 10, PiercingDamage = 3, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"protoss-zealot-selected\",\n    \"acknowledge\", \"protoss-zealot-acknowledge\",\n    \"ready\", \"protoss-zealot-ready\",\n    \"help\", \"protoss-zealot-attacked\",} } )\n\n\n\n"
  },
  {
    "path": "scripts/protoss/units.lua",
    "content": "Load(\"scripts/protoss/unit-protoss-nexus.lua\")\nLoad(\"scripts/protoss/unit-protoss-pylon.lua\")\nLoad(\"scripts/protoss/unit-protoss-gateway.lua\")\nLoad(\"scripts/protoss/unit-protoss-zealot.lua\")\nLoad(\"scripts/protoss/unit-protoss-dragoon.lua\")\nLoad(\"scripts/protoss/unit-protoss-photon-cannon.lua\")\nLoad(\"scripts/protoss/unit-protoss-assimulator.lua\")\nLoad(\"scripts/protoss/unit-protoss-forge.lua\")\nLoad(\"scripts/protoss/unit-protoss-cybernetics-core.lua\")\nLoad(\"scripts/protoss/unit-protoss-shield-battery.lua\")\nLoad(\"scripts/protoss/unit-protoss-robotics-support-bay.lua\")\nLoad(\"scripts/protoss/unit-protoss-probe.lua\")\nLoad(\"scripts/protoss/unit-protoss-stargate.lua\")\nLoad(\"scripts/protoss/unit-protoss-citadel-of-adun.lua\")\nLoad(\"scripts/protoss/unit-protoss-fleet-beacon.lua\")\nLoad(\"scripts/protoss/unit-protoss-templar-archives.lua\")\nLoad(\"scripts/protoss/unit-protoss-observatory.lua\")\nLoad(\"scripts/protoss/unit-protoss-arbiter-tribunal.lua\")\nLoad(\"scripts/protoss/unit-protoss-robotics-facility.lua\")\nLoad(\"scripts/protoss/unit-protoss-high-templar.lua\")\nLoad(\"scripts/protoss/unit-protoss-dark-templar.lua\")\nLoad(\"scripts/protoss/unit-protoss-observer.lua\")\nLoad(\"scripts/protoss/unit-protoss-reaver.lua\")\n--Load(\"scripts/protoss/unit-protoss-shuttle.lua\")\n--Load(\"scripts/protoss/unit-protoss-scout.lua\")\n\n\n--\n-- Buttons\n--\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-move\",\n  Action = \"move\",\n  Key = \"m\", Hint = \"~!Move\",\n  ForUnit = {\n    \"protoss-group\",\n    \"unit-protoss-probe\",\n    \"unit-protoss-zealot\",\n    \"unit-protoss-dragoon\",\n    \"unit-protoss-high-templar\",\n    \"unit-protoss-observer\",\n    \"unit-protoss-reaver\",\n    \"unit-protoss-shuttle\",\n    --\"unit-protoss-scout\",\n  } } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-stop\",\n  Action = \"stop\",\n  Key = \"s\", Hint = \"~!Stop\",\n  ForUnit = {\n    \"protoss-group\",\n    \"unit-protoss-dragoon\",\n    \"unit-protoss-probe\",\n    \"unit-protoss-zealot\",\n    \"unit-protoss-photon-cannon\",\n    \"unit-protoss-high-templar\",\n    \"unit-protoss-dark-templar\",\n    \"unit-protoss-observer\",\n    \"unit-protoss-reaver\",\n    \"unit-protoss-shuttle\",\n    --\"unit-protoss-scout\",\n  } } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-attack\",\n  Action = \"attack\",\n  Key = \"a\", Hint = \"~!Attack\",\n  ForUnit = {\n    \"protoss-group\",\n    \"unit-protoss-dragoon\",\n    \"unit-protoss-probe\",\n    \"unit-protoss-zealot\",\n    \"unit-protoss-photon-cannon\",\n    \"unit-protoss-dark-templar\",\n    \"unit-protoss-reaver\",\n    --\"unit-protoss-scout\",\n  } } )\n\nDefineButton( { Pos = 4, Level = 0, Icon = \"icon-patrol\",\n  Action = \"patrol\",\n  Key = \"p\", Hint = \"~!Patrol\",\n  ForUnit = {\n    \"protoss-group\",\n    \"unit-protoss-dragoon\",\n    \"unit-protoss-probe\",\n    \"unit-protoss-zealot\",\n    \"unit-protoss-high-templar\",\n    \"unit-protoss-dark-templar\",\n    \"unit-protoss-observer\",\n    \"unit-protoss-reaver\",\n    \"unit-protoss-shuttle\",\n    --\"unit-protoss-scout\",\n  } } )\n\nDefineButton( { Pos = 5, Level = 0, Icon = \"icon-hold-position\",\n  Action = \"stand-ground\",\n  Key = \"h\", Hint = \"~!Hold Position\",\n  ForUnit = {\n    \"protoss-group\",\n    \"unit-protoss-dragoon\",\n    \"unit-protoss-probe\",\n    \"unit-protoss-zealot\",\n    \"unit-protoss-high-templar\",\n    \"unit-protoss-dark-templar\",\n    \"unit-protoss-observer\",\n    \"unit-protoss-reaver\",\n    \"unit-protoss-shuttle\",\n    --\"unit-protoss-scout\",\n  } } )\n\nDefineButton( { Pos = 6, Level = 0, Icon = \"icon-rally-point\",\n  Action = \"move\",\n  Key = \"r\", Hint = \"Set ~!Rally Point\",\n  ForUnit = {\n    \"unit-protoss-nexus\",\n    \"unit-protoss-gateway\",\n    \"unit-protoss-robotics-facility\",\n    \"unit-protoss-stargate\",\n  } } )\n\n\n\n--\n-- Allow\n--\nDefineAllow(\"unit-protoss-probe\",            \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-zealot\",         \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-dragoon\",        \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-probe\",            \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-high-templar\",\t\"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-dark-templar\",\t\"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-observer\",\t\"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-reaver\",\t\"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-shuttle\",\t\"AAAAAAAAAAAAAAAA\")\n--DefineAllow(\"unit-protoss-scout\",\t\"AAAAAAAAAAAAAAAA\")\n\n\nDefineAllow(\"unit-protoss-nexus\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-pylon\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-gateway\",         \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-photon-cannon\",   \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-assimulator\",   \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-forge\",  \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-cybernetics-core\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-shield-battery\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-robotics-support-bay\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-stargate\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-citadel-of-adun\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-fleet-beacon\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-templar-archives\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-observatory\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-arbiter-tribunal\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-protoss-robotics-facility\",          \"AAAAAAAAAAAAAAAA\")\n\n"
  },
  {
    "path": "scripts/protoss/upgrade.lua",
    "content": "--\n--  Upgrades\n--[[\n\nupgrades = {\n{ \"upgrade-zerg-zergling-speed\", \"icon-zerg-zergling-attack-speed\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-weapons2\", \"icon-terran-upgrade-infantry-weapons\",\n  {   200,   175,   175,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-weapons3\", \"icon-terran-upgrade-infantry-weapons\",\n  {   200,   250,   250,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-armor1\", \"icon-terran-upgrade-infantry-armor\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-armor2\", \"icon-terran-upgrade-infantry-armor\",\n  {   200,   175,   175,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-armor3\", \"icon-terran-upgrade-infantry-armor\",\n  {   200,   250,   250,     0,     0,     0,     0}},\n\n{ \"upgrade-terran-u238-shells\", \"icon-terran-u238-shells\",\n  {   200,   150,   150,     0,     0,     0,     0}},\n\n{ \"upgrade-terran-stim-pack\", \"icon-terran-stim-pack\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n}\n\nfor i = 1,table.getn(upgrades) do\n  u = CUpgrade:New(upgrades[i][1])\n  u.Icon = Icons[upgrades[i][2]]\n  --[[\n  for j = 1,table.getn(upgrades[1][3]) do\n    u.Costs[j - 1] = upgrades[i][3][j]\n  end\nend\n\n\n--\n--  Modifiers\n--\n\nDefineModifier(\"upgrade-terran-infantry-weapons1\",\n  {\"Level\", 1}, {\"PiercingDamage\", 2},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-weapons2\",\n  {\"Level\", 2}, {\"PiercingDamage\", 3},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-weapons3\",\n  {\"Level\", 3}, {\"PiercingDamage\", 4},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\nDefineModifier(\"upgrade-terran-infantry-armor1\",\n  {\"Level\", 1}, {\"Armor\", 2},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-armor2\",\n  {\"Level\", 2}, {\"Armor\", 3},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-armor3\",\n  {\"Level\", 3}, {\"Armor\", 4},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\nDefineModifier(\"upgrade-terran-u238-shells\",\n  {\"Level\", 1}, {\"AttackRange\", 4},\n  {\"apply-to\", \"unit-terran-marine\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\nDefineModifier(\"upgrade-terran-stim-pack\",\n  {\"Level\", 1}, {\"Armor\", 2},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\n\n--\n--  Allow\n--\n\nDefineAllow(\"upgrade-terran-infantry-weapons1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-weapons2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-weapons3\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-armor1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-armor2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-armor3\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-stim-pack\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-u238-shells\", \"AAAAAAAAAAAAAAAA\")\n\n\n--\n--  Dependencies\n--\n\nDefineDependency(\"upgrade-terran-infantry-weapons2\",\n  {\"upgrade-terran-infantry-weapons1\"})\nDefineDependency(\"upgrade-terran-infantry-weapons3\",\n  {\"upgrade-terran-infantry-weapons2\"})\nDefineDependency(\"upgrade-terran-infantry-armor2\",\n  {\"upgrade-terran-infantry-armor1\"})\nDefineDependency(\"upgrade-terran-infantry-armor3\",\n  {\"upgrade-terran-infantry-armor2\"})\n\nDefineDependency(\"unit-terran-ghost\",\n  {\"unit-terran-academy\", \"unit-terran-science-facility\",\n   --[[\"unit-terran-covert-ops\"]]})\n\nDefineDependency(\"unit-terran-supply-depot\",\n  {\"unit-terran-command-center\"})\nDefineDependency(\"unit-terran-engineering-bay\",\n  {\"unit-terran-command-center\"})\nDefineDependency(\"unit-terran-barracks\",\n  {\"unit-terran-command-center\"})\nDefineDependency(\"unit-terran-refinery\",\n  {\"unit-terran-command-center\"})\n\nDefineDependency(\"unit-terran-missile-turret\",\n  {\"unit-terran-engineering-bay\"})\n\nDefineDependency(\"unit-terran-academy\",\n  {\"unit-terran-barracks\"})\nDefineDependency(\"unit-terran-bunker\",\n  {\"unit-terran-barracks\"})\nDefineDependency(\"unit-terran-factory\",\n  {\"unit-terran-barracks\"})\n\nDefineDependency(\"unit-terran-armory\",\n  {\"unit-terran-factory\"})\nDefineDependency(\"unit-terran-starport\",\n  {\"unit-terran-factory\"})\n\nDefineDependency(\"unit-terran-science-facility\",\n  {\"unit-terran-starport\"})\n  --]]\n"
  },
  {
    "path": "scripts/sc.lua",
    "content": "--       _________ __                 __\n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      wc2.lua - WC2 compatibility level\n--\n--      (c) Copyright 2001-2006 by Lutz Sammer and Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nDefineRaceNames(\n  \"race\", {\n    \"name\", \"terran\",\n    \"display\", \"Terran\",\n    \"visible\"},\n  \"race\", {\n    \"name\", \"zerg\",\n    \"display\", \"Zerg\",\n    \"visible\"},\n  \"race\", {\n    \"name\", \"protoss\",\n    \"display\", \"Protoss\",\n    \"visible\"},\n  \"race\", {\n    \"name\", \"neutral\",\n    \"display\", \"Neutral\"})\n\n\nlocal t = {\n  {\"unit-terran-scv\", \"unit-zerg-drone\", \"unit-protoss-probe\"},\n  {\"unit-terran-command-center\", \"unit-zerg-hatchery\", \"unit-protoss-nexus\"},\n}\n\nlocal TerranEquivalent = {}\nlocal ZergEquivalent = {}\nlocal ProtossEquivalent = {}\n\nfor i=1,table.getn(t) do\n  TerranEquivalent[t[i][2]] = t[i][1]\n  TerranEquivalent[t[i][3]] = t[i][1]\n  ZergEquivalent[t[i][1]] = t[i][2]\n  ZergEquivalent[t[i][3]] = t[i][2]\n  ProtossEquivalent[t[i][1]] = t[i][3]\n  ProtossEquivalent[t[i][2]] = t[i][3]\nend\n\n-- Convert a unit type to the equivalent for a different race\nfunction ConvertUnitType(unittype, race)\n  local equiv\n\n  if (race == \"terran\") then\n    equiv = TerranEquivalent[unittype]\n  elseif (race == \"zerg\") then\n    equiv = ZergEquivalent[unittype]\n  else\n    equiv = ProtossEquivalent[unittype]\n  end\n\n  if (equiv ~= nil) then\n    return equiv\n  else\n    return unittype\n  end\nend\n\n\nif (OldSetPlayerData == nil) then\n  OldSetPlayerData = SetPlayerData\nend\n\n-- Override with game settings\nfunction SetPlayerData(player, data, arg1, arg2)\n  if (GameCycle ~= 0) then\n    return OldSetPlayerData(player, data, arg1, arg2)\n  end\n\n  local res = {arg2, arg2}\n\n  if (data == \"RaceName\") then\n    -- FIXME: support multiplayer\n    if (ThisPlayer ~= nil and ThisPlayer.Index == player) then\n      if (GameSettings.Presets[0].Race == 1) then\n        arg1 = \"terran\"\n      elseif (GameSettings.Presets[0].Race == 2) then\n        arg1 = \"zerg\"\n\tSetMusic(\"zerg\")\n      elseif (GameSettings.Presets[0].Race == 3) then\n        arg1 = \"protoss\"\n\tSetMusic(\"protoss\")\n      end\n    end\n  elseif (data == \"Resources\") then\n    res = {50, 0}\n    if (arg1 == \"minerals\") then\n      arg2 = res[1]\n    elseif (arg1 == \"gas\") then\n      arg2 = res[2]\n    end\n  end\n\n  OldSetPlayerData(player, data, arg1, arg2)\n\n\n  if (data == \"RaceName\") then\n    -- If this is 1 peasant mode add the peasant now\n    if (GameSettings.NumUnits == 1) then\n      if (player ~= 15 and Players[player].Type ~= PlayerNobody) then\n        local unittype = ConvertUnitType(\"unit-terran-scv\", GetPlayerData(player, \"RaceName\"))\n        CreateUnit(unittype, player, {Players[player].StartPos.x, Players[player].StartPos.y})\n      end\n    end\n    -- Set AI\n    if (arg1 == \"terran\") then\n      SetAiType(player, \"terran-ai\")\n    elseif (arg1 == \"zerg\") then\n      SetAiType(player, \"zerg-ai\")\n    else\n      SetAiType(player, \"protoss-ai\")\n    end\n  end\nend\n\nif (OldDefinePlayerTypes == nil) then\n  OldDefinePlayerTypes = DefinePlayerTypes\nend\n\nfunction DefinePlayerTypes(p1, p2, p3, p4, p5, p6, p7, p8)\n  local p = {p1, p2, p3, p4, p5, p6, p7, p8}\n  local foundperson = false\n  local nump = GameSettings.Opponents\n  if (nump == 0) then nump = 8 end\n\n  -- FIXME: should randomly pick players to use\n  for i=1,8 do\n    if (p[i] == \"person\" or p[i] == \"computer\") then\n      if (p[i] == \"person\" and foundperson == false) then\n        foundperson = true\n      else\n        if (nump == 0) then\n          p[i] = \"nobody\"\n        else\n          nump = nump - 1\n        end\n      end\n    end\n  end\n\n  OldDefinePlayerTypes(p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8])\nend\n\nfunction MapLoaded()\n  for i=0,7 do\n    if (Players[i].Type ~= PlayerNobody) then\n      if (Players[i]:GetUnitCount() == 0) then\n        CreateUnit(ConvertUnitType(\"unit-terran-command-center\", GetPlayerData(i, \"RaceName\")),\n          i, {Players[i].StartPos.x, Players[i].StartPos.y})\n        for j=0,3 do\n          CreateUnit(ConvertUnitType(\"unit-terran-scv\", GetPlayerData(i, \"RaceName\")),\n            i, {Players[i].StartPos.x + j, Players[i].StartPos.y + 3})\n        end\n      end\n    end\n  end\n\n  LoadUI(GetPlayerData(GetThisPlayer(), \"RaceName\"))\nend\n\n"
  },
  {
    "path": "scripts/sound.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      sound.lua - Define the used sounds.\n--\n--      (c) Copyright 2004-2007 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\n--  Uncomment this to enable threaded sound\n--SoundThread()\n\n------------------------------------------------------------------------------\n--  Music part\n\n------------------------------------------------------------------------------\n--  MusicStopped is called if the current music is finished.\n--\n--    This is a random music player demo\n--\n\nlocal playlist = {\n  \"music/title.ogg\"\n}\n\nfunction SetMusic(music)\n  if (music == \"menu\") then\n    playlist = {\"music/title.ogg\"}\n  elseif (music == \"terran\") then\n    playlist = {\n      \"music/terran/1.ogg\",\n      \"music/terran/2.ogg\",\n      \"music/terran/3.ogg\"\n    }\n  elseif (music == \"zerg\") then\n    playlist = {\n      \"music/zerg/1.ogg\",\n      \"music/zerg/2.ogg\",\n      \"music/zerg/3.ogg\"\n    }\n  elseif (music == \"protoss\") then\n    playlist = {\n      \"music/protoss/1.ogg\",\n      \"music/protoss/2.ogg\",\n      \"music/protoss/3.ogg\"\n    }\n  end\n  MusicStopped()\nend\n\nfunction MusicStopped()\n  if (table.getn(playlist) ~= 0) then\n    PlayMusic(playlist[math.random(table.getn(playlist))])\n  end\nend\n\n-- SetCdMode(\"off\")\nMakeSound(\"building-placed\", \"terran/building place.ogg\")\nMakeSound(\"button\", \"ui/button.ogg\")\nMakeSound(\"buzz\", \"ui/buzz.ogg\")\n\n-- Explosions\n\nMakeSound(\"explosion-large\", \"misc/explolrg.ogg\")\nMakeSound(\"explosion-medium\", \"misc/explomed.ogg\")\n\n\nLoad(\"scripts/terran/sound.lua\")\nLoad(\"scripts/zerg/sound.lua\")\nLoad(\"scripts/protoss/sound.lua\")\n\n\n------------------------------------------------------------------------------\n--  Define sound remapping. (FIXME: somebody must clean the order.)\n--\n--MapSound(\"peon-acknowledge\", \"basic orc voices acknowledge\")\n\n--  Define sounds used by game\n--\nDefineGameSounds(\n  \"placement-error\", {\"terran\", SoundForName(\"buzz\")},\n  \"placement-error\", {\"zerg\", SoundForName(\"buzz\")},\n  \"placement-error\", {\"protoss\", SoundForName(\"buzz\")},\n  \"placement-success\", {\"terran\", SoundForName(\"building-placed\")},\n  \"placement-success\", {\"zerg\", SoundForName(\"building-placed\")},\n  \"placement-success\", {\"protoss\", SoundForName(\"building-placed\")},\n  \"click\", SoundForName(\"button\")\n\n-- FIXME: Not ready\n--  \"transport-docking\",\n--  \"building-construction\",\n\n--  \"work-complete\", {\"terran\", MakeSound(\"basic terran voices work complete\", \"terran/units/scv/upd00.ogg\")},\n--  \"work-complete\", {\"orc\", MakeSound(\"basic orc voices work complete\", \"orc/basic_voices/work_complete.ogg\")},\n\n--  \"rescue\", {\"terran\", MakeSound(\"terran rescue\", \"terran/rescue.ogg\")},\n--  \"rescue\", {\"orc\", MakeSound(\"orc rescue\", \"orc/rescue.ogg\")}\n)\n\n--MakeSound(\"highclick\", \"ui/highclick.ogg\")\n--MakeSound(\"statsthump\", \"ui/statsthump.ogg\")\n"
  },
  {
    "path": "scripts/spells.lua",
    "content": "--       _________ __                 __\n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      spells.lua - The spells.\n--\n--      (c) Copyright 1998-2005 by Joris Dauphin and Jimmy Salmon.\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--\n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\n-- For documentation see stratagus/doc/ccl/ccl.html\n\nDefineBoolFlags(\"isundead\", \"organic\", \"hero\", \"volatile\", \"mechanical\")\n-- mechanical for goliath, tank, dragoon, etc. Can be repaired by the scv (terran), spawn broodling spell can only hit mechanical units\n--medics (broodwar) can heal organic units; marine, firebat, etc.\n\n--\n--  Speed     : just drawing\n--  ShadowFly : Shadow of flying unit (0:big, 1:normal, 2:small)\n--  Level     : Increase each time an upgrade is applyed to an unit.\n--\nDefineVariables(\"Speed\", \"Level\", \"LarvaTimeout\", {Max = 20})\n\n-- And declare upgrade for dependency...\n-- For human\nCUpgrade:New(\"upgrade-holy-vision\")\nCUpgrade:New(\"upgrade-healing\")\nCUpgrade:New(\"upgrade-exorcism\")\nCUpgrade:New(\"upgrade-flame-shield\")\nCUpgrade:New(\"upgrade-fireball\")\nCUpgrade:New(\"upgrade-slow\")\nCUpgrade:New(\"upgrade-invisibility\")\nCUpgrade:New(\"upgrade-polymorph\")\nCUpgrade:New(\"upgrade-blizzard\")\n-- For orc\nCUpgrade:New(\"upgrade-eye-of-kilrogg\")\nCUpgrade:New(\"upgrade-bloodlust\")\nCUpgrade:New(\"upgrade-raise-dead\")\nCUpgrade:New(\"upgrade-death-coil\")\nCUpgrade:New(\"upgrade-whirlwind\")\nCUpgrade:New(\"upgrade-haste\")\nCUpgrade:New(\"upgrade-unholy-armor\")\nCUpgrade:New(\"upgrade-runes\")\nCUpgrade:New(\"upgrade-death-and-decay\")\n\n"
  },
  {
    "path": "scripts/stratagus.lua",
    "content": "--       _________ __                 __\n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      stratagus.lua - The craft configuration language.\n--\n--      (c) Copyright 2005-2006 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\n-- For documentation see stratagus/doc/scripts/scripts.html\n--print(\"Stratagus default config file loading ...\\n\")\n\n-- Config file version\n--(define media-version (list 'wc2 'class 'wc2 'version '(1 18 0)))\n\n-------------------------------------------------------------------------------\n--  Version\n-------------------------------------------------------------------------------\n\nstargus = {}\n\nstargus.Name = \"Stargus\"\nstargus.Homepage = \"https://github.com/Wargus/stargus\"\nstargus.Copyright = \"(c) 1998-2021 by The Stratagus Project.\"\nstargus.Version = \"3.3.0\"\nstargus.Licence = \"GPL v2+\"\n\n\n-- activate debugging\npcall(function() require(\"scripts/mobdebug\").start() end)\n\n-------------------------------------------------------------------------------\n--  Config-Part\n-------------------------------------------------------------------------------\n\nInitFuncs = {}\nfunction InitFuncs:add(f)\n  table.insert(self, f)\nend\n\nfunction InitGameVariables()\n  for i=1,table.getn(InitFuncs) do\n    InitFuncs[i]()\n  end\nend\n\n--  Set the game name. It's used so we can mantain different savegames\n--  and setting. Might also be used for multiplayer.\nSetGameName(\"sc\")\nSetFullGameName(stargus.Name)\n\nLoad(\"preferences.lua\")\n\nif (preferences == nil) then\n  preferences = {\n    VideoWidth = 800,\n    VideoHeight = 600,\n    VideoFullScreen = false,\n    PlayerName = \"Player\",\n    FogOfWar = true,\n    ShowCommandKey = true,\n    GroupKeys = \"0123456789`\",\n    GameSpeed = 30,\n    EffectsEnabled = true,\n    EffectsVolume = 128,\n    MusicEnabled = true,\n    MusicVolume = 128,\n    StratagusTranslation = \"\",\n    GameTranslation = \"\",\n    TipNumber = 0,\n    ShowTips = true,\n    GrabMouse = false,\n    RapidStratagusIDE = false\n  }\nend\n\n-- nil this option to false if not given in users preferences\nif (preferences.RapidStratagusIDE == nil) then \n  preferences.RapidStratagusIDE = false\nend\n\n--  Edit the next sections to get your look and feel.\n--  Note, some of those values are overridden by user preferences,\n--  see preferences.lua\n\n--  Enter your default title screen.\nif (preferences.RapidStratagusIDE == false) then\n  SetTitleScreens(\n    {Image = \"videos/blizzard.ogv\"},\n    {Image = \"ui/title.png\", Music = \"music/title.ogg\",  Timeout = 5}\n  )\nend\n\nSetSelectionStyle(\"ellipse\", 0.589)\nPreference.ShowSightRange = false\nPreference.ShowAttackRange = false\nPreference.ShowReactionRange = false\n\nPreference.ShowOrders = 2\n\n-- SetMetaServer(\"stratagus.game-host.org\", 7775)\n\n--  Enable/disable the short display of the orders after command.\n--  FIXME: planned\n--(set-order-feedback! #t)\n--(set-order-feedback! #f)\n\n-------------------------------------------------------------------------------\n--  Game modification\n\n--  Edit this to enable/disable extended features.\n--    Currently enables some additional buttons.\nextensions = true\n--extensions = false\n\n--  Edit this to enable/disable the training queues.\nSetTrainingQueue(true)\n--SetTrainingQueue(false)\n\n--  Edit this to enable/disable building capture.\n--SetBuildingCapture(true)\nSetBuildingCapture(false)\n\n--  Edit this to enable/disable the reveal of the attacker.\n--SetRevealAttacker(true)\nSetRevealAttacker(true)\nSetRevelationType(\"all-units\")\n\n-------------------------------------------------------------------------------\n\n--  If you prefer fighters are attacking by right clicking empty space\n--  uncomment this (you must comment the next).\n--  FIXME: this option will be renamed\n--RightButtonAttacks()\n\n--  If you prefer fighters are moving by right clicking empty space\n--  uncomment this.\n--  FIXME: this option will be renamed\nRightButtonMoves()\n\n--  Set the name of the missile to use when clicking\nSetClickMissile(\"missile-green-cross\")\n\n--  Set the name of the missile to use when displaying damage\nSetDamageMissile(\"missile-hit\")\n\n--  Edit this to enable/disable grabbing the mouse.\nSetGrabMouse(false)\n\n--  Edit this to enable/disable stopping scrolling on mouse leave.\nSetLeaveStops(true)\n\n--  Edit this to enable/disable mouse scrolling.\nSetMouseScroll(true)\n--SetMouseScroll(false)\n\n--  Edit this to enable/disable keyboard scrolling.\nSetKeyScroll(true)\n--SetKeyScroll(false)\n\n--  While middle-mouse is pressed:\n--  Pixels to move per scrolled mouse pixel, negative = reversed\nSetMouseScrollSpeedDefault(4)\n\nSetKeyScrollSpeed(8);\n\n--  Same if Control is pressed\nSetMouseScrollSpeedControl(15)\n\n--  Change next, for the wanted double-click delay (in ms).\nSetDoubleClickDelay(300)\n\n--  Change next, for the wanted hold-click delay (in ms).\nSetHoldClickDelay(1000)\n\n--  Uncomment next, to reveal the complete map.\nRevealMap(\"known\")\n\n--  Choose your default fog of war state (enabled #t/disabled #f).\n--    disabled is a C&C like fog of war.\nSetFogOfWar(true)\n--SetFogOfWar(false)\nSetFogOfWarBlur(2.0, 1.5, 3) -- radiuses for simple and bilinear FOW postprocessing, number of blur iterations\n-- Set opacity levels of fog for explored, \"known\"(when map revealed) and hidden tiles\nSetFogOfWarOpacityLevels(0x7F, 0xBE, 0xFE)\n-- Set opacity levels of fog for explored, \"known\"(when map revealed) and hidden tiles in the minimap\nSetMMFogOfWarOpacityLevels(0x55, 0xAA, 0xFF) -- default values\n\nSetFogOfWarType(\"enhanced\") -- set to \"fast\", \"tiled\", or \"enhanced\"\nSetFogOfWarBilinear(true)\n\n-- Define the factor when computer AI reacts relative to sight of a unit\nComputerReactionRangeFactor = 1.5\n\n-- Define the factor when person AI reacts relative to sight of a unit\nPersonReactionRangeFactor = 0.8\n\nif CanAccessFile(\"tilesets/fog.png\") then\n  SetFogOfWarGraphics(\"tilesets/fog.png\")\nelse\n  SetFogOfWarGraphics(\"contrib/fog.png\")\nend\n\n-- path finding debug option only!\nSetEnableMapGrid(false)\n\nSetTileSize(8, 8)\n\n--  Choose your default for minimap with/without terrain.\nSetMinimapTerrain(true)\n--SetMinimapTerrain(false)\n\nPreference.GrayscaleIcons = true\n\n-- Western European Codepage\nSetFontCodePage(1252)\n\n-- Maximum fps for portraits and other animations\nMng.MaxFPS = 15\n\n-------------------------------------------------------------------------------\n\n--  Define default resources\n\n-- FIXME: Must be removed: Use and write (define-resource)\n--\n--  (define-resource 'gold 'name \"Gold\"\n--    'start-resource-default 2000\n--    'start-resource-low 2000\n--    'start-resource-medium 5000\n--    'start-resource-high 10000\n--    'income 100)\n--  FIXME: Must describe how geting resources work.\n--\n\nDefineDefaultIncomes(\n  0, 100, 100, 100, 100, 100, 100)\n\nDefineDefaultActions(\n  \"stop\", \"harvest\", \"harvest\", \"unused\", \"unused\", \"unused\", \"unused\")\n\nDefineDefaultResourceNames(\n  \"time\", \"minerals\", \"gas\", \"unused\", \"unused\", \"unused\", \"unused\")\n\nDefineDefaultResourceAmounts(\n  \"minerals\", 100000,\n  \"gas\", 50000)\n\nDefineDefaultResourceMaxAmounts(-1, -1, -1, -1, -1, -1)\n  \n-------------------------------------------------------------------------------\n\nDefinePlayerColorIndex(8, 8)\n\nDefinePlayerColors({\n  \"red\", {{244, 4, 4}, {168, 8, 8}, {168, 8, 8}, {132, 4, 4},\n    {96, 0, 0}, {72, 0, 0}, {52, 0, 0}, {16, 0, 0}},\n  \"blue\", {{12, 72, 204}, {8, 52, 152}, {8, 52, 152}, {20, 52, 124},\n    {4, 32, 100}, {0, 8, 80}, { 0, 16, 52}, { 0, 0, 24}},\n  \"green\", {{44, 180, 148}, {32, 144, 112}, {32, 144, 112}, {32, 144, 112},\n    {16, 84, 60}, {16, 84, 60}, {16, 84, 60}, {0, 40, 0}},\n  \"violet\", {{136, 64, 156}, {136, 64, 156}, {136, 64, 156}, {104, 48, 120},\n    {72, 28, 80}, {72, 28, 80}, {72, 28, 80}, {56, 16, 32}},\n  \"orange\", {{248, 140, 20}, {232, 120, 36}, {188, 104, 36}, {160, 84, 28},\n    {124, 64, 24}, {92, 44, 20}, {52, 32, 12}, {28, 16, 8}},\n  \"black\", {{112, 48, 20}, {92, 44, 20}, {92, 44, 20}, {68, 52, 8},\n    {68, 52, 8}, {52, 32, 12}, {52, 16, 8}, {28, 16, 8}},\n  \"white\", {{204, 224, 208}, {196, 192, 188}, {176, 176, 176}, {152, 148, 140},\n    {132, 116, 116}, {88, 88, 104}, {68, 68, 68}, {40, 40, 48}},\n  \"yellow\", {{252, 252, 56}, {220, 220, 60}, {188, 184, 52}, {156, 144, 64},\n    {112, 100, 32}, {92, 84, 20}, {68, 52, 8}, {28, 16, 8}},\n\n  \"green\", {{8, 128, 8}, {0, 100, 0}, {0, 100, 0}, {0, 100, 0},\n    {0, 68, 0}, {0, 68, 0}, {0, 68, 0}, {0, 40, 0}},\n  \"light-yellow\", {{252, 252, 124}, {252, 252, 124}, {204, 184, 96}, {188, 164, 92},\n    {156, 144, 64}, {116, 104, 56}, {104, 76, 52}, {56, 48, 36}},\n  \"green\", {{44, 180, 148}, {20, 132, 92}, {4, 84, 44}, {0, 40, 12},\n    {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},\n  \"violet\", {{152, 72, 176}, {116, 44, 132}, {80, 24, 88}, {44, 8, 44},\n    {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},\n  \"orange\", {{248, 140, 20}, {200, 96, 16}, {152, 60, 16}, {108, 32, 12},\n    {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},\n  \"black\", {{40, 40, 60}, {28, 28, 44}, {20, 20, 32}, {12, 12, 20},\n    {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},\n  \"white\", {{224, 224, 224}, {152, 152, 180}, {84, 84, 128}, {36, 40, 76},\n    {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},\n  \"yellow\", {{252, 252, 72}, {228, 204, 40}, {204, 160, 16}, {180, 116, 0},\n    {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},\n})\n\n\n-------------------------------------------------------------------------------\n\n--  Edit next to increase the speed, for debugging.\n\n--  Decrease the mining time by this factor.\n--SetSpeedResourcesHarvest(\"gold\", 10)\n--  Decrease the time in a gold deposit by this factor.\n--SetSpeedResourcesReturn(\"gold\", 10)\n--  Decrease the time for chopping a tree by this factor.\n--SetSpeedResourcesHarvest(\"wood\", 10)\n--  Decrease the time in a wood deposit by this factor.\n--SetSpeedResourcesReturn(\"wood\", 10)\n--  Decrease the time for haul oil by this factor.\n--SetSpeedResourcesHarvest(\"oil\", 10)\n--  Decrease the time in an oil deposit by this factor.\n--SetSpeedResourcesReturn(\"oil\", 10)\n--  Decrease the time to build a unit by this factor.\n--SetSpeedBuild(10)\n--  Decrease the time to train a unit by this factor.\n--SetSpeedTrain(10)\n--  Decrease the time to upgrade a unit by this factor.\n--SetSpeedUpgrade(10)\n--  Decrease the time to research by this factor.\n--SetSpeedResearch(10)\n\n--  You can do all the above with this\nInitFuncs:add(function()\n  SetSpeeds(1)\nend)\n\n-------------------------------------------------------------------------------\n\nAStar(\"fixed-unit-cost\", 1000,\n      \"moving-unit-cost\", 20,\n      \"dont-know-unseen-terrain\",\n      \"unseen-terrain-cost\", 2)\n\n-------------------------------------------------------------------------------\n\n--  All player food unit limit\nSetAllPlayersUnitLimit(400)\n--  All player building limit\nSetAllPlayersBuildingLimit(400)\n--  All player total unit limit\nSetAllPlayersTotalUnitLimit(1000)\n\n-------------------------------------------------------------------------------\n--  Default triggers for single player\n--    (FIXME: must be combined with game types)\n\nfunction SinglePlayerTriggers()\n  function SinglePlayerTriggers()\n    AddTrigger(\n      function() return GetPlayerData(GetThisPlayer(), \"TotalNumUnits\") == 0 end,\n      function() return ActionDefeat() end)\n  \n    AddTrigger(\n      function() return GetNumOpponents(GetThisPlayer()) == 0 end,\n      function() return ActionVictory() end)\n  end\nend\n\n-------------------------------------------------------------------------------\n--  Tables-Part\n-------------------------------------------------------------------------------\n\nSetVideoResolution(preferences.VideoWidth, preferences.VideoHeight)\nSetVideoFullScreen(preferences.VideoFullScreen)\nSetLocalPlayerName(preferences.PlayerName)\nSetFogOfWar(preferences.FogOfWar)\nUI.ButtonPanel.ShowCommandKey = preferences.ShowCommandKey\nSetGroupKeys(preferences.GroupKeys)\nSetGameSpeed(preferences.GameSpeed)\nSetEffectsEnabled(preferences.EffectsEnabled)\nSetEffectsVolume(preferences.EffectsVolume)\nSetMusicEnabled(preferences.MusicEnabled)\nSetMusicVolume(preferences.MusicVolume)\nSetTranslationsFiles(preferences.StratagusTranslation, preferences.GameTranslation)\nSetGrabMouse(preferences.GrabMouse)\n\n--- Uses Stratagus Library path!\nLoad(\"scripts/sc.lua\")\nLoad(\"scripts/icons.lua\")\nLoad(\"scripts/sound.lua\")\nLoad(\"scripts/missiles.lua\")\nLoad(\"scripts/spells.lua\")\nLoad(\"scripts/units.lua\")\nLoad(\"scripts/upgrade.lua\")\nLoad(\"scripts/fonts.lua\")\nLoad(\"scripts/buttons.lua\")\nLoad(\"scripts/ui.lua\")\nLoad(\"scripts/ai.lua\")\nLoad(\"scripts/commands.lua\")\nLoad(\"scripts/cheats.lua\")\n\n\n\n--print(\"... ready!\\n\")\n"
  },
  {
    "path": "scripts/terran/campaign1.lua",
    "content": "campaign_steps = {}\ncampaign_menu = {}\n\ncampaign_steps[#campaign_steps + 1] = function() RunImageStep(\"campaigns/terran/EstT0t.txt\", i) end\ncampaign_menu[#campaign_menu + 1] = #campaign_steps\ncampaign_steps[#campaign_steps + 1] = CreateMapStep(\"campaigns/terran/tutorial/scenario.smp\")\n\nfor i=1,12 do\n  campaign_steps[#campaign_steps + 1] = function() RunImageStep(string.format(\"campaigns/terran/EstT%02d.txt\", i)) end\n  campaign_menu[#campaign_menu + 1] = #campaign_steps\n  campaign_steps[#campaign_steps + 1] = CreateMapStep(string.format(\"campaigns/terran/%02d/scenario.smp\", i))\nend\n"
  },
  {
    "path": "scripts/terran/icons.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      icons.lua - Define the icons.\n--\n--      (c) Copyright 2005 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nlocal terran_icons = {\n  {\"icon-terran-marine\", 0},\n  {\"icon-terran-ghost\", 1},\n  {\"icon-terran-vulture\", 2},\n  {\"icon-terran-goliath\", 3},\n  {\"icon-terran-tank\", 5},\n  {\"icon-terran-scv\", 7},\n  {\"icon-terran-wraith\", 8},\n  {\"icon-terran-science-vessel\", 9},\n  {\"icon-terran-gui-montang\", 10},\n  {\"icon-terran-dropship\", 11},\n  {\"icon-terran-battlecruiser\", 12},\n  {\"icon-terran-vulture-spider-mine\", 13},\n  {\"icon-terran-nuclear-missile\", 14},\n  {\"icon-terran-terran-civilian\", 15},\n  {\"icon-terran-sarah-kerrigan\", 16},\n  {\"icon-terran-jim-raynor-vulture\", 19},\n  {\"icon-terran-jim-raynor-marine\", 20},\n  {\"icon-terran-siege-tank\", 31},\n  {\"icon-terran-firebat\", 32},\n  {\"icon-terran-command-center\", 106},\n  {\"icon-terran-comsat-station\", 107},\n  {\"icon-terran-nuclear-silo\", 108},\n  {\"icon-terran-supply-depot\", 109},\n  {\"icon-terran-refinery\", 110},\n  {\"icon-terran-barracks\", 111},\n  {\"icon-terran-academy\", 112},\n  {\"icon-terran-factory\", 113},\n  {\"icon-terran-starport\", 114},\n  {\"icon-terran-control-tower\", 115},\n  {\"icon-terran-science-facility\", 116},\n  {\"icon-terran-covert-ops\", 117},\n  {\"icon-terran-physics-lab\", 118},\n  {\"icon-terran-machine-shop\", 120},\n  {\"icon-terran-engineering-bay\", 122},\n  {\"icon-terran-armory\", 123},\n  {\"icon-terran-missile-turret\", 124},\n  {\"icon-terran-bunker\", 125},\n  {\"icon-terran-stim-pack\", 237},\n  {\"icon-terran-u238-shells\", 238},\n  {\"icon-terran-emp-shockwave\", 241},\n  {\"icon-terran-irradiate\", 242},\n  {\"icon-terran-spider-mines\", 243},\n  {\"icon-terran-siege-tank\", 245},\n  {\"icon-terran-titan-reactor\", 248},\n  {\"icon-terran-scanner-sweep\", 250},\n  {\"icon-terran-yamato-gun\", 251},\n  {\"icon-terran-cloak\", 252},\n  {\"icon-terran-liftoff\", 282},\n  {\"icon-terran-land\", 283},\n  {\"icon-terran-apollo-reactor\", 284},\n  {\"icon-terran-colossus-reactor\", 285},\n  {\"icon-terran-ion-thrusters\", 287},\n  {\"icon-terran-upgrade-infantry-weapons\", 288},\n  {\"icon-terran-upgrade-vehicle-weapons\", 289},\n  {\"icon-terran-upgrade-ship-weapons\", 290},\n  {\"icon-terran-upgrade-ship-plating\", 291},\n  {\"icon-terran-upgrade-infantry-armor\", 292},\n  {\"icon-terran-upgrade-ship-plating\", 293},\n  {\"icon-terran-nuke\", 311},\n}\n\nlocal pos = table.getn(icons) + 1\n\nfor i = 1,table.getn(terran_icons) do\n  icons[pos] = terran_icons[i]\n  pos = pos + 1\nend\n\n\n"
  },
  {
    "path": "scripts/terran/missiles.lua",
    "content": "--\n--  Missiles\n--\n\nDefineMissileType(\"missile-terran-explosion-small\", {\n  File = image_213_thingy_tbangs_file, Size = image_213_thingy_tbangs_size,\n  Frames = 9, NumDirections = image_213_thingy_tbangs_NumDirections, DrawLevel = 50,\n  Class = \"missile-class-stay\", Sleep = 2,\n})\n\nDefineMissileType(\"missile-terran-explosion-medium\", {\n  File = image_214_thingy_tbangl_file, Size = image_214_thingy_tbangl_size,\n  Frames = 10, NumDirections = image_214_thingy_tbangl_NumDirections, DrawLevel = 50,\n  Class = \"missile-class-stay\", Sleep = 2,\n})\n\nDefineMissileType(\"missile-terran-explosion-large\", {\n  File = image_215_thingy_tbangx_file, Size = image_215_thingy_tbangx_size,\n  Frames = 14, NumDirections = image_215_thingy_tbangx_NumDirections, DrawLevel = 50,\n  Class = \"missile-class-stay\", Sleep = 2,\n})\n\nDefineMissileType(\"missile-terran-firebat-flame\", {\n  File = image_421_thingy_flamer_file, Size = image_421_thingy_flamer_size,\n  Frames = 221, NumDirections = image_421_thingy_flamer_NumDirections, DrawLevel = 50,\n  SplashFactor = 10;\n  Class = \"missile-class-point-to-point\", Sleep = 1, Speed = 4, Range = 2,\n})\n\nDefineMissileType(\"missile-terran-vulture-grenade\", {\n  File = image_532_bullet_grenade_file, Size = image_532_bullet_grenade_size,\n  Frames = 4, NumDirections = image_532_bullet_grenade_NumDirections, DrawLevel = 50,\n  Class = \"missile-class-point-to-point\", Sleep = 1, Speed = 4, Range = 2,\n})\n\n-- FIXME: wrong graphic\nDefineMissileType(\"missile-terran-battlecruiser-laser\", {\n  File = image_534_thingy_elbfire_file, Size = image_534_thingy_elbfire_size,\n  Frames = 17, NumDirections = image_534_thingy_elbfire_NumDirections, DrawLevel = 50,\n  Class = \"missile-class-point-to-point-with-hit\", Sleep = 1, Speed = 4, Range = 2,\n})\n\n-- FIXME: wrong graphic\nDefineMissileType(\"missile-terran-wraith-laser\", {\n  File = image_535_thingy_elbfirew_file, Size = image_535_thingy_elbfirew_size,\n  Frames = 17, NumDirections = image_535_thingy_elbfirew_NumDirections, DrawLevel = 50,\n  Class = \"missile-class-point-to-point\", Sleep = 1, Speed = 4, Range = 2,\n})\n\n"
  },
  {
    "path": "scripts/terran/sound.lua",
    "content": "-- Basic Terran sounds\n\nMakeSound(\"terran-base-attacked\", \"terran/units/advisor/upd00.ogg\")\nMakeSound(\"terran-units-attacked\", \"terran/units/advisor/upd01.ogg\")\n\n-- Marine sounds\n\nMakeSound(\"terran-marine-ready\", \"terran/units/marine/ready.ogg\")\nMakeSound(\"terran-marine-death\",\n  {\"terran/units/marine/death/1.ogg\",\n  \"terran/units/marine/death/2.ogg\"})\n\nMakeSound(\"terran-marine-attack\", \"terran/units/marine/fire.ogg\")\n\nMakeSound(\"terran-marine-acknowledge\",\n  {\"terran/units/marine/acknowledgement/1.ogg\",\n  \"terran/units/marine/acknowledgement/2.ogg\",\n  \"terran/units/marine/acknowledgement/3.ogg\",\n  \"terran/units/marine/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-marine-select\",\n  {\"terran/units/marine/selected/1.ogg\",\n  \"terran/units/marine/selected/2.ogg\",\n  \"terran/units/marine/selected/3.ogg\",\n  \"terran/units/marine/selected/4.ogg\"})\n\nMakeSound(\"terran-marine-annoyed\",\n  {\"terran/units/marine/pissed/1.ogg\",\n  \"terran/units/marine/pissed/2.ogg\",\n  \"terran/units/marine/pissed/3.ogg\",\n  \"terran/units/marine/pissed/4.ogg\",\n  \"terran/units/marine/pissed/5.ogg\",\n  \"terran/units/marine/pissed/6.ogg\",\n  \"terran/units/marine/pissed/7.ogg\"})\n\nMakeSoundGroup(\"terran-marine-selected\",\n  \"terran-marine-select\", \"terran-marine-annoyed\")\n\n-- Firebat sounds\n\nMakeSound(\"terran-firebat-ready\", \"terran/units/firebat/ready.ogg\")\nMakeSound(\"terran-firebat-death\",\n  {\"terran/units/firebat/death/1.ogg\",\n  \"terran/units/firebat/death/2.ogg\",\n  \"terran/units/firebat/death/3.ogg\"})\n\nMakeSound(\"terran-firebat-attack\",\n  {\"terran/units/firebat/fire1.ogg\",\n  \"terran/units/firebat/fire2.ogg\"})\n\nMakeSound(\"terran-firebat-acknowledge\",\n  {\"terran/units/firebat/acknowledgement/1.ogg\",\n  \"terran/units/firebat/acknowledgement/2.ogg\",\n  \"terran/units/firebat/acknowledgement/3.ogg\",\n  \"terran/units/firebat/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-firebat-select\",\n  {\"terran/units/firebat/selected/1.ogg\",\n  \"terran/units/firebat/selected/2.ogg\",\n  \"terran/units/firebat/selected/3.ogg\",\n  \"terran/units/firebat/selected/4.ogg\"})\n\nMakeSound(\"terran-firebat-annoyed\",\n  {\"terran/units/firebat/pissed/1.ogg\",\n  \"terran/units/firebat/pissed/2.ogg\",\n  \"terran/units/firebat/pissed/3.ogg\",\n  \"terran/units/firebat/pissed/4.ogg\",\n  \"terran/units/firebat/pissed/5.ogg\",\n  \"terran/units/firebat/pissed/6.ogg\",\n  \"terran/units/firebat/pissed/7.ogg\"})\n\nMakeSoundGroup(\"terran-firebat-selected\",\n  \"terran-firebat-select\", \"terran-firebat-annoyed\")\n\n-- Ghost sounds\n\nMakeSound(\"terran-ghost-ready\", \"terran/units/ghost/ready.ogg\")\nMakeSound(\"terran-ghost-death\",\n  {\"terran/units/ghost/death/1.ogg\",\n  --[[\"terran/units/ghost/death/2.ogg\"]]})\n\nMakeSound(\"terran-ghost-attack\",\n  {\"terran/units/ghost/fire.ogg\"})\n\nMakeSound(\"terran-ghost-acknowledge\",\n  {\"terran/units/ghost/acknowledgement/1.ogg\",\n  \"terran/units/ghost/acknowledgement/2.ogg\",\n  \"terran/units/ghost/acknowledgement/3.ogg\",\n  \"terran/units/ghost/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-ghost-select\",\n  {\"terran/units/ghost/selected/1.ogg\",\n  \"terran/units/ghost/selected/2.ogg\",\n  \"terran/units/ghost/selected/3.ogg\",\n  \"terran/units/ghost/selected/4.ogg\"})\n\nMakeSound(\"terran-ghost-annoyed\",\n  {\"terran/units/ghost/pissed/1.ogg\",\n  \"terran/units/ghost/pissed/2.ogg\",\n  \"terran/units/ghost/pissed/3.ogg\",\n  \"terran/units/ghost/pissed/4.ogg\"})\n\nMakeSoundGroup(\"terran-ghost-selected\",\n  \"terran-ghost-select\", \"terran-ghost-annoyed\")\n\n-- Goliath sounds\n\nMakeSound(\"terran-goliath-ready\", \"terran/units/goliath/ready.ogg\")\nMakeSound(\"terran-goliath-death\", \"terran/units/goliath/death/1.ogg\")\n\nMakeSound(\"terran-goliath-attack\",\n  {\"terran/units/goliath/fire.ogg\",\n  \"terran/units/goliath/fire2.ogg\"})\n\nMakeSound(\"terran-goliath-acknowledge\",\n  {\"terran/units/goliath/acknowledgement/1.ogg\",\n  \"terran/units/goliath/acknowledgement/2.ogg\",\n  \"terran/units/goliath/acknowledgement/3.ogg\",\n  \"terran/units/goliath/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-goliath-select\",\n  {\"terran/units/goliath/selected/1.ogg\",\n  \"terran/units/goliath/selected/2.ogg\",\n  \"terran/units/goliath/selected/3.ogg\",\n  \"terran/units/goliath/selected/4.ogg\"})\n\nMakeSound(\"terran-goliath-annoyed\",\n  {\"terran/units/goliath/pissed/1.ogg\",\n  \"terran/units/goliath/pissed/2.ogg\",\n  \"terran/units/goliath/pissed/3.ogg\",\n  \"terran/units/goliath/pissed/4.ogg\",\n  \"terran/units/goliath/pissed/5.ogg\",\n  \"terran/units/goliath/pissed/6.ogg\"})\n\nMakeSoundGroup(\"terran-goliath-selected\",\n  \"terran-goliath-select\", \"terran-goliath-annoyed\")\n\n-- Siege tank sounds\n\nMakeSound(\"terran-siege-tank-ready\", \"terran/units/tank/ready.ogg\")\nMakeSound(\"terran-siege-tank-death\", \"terran/units/tank/death/1.ogg\")\n\nMakeSound(\"terran-siege-tank-attack\", \"terran/units/tank/fire.ogg\")\n\nMakeSound(\"terran-siege-tank-acknowledge\",\n  {\"terran/units/tank/acknowledgement/1.ogg\",\n  \"terran/units/tank/acknowledgement/2.ogg\",\n  \"terran/units/tank/acknowledgement/3.ogg\",\n  \"terran/units/tank/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-siege-tank-select\",\n  {\"terran/units/tank/selected/1.ogg\",\n  \"terran/units/tank/selected/2.ogg\",\n  \"terran/units/tank/selected/3.ogg\",\n  \"terran/units/tank/selected/4.ogg\"})\n\nMakeSound(\"terran-siege-tank-annoyed\",\n  {\"terran/units/tank/pissed/1.ogg\",\n  \"terran/units/tank/pissed/2.ogg\",\n  \"terran/units/tank/pissed/3.ogg\",\n  \"terran/units/tank/pissed/4.ogg\"})\n\nMakeSoundGroup(\"terran-siege-tank-selected\",\n  \"terran-siege-tank-select\", \"terran-siege-tank-annoyed\")\n\n-- SCV sounds\n\nMakeSound(\"terran-scv-ready\", \"terran/units/scv/ready.ogg\")\nMakeSound(\"terran-scv-death\", \"terran/units/scv/death/1.ogg\")\nMakeSound(\"terran-scv-done\", \"terran/units/scv/upd00.ogg\")\nMakeSound(\"terran-scv-attack\", \"terran/units/scv/edrrep00.ogg\")\n\nMakeSound(\"terran-scv-acknowledge\",\n  {\"terran/units/scv/acknowledgement/1.ogg\",\n  \"terran/units/scv/acknowledgement/2.ogg\",\n  \"terran/units/scv/acknowledgement/3.ogg\",\n  \"terran/units/scv/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-scv-select\",\n  {\"terran/units/scv/selected/1.ogg\",\n  \"terran/units/scv/selected/2.ogg\",\n  \"terran/units/scv/selected/3.ogg\",\n  \"terran/units/scv/selected/4.ogg\"})\n\nMakeSound(\"terran-scv-annoyed\",\n  {\"terran/units/scv/pissed/1.ogg\",\n  \"terran/units/scv/pissed/2.ogg\",\n  \"terran/units/scv/pissed/3.ogg\",\n  \"terran/units/scv/pissed/4.ogg\",\n  \"terran/units/scv/pissed/5.ogg\",\n  \"terran/units/scv/pissed/6.ogg\",\n  \"terran/units/scv/pissed/7.ogg\"})\n\nMakeSoundGroup(\"terran-scv-selected\",\n  \"terran-scv-select\", \"terran-scv-annoyed\")\n\n-- Vulture sounds\n\nMakeSound(\"terran-vulture-ready\", \"terran/units/vulture/ready.ogg\")\nMakeSound(\"terran-vulture-death\", \"terran/units/vulture/death/1.ogg\")\nMakeSound(\"terran-vulture-attack\", \"terran/units/vulture/fire.ogg\")\n\nMakeSound(\"terran-vulture-acknowledge\",\n  {\"terran/units/vulture/acknowledgement/1.ogg\",\n  \"terran/units/vulture/acknowledgement/2.ogg\",\n  \"terran/units/vulture/acknowledgement/3.ogg\",\n  \"terran/units/vulture/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-vulture-select\",\n  {\"terran/units/vulture/selected/1.ogg\",\n  \"terran/units/vulture/selected/2.ogg\",\n  \"terran/units/vulture/selected/3.ogg\",\n  \"terran/units/vulture/selected/4.ogg\"})\n\nMakeSound(\"terran-vulture-annoyed\",\n  {\"terran/units/vulture/pissed/1.ogg\",\n  \"terran/units/vulture/pissed/2.ogg\",\n  \"terran/units/vulture/pissed/3.ogg\",\n  \"terran/units/vulture/pissed/4.ogg\"})\n\nMakeSoundGroup(\"terran-vulture-selected\",\n  \"terran-vulture-select\", \"terran-vulture-annoyed\")\n\n-- Dropship sounds\n\nMakeSound(\"terran-dropship-ready\", \"terran/units/dropship/ready.ogg\")\nMakeSound(\"terran-dropship-death\", {\"terran/units/dropship/death/1.ogg\"})\n\nMakeSound(\"terran-dropship-acknowledge\",\n  {\"terran/units/dropship/acknowledgement/1.ogg\",\n  \"terran/units/dropship/acknowledgement/2.ogg\",\n  \"terran/units/dropship/acknowledgement/3.ogg\",\n  \"terran/units/dropship/acknowledgement/4.ogg\",\n  \"terran/units/dropship/acknowledgement/5.ogg\",\n  \"terran/units/dropship/acknowledgement/6.ogg\"})\n\nMakeSound(\"terran-dropship-select\",\n  {\"terran/units/dropship/selected/1.ogg\",\n  \"terran/units/dropship/selected/2.ogg\",\n  \"terran/units/dropship/selected/3.ogg\",\n  \"terran/units/dropship/selected/4.ogg\"})\n\nMakeSound(\"terran-dropship-annoyed\",\n  {\"terran/units/dropship/pissed/1.ogg\",\n  \"terran/units/dropship/pissed/2.ogg\",\n  \"terran/units/dropship/pissed/3.ogg\",\n  \"terran/units/dropship/pissed/4.ogg\"})\n\nMakeSoundGroup(\"terran-dropship-selected\",\n  \"terran-dropship-select\", \"terran-dropship-annoyed\")\n\n--- Science Vessel sounds\n\nMakeSound(\"terran-science-vessel-ready\", \"terran/units/science vessel/ready.ogg\")\nMakeSound(\"terran-science-vessel-death\", \"terran/units/science vessel/death/1.ogg\")\nMakeSound(\"terran-science-vessel-attack\", \"terran/units/science vessel/irr00.ogg\")\n\nMakeSound(\"terran-science-vessel-acknowledge\",\n  {\"terran/units/science vessel/acknowledgement/1.ogg\",\n  \"terran/units/science vessel/acknowledgement/2.ogg\",\n  \"terran/units/science vessel/acknowledgement/3.ogg\",\n  \"terran/units/science vessel/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-science-vessel-select\",\n  {\"terran/units/science vessel/selected/1.ogg\",\n  \"terran/units/science vessel/selected/2.ogg\",\n  \"terran/units/science vessel/selected/3.ogg\",\n  \"terran/units/science vessel/selected/4.ogg\"})\n\nMakeSound(\"terran-science-vessel-annoyed\",\n  {\"terran/units/science vessel/pissed/1.ogg\",\n  \"terran/units/science vessel/pissed/2.ogg\",\n  \"terran/units/science vessel/pissed/3.ogg\",\n  \"terran/units/science vessel/pissed/4.ogg\",\n  \"terran/units/science vessel/pissed/5.ogg\",\n  \"terran/units/science vessel/pissed/6.ogg\",\n  \"terran/units/science vessel/pissed/7.ogg\"})\n\nMakeSoundGroup(\"terran-science-vessel-selected\",\n  \"terran-science-vessel-select\", \"terran-science-vessel-annoyed\")\n\n--- Wraith sounds\n\nMakeSound(\"terran-wraith-ready\", \"terran/units/wraith/ready.ogg\")\nMakeSound(\"terran-wraith-death\", \"terran/units/wraith/death/1.ogg\")\nMakeSound(\"terran-wraith-attack\", \"terran/units/wraith/fire100.ogg\")\n\nMakeSound(\"terran-wraith-acknowledge\",\n  {\"terran/units/wraith/acknowledgement/1.ogg\",\n  \"terran/units/wraith/acknowledgement/2.ogg\",\n  \"terran/units/wraith/acknowledgement/3.ogg\",\n  \"terran/units/wraith/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-wraith-select\",\n  {\"terran/units/wraith/selected/1.ogg\",\n  \"terran/units/wraith/selected/2.ogg\",\n  \"terran/units/wraith/selected/3.ogg\",\n  \"terran/units/wraith/selected/4.ogg\"})\n\nMakeSound(\"terran-wraith-annoyed\",\n  {\"terran/units/wraith/pissed/1.ogg\",\n  \"terran/units/wraith/pissed/2.ogg\",\n  \"terran/units/wraith/pissed/3.ogg\",\n  \"terran/units/wraith/pissed/4.ogg\",\n  \"terran/units/wraith/pissed/5.ogg\",\n  \"terran/units/wraith/pissed/6.ogg\",\n  \"terran/units/wraith/pissed/7.ogg\"})\n\nMakeSoundGroup(\"terran-wraith-selected\",\n  \"terran-wraith-select\", \"terran-wraith-annoyed\")\n\n--- Battlecruiser sounds\n\nMakeSound(\"terran-battlecruiser-ready\", \"terran/units/battlecruiser/ready.ogg\")\nMakeSound(\"terran-battlecruiser-death\", \"terran/units/battlecruiser/death/1.ogg\")\nMakeSound(\"terran-battlecruiser-attack\", \"terran/units/battlecruiser/yamato.ogg\")\n\nMakeSound(\"terran-battlecruiser-acknowledge\",\n  {\"terran/units/battlecruiser/acknowledgement/1.ogg\",\n  \"terran/units/battlecruiser/acknowledgement/2.ogg\",\n  \"terran/units/battlecruiser/acknowledgement/3.ogg\",\n  \"terran/units/battlecruiser/acknowledgement/4.ogg\"})\n\nMakeSound(\"terran-battlecruiser-select\",\n  {\"terran/units/battlecruiser/selected/1.ogg\",\n  \"terran/units/battlecruiser/selected/2.ogg\",\n  \"terran/units/battlecruiser/selected/3.ogg\",\n  \"terran/units/battlecruiser/selected/4.ogg\"})\n\nMakeSound(\"terran-battlecruiser-annoyed\",\n  {\"terran/units/battlecruiser/pissed/1.ogg\",\n  \"terran/units/battlecruiser/pissed/2.ogg\",\n  \"terran/units/battlecruiser/pissed/3.ogg\",\n  \"terran/units/battlecruiser/pissed/4.ogg\",\n  \"terran/units/battlecruiser/pissed/5.ogg\"})\n\nMakeSoundGroup(\"terran-battlecruiser-selected\",\n  \"terran-battlecruiser-select\", \"terran-battlecruiser-annoyed\")\n\n-- Terran buildings\n\nMakeSound(\"terran-academy-selected\", \"terran/units/academy.ogg\")\nMakeSound(\"terran-armory-selected\", \"terran/units/armory.ogg\")\nMakeSound(\"terran-supply-depot-selected\", \"terran/units/supply depot.ogg\")\nMakeSound(\"terran-missile-turret-selected\", \"terran/units/missile turret.ogg\")\nMakeSound(\"terran-engineering-bay-selected\", \"terran/units/engineering bay.ogg\")\nMakeSound(\"terran-factory-selected\", \"terran/units/factory.ogg\")\nMakeSound(\"terran-refinery-selected\", \"terran/units/refinery.ogg\")\nMakeSound(\"terran-science-facility-selected\", \"terran/units/science facility.ogg\")\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-academy.lua",
    "content": "--\n-- unit-terran-academy\n--\n\nDefineAnimations(\"animations-terran-academy\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Research = {--[[FIXME: active overlay 264]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-academy\", {\n  Files = image_327_terran_tbldmed_var,\n  ShadowFiles = image_327_terran_tbldmed_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-academy\", {\n  Animations = \"animations-terran-academy\", Icon = \"icon-terran-academy\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-academy\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"terran-academy-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\nCUpgrade:New(\"upgrade-terran-u238-shells\")\nCUpgrade:New(\"upgrade-terran-stim-pack\")\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-u238-shells\",\n  Action = \"research\", Value = \"upgrade-terran-u238-shells\",\n  Allowed = \"check-single-research\",\n  Key = \"u\", Hint = \"Research ~!U-238 Shells\",\n  ForUnit = {\"unit-terran-academy\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-terran-stim-pack\",\n  Action = \"research\", Value = \"upgrade-terran-stim-pack\",\n  Allowed = \"check-single-research\",\n  Key = \"t\", Hint = \"Research S~!tim Pack Tech\",\n  ForUnit = {\"unit-terran-academy\"} } )\n"
  },
  {
    "path": "scripts/terran/unit-terran-armory.lua",
    "content": "--\n-- unit-terran-armory\n--\n\nDefineAnimations(\"animations-terran-armory\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Research = {--[[FIXME: active overlay 269]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-armory\", {\n  Files = image_327_terran_tbldmed_var,\n  ShadowFiles = image_327_terran_tbldmed_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-armory\", {\n  Animations = \"animations-terran-armory\", Icon = \"icon-terran-armory\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-armory\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"terran-armory-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n"
  },
  {
    "path": "scripts/terran/unit-terran-barracks.lua",
    "content": "--\n-- unit-terran-barracks\n--\n\nDefineAnimations(\"animations-terran-barracks\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {\n    \"frame 7\", \"wait 4\", \"frame 8\", \"wait 2\", \"frame 7\", \"wait 2\",\n    \"frame 8\", \"wait 2\", \"frame 7\", \"wait 4\", \"frame 8\", \"wait 2\",\n    \"frame 7\", \"wait 2\",\n  },\n})\n\nDefineConstruction(\"construction-terran-barracks\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-barracks\", {\n  Animations = \"animations-terran-barracks\", Icon = \"icon-terran-barracks\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-barracks\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"button\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n\nDefineUnitType(\"unit-terran-marine\", {})\nDefineUnitType(\"unit-terran-firebat\", {})\nDefineUnitType(\"unit-terran-ghost\", {})\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-marine\",\n  Action = \"train-unit\", Value = \"unit-terran-marine\",\n  Key = \"m\", Hint = \"Train ~!Marine\",\n  ForUnit = {\"unit-terran-barracks\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-terran-firebat\",\n  Action = \"train-unit\", Value = \"unit-terran-firebat\",\n  Key = \"f\", Hint = \"Train ~!Firebat\",\n  ForUnit = {\"unit-terran-barracks\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-terran-ghost\",\n  Action = \"train-unit\", Value = \"unit-terran-ghost\",\n  Key = \"g\", Hint = \"Train ~!Ghost\",\n  ForUnit = {\"unit-terran-barracks\"} } )\n"
  },
  {
    "path": "scripts/terran/unit-terran-battlecruiser.lua",
    "content": "--\n-- unit-terran-battlecruiser\n--\n\nDefineAnimations(\"animations-terran-battlecruiser\", {\n  Still = {\"frame 0\", \"wait 125\",},\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"attack\", \"sound terran-battlecruiser-attack\",\n    \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"sound terran-battlecruiser-death\",\n    --[[active overlay 333,0]] \"wait 3\", \"unbreakable end\", \"wait 1\",},\n})\n\nDefineUnitType(\"unit-terran-battlecruiser\", {\n  DrawLevel = 45,\n  Animations = \"animations-terran-battlecruiser\", Icon = \"icon-terran-battlecruiser\",\n  Speed = 14,\n  DrawLevel = 60,\n  Armor = 5, BasicDamage = 0, PiercingDamage = 16, Missile = \"missile-terran-battlecruiser-laser\",\n  AnnoyComputerFactor = 55,\n  MaxAttackRange = 4,\n  Priority = 65,\n  Points = 150,\n  Demand = 6,\n  ExplodeWhenKilled = \"missile-terran-explosion-medium\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetSea = true, CanTargetAir = true,\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-battlecruiser-selected\",\n    \"acknowledge\", \"terran-battlecruiser-acknowledge\",\n    \"ready\", \"terran-battlecruiser-ready\",\n    \"help\", \"terran-units-attacked\",\n    \"dead\", \"terran-battlecruiser-death\"} } )\n"
  },
  {
    "path": "scripts/terran/unit-terran-bunker.lua",
    "content": "--\n-- unit-terran-bunker\n--\n\nDefineAnimations(\"animations-terran-bunker\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-bunker\", {\n  Files = image_327_terran_tbldmed_var,\n  ShadowFiles = image_327_terran_tbldmed_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-bunker\", {\n  Animations = \"animations-terran-bunker\", Icon = \"icon-terran-bunker\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-bunker\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true,\n  AttackFromTransporter = true,\n  CanTransport = {},\n  MaxOnBoard = 4,\n  Sounds = {\n    \"selected\", \"button\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-command-center.lua",
    "content": "--\n-- unit-terran-command-center\n--\n\nDefineAnimations(\"animations-terran-command-center\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-command-center\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-command-center\", {\n  Animations = \"animations-terran-command-center\", Icon = \"icon-terran-command-center\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-command-center\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 35, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 10,\n  --Corpse = \"unit-destroyed-4x4-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \">\", Type = \"unit-resource-mineral-field\"} } },\n  CanStore = {\"gas\", \"minerals\"},\n  Sounds = {\n    \"selected\", \"button\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n\nDefineUnitType(\"unit-terran-scv\", {})\nDefineUnitType(\"unit-terran-comsat-station\", {})\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-scv\",\n  Action = \"train-unit\", Value = \"unit-terran-scv\",\n  Key = \"s\", Hint = \"Build ~!SCV\",\n  ForUnit = {\"unit-terran-command-center\"} } )\n  \nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-terran-comsat-station\",\n  Action = \"train-unit\", Value = \"unit-terran-comsat-station\",\n  Key = \"c\", Hint = \"Comsat Station\",\n  ForUnit = {\"unit-terran-command-center\"} } )\n--[[\nDefineButton( { Pos = 8, Level = 0, Icon = \"icon-terran-nuclear-silo\",\n  Action = \"train-unit\", Value = \"unit-terran-nuclear-silo\",\n  Key = \"c\", Hint = \"Nuclear Silo\",\n  ForUnit = {\"unit-terran-command-center\"} } )\n]]\n"
  },
  {
    "path": "scripts/terran/unit-terran-comsat-station.lua",
    "content": "--\n-- unit-terran-command-center\n--\n\nDefineAnimations(\"animations-terran-comsat-station\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineUnitType(\"unit-terran-comsat-station\", {\n  Animations = \"animations-terran-comsat-station\", Icon = \"icon-terran-comsat-station\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n--  Construction = \"construction-terran-comsat-station\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 35, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 10,\n  --Corpse = \"unit-destroyed-4x4-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  VisibleUnderFog = true, \n  BuildingRules = { { \"addon\", { OffsetX = 4, OffsetY = -5, Type = \"unit-terran-command-center\"}}},\n  Sounds = {\n    \"selected\", \"button\",\n--    \"ready\", \"\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-dropship.lua",
    "content": "--\n-- unit-terran-dropship\n--\n\nDefineAnimations(\"animations-terran-dropship\", {\n  Still = {\"frame 0\", \"wait 125\",--[[FIXME: shift down 79A2]]},\n  Move = {\n    \"unbreakable begin\", -- accellerate\n      \"frame 0\", \"move 1\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n      \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\",\n    \"unbreakable end\", \"wait 1\",\n    \"label fullspeed\", \"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\", \"frame 0\", \"move 3\", \"unbreakable end\", \"wait 1\",\n    \"goto fullspeed\",},\n  Death = {\"unbreakable begin\", \"sound terran-dropship-death\",\n    --[[active overlay 332,0]] \"wait 3\", \"unbreakable end\", \"wait 1\",},\n})\n\nDefineUnitType(\"unit-terran-dropship\", {\n  DrawLevel = 45,\n  Animations = \"animations-terran-dropship\", Icon = \"icon-terran-dropship\",\n  Speed = 14,\n  DrawLevel = 60,\n  MaxOnBoard = 8,\n  -- PersonalSpace = {7, 7}, TileSize = {2, 2}\n  Armor = 5, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  MaxAttackRange = 4,\n  Priority = 65,\n  Points = 150,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"move\",\n  CanAttack = false,\n  CanTransport = {},\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-dropship-selected\",\n    \"acknowledge\", \"terran-dropship-acknowledge\",\n    \"ready\", \"terran-dropship-ready\",\n    \"help\", \"terran-units-attacked\",\n    \"dead\", \"terran-dropship-death\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-engineering-bay.lua",
    "content": "--\n-- unit-terran-engineering-bay\n--\n\nDefineAnimations(\"animations-terran-engineering-bay\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Research = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-engineering-bay\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-engineering-bay\", {\n  Animations = \"animations-terran-engineering-bay\", Icon = \"icon-terran-engineering-bay\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-engineering-bay\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"terran-engineering-bay-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\nCUpgrade:New(\"upgrade-terran-infantry-weapons1\")\nCUpgrade:New(\"upgrade-terran-infantry-weapons2\")\nCUpgrade:New(\"upgrade-terran-infantry-weapons3\")\nCUpgrade:New(\"upgrade-terran-infantry-armor1\")\nCUpgrade:New(\"upgrade-terran-infantry-armor2\")\nCUpgrade:New(\"upgrade-terran-infantry-armor3\")\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-upgrade-infantry-weapons\",\n  Action = \"research\", Value = \"upgrade-terran-infantry-weapons1\",\n  Allowed = \"check-single-research\",\n  Key = \"w\", Hint = \"Upgrade Infantry ~!Weapons\",\n  ForUnit = {\"unit-terran-engineering-bay\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-upgrade-infantry-weapons\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-terran-infantry-weapons2\",\n  Key = \"w\", Hint = \"Upgrade Infantry ~!Weapons\",\n  ForUnit = {\"unit-terran-engineering-bay\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-upgrade-infantry-weapons\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-terran-infantry-weapons3\",\n  Key = \"w\", Hint = \"Upgrade Infantry ~!Weapons\",\n  ForUnit = {\"unit-terran-engineering-bay\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-terran-upgrade-infantry-armor\",\n  Action = \"research\", Value = \"upgrade-terran-infantry-armor1\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Infantry ~!Armor\",\n  ForUnit = {\"unit-terran-engineering-bay\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-terran-upgrade-infantry-armor\",\n  Action = \"research\", Value = \"upgrade-terran-infantry-armor1\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Infantry ~!Armor\",\n  ForUnit = {\"unit-terran-engineering-bay\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-terran-upgrade-infantry-armor\",\n  Action = \"research\", Value = \"upgrade-terran-infantry-armor2\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Infantry ~!Armor\",\n  ForUnit = {\"unit-terran-engineering-bay\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-factory.lua",
    "content": "--\n-- unit-terran-factory\n--\n\nDefineAnimations(\"animations-terran-factory\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Research = {--[[FIXME: active overlay 286]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-factory\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-factory\", {\n  Animations = \"animations-terran-factory\", Icon = \"icon-terran-factory\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-factory\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"terran-factory-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\nDefineUnitType(\"unit-terran-vulture\", {})\nDefineUnitType(\"unit-terran-siege-tank\", {})\nDefineUnitType(\"unit-terran-goliath\", {})\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-vulture\",\n  Action = \"train-unit\", Value = \"unit-terran-vulture\",\n  Key = \"v\", Hint = \"Build ~!Vulture\",\n  ForUnit = {\"unit-terran-factory\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-terran-siege-tank\",\n  Action = \"train-unit\", Value = \"unit-terran-siege-tank\",\n  Key = \"t\", Hint = \"Build Siege ~!Tank\",\n  ForUnit = {\"unit-terran-factory\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-terran-goliath\",\n  Action = \"train-unit\", Value = \"unit-terran-goliath\",\n  Key = \"g\", Hint = \"Build ~!Goliath\",\n  ForUnit = {\"unit-terran-factory\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-firebat.lua",
    "content": "--\n-- unit-terran-firebat\n--\n\n\nDefineAnimations(\"animations-terran-firebat\", {\n  Still = {\n    \"label 6D07\", \"frame 34\",\n    \"label 6D0A\", \"random-wait 63 75\", \"random-goto 10 6D2E\",\n      \"random-goto 50 6D18\", \"goto 6D0A\",\n    \"label 6D18\", \"frame 51\", \"wait 1\", \"frame 68\", \"wait 1\",\n      \"random-rotate 3\", \"wait 1\", \"frame 51\", \"wait 1\", \"goto 6D07\",\n    \"label 6D2E\", \"frame 0\", \"wait 1\", \"random-goto 75 6D72\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"wait 6\",\n      \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\",\n      \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\", \"wait 6\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\",\n      \"goto 6D07\",\n    \"label 6D72\", \"wait 13\", \"goto 6D07\",\n  },\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"frame 51\", \"move 4\", \"wait 1\", \"frame 68\",\n    \"move 4\", \"wait 1\", \"frame 85\", \"move 4\", \"wait 1\", \"frame 102\",\n    \"move 4\", \"wait 1\", \"frame 119\", \"move 4\", \"wait 1\", \"frame 136\",\n    \"move 4\", \"wait 1\", \"frame 153\", \"move 4\", \"unbreakable end\",\n    \"wait 1\", \"frame 34\",},\n--  StartAttack = {\"frame 0\",},\n  Attack = {\n    \"frame 0\", \"wait 1\", \"unbreakable begin\", --[[active overlay 421,0]] \"attack\", \"sound terran-firebat-attack\",\n    \"wait 2\", --[[\"attack\",]] \"wait 1\", --[[\"attack\",]] \"wait 8\", \"frame 0\", \"wait 2\",\n    \"unbreakable end\", \"wait 22\",\n  },\n  Death = {\n    \"unbreakable begin\",\n    \"sound terran-firebat-death\", --[[active overlay 332,0]] \"wait 3\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-terran-firebat\", {\n  Animations = \"animations-terran-firebat\", Icon = \"icon-terran-firebat\",\n  Speed = 10,\n  DrawLevel = 40,\n  Armor = 2, BasicDamage = 6, PiercingDamage = 3, Missile = \"missile-terran-firebat-flame\",\n  AnnoyComputerFactor = 50,\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-firebat-selected\",\n    \"acknowledge\", \"terran-firebat-acknowledge\",\n    \"ready\", \"terran-firebat-ready\",\n    \"help\", \"terran-units-attacked\",} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-ghost.lua",
    "content": "--\n-- unit-terran-ghost\n--\n\n\nDefineAnimations(\"animations-terran-ghost\", {\n  Still = {\n    \"label 6E17\", \"frame 51\",\n    \"label 6E1A\", \"random-wait 63 75\", \"random-goto 10 6E3E\",\n      \"random-goto 50 6E28\", \"goto 6E1A\",\n    \"label 6E28\", \"frame 68\", \"wait 1\", \"frame 85\", \"wait 1\",\n      \"random-rotate 3\", \"wait 1\", \"frame 68\", \"wait 1\", \"goto 6E17\",\n    \"label 6E3E\", \"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",\n      \"random-goto 75 6E8A\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"wait 6\",\n      \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\",\n      \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\", \"wait 6\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\",\n      \"goto 6E8C\",\n    \"label 6E8A\", \"wait 13\",\n    \"label 6E8C\", \"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", \"goto 6E17\",\n  },\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"frame 68\", \"move 4\", \"wait 1\", \"frame 85\",\n    \"move 4\", \"wait 1\", \"frame 102\", \"move 4\", \"wait 1\", \"frame 119\",\n    \"move 4\", \"wait 1\", \"frame 136\", \"move 4\", \"wait 1\", \"frame 153\",\n    \"move 4\", \"wait 1\", \"frame 170\",\n    --FIXME: subtile movement not supported\n    --[[\"move 4\", \"wait 1\", \"frame 187\",]]\n    \"move 4\", \"unbreakable end\", \"wait 1\", \"frame 51\",\n  },\n--  StartAttack = {\"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",},\n  Attack = {\n    \"wait 1\", \"unbreakable begin\", \"sound terran-ghost-attack\", \"attack\",\n    \"frame 204\", \"wait 1\", \"frame 34\", \"unbreakable end\",\n  },\n--  EndAttack = {\"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", --[[goto 6E17]]},\n  Death = {\n    \"unbreakable begin\",\n    \"sound terran-ghost-death\", \"exact-frame 221\", \"wait 2\",\n    \"exact-frame 222\", \"wait 2\", \"exact-frame 223\", \"wait 2\",\n    \"exact-frame 224\", \"wait 2\", \"exact-frame 225\", \"wait 2\",\n    \"exact-frame 226\", \"wait 2\", \"exact-frame 227\", \"wait 2\",\n    \"exact-frame 228\", \"wait 2\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-terran-ghost\", {\n  Animations = \"animations-terran-ghost\", Icon = \"icon-terran-ghost\",\n  Speed = 10,\n  DrawLevel = 40,\n  Armor = 2, BasicDamage = 6, PiercingDamage = 3, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n--  Corpse = \"unit-dead-body\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-ghost-selected\",\n    \"acknowledge\", \"terran-ghost-acknowledge\",\n    \"ready\", \"terran-ghost-ready\",\n    \"help\", \"terran-units-attacked\",} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-goliath.lua",
    "content": "--\n-- unit-terran-goliath\n--\n\n\nDefineAnimations(\"animations-terran-goliath\", {\n  Still = {\n    \"frame 119\", \"wait 125\",\n  },\n  Move = {\"unbreakable begin\",\n    \"move 6\", \"wait 1\", \"frame 136\", \"move 3\", \"wait 1\", \"frame 153\",\n    \"move 3\", \"wait 1\", \"frame 0\", \"move 3\", \"wait 1\", \"frame 17\",\n    \"move 5\", \"wait 1\", \"frame 34\", \"move 5\", \"wait 1\", \"frame 51\",\n    \"move 4\", \"wait 1\", \"frame 68\",\n    --FIXME: sub-tile movement\n    --[[\"move 8\", \"wait 1\", \"frame 85\",\n    \"move 6\", \"wait 1\", \"frame 102\", \"move 4\",\n    \"unbreakable end\", \"wait 1\", \"frame 119\",]]\n    \"move 3\", \"unbreakable end\", \"wait 1\", \"frame 119\",\n  },\n  Attack = {\n    \"unbreakable begin\", \"sound terran-goliath-attack\", \"attack\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Death = {\n    \"unbreakable begin\",\n    --[[sound 8]] --[[active overlay 332,0]] \"wait 3\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-terran-goliath\", {\n  Animations = \"animations-terran-goliath\", Icon = \"icon-terran-goliath\",\n  Speed = 10,\n  DrawLevel = 40,\n  Armor = 2, BasicDamage = 6, PiercingDamage = 3, Missile = \"missile-none\",\n  AnnoyComputerFactor = 55,\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-goliath-selected\",\n    \"acknowledge\", \"terran-goliath-acknowledge\",\n    \"ready\", \"terran-goliath-ready\",\n    \"help\", \"terran-units-attacked\",\n    \"dead\", \"terran-goliath-death\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-marine.lua",
    "content": "--\n-- unit-terran-marine\n--\n\n\nDefineAnimations(\"animations-terran-marine-death\", {\n  Death = {\"unbreakable begin\", \"frame 0\", \"wait 50\", \"frame 1\", \"wait 50\",\n    \"frame 2\", \"wait 50\", \"unbreakable end\", \"wait 1\", },\n})\n\nDefineUnitType(\"unit-terran-marine-death\", { Name = \"Dead Marine\",\n  Image = image_241_terran_tmadeath,\n  Animations = \"animations-terran-marine-death\", Icon = \"icon-terran-marine\",\n  NumDirections = 1,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {2, 2}, BoxSize = {31, 31},\n  SightRange = 4,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  Vanishes = true,\n  Sounds = {} } )\n\n\n\nDefineAnimations(\"animations-terran-marine\", {\n  Still = {\n    \"label 70FD\", \"frame 68\",\n    \"label 7100\", \"random-wait 63 75\", \"random-goto 10 7124\",\n      \"random-goto 50 710E\", \"goto 7100\",\n    \"label 710E\", \"frame 85\", \"wait 1\", \"frame 102\", \"wait 1\",\n      \"random-rotate 3\", \"wait 1\", \"frame 85\", \"wait 1\", \"goto 70FD\",\n    \"label 7124\", \"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",\n      \"random-goto 75 7170\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"wait 6\",\n      \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\",\n      \"rotate 2\", \"wait 3\", \"rotate 2\", \"wait 3\", \"wait 6\",\n      \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\", \"rotate -2\", \"wait 3\",\n      \"goto 7172\",\n    \"label 7170\", \"wait 13\",\n    \"label 7172\", \"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", \"goto 70FD\",\n  },\n  Move = {\n    \"unbreakable begin\", \"move 4\", \"frame 85\", \"wait 1\", \"move 4\", \"frame 102\", \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\", \"move 4\", \"frame 119\", \"wait 1\", \"move 4\", \"frame 136\", \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\", \"move 4\", \"frame 153\", \"wait 1\", \"move 4\", \"frame 170\", \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\", \"move 4\", \"frame 187\", \"wait 1\", \"move 4\", \"frame 68\", \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\", \"move 4\", \"frame 204\", \"wait 1\", \"move 4\", \"frame 85\", \"unbreakable end\", \"wait 1\",\n  },\n--  StartAttack = {\"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\",},\n  Attack = {\n    \"wait 1\", \"unbreakable begin\", \"sound terran-marine-attack\", \"attack\",\n    \"frame 51\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 51\", \"wait 1\",\n    \"frame 34\", \"wait 1\", \"frame 51\", \"wait 1\", \"frame 34\",\n    \"unbreakable end\", \"wait 1\",\n  },\n--  EndAttack = {\"frame 17\", \"wait 1\", \"frame 0\", \"wait 1\", --[[goto 70FD]]},\n  Death = {\n    \"unbreakable begin\",\n    \"sound terran-marine-death\", \"exact-frame 221\", \"wait 2\",\n    \"exact-frame 222\", \"wait 2\", \"exact-frame 223\", \"wait 2\",\n    \"exact-frame 224\", \"wait 2\", \"exact-frame 225\", \"wait 2\",\n    \"exact-frame 226\", \"wait 2\", \"exact-frame 227\", \"wait 2\",\n    \"exact-frame 228\", \"wait 2\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-terran-marine\", {\n  Animations = \"animations-terran-marine\", Icon = \"icon-terran-marine\",\n  Speed = 10,\n  DrawLevel = 40,\n  -- TileSize = {2, 2}, BoxSize = {31, 31}, Offset = {0, -8}, BoxOffset = {0, -8}, PersonalSpace = {1, 1},\n  Armor = 2, BasicDamage = 6, PiercingDamage = 2, Missile = \"missile-none\",\n  AnnoyComputerFactor = 50,\n  MaxAttackRange = 4*4,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  Corpse = \"unit-terran-marine-death\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  CanTargetAir = true,\n  SelectableByRectangle = true,\n  --[[Sounds = {\n    \"selected\", \"terran-marine-selected\",\n    \"acknowledge\", \"terran-marine-acknowledge\",\n    \"ready\", \"terran-marine-ready\",\n    \"help\", \"terran-units-attacked\",} ]]--\n    \n    } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-missile-turret.lua",
    "content": "--\n-- unit-terran-missile-turret\n--\n\nDefineAnimations(\"animations-terran-missile-turret\", {\n  Still = {\n    \"frame 2\", \"wait 125\",\n  },\n  Attack = {--[[FIXME: active overlay 297]]\n    \"frame 2\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-missile-turret\", {\n  Files = image_329_terran_tbldsml_var,\n  ShadowFiles = image_329_terran_tbldsml_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-missile-turret\", {\n  Animations = \"animations-terran-missile-turret\", Icon = \"icon-terran-missile-turret\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-missile-turret\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 50, PiercingDamage = 0, Missile = \"missile-small-cannon\",\n  MinAttackRange = 2, MaxAttackRange = 7,\n  Priority = 40, AnnoyComputerFactor = 50,\n  Points = 250,\n  --Corpse = \"unit-destroyed-2x2-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetSea = true,\n  VisibleUnderFog = true, \n  DetectCloak = true,\n  Sounds = {\n    \"selected\", \"terran-missile-turret-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-refinery.lua",
    "content": "--\n-- unit-terran-refinery\n--\n\nDefineAnimations(\"animations-terran-refinery\", {\n  Still = {\n    \"frame 0\", \"wait 5\", \"label 691B\", --[[0x38 0x00]]\n    \"wait 20\", \"random-wait 5 100\", \"goto 691B\",\n  }\n})\n\nDefineConstruction(\"construction-terran-refinery\", {\n  Constructions = {\n   {Percent = 0,\n    File = \"main\",\n    Frame = 1},\n   {Percent = 20,\n    File = \"main\",\n    Frame = 2},\n   {Percent = 40,\n    File = \"main\",\n    Frame = 3},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 4}}\n})\n\nDefineUnitType(\"unit-terran-refinery\", { Name = \"Refinery\",\n  Animations = \"animations-terran-refinery\", Icon = \"icon-terran-refinery\",\n  Construction = \"construction-terran-refinery\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 20,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-explosion\",\n  VisibleUnderFog = true,\n  BuildingRules = { { \"ontop\", { Type = \"unit-resource-vespene-geyser\", ReplaceOnDie = true, ReplaceOnBuild = true} } },\n  GivesResource = \"gas\", CanHarvest = true,\n  Sounds = {\n    \"selected\", \"terran-refinery-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-science-facility.lua",
    "content": "--\n-- unit-terran-science-facility\n--\n\nDefineAnimations(\"animations-terran-science-facility\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Research = {--[[FIXME: active overlay 310]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-science-facility\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-science-facility\", {\n  Animations = \"animations-terran-science-facility\", Icon = \"icon-terran-science-facility\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-science-facility\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"terran-science-facility-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-science-vessel.lua",
    "content": "--\n-- unit-terran-science-vessel\n--\n\nDefineAnimations(\"animations-terran-science-vessel\", {\n  Still = {\"frame 0\", \"wait 125\",},\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"attack\", \"sound terran-science-vessel-attack\",\n    \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"sound terran-science-vessel-death\",\n    --[[active overlay 333,0]] \"wait 3\", \"unbreakable end\", \"wait 1\",},\n})\n\nDefineUnitType(\"unit-terran-science-vessel\", {\n  DrawLevel = 45,\n  Animations = \"animations-terran-science-vessel\", Icon = \"icon-terran-science-vessel\",\n  Speed = 14,\n  DrawLevel = 60,\n  Armor = 5, BasicDamage = 0, PiercingDamage = 16, Missile = \"missile-none\",\n  MaxAttackRange = 4,\n  Priority = 65,\n  Points = 150,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-medium\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetSea = true, CanTargetAir = true,\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-science-vessel-selected\",\n    \"acknowledge\", \"terran-science-vessel-acknowledge\",\n    \"ready\", \"terran-science-vessel-ready\",\n    \"help\", \"terran-units-attacked\",\n    \"dead\", \"terran-science-vessel-death\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-scv.lua",
    "content": "--\n-- unit-terran-scv\n--\n\nDefineAnimations(\"animations-terran-scv\", {\n  Still = {\"frame 0\", \"wait 125\",},\n  Move = {\"unbreakable begin\",\n          \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n          \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"frame 34\", \"sound terran-scv-attack\",\n    \"wait 1\", \"frame 17\", \"unbreakable end\", \"wait 1\",},\n  Harvest_minerals = {\"unbreakable begin\",\n      \"sound terran-scv-attack\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n      \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n    \"unbreakable end\", \"wait 4\",},\n  Repair = {\"unbreakable begin\", \"frame 34\", \"sound terran-scv-attack\",\n    \"wait 1\", \"frame 17\", \"unbreakable end\", \"wait 1\",},\n  Build = {\n    \"wait 1\", \"rotate target\",\n    \"unbreakable begin\",\n      \"label NW\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 1\", \"wiggle t.PosX.Value t.PosY.Value 4 NW\",\n        \"wait 1\", \"rotate target\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"sound terran-scv-attack\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 32\",\n      \"label SE\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 1\", \"wiggle t.PosRight.Value t.PosBottom.Value 4 SE\",\n        \"wait 1\", \"rotate target\",\n          \"wiggle -4 -4 absolute\", \"wait 1\", \"wiggle -4 -4 absolute\", \"wait 1\",\n          \"wiggle -4 -4 absolute\", \"wait 1\", \"wiggle -4 -4 absolute\", \"wait 1\",\n          \"wiggle -4 -4 absolute\", \"wait 1\", \"wiggle -4 -4 absolute\", \"wait 1\",\n          \"wiggle -4 -4 absolute\", \"wait 1\", \"wiggle -4 -4 absolute\", \"wait 1\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"sound terran-scv-attack\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 32\",\n      \"label SW\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 1\", \"wiggle t.PosX.Value t.PosBottom.Value 4 SW\",\n        \"wait 1\", \"rotate target\",\n          \"wiggle 0 -4 absolute\", \"wait 1\", \"wiggle 0 -4 absolute\", \"wait 1\",\n          \"wiggle 0 -4 absolute\", \"wait 1\", \"wiggle 0 -4 absolute\", \"wait 1\",\n          \"wiggle 0 -4 absolute\", \"wait 1\", \"wiggle 0 -4 absolute\", \"wait 1\",\n          \"wiggle 0 -4 absolute\", \"wait 1\", \"wiggle 0 -4 absolute\", \"wait 1\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"sound terran-scv-attack\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 32\",\n      \"label NE\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 1\", \"wiggle t.PosRight.Value t.PosY.Value 4 NE\",\n        \"wait 1\", \"rotate target\",\n          \"wiggle -4 0 absolute\", \"wait 1\", \"wiggle -4 0 absolute\", \"wait 1\",\n          \"wiggle -4 0 absolute\", \"wait 1\", \"wiggle -4 0 absolute\", \"wait 1\",\n          \"wiggle -4 0 absolute\", \"wait 1\", \"wiggle -4 0 absolute\", \"wait 1\",\n          \"wiggle -4 0 absolute\", \"wait 1\", \"wiggle -4 0 absolute\", \"wait 1\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"sound terran-scv-attack\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n          \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 17\",\n        \"if-var t.HitPoints.Percent == 100 start\", \"if-var t.IsAlive.Value == 0 start\",\n        \"wait 32\",\n      \"label start\",\n        \"wait 1\", \"wiggle v.PosX.Value v.PosY.Value 4 start\",\n        \"wait 1\", \"rotate target\",\n    \"unbreakable end\",\n    \"wait 1\",\n  },\n  Death = {\"unbreakable begin\", \"frame 50\", \"wait 3\", \"frame 55\", \"wait 3\", \"frame 60\", \"wait 100\",\n    \"frame 60\", \"unbreakable end\", \"wait 1\",},\n})\n\nDefineUnitType(\"unit-terran-scv\", {\n  Animations = \"animations-terran-scv\", Icon = \"icon-terran-scv\",\n  Speed = 10,\n  DrawLevel = 45,\n  BasicDamage = 3, PiercingDamage = 2, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 50,\n  Points = 30,\n  Demand = 1,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"harvest\",\n  CanAttack = true, RepairRange = 1,\n  CanTargetLand = true,\n  Coward = true,\n  CanGatherResources = {\n   {\"file-when-loaded\", image_247_terran_scv_file,\n    \"resource-id\", \"minerals\",\n    \"harvest-from-outside\",\n    \"resource-capacity\", 8,\n    \"wait-at-resource\", 150,\n    \"wait-at-depot\", 50},\n   {\"file-when-loaded\", image_247_terran_scv_file,\n    \"resource-id\", \"gas\",\n    \"resource-capacity\", 8,\n    \"wait-at-resource\", 50,\n    \"wait-at-depot\", 50,}},\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-scv-selected\",\n    \"acknowledge\", \"terran-scv-acknowledge\",\n    \"ready\", \"terran-scv-ready\",\n    \"help\", \"terran-units-attacked\",\n    \"dead\", \"terran-scv-death\"} \n  \n  } )\n\n\n--\n-- Default\n--\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-move\",\n  Action = \"move\",\n  Key = \"m\", Hint = \"~!Move\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-stop\",\n  Action = \"stop\",\n  Key = \"s\", Hint = \"~!Stop\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-attack\",\n  Action = \"attack\",\n  Key = \"a\", Hint = \"~!Attack\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 4, Level = 0, Icon = \"icon-repair\",\n  Action = \"repair\",\n  Key = \"r\", Hint = \"~!Repair\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 5, Level = 0, Icon = \"icon-gather\",\n  Action = \"harvest\",\n  Key = \"g\", Hint = \"~!Gather\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-build\",\n  Action = \"button\", Value = 1,\n  Key = \"b\", Hint = \"~!Build Structure\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 8, Level = 0, Icon = \"icon-advanced-build\",\n  Action = \"button\", Value = 2,\n  Key = \"v\", Hint = \"Build Ad~!vanced Structure\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\n\n--\n-- Build\n--\nDefineButton( { Pos = 1, Level = 1, Icon = \"icon-terran-command-center\",\n  Action = \"build\", Value = \"unit-terran-command-center\",\n  Key = \"c\", Hint = \"Build ~!Command Center\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 2, Level = 1, Icon = \"icon-terran-supply-depot\",\n  Action = \"build\", Value = \"unit-terran-supply-depot\",\n  Key = \"s\", Hint = \"Build ~!Supply Depot\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 3, Level = 1, Icon = \"icon-terran-refinery\",\n  Action = \"build\", Value = \"unit-terran-refinery\",\n  Key = \"r\", Hint = \"Build ~!Refinery\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 4, Level = 1, Icon = \"icon-terran-barracks\",\n  Action = \"build\", Value = \"unit-terran-barracks\",\n  Key = \"b\", Hint = \"Build ~!Barracks\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 5, Level = 1, Icon = \"icon-terran-engineering-bay\",\n  Action = \"build\", Value = \"unit-terran-engineering-bay\",\n  Key = \"e\", Hint = \"Build ~!Engineering Bay\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 6, Level = 1, Icon = \"icon-terran-missile-turret\",\n  Action = \"build\", Value = \"unit-terran-missile-turret\",\n  Key = \"t\", Hint = \"Build Missile ~!Turret\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 7, Level = 1, Icon = \"icon-terran-academy\",\n  Action = \"build\", Value = \"unit-terran-academy\",\n  Key = \"a\", Hint = \"Build ~!Academy\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 8, Level = 1, Icon = \"icon-terran-bunker\",\n  Action = \"build\", Value = \"unit-terran-bunker\",\n  Key = \"u\", Hint = \"Build B~!unker\",\n  ForUnit = {\"unit-terran-scv\"} } )\n  \nDefineButton( { Pos = 9, Level = 1, Icon = \"icon-cancel\",\n  Action = \"button\", Value = 0,\n  Key = \"\\27\", Hint = \"~<ESC~> - Cancel\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\n--\n-- Advanced Build\n--\nDefineButton( { Pos = 1, Level = 2, Icon = \"icon-terran-factory\",\n  Action = \"build\", Value = \"unit-terran-factory\",\n  Key = \"f\", Hint = \"Build ~!Factory\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 2, Level = 2, Icon = \"icon-terran-starport\",\n  Action = \"build\", Value = \"unit-terran-starport\",\n  Key = \"s\", Hint = \"Build ~!Starport\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 3, Level = 2, Icon = \"icon-terran-science-facility\",\n  Action = \"build\", Value = \"unit-terran-science-facility\",\n  Key = \"i\", Hint = \"Build Sc~!ience Facility\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 4, Level = 2, Icon = \"icon-terran-armory\",\n  Action = \"build\", Value = \"unit-terran-armory\",\n  Key = \"a\", Hint = \"Build ~!Armory\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\nDefineButton( { Pos = 9, Level = 2, Icon = \"icon-cancel\",\n  Action = \"button\", Value = 0,\n  Key = \"\\27\", Hint = \"~<ESC~> - Cancel\",\n  ForUnit = {\"unit-terran-scv\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-siege-tank.lua",
    "content": "--\n-- unit-terran-siege-tank\n--\n\nfunction moveTurret(self)\n  local turret = GetUnitVariable(self, \"Summoned\")\n  local pixelPos = GetUnitVariable(self, \"PixelPos\")\n  local ix = math.fmod(pixelPos.x, 8)\n  local iy = math.fmod(pixelPos.y, 8)\n  local x = math.floor(pixelPos.x / 8) - 2\n  local y = math.floor(pixelPos.y / 8) - 3\n  MoveUnit(turret, {x, y}, {ix, iy})\nend\n\nfunction turnTurret(self, goal, y)\n  local turret = GetUnitVariable(self, \"Summoned\")\n  if y then\n    TurnTowardsLocation(turret, {goal, y})\n  else\n    TurnTowardsLocation(turret, goal)\n  end\nend\n\nDefineAnimations(\"animations-terran-siege-tank\", {\n  Still = {\n    \"label still\", \"frame 0\", \"wait 125\",\n    \"random-goto 25 turn\",\n    \"goto still\",\n    \"label turn\", \"lua-callback turnTurret U r.64 r.64\",\n  },\n  Move = {\n    \"unbreakable begin\", \"move 4\", \"lua-callback moveTurret U\", \"wait 1\", \"frame 0\", \"move 4\", \"lua-callback moveTurret U\", \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\", \"frame 17\", \"move 4\", \"lua-callback moveTurret U\", \"wait 1\", \"frame 34\", \"move 4\", \"lua-callback moveTurret U\", \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\", \"frame 0\", \"move 4\", \"lua-callback moveTurret U\", \"wait 1\", \"frame 17\", \"move 4\", \"lua-callback moveTurret U\", \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\", \"frame 34\", \"move 4\", \"lua-callback moveTurret U\", \"wait 1\", \"frame 0\", \"move 4\", \"lua-callback moveTurret U\", \"unbreakable end\", \"wait 1\", \"frame 17\",\n  },\n  Attack = {\n    \"label shoot\",\n    \"unbreakable begin\",\n      \"lua-callback turnTurret U G\", \"wait 3\",\n      \"sound terran-siege-tank-attack\", \"attack\", \"wait 60\",\n    \"unbreakable end\", \"wait 1\",\n    \"goto shoot\",\n  },\n  Death = {\n    \"unbreakable begin\",\n    --[[sound 317]] --[[active overlay 333,0]] \"wait 3\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-terran-siege-tank-tank-mode\", {\n  Animations = \"animations-terran-siege-tank\", Icon = \"icon-terran-siege-tank\",\n  Speed = 10,\n  RotationSpeed = 4,\n  DrawLevel = 40,\n  Armor = 2, BasicDamage = 6, PiercingDamage = 3, Missile = \"missile-none\",\n  AnnoyComputerFactor = 55,\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  MinAttackRange = 8, MaxAttackRange = 48,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-medium\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SurroundAttack = true,\n  SelectableByRectangle = true,\n  OnInit = function(self)\n    local turret = CreateUnit(\"unit-terran-siege-tank-tank-mode-turret\", GetUnitVariable(self, \"Player\"), {0, 0})\n    SetUnitVariable(self, \"Summoned\", turret)\n    moveTurret(self)\n  end,\n  OnDeath = function(self)\n    local turret = GetUnitVariable(self, \"Summoned\", turret)\n    RemoveUnit(turret)\n  end,\n  Sounds = {\n    \"selected\", \"terran-siege-tank-selected\",\n    \"acknowledge\", \"terran-siege-tank-acknowledge\",\n    \"ready\", \"terran-siege-tank-ready\",\n    \"help\", \"terran-units-attacked\",\n    \"dead\", \"terran-siege-tank-death\"} } )\n\nDefineAnimations(\"animations-terran-siege-tank-turret\", {\n  Still = {\n    \"frame 0\", \"wait 125\", -- \"random-rotate 1\", \"wait 8\",\n  },\n})\n\nDefineUnitType(\"unit-terran-siege-tank-tank-mode-turret\", {\n  Animations = \"animations-terran-siege-tank-turret\",\n  RotationSpeed = 8,\n  DrawLevel = 50,\n  Indestructible = 1,\n  Flip = false,\n  IsNotSelectable = true,\n  NonSolid = true,\n  ComputerReactionRange = 0,\n  PersonReactionRange = 0,\n  AnnoyComputerFactor = -100,\n  AiAdjacentRange = 0,\n  Revealer = false,\n  Decoration = true\n})\n"
  },
  {
    "path": "scripts/terran/unit-terran-starport.lua",
    "content": "--\n-- unit-terran-starport\n--\n\nDefineAnimations(\"animations-terran-starport\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Train = {--[[FIXME: active overlay 320]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-starport\", {\n  Files = image_325_terran_tbldlrg_var,\n  ShadowFiles = image_325_terran_tbldlrg_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 5}}\n})\n\nDefineUnitType(\"unit-terran-starport\", {\n  Animations = \"animations-terran-starport\", Icon = \"icon-terran-starport\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-starport\",\n  Speed = 0,\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"button\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\nDefineUnitType(\"unit-terran-wraith\", {})\nDefineUnitType(\"unit-terran-dropship\", {})\nDefineUnitType(\"unit-terran-science-vessel\", {})\nDefineUnitType(\"unit-terran-battlecruiser\", {})\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-terran-wraith\",\n  Action = \"train-unit\", Value = \"unit-terran-wraith\",\n  Key = \"w\", Hint = \"Build ~!Wraith\",\n  ForUnit = {\"unit-terran-starport\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-terran-dropship\",\n  Action = \"train-unit\", Value = \"unit-terran-dropship\",\n  Key = \"d\", Hint = \"Build ~!Dropship\",\n  ForUnit = {\"unit-terran-starport\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-terran-science-vessel\",\n  Action = \"train-unit\", Value = \"unit-terran-science-vessel\",\n  Key = \"v\", Hint = \"Build Science ~!Vessel\",\n  ForUnit = {\"unit-terran-starport\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-terran-battlecruiser\",\n  Action = \"train-unit\", Value = \"unit-terran-battlecruiser\",\n  Key = \"b\", Hint = \"Build ~!Battlecruiser\",\n  ForUnit = {\"unit-terran-starport\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-supply-depot.lua",
    "content": "--\n-- unit-terran-supply-depot\n--\n\nDefineAnimations(\"animations-terran-supply-depot\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineConstruction(\"construction-terran-supply-depot\", {\n  Files = image_327_terran_tbldmed_var,\n  ShadowFiles = image_327_terran_tbldmed_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 20,\n    File = \"construction\",\n    Frame = 1},\n   {Percent = 40,\n    File = \"construction\",\n    Frame = 2},\n   {Percent = 60,\n    File = \"main\",\n    Frame = 1}}\n})\n\nDefineUnitType(\"unit-terran-supply-depot\", {\n  Animations = \"animations-terran-supply-depot\", Icon = \"icon-terran-supply-depot\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-terran-supply-depot\",\n  BurnPercent = 30,\n  BurnDamageRate = 1,\n  Speed = 0,\n  DrawLevel = 50,\n  BuilderOutside = true,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 45,\n  Points = 100,\n  Supply = 8,\n  --Corpse = \"unit-destroyed-2x2-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"terran-supply-depot-selected\",\n    \"ready\", \"terran-scv-done\",\n    \"help\", \"terran-base-attacked\",\n    \"dead\", \"explosion-large\"} } )\n\n"
  },
  {
    "path": "scripts/terran/unit-terran-vulture.lua",
    "content": "--\n-- unit-terran-vulture\n--\n\nDefineAnimations(\"animations-terran-vulture\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Move = {\n    \"label accel1\", \"unbreakable begin\",\n      \"frame 0\", \"move 1\", \"wait 1\", \"frame 0\", \"move 1\", \"wait 1\",\n      \"frame 0\", \"move 1\", \"wait 1\", \"frame 0\", \"move 1\", \"wait 1\",\n      \"frame 0\", \"move 2\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"unbreakable end\", \"wait 1\",\n      \"if-var R >= 80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R <= -80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var W < 2 accel1\", -- less than 4 tiles remaining on path, slow down\n    \n    \"label accel2\", \"unbreakable begin\",\n      \"frame 0\", \"move 2\", \"wait 1\", \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 3\",\n    \"unbreakable end\", \"wait 1\",\n      \"if-var R >= 80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R <= -80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R >= 20 accel2\", -- 90 turn, accellerate from med\n      \"if-var R <= -20 accel2\", -- 90 turn, accellerate from med\n      \"lua-callback print W\",\n      \"if-var W < 4 accel2\", -- less than 8 tiles remaining on path, slow down\n      \"if-var W < 2 accel1\", -- less than 4 tiles remaining on path, slow down\n\n    \"label fullspeed\",\n      \"unbreakable begin\", \"frame 0\", \"move 4\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",\n      \"if-var R >= 80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R <= -80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R >= 20 accel2\", -- 90 turn, accellerate from med\n      \"if-var R <= -20 accel2\", -- 90 turn, accellerate from med\n      \"lua-callback print W\",\n      \"if-var W < 4 accel2\", -- less than 8 tiles remaining on path, slow down\n      \"if-var W < 2 accel1\", -- less than 4 tiles remaining on path, slow down\n      \"unbreakable begin\", \"frame 0\", \"move 2\", \"wait 1\", \"move 2\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",\n      \"if-var R >= 80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R <= -80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R >= 20 accel2\", -- 90 turn, accellerate from med\n      \"if-var R <= -20 accel2\", -- 90 turn, accellerate from med\n      \"lua-callback print W\",\n      \"if-var W < 4 accel2\", -- less than 8 tiles remaining on path, slow down\n      \"if-var W < 2 accel1\", -- less than 4 tiles remaining on path, slow down\n      \"unbreakable begin\", \"frame 0\", \"move 4\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",\n      \"if-var R >= 80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R <= -80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R >= 20 accel2\", -- 90 turn, accellerate from med\n      \"if-var R <= -20 accel2\", -- 90 turn, accellerate from med\n      \"lua-callback print W\",\n      \"if-var W < 4 accel2\", -- less than 8 tiles remaining on path, slow down\n      \"if-var W < 2 accel1\", -- less than 4 tiles remaining on path, slow down\n      \"unbreakable begin\", \"frame 0\", \"move 2\", \"wait 1\", \"move 2\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",\n      \"if-var R >= 80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R <= -80 accel1\", -- 180 turn, accellerate from slow\n      \"if-var R >= 20 accel2\", -- 90 turn, accellerate from med\n      \"if-var R <= -20 accel2\", -- 90 turn, accellerate from med\n      \"lua-callback print W\",\n      \"if-var W < 4 accel2\", -- less than 8 tiles remaining on path, slow down\n      \"if-var W < 2 accel1\", -- less than 4 tiles remaining on path, slow down\n      \"goto fullspeed\",\n  },\n  Attack = {\n    \"unbreakable begin\", \"attack\",\n    \"unbreakable end\", \"wait 1\",\n  },\n--\n  Death = {\n    \"unbreakable begin\",\n    \"sound terran-vulture-death\", --[[active overlay 332,0]] \"wait 3\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-terran-vulture\", {\n  Animations = \"animations-terran-vulture\", Icon = \"icon-terran-vulture\",\n  Speed = 10,\n  DrawLevel = 40,\n  RotationSpeed = 10,\n  -- TileSize = {5, 5}, BoxSize = {47, 47}, Offset = {1, -2}, BoxOffset = {1, -2},\n  BoardSize = 2,\n  Armor = 2, BasicDamage = 6, PiercingDamage = 3, Missile = \"missile-terran-vulture-grenade\",\n  AnnoyComputerFactor = 55,\n  Priority = 60,\n  Points = 50,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-vulture-selected\",\n    \"acknowledge\", \"terran-vulture-acknowledge\",\n    \"ready\", \"terran-vulture-ready\",\n    \"help\", \"terran-units-attacked\",} } )\n\n-- TODO: temporarily Jim is the same as any other vulture\nCopyUnitType(\"unit-terran-vulture\", \"Jim-Raynor-(Vulture)\")\nDefineUnitType(\"Jim-Raynor-(Vulture)\", { Name = \"Jim Raynor\" })\n"
  },
  {
    "path": "scripts/terran/unit-terran-wraith.lua",
    "content": "--\n-- unit-terran-wraith\n--\n\nDefineAnimations(\"animations-terran-wraith\", {\n  Still = {\"frame 0\", \"wait 125\",--[[FIXME: shift down 79A2]]},\n  Move = {\"unbreakable begin\", \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 3\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 2\", \"frame 0\", \"move 2\", \"wait 1\",\n    \"frame 0\", \"move 3\", \"wait 1\", \"frame 0\", \"move 2\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"attack\", \"sound terran-wraith-attack\",\n    \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"sound terran-wraith-death\",\n    --[[active overlay 332,0]] \"wait 3\", \"unbreakable end\", \"wait 1\",},\n})\n\nDefineUnitType(\"unit-terran-wraith\", {\nDrawLevel = 45,\n  Animations = \"animations-terran-wraith\", Icon = \"icon-terran-wraith\",\n  Speed = 14,\n  DrawLevel = 60,\n  Armor = 5, BasicDamage = 0, PiercingDamage = 16, Missile = \"missile-terran-wraith-laser\",\n  AnnoyComputerFactor = 55,\n  MaxAttackRange = 4,\n  Priority = 65,\n  Points = 150,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetSea = true, CanTargetAir = true,\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"terran-wraith-selected\",\n    \"acknowledge\", \"terran-wraith-acknowledge\",\n    \"ready\", \"terran-wraith-ready\",\n    \"help\", \"terran-units-attacked\",\n    \"dead\", \"terran-wraith-death\"} } )\n\n"
  },
  {
    "path": "scripts/terran/units.lua",
    "content": "Load(\"scripts/terran/unit-terran-academy.lua\")\nLoad(\"scripts/terran/unit-terran-armory.lua\")\nLoad(\"scripts/terran/unit-terran-barracks.lua\")\nLoad(\"scripts/terran/unit-terran-bunker.lua\")\nLoad(\"scripts/terran/unit-terran-command-center.lua\")\nLoad(\"scripts/terran/unit-terran-engineering-bay.lua\")\nLoad(\"scripts/terran/unit-terran-factory.lua\")\nLoad(\"scripts/terran/unit-terran-missile-turret.lua\")\nLoad(\"scripts/terran/unit-terran-refinery.lua\")\nLoad(\"scripts/terran/unit-terran-science-facility.lua\")\nLoad(\"scripts/terran/unit-terran-starport.lua\")\nLoad(\"scripts/terran/unit-terran-supply-depot.lua\")\nLoad(\"scripts/terran/unit-terran-comsat-station.lua\")\n\nLoad(\"scripts/terran/unit-terran-battlecruiser.lua\")\nLoad(\"scripts/terran/unit-terran-dropship.lua\")\nLoad(\"scripts/terran/unit-terran-firebat.lua\")\nLoad(\"scripts/terran/unit-terran-ghost.lua\")\nLoad(\"scripts/terran/unit-terran-goliath.lua\")\nLoad(\"scripts/terran/unit-terran-marine.lua\")\nLoad(\"scripts/terran/unit-terran-science-vessel.lua\")\nLoad(\"scripts/terran/unit-terran-scv.lua\")\nLoad(\"scripts/terran/unit-terran-siege-tank.lua\")\n--Load(\"scripts/terran/unit-terran-vulture.lua\")\nLoad(\"scripts/terran/unit-terran-wraith.lua\")\n\n--\n-- Buttons\n--\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-move\",\n  Action = \"move\",\n  Key = \"m\", Hint = \"~!Move\",\n  ForUnit = {\n    \"terran-group\",\n    \"unit-terran-battlecruiser\",\n    \"unit-terran-dropship\",\n    \"unit-terran-firebat\",\n    \"unit-terran-ghost\",\n    \"unit-terran-goliath\",\n    \"unit-terran-marine\",\n    \"unit-terran-science-vessel\",\n    \"unit-terran-scv\",\n    \"unit-terran-siege-tank-tank-mode\",\n    \"unit-terran-vulture\",\n    \"unit-terran-wraith\",\n  } } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-stop\",\n  Action = \"stop\",\n  Key = \"s\", Hint = \"~!Stop\",\n  ForUnit = {\n    \"terran-group\",\n    \"unit-terran-battlecruiser\",\n    \"unit-terran-dropship\",\n    \"unit-terran-firebat\",\n    \"unit-terran-ghost\",\n    \"unit-terran-goliath\",\n    \"unit-terran-marine\",\n    \"unit-terran-missile-turret\",\n    \"unit-terran-science-vessel\",\n    \"unit-terran-scv\",\n    \"unit-terran-siege-tank-tank-mode\",\n    \"unit-terran-vulture\",\n    \"unit-terran-wraith\",\n  } } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-attack\",\n  Action = \"attack\",\n  Key = \"a\", Hint = \"~!Attack\",\n  ForUnit = {\n    \"terran-group\",\n    \"unit-terran-battlecruiser\",\n    \"unit-terran-firebat\",\n    \"unit-terran-ghost\",\n    \"unit-terran-goliath\",\n    \"unit-terran-marine\",\n    \"unit-terran-scv\",\n    \"unit-terran-missile-turret\",\n    \"unit-terran-siege-tank-tank-mode\",\n    \"unit-terran-vulture\",\n    \"unit-terran-wraith\",\n  } } )\n\nDefineButton( { Pos = 4, Level = 0, Icon = \"icon-patrol\",\n  Action = \"patrol\",\n  Key = \"p\", Hint = \"~!Patrol\",\n  ForUnit = {\n    \"terran-group\",\n    \"unit-terran-battlecruiser\",\n    \"unit-terran-dropship\",\n    \"unit-terran-firebat\",\n    \"unit-terran-ghost\",\n    \"unit-terran-goliath\",\n    \"unit-terran-marine\",\n    \"unit-terran-missile-turret\",\n    \"unit-terran-science-vessel\",\n    \"unit-terran-siege-tank-tank-mode\",\n    \"unit-terran-vulture\",\n    \"unit-terran-wraith\",\n  } } )\n\nDefineButton( { Pos = 5, Level = 0, Icon = \"icon-hold-position\",\n  Action = \"stand-ground\",\n  Key = \"h\", Hint = \"~!Hold Position\",\n  ForUnit = {\n    \"terran-group\",\n    \"unit-terran-battlecruiser\",\n    \"unit-terran-dropship\",\n    \"unit-terran-firebat\",\n    \"unit-terran-ghost\",\n    \"unit-terran-goliath\",\n    \"unit-terran-marine\",\n    \"unit-terran-missile-turret\",\n    \"unit-terran-science-vessel\",\n    \"unit-terran-siege-tank-tank-mode\",\n    \"unit-terran-vulture\",\n    \"unit-terran-wraith\",\n  } } )\n\nDefineButton( { Pos = 6, Level = 0, Icon = \"icon-rally-point\",\n  Action = \"move\",\n  Key = \"r\", Hint = \"Set ~!Rally Point\",\n  ForUnit = {\n    \"unit-terran-barracks\",\n    \"unit-terran-command-center\",\n    \"unit-terran-starport\",\n  } } )\n\nDefineButton( { Pos = 9, Level = 0, Icon = \"icon-terran-liftoff\",\n  Action = \"move\",\n  Key = \"l\", Hint = \"~!Liftoff\",\n  ForUnit = {\n    \"unit-terran-barracks\",\n    \"unit-terran-command-center\",\n    \"unit-terran-engineering-bay\",\n    \"unit-terran-starport\",\n  } } )\n\n\n\n--\n-- Allow\n--\nDefineAllow(\"unit-terran-battlecruiser\",  \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-dropship\",       \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-firebat\",        \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-ghost\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-goliath\",        \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-marine\",         \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-science-vessel\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-scv\",            \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-siege-tank\",     \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-vulture\",        \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-wraith\",         \"AAAAAAAAAAAAAAAA\")\n\nDefineAllow(\"unit-terran-academy\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-armory\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-barracks\",         \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-bunker\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-command-center\",   \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-engineering-bay\",  \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-factory\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-missile-turret\",   \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-refinery\",         \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-science-facility\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-starport\",         \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-supply-depot\",     \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-terran-comsat-station\",   \"AAAAAAAAAAAAAAAA\")"
  },
  {
    "path": "scripts/terran/upgrade.lua",
    "content": "--\n--  Upgrades\n--\n\nlocal upgrades = {\n{ \"upgrade-terran-infantry-weapons1\", \"icon-terran-upgrade-infantry-weapons\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-weapons2\", \"icon-terran-upgrade-infantry-weapons\",\n  {   200,   175,   175,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-weapons3\", \"icon-terran-upgrade-infantry-weapons\",\n  {   200,   250,   250,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-armor1\", \"icon-terran-upgrade-infantry-armor\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-armor2\", \"icon-terran-upgrade-infantry-armor\",\n  {   200,   175,   175,     0,     0,     0,     0}},\n{ \"upgrade-terran-infantry-armor3\", \"icon-terran-upgrade-infantry-armor\",\n  {   200,   250,   250,     0,     0,     0,     0}},\n\n{ \"upgrade-terran-u238-shells\", \"icon-terran-u238-shells\",\n  {   200,   150,   150,     0,     0,     0,     0}},\n\n{ \"upgrade-terran-stim-pack\", \"icon-terran-stim-pack\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n}\n\nfor i = 1,table.getn(upgrades) do\n  u = CUpgrade:New(upgrades[i][1])\n  u.Icon = Icons[upgrades[i][2]]\n  for j = 1,table.getn(upgrades[1][3]) do\n    u.Costs[j - 1] = upgrades[i][3][j]\n  end\nend\n\n\n--\n--  Modifiers\n--\n\nDefineModifier(\"upgrade-terran-infantry-weapons1\",\n  {\"Level\", 1}, {\"PiercingDamage\", 2},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-weapons2\",\n  {\"Level\", 2}, {\"PiercingDamage\", 3},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-weapons3\",\n  {\"Level\", 3}, {\"PiercingDamage\", 4},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\nDefineModifier(\"upgrade-terran-infantry-armor1\",\n  {\"Level\", 1}, {\"Armor\", 2},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-armor2\",\n  {\"Level\", 2}, {\"Armor\", 3},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\nDefineModifier(\"upgrade-terran-infantry-armor3\",\n  {\"Level\", 3}, {\"Armor\", 4},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\nDefineModifier(\"upgrade-terran-u238-shells\",\n  {\"Level\", 1}, {\"AttackRange\", 5},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\nDefineModifier(\"upgrade-terran-stim-pack\",\n  {\"Level\", 1}, {\"Armor\", 2},\n  {\"apply-to\", \"unit-terran-marine\"}, {\"apply-to\", \"unit-terran-firebat\"},\n  {\"apply-to\", \"unit-terran-ghost\"})\n\n\n--\n--  Allow\n--\n\nDefineAllow(\"upgrade-terran-infantry-weapons1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-weapons2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-weapons3\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-armor1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-armor2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-infantry-armor3\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-stim-pack\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-terran-u238-shells\", \"AAAAAAAAAAAAAAAA\")\n\n\n--\n--  Dependencies\n--\n\nDefineDependency(\"upgrade-terran-infantry-weapons2\",\n  {\"upgrade-terran-infantry-weapons1\"})\nDefineDependency(\"upgrade-terran-infantry-weapons3\",\n  {\"upgrade-terran-infantry-weapons2\"})\nDefineDependency(\"upgrade-terran-infantry-armor2\",\n  {\"upgrade-terran-infantry-armor1\"})\nDefineDependency(\"upgrade-terran-infantry-armor3\",\n  {\"upgrade-terran-infantry-armor2\"})\n\nDefineDependency(\"unit-terran-ghost\",\n  {\"unit-terran-academy\", \"unit-terran-science-facility\",\n   --[[\"unit-terran-covert-ops\"]]})\n\nDefineDependency(\"unit-terran-supply-depot\",\n  {\"unit-terran-command-center\"})\nDefineDependency(\"unit-terran-engineering-bay\",\n  {\"unit-terran-command-center\"})\nDefineDependency(\"unit-terran-barracks\",\n  {\"unit-terran-command-center\"})\nDefineDependency(\"unit-terran-refinery\",\n  {\"unit-terran-command-center\"})\n\nDefineDependency(\"unit-terran-missile-turret\",\n  {\"unit-terran-engineering-bay\"})\n\nDefineDependency(\"unit-terran-academy\",\n  {\"unit-terran-barracks\"})\nDefineDependency(\"unit-terran-bunker\",\n  {\"unit-terran-barracks\"})\nDefineDependency(\"unit-terran-factory\",\n  {\"unit-terran-barracks\"})\n\nDefineDependency(\"unit-terran-armory\",\n  {\"unit-terran-factory\"})\nDefineDependency(\"unit-terran-starport\",\n  {\"unit-terran-factory\"})\n\nDefineDependency(\"unit-terran-science-facility\",\n  {\"unit-terran-starport\"})\n"
  },
  {
    "path": "scripts/tilesets.lua",
    "content": "Load(\"luagen/tilesets/ashworld.lua\")\nLoad(\"luagen/tilesets/badlands.lua\")\nLoad(\"luagen/tilesets/install.lua\")\nLoad(\"luagen/tilesets/jungle.lua\")\nLoad(\"luagen/tilesets/platform.lua\")\n"
  },
  {
    "path": "scripts/ui.lua",
    "content": "--       _________ __                 __\n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      ui.lua - Define the user interface\n--\n--      (c) Copyright 2004-2006 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nLoad(\"scripts/widgets.lua\")\nLoad(\"scripts/gameui.lua\")\n\n--\n--  Define Decorations.\n--\n\n--ManaSprite(\"ui/mana.png\", -7, -7, 7, 7)\n--ManaSprite(\"ui/ppbrfull.png\", 0, -1, 108, 9)\n-- DefineSprites({Name=\"sprite-mana\", File=\"ui/ppbrfull.png\",\n--   Offset={0, -1}, Size={108, 9}})\n--HealthSprite(\"ui/health.png\", 1, -7, 7, 7)\n--HealthSprite(\"ui/ppbrfull.png\", 0, -1, 108, 9)\n\n--DefineSprites({Name = \"sprite-spell\", File = \"ui/bloodlust,haste,slow,invisible,shield.png\",\n--        Offset = {1, 1}, Size = {16, 16}})\n\n--DefineDecorations({Index = \"Bloodlust\", ShowOpponent = true,\n--  Offset = {0, 0}, Method = {\"static-sprite\", {\"sprite-spell\", 0}}})\n--DefineDecorations({Index = \"Haste\", ShowOpponent = true,\n--  Offset = {16, 0}, Method = {\"static-sprite\", {\"sprite-spell\", 1}}})\n--DefineDecorations({Index = \"Slow\", ShowOpponent = true,\n--  Offset = {16, 0}, Method = {\"static-sprite\", {\"sprite-spell\", 2}}})\n--DefineDecorations({Index = \"Invisible\", ShowOpponent = true,\n--  Offset = {32, 0}, Method = {\"static-sprite\", {\"sprite-spell\", 3}}})\n--DefineDecorations({Index = \"UnholyArmor\", ShowOpponent = true,\n--  Offset = {48, 0}, Method = {\"static-sprite\", {\"sprite-spell\", 4}}})\n\n--ShowHealthBar()\n--ShowHealthVertical()\n--ShowHealthHorizontal()\n--ShowHealthDot()\n\n-- DefineSprites({Name=\"sprite-health\", File=\"ui/ppbrfull.png\",\n--   Offset={0, -1}, Size={108, 9}})\n-- DefineDecorations({Index=\"HitPoints\", HideNeutral=true, CenterX=true, ShowWhenMax=true,\n--   ShowOnlySelected=false,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-health\"}}})\n\n--ShowManaBar()\n--ShowManaVertical()\n--ShowManaHorizontal()\n--ShowManaDot()\n-- DefineDecorations({Index=\"Mana\", HideNeutral=true, CenterX=true,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-mana\"}}})\n-- DefineDecorations({Index=\"Transport\", HideNeutral=true, CenterX=true,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-mana\"}}})\n-- DefineDecorations({Index=\"Research\", HideNeutral=true, CenterX=true,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-mana\"}}})\n-- DefineDecorations({Index=\"Training\", HideNeutral=true, CenterX=true,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-mana\"}}})\n-- DefineDecorations({Index=\"UpgradeTo\", HideNeutral=true, CenterX=true,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-mana\"}}})\n-- DefineDecorations({Index=\"GiveResource\", HideNeutral=true, CenterX=true,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-mana\"}}})\n-- DefineDecorations({Index=\"CarryResource\", HideNeutral=true, CenterX=true,\n--   OffsetPercent={50, 100}, Method={\"sprite\", {\"sprite-mana\"}}})\n\n--ShowNoFull()\n--ShowFull()\n\n--  Uncomment next, to show bars and dots always on top.\n--  FIXME: planned feature\n--DecorationOnTop()\n\nlocal original_width = 640\nlocal original_height = 480\n\nlocal offx = 0\n-- TODO: for centered panel, use the offx below\n-- local offx = (Video.Width - original_width) / 2\nlocal offy = Video.Height - original_height\n\n--\n--  Define Panels\n--\nlocal info_panel_x = offx + 0\nlocal info_panel_y = Video.Height - original_height + 200\n\nlocal name_line_x = 280\nlocal name_line_y = 198\n\nlocal line_height = Fonts[\"small\"]:Height()\n\nlocal min_damage = Div(ActiveUnitVar(\"PiercingDamage\"), 2)\nlocal max_damage = Add(ActiveUnitVar(\"PiercingDamage\"), ActiveUnitVar(\"BasicDamage\"))\nlocal damage_bonus = Sub(ActiveUnitVar(\"PiercingDamage\", \"Value\", \"Type\"),\n              ActiveUnitVar(\"PiercingDamage\", \"Value\", \"Initial\"));\n\nMainPanelGraphics = CGraphic:New(\"pcmdbtns.png\", 36, 36)\nMainPanelGraphics:Load()\nProgressBarEmpty = CGraphic:New(\"ui/tpbrempt.png\", 108, 9)\nProgressBarEmpty:Load()\nProgressBarFull = CGraphic:New(\"ui/tpbrfull.png\", 3, 9)\nProgressBarFull:Load()\n\nDefinePanelContents(\n-- Default presentation. ------------------------\n  {\n    Ident = \"panel-general-contents\",\n    Pos = {info_panel_x, info_panel_y},\n    DefaultFont = \"game\",\n    Contents = {\n      {\n        Pos = {160, 192}, More = {\"Icon\", {Unit = \"ItSelf\", SingleSelection = true}},\n      },\n      {\n        Pos = {192, 256}, Condition = {ShowOpponent = false, HideNeutral = true},\n        More = {\"FormattedText2\", {\n          Font = \"small\", Variable = \"HitPoints\", Format = \"~light-green~%d/%d\",\n          Component1 = \"Value\", Component2 = \"Max\", Centered = true}}\n      },\n      {\n        Pos = {192, 256 + line_height}, Condition = {ShowOpponent = false, HideNeutral = true, ShieldPoints = \"only\"},\n        More = {\"FormattedText2\", {\n          Font = \"small\", Variable = \"ShieldPoints\", Format = \"~light-blue~%d/%d\",\n          Component1 = \"Value\", Component2 = \"Max\", Centered = true}}\n      },\n      { Pos = {name_line_x, name_line_y}, More = {\"Text\", {Text = Line(1, UnitName(\"Active\"), 110, \"game\"), Centered = false}} },\n      { Pos = {name_line_x, name_line_y + line_height}, More = {\"Text\", {Text = Line(2, UnitName(\"Active\"), 110, \"game\"), Centered = false}} },\n\n      -- Resource Left\n      { Pos = {name_line_x, name_line_y + 2 * line_height}, Condition = {ShowOpponent = false, GiveResource = \"only\"},\n        More = {\"FormattedText2\", {\n          Format = \"%s Left:%d\", Variable = \"GiveResource\",\n          Component1 = \"Name\", Component2 = \"Value\", Centered = false}}\n      },\n    }\n  },\n  {\n    Ident = \"panel-supply-building-contents\",\n    Pos = {info_panel_x, info_panel_y}, DefaultFont = \"game\",\n    Condition = {ShowOpponent = false, HideNeutral = true, Build = \"false\", Supply = \"only\", Training = \"false\", UpgradeTo = \"false\"},\n    Contents = {\n      {\n        Pos = {name_line_x, name_line_y + 2 * line_height},\n        More = { \"Text\", { Text = Concat(_(\"Supply: \"), String(PlayerData(ActiveUnitVar(\"Player\", \"Value\"), \"Supply\", \"\"))) } }\n      },\n      {\n        Pos = {name_line_x, name_line_y + 3 * line_height},\n        More = {\n          \"Text\",\n          {\n            Text = Concat(_(\"Demand: \"),\n            If(GreaterThan(\n            PlayerData(ActiveUnitVar(\"Player\", \"Value\"), \"Demand\", \"\"),\n            PlayerData(ActiveUnitVar(\"Player\", \"Value\"), \"Supply\", \"\")),\n            InverseVideo(String(PlayerData(ActiveUnitVar(\"Player\", \"Value\"), \"Demand\", \"\"))),\n            String(PlayerData(ActiveUnitVar(\"Player\", \"Value\"), \"Demand\", \"\"))))\n          },\n        },\n      },\n    },\n  },\n  {\n    Ident = \"panel-unit-under-construction\",\n    Pos = {info_panel_x, info_panel_y},\n    DefaultFont = \"game\",\n    Condition = {ShowOpponent = false, Build = \"only\"},\n    Contents = {\n      -- { Pos = {205, info_panel_y + 100}, Condition = {ShowOpponent = false, HideNeutral = true, Build = \"only\"},\n      --   More = {\"CompleteBar\", {Variable = \"Build\", Width = 100, Height = 6, Color = \"green\", Border = true}}\n      -- },\n      { Pos = {name_line_x - 2,        name_line_y + line_height * 2}, Condition = {Build = \"only\"}, More = {\"Graphic\", \"ui/tpbrempt.png\"}},\n      { Pos = {name_line_x - 2 +  1*3, name_line_y + line_height * 2}, Condition = {Build =  \">3\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  1}}},\n      { Pos = {name_line_x - 2 +  2*3, name_line_y + line_height * 2}, Condition = {Build =  \">6\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  2}}},\n      { Pos = {name_line_x - 2 +  3*3, name_line_y + line_height * 2}, Condition = {Build =  \">9\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  3}}},\n      { Pos = {name_line_x - 2 +  4*3, name_line_y + line_height * 2}, Condition = {Build = \">12\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  4}}},\n      { Pos = {name_line_x - 2 +  5*3, name_line_y + line_height * 2}, Condition = {Build = \">15\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  5}}},\n      { Pos = {name_line_x - 2 +  6*3, name_line_y + line_height * 2}, Condition = {Build = \">18\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  6}}},\n      { Pos = {name_line_x - 2 +  7*3, name_line_y + line_height * 2}, Condition = {Build = \">21\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  7}}},\n      { Pos = {name_line_x - 2 +  8*3, name_line_y + line_height * 2}, Condition = {Build = \">24\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  8}}},\n      { Pos = {name_line_x - 2 +  9*3, name_line_y + line_height * 2}, Condition = {Build = \">27\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  9}}},\n      { Pos = {name_line_x - 2 + 10*3, name_line_y + line_height * 2}, Condition = {Build = \">30\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 10}}},\n      { Pos = {name_line_x - 2 + 11*3, name_line_y + line_height * 2}, Condition = {Build = \">33\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 11}}},\n      { Pos = {name_line_x - 2 + 12*3, name_line_y + line_height * 2}, Condition = {Build = \">36\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 12}}},\n      { Pos = {name_line_x - 2 + 13*3, name_line_y + line_height * 2}, Condition = {Build = \">39\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 13}}},\n      { Pos = {name_line_x - 2 + 14*3, name_line_y + line_height * 2}, Condition = {Build = \">42\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 14}}},\n      { Pos = {name_line_x - 2 + 15*3, name_line_y + line_height * 2}, Condition = {Build = \">45\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 15}}},\n      { Pos = {name_line_x - 2 + 16*3, name_line_y + line_height * 2}, Condition = {Build = \">48\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 16}}},\n      { Pos = {name_line_x - 2 + 17*3, name_line_y + line_height * 2}, Condition = {Build = \">51\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 17}}},\n      { Pos = {name_line_x - 2 + 18*3, name_line_y + line_height * 2}, Condition = {Build = \">54\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 18}}},\n      { Pos = {name_line_x - 2 + 19*3, name_line_y + line_height * 2}, Condition = {Build = \">57\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 19}}},\n      { Pos = {name_line_x - 2 + 20*3, name_line_y + line_height * 2}, Condition = {Build = \">60\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 20}}},\n      { Pos = {name_line_x - 2 + 21*3, name_line_y + line_height * 2}, Condition = {Build = \">63\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 21}}},\n      { Pos = {name_line_x - 2 + 22*3, name_line_y + line_height * 2}, Condition = {Build = \">66\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 22}}},\n      { Pos = {name_line_x - 2 + 23*3, name_line_y + line_height * 2}, Condition = {Build = \">69\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 23}}},\n      { Pos = {name_line_x - 2 + 24*3, name_line_y + line_height * 2}, Condition = {Build = \">72\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 24}}},\n      { Pos = {name_line_x - 2 + 25*3, name_line_y + line_height * 2}, Condition = {Build = \">75\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 25}}},\n      { Pos = {name_line_x - 2 + 26*3, name_line_y + line_height * 2}, Condition = {Build = \">78\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 26}}},\n      { Pos = {name_line_x - 2 + 27*3, name_line_y + line_height * 2}, Condition = {Build = \">81\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 27}}},\n      { Pos = {name_line_x - 2 + 28*3, name_line_y + line_height * 2}, Condition = {Build = \">84\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 28}}},\n      { Pos = {name_line_x - 2 + 29*3, name_line_y + line_height * 2}, Condition = {Build = \">87\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 29}}},\n      { Pos = {name_line_x - 2 + 30*3, name_line_y + line_height * 2}, Condition = {Build = \">90\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 30}}},\n      { Pos = {name_line_x - 2 + 31*3, name_line_y + line_height * 2}, Condition = {Build = \">93\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 31}}},\n      { Pos = {name_line_x - 2 + 32*3, name_line_y + line_height * 2}, Condition = {Build = \">96\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 32}}},\n      { Pos = {name_line_x - 2 + 33*3, name_line_y + line_height * 2}, Condition = {Build = \">99\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 33}}},\n\n      { Pos = {name_line_x, name_line_y + line_height * 3}, More = {\"Text\", \"Under Construction\", \"Centered\", false} },\n\n      -- { Pos = {165, info_panel_y + 78}, Condition = {ShowOpponent = false, HideNeutral = true, Build = \"only\"},\n      --   More = {\"Icon\", {Unit = \"Worker\"}}}\n    }\n  },\n  {\n    Ident = \"panel-training-contents\",\n    Pos = {info_panel_x, info_panel_y},\n    DefaultFont = \"game\",\n    Condition = {ShowOpponent = false, HideNeutral = true, Training = \"only\"},\n    Contents = {\n      -- boxes\n      { Pos = {238, 194}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {238, 232}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {276, 232}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {314, 232}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {352, 232}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      -- numbers\n      { Pos = {238 + 7, 194 + 10}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 12}}},\n      { Pos = {238 + 7, 232 + 10}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 14}}},\n      { Pos = {276 + 7, 232 + 10}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 16}}},\n      { Pos = {314 + 7, 232 + 10}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 18}}},\n      { Pos = {352 + 7, 232 + 10}, Condition = {Training = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 20}}},\n      -- progressbar\n      { Pos = {name_line_x - 2,        name_line_y + line_height * 2}, Condition = {Training = \"only\"}, More = {\"Graphic\", \"ui/tpbrempt.png\"}},\n      { Pos = {name_line_x - 2 +  1*3, name_line_y + line_height * 2}, Condition = {Training =  \">3\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  1}}},\n      { Pos = {name_line_x - 2 +  2*3, name_line_y + line_height * 2}, Condition = {Training =  \">6\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  2}}},\n      { Pos = {name_line_x - 2 +  3*3, name_line_y + line_height * 2}, Condition = {Training =  \">9\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  3}}},\n      { Pos = {name_line_x - 2 +  4*3, name_line_y + line_height * 2}, Condition = {Training = \">12\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  4}}},\n      { Pos = {name_line_x - 2 +  5*3, name_line_y + line_height * 2}, Condition = {Training = \">15\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  5}}},\n      { Pos = {name_line_x - 2 +  6*3, name_line_y + line_height * 2}, Condition = {Training = \">18\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  6}}},\n      { Pos = {name_line_x - 2 +  7*3, name_line_y + line_height * 2}, Condition = {Training = \">21\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  7}}},\n      { Pos = {name_line_x - 2 +  8*3, name_line_y + line_height * 2}, Condition = {Training = \">24\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  8}}},\n      { Pos = {name_line_x - 2 +  9*3, name_line_y + line_height * 2}, Condition = {Training = \">27\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  9}}},\n      { Pos = {name_line_x - 2 + 10*3, name_line_y + line_height * 2}, Condition = {Training = \">30\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 10}}},\n      { Pos = {name_line_x - 2 + 11*3, name_line_y + line_height * 2}, Condition = {Training = \">33\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 11}}},\n      { Pos = {name_line_x - 2 + 12*3, name_line_y + line_height * 2}, Condition = {Training = \">36\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 12}}},\n      { Pos = {name_line_x - 2 + 13*3, name_line_y + line_height * 2}, Condition = {Training = \">39\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 13}}},\n      { Pos = {name_line_x - 2 + 14*3, name_line_y + line_height * 2}, Condition = {Training = \">42\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 14}}},\n      { Pos = {name_line_x - 2 + 15*3, name_line_y + line_height * 2}, Condition = {Training = \">45\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 15}}},\n      { Pos = {name_line_x - 2 + 16*3, name_line_y + line_height * 2}, Condition = {Training = \">48\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 16}}},\n      { Pos = {name_line_x - 2 + 17*3, name_line_y + line_height * 2}, Condition = {Training = \">51\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 17}}},\n      { Pos = {name_line_x - 2 + 18*3, name_line_y + line_height * 2}, Condition = {Training = \">54\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 18}}},\n      { Pos = {name_line_x - 2 + 19*3, name_line_y + line_height * 2}, Condition = {Training = \">57\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 19}}},\n      { Pos = {name_line_x - 2 + 20*3, name_line_y + line_height * 2}, Condition = {Training = \">60\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 20}}},\n      { Pos = {name_line_x - 2 + 21*3, name_line_y + line_height * 2}, Condition = {Training = \">63\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 21}}},\n      { Pos = {name_line_x - 2 + 22*3, name_line_y + line_height * 2}, Condition = {Training = \">66\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 22}}},\n      { Pos = {name_line_x - 2 + 23*3, name_line_y + line_height * 2}, Condition = {Training = \">69\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 23}}},\n      { Pos = {name_line_x - 2 + 24*3, name_line_y + line_height * 2}, Condition = {Training = \">72\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 24}}},\n      { Pos = {name_line_x - 2 + 25*3, name_line_y + line_height * 2}, Condition = {Training = \">75\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 25}}},\n      { Pos = {name_line_x - 2 + 26*3, name_line_y + line_height * 2}, Condition = {Training = \">78\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 26}}},\n      { Pos = {name_line_x - 2 + 27*3, name_line_y + line_height * 2}, Condition = {Training = \">81\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 27}}},\n      { Pos = {name_line_x - 2 + 28*3, name_line_y + line_height * 2}, Condition = {Training = \">84\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 28}}},\n      { Pos = {name_line_x - 2 + 29*3, name_line_y + line_height * 2}, Condition = {Training = \">87\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 29}}},\n      { Pos = {name_line_x - 2 + 30*3, name_line_y + line_height * 2}, Condition = {Training = \">90\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 30}}},\n      { Pos = {name_line_x - 2 + 31*3, name_line_y + line_height * 2}, Condition = {Training = \">93\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 31}}},\n      { Pos = {name_line_x - 2 + 32*3, name_line_y + line_height * 2}, Condition = {Training = \">96\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 32}}},\n      { Pos = {name_line_x - 2 + 33*3, name_line_y + line_height * 2}, Condition = {Training = \">99\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 33}}},\n    }, \n  },\n  {\n    Ident = \"panel-upgrading-contents\",\n    Pos = {info_panel_x, info_panel_y},\n    DefaultFont = \"game\",\n    Condition = {ShowOpponent = false, HideNeutral = true, UpgradeTo = \"only\"},\n    Contents = {\n      -- boxes\n      { Pos = {238, 194}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {238, 232}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {276, 232}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {314, 232}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      { Pos = {352, 232}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 6}}},\n      -- numbers\n      { Pos = {238 + 7, 194 + 10}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 12}}},\n      { Pos = {238 + 7, 232 + 10}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 14}}},\n      { Pos = {276 + 7, 232 + 10}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 16}}},\n      { Pos = {314 + 7, 232 + 10}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 18}}},\n      { Pos = {352 + 7, 232 + 10}, Condition = {UpgradeTo = \"only\", Building = \"only\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 20}}},\n      -- progressbar\n      { Pos = {name_line_x - 2,        name_line_y + line_height * 2}, Condition = {UpgradeTo = \"only\"}, More = {\"Graphic\", \"ui/tpbrempt.png\"}},\n      { Pos = {name_line_x - 2 +  1*3, name_line_y + line_height * 2}, Condition = {UpgradeTo =  \">3\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  1}}},\n      { Pos = {name_line_x - 2 +  2*3, name_line_y + line_height * 2}, Condition = {UpgradeTo =  \">6\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  2}}},\n      { Pos = {name_line_x - 2 +  3*3, name_line_y + line_height * 2}, Condition = {UpgradeTo =  \">9\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  3}}},\n      { Pos = {name_line_x - 2 +  4*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">12\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  4}}},\n      { Pos = {name_line_x - 2 +  5*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">15\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  5}}},\n      { Pos = {name_line_x - 2 +  6*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">18\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  6}}},\n      { Pos = {name_line_x - 2 +  7*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">21\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  7}}},\n      { Pos = {name_line_x - 2 +  8*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">24\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  8}}},\n      { Pos = {name_line_x - 2 +  9*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">27\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame =  9}}},\n      { Pos = {name_line_x - 2 + 10*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">30\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 10}}},\n      { Pos = {name_line_x - 2 + 11*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">33\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 11}}},\n      { Pos = {name_line_x - 2 + 12*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">36\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 12}}},\n      { Pos = {name_line_x - 2 + 13*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">39\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 13}}},\n      { Pos = {name_line_x - 2 + 14*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">42\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 14}}},\n      { Pos = {name_line_x - 2 + 15*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">45\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 15}}},\n      { Pos = {name_line_x - 2 + 16*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">48\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 16}}},\n      { Pos = {name_line_x - 2 + 17*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">51\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 17}}},\n      { Pos = {name_line_x - 2 + 18*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">54\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 18}}},\n      { Pos = {name_line_x - 2 + 19*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">57\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 19}}},\n      { Pos = {name_line_x - 2 + 20*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">60\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 20}}},\n      { Pos = {name_line_x - 2 + 21*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">63\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 21}}},\n      { Pos = {name_line_x - 2 + 22*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">66\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 22}}},\n      { Pos = {name_line_x - 2 + 23*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">69\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 23}}},\n      { Pos = {name_line_x - 2 + 24*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">72\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 24}}},\n      { Pos = {name_line_x - 2 + 25*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">75\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 25}}},\n      { Pos = {name_line_x - 2 + 26*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">78\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 26}}},\n      { Pos = {name_line_x - 2 + 27*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">81\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 27}}},\n      { Pos = {name_line_x - 2 + 28*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">84\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 28}}},\n      { Pos = {name_line_x - 2 + 29*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">87\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 29}}},\n      { Pos = {name_line_x - 2 + 30*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">90\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 30}}},\n      { Pos = {name_line_x - 2 + 31*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">93\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 31}}},\n      { Pos = {name_line_x - 2 + 32*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">96\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 32}}},\n      { Pos = {name_line_x - 2 + 33*3, name_line_y + line_height * 2}, Condition = {UpgradeTo = \">99\"}, More = {\"Graphic\", {Graphic = \"ui/tpbrfull.png\", Frame = 33}}},\n    }, \n  },\n  {\n    Ident = \"panel-armored-unit-contents\",\n    Pos = {info_panel_x, info_panel_y},\n    DefaultFont = \"small\",\n    Condition = {ShowOpponent = false, HideNeutral = false, Build = \"false\", Training = \"false\"},\n    Contents = {\n      { Pos = {238 + 9, 232 + 12}, Condition = {Armor = \"only\", Transport = \"<1\"}, More = {\"Graphic\", {Graphic = \"cmdicons.png\", Frame = 292}}},\n      { Pos = {238 + 7, 232 + 10}, Condition = {Armor = \"only\", Transport = \"<1\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 24}}},\n      { Pos = {238 + 7 + 24, 232 + 34}, Condition = {Armor = \"only\", Transport = \"<1\"},  More = {\"Text\", { Text = \"\", Variable = \"Armor\", Stat = true, Centered = true}}},\n\n      { Pos = {276 + 9, 232 + 12}, Condition = {PiercingDamage = \"only\", Transport = \"<1\"}, More = {\"Graphic\", {Graphic = \"cmdicons.png\", Frame = 290}}},\n      { Pos = {276 + 7, 232 + 10}, Condition = {PiercingDamage = \"only\", Transport = \"<1\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 24}}},\n      { Pos = {276 + 7 + 24, 232 + 34}, Condition = {PiercingDamage = \"only\", Transport = \"<1\"},  More = {\"Text\", { Text = \"\", Variable = \"PiercingDamage\", Stat = true, Centered = true}}},\n\n      { Pos = {314 + 9, 232 + 12}, Condition = {AttackRange = \"only\", Transport = \"<1\"}, More = {\"Graphic\", {Graphic = \"cmdicons.png\", Frame = 288}}},\n      { Pos = {314 + 7, 232 + 10}, Condition = {AttackRange = \"only\", Transport = \"<1\"}, More = {\"Graphic\", {Graphic = \"pcmdbtns.png\", Frame = 24}}},\n      { Pos = {314 + 7 + 24, 232 + 34}, Condition = {AttackRange = \"only\", Transport = \"<1\"},  More = {\"Text\", { Text = \"\", Variable = \"AttackRange\", Stat = true, Centered = true}}},\n    }\n  },\n  {\n    Ident = \"panel-own-unit-contents\",\n    Pos = {info_panel_x, info_panel_y},\n    DefaultFont = \"game\",\n    Condition = {ShowOpponent = false, HideNeutral = true, Build = \"false\"},\n    Contents = {\n      { Pos = {37, 86}, Condition = {PiercingDamage = \"only\"},\n        More = {\"Text\", {Text = Concat(\"Damage: \", String(min_damage), \"-\", String(max_damage),\n                                        If(Equal(0, damage_bonus), \"\",\n                                        InverseVideo(Concat(\"+\", String(damage_bonus)))) )}}\n      \n      },\n      { Pos = {47, 102}, Condition = {AttackRange = \"only\"},\n        More = {\"Text\", { Text = \"Range: \", Variable = \"AttackRange\" , Stat = true}}\n      },\n      -- Research\n      { Pos = {12, 153}, Condition = {Research = \"only\"},\n        More = {\"CompleteBar\", {Variable = \"Research\", Width = 152, Height = 12}}\n      },\n      { Pos = {16, 86}, Condition = {Research = \"only\"}, More = {\"Text\", \"Researching:\"}},\n      { Pos = {50, 154}, Condition = {Research = \"only\"}, More = {\"Text\", \"% Complete\"}},\n      -- Mana\n      { Pos = {16, 148}, Condition = {Mana = \"only\"},\n        More = {\"CompleteBar\", {Variable = \"Mana\", Height = 16, Width = 140, Border = true}}\n      },\n      { Pos = {86, 150}, More = {\"Text\", {Variable = \"Mana\"}}, Condition = {Mana = \"only\"} },\n      -- Ressource Carry\n      { Pos = {name_line_x, name_line_y + 2 * line_height}, Condition = {CarryResource = \"only\"},\n        More = {\"FormattedText2\", {\n          Format = \"Carry: %d %s\", Variable = \"CarryResource\",\n          Component1 = \"Value\", Component2 = \"Name\"\n        }}\n      }\n\n    }\n  }\n  )\n\nUI.MessageFont = Fonts[\"game\"]\nUI.MessageScrollSpeed = 5\n\nDefineCursor({\n  Name = \"cursor-point\",\n  Race = \"any\",\n  File = \"ui/cursors/arrow.png\",\n  Rate = 50,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-glass\",\n  Race = \"any\",\n  File = \"ui/cursors/magg.png\",\n  Rate = 50,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-cross\",\n  Race = \"any\",\n  File = \"ui/cursors/drag.png\",\n  Rate = 50,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-scroll\",\n  Race = \"any\",\n  File = \"ui/cursors/drag.png\",\n  HotSpot = {63, 63},\n  Size = {128, 128}})\n  \n  \nDefineCursor({\n  Name = \"cursor-green-hair\",\n  Race = \"any\",\n  File = \"ui/cursors/targg.png\",\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-yellow-hair\",\n  Race = \"any\",\n  File = \"ui/cursors/targn.png\",\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-red-hair\",\n  Race = \"any\",\n  File = \"ui/cursors/targr.png\",\n  HotSpot = {63, 63},\n  Size = {128, 128}})\n\n\n\nDefineCursor({\n  Name = \"cursor-arrow-e\",\n  Race = \"any\",\n  File = \"ui/cursors/scrollr.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-arrow-ne\",\n  Race = \"any\",\n  File = \"ui/cursors/scrollur.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-arrow-n\",\n  Race = \"any\",\n  File = \"ui/cursors/scrollu.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-arrow-nw\",\n  Race = \"any\",\n  File = \"ui/cursors/scrollul.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-arrow-w\",\n  Race = \"any\",\n  File = \"ui/cursors/scrolll.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-arrow-s\",\n  Race = \"any\",\n  File = \"ui/cursors/scrolld.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-arrow-sw\",\n  Race = \"any\",\n  File = \"ui/cursors/scrolldl.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\nDefineCursor({\n  Name = \"cursor-arrow-se\",\n  Race = \"any\",\n  File = \"ui/cursors/scrolldr.png\",\n  Rate = 67,\n  HotSpot = {63, 63},\n  Size = {128, 128}})\n"
  },
  {
    "path": "scripts/units.lua",
    "content": "--       _________ __                 __\n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      units.lua - Define the used unit-types.\n--\n--      (c) Copyright 2005 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nUnitTypeFiles = {}\n\n-- this is just a dummy still animation as fallback\nDefineAnimations(\"animations-dummy-still\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n-- order of lua includes matter\nLoad(\"luagen/portrait/luagen-portrait.lua\")\nLoad(\"luagen/images/luagen-images.lua\")\nLoad(\"luagen/units/luagen-units.lua\")\n\nLoad(\"scripts/terran/units.lua\")\nLoad(\"scripts/zerg/units.lua\")\nLoad(\"scripts/protoss/units.lua\")\nLoad(\"scripts/neutral/units.lua\")\n\nLoad(\"luagen/tests/CreateUnitLuaTest.lua\")\n\nfunction CreateUnitTest(unit, num)\n  if not num then num = 10 end\n  \n  for i=1,num do \n    CreateUnit(unit, 0, {10, 10})\n  end    \nend\n\n"
  },
  {
    "path": "scripts/upgrade.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      upgrade.lua - Define the dependencies and upgrades.\n--\n--      (c) Copyright 2005 by Lutz Sammer and Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\n-- Load the different races\nLoad(\"scripts/terran/upgrade.lua\")\nLoad(\"scripts/zerg/upgrade.lua\")\n\n"
  },
  {
    "path": "scripts/widgets.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      widgets.lua - Define the widgets\n--\n--      (c) Copyright 2005 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nfunction DefineButtonStyles(race)\n  DefineButtonStyle(race..\" menu button\", {\n    Size = {64, 20},\n    Font = \"font8\",\n    TextNormalColor = \"white\",\n    TextReverseColor = \"white\",\n    TextAlign = \"Center\",\n    TextPos = {33, 6},\n    Default = {\n      File = \"ui/\"..race..\"/menu.png\",\n    },\n    Hover = {\n      TextNormalColor = \"white\",\n    },\n    Clicked = {\n      File = \"ui/\"..race..\"/menu_pressed.png\",\n      TextPos = {31, 4},\n    },\n  })\n\n  DefineButtonStyle(race..\" diplomacy button\", {\n    Size = {64, 20},\n    Font = \"font8\",\n    TextNormalColor = \"white\",\n    TextReverseColor = \"white\",\n    TextAlign = \"Center\",\n    TextPos = {33, 6},\n    Default = {\n      File = \"ui/\"..race..\"/diplomacy.png\",\n    },\n    Hover = {\n      TextNormalColor = \"white\",\n    },\n    Clicked = {\n      File = \"ui/\"..race..\"/diplomacy_pressed.png\",\n      TextPos = {31, 4},\n    },\n  })\n  \n  DefineButtonStyle(race..\" minimap terrain button\", {\n    Size = {64, 20},\n    Font = \"font8\",\n    TextNormalColor = \"white\",\n    TextReverseColor = \"white\",\n    TextAlign = \"Center\",\n    TextPos = {33, 6},\n    Default = {\n      File = \"ui/\"..race..\"/minimap.png\",\n    },\n    Hover = {\n      TextNormalColor = \"white\",\n    },\n    Clicked = {\n      File = \"ui/\"..race..\"/minimap_pressed.png\",\n      TextPos = {31, 4},\n    },\n  })\nend\n\nDefineButtonStyles(\"terran\")\nDefineButtonStyles(\"zerg\")\nDefineButtonStyles(\"protoss\")\n\n\nDefineButtonStyle(\"icon\", {\n  Size = {36, 34},\n  Font = \"game\",\n  TextNormalColor = \"white\",\n  TextReverseColor = \"white\",\n  TextAlign = \"Right\",\n  TextPos = {36, 24},\n  Default = {\n    --[[Border = {\n      Color = {0, 0, 0}, Size = 1,\n    },]]\n  },\n  Hover = {\n    TextNormalColor = \"white\",\n    --[[Border = {\n      Color = {128, 128, 128}, Size = 1,\n    },]]\n  },\n--[[\n  Selected = {\n    Border = {\n      Color = {0, 252, 0}, Size = 1,\n    },\n  },]]\n  Clicked = {\n    TextNormalColor = \"white\",\n    --[[Border = {\n      Color = {128, 128, 128}, Size = 1,\n    },]]\n  },\n--[[\n  Disabled = {\n  },]]\n})\n\n\nDefineButtonStyle(\"training\", {\n  Size = {36, 34},\n  Font = \"game\",\n  TextNormalColor = \"white\",\n  TextReverseColor = \"white\",\n  TextAlign = \"Right\",\n  TextPos = {36, 24},\n  Default = {\n  },\n  Hover = {\n    -- File = \"ui/pcmdbtns.png\", -- TODO: per race buttons\n    -- Frame = 5,\n    Size = {36, 34},\n    Border = {\n      SolidColor = {99, 99, 255},\n      Size = 2,\n    }\n  },\n--[[\n  Selected = {\n    Border = {\n      Color = {0, 252, 0}, Size = 1,\n    },\n  },]]\n  Clicked = {\n    TextNormalColor = \"white\",\n    --[[Border = {\n      Color = {128, 128, 128}, Size = 1,\n    },]]\n  },\n--[[\n  Disabled = {\n  },]]\n})\n"
  },
  {
    "path": "scripts/zerg/campaign1.lua",
    "content": "campaign_steps = {}\ncampaign_menu = {}\n\ncampaign_steps[#campaign_steps + 1] = function() RunImageStep(\"campaigns/zerg/EstZ0t.txt\") end\ncampaign_menu[#campaign_menu + 1] = #campaign_steps\ncampaign_steps[#campaign_steps + 1] = CreateMapStep(\"campaigns/zerg/tutorial/scenario.smp\")\n\nfor i=1,10 do\n  campaign_steps[#campaign_steps + 1] = function() RunImageStep(string.format(\"campaigns/zerg/EstZ%02d.txt\", i)) end\n  campaign_menu[#campaign_menu + 1] = #campaign_steps\n  campaign_steps[#campaign_steps + 1] = CreateMapStep(string.format(\"campaigns/zerg/%02d/scenario.smp\", i))\nend\n"
  },
  {
    "path": "scripts/zerg/construction.lua",
    "content": "-- FIXME: need support for animations while building\n\nDefineConstruction(\"construction-zerg\", {\n  Files = image_102_zerg_zbuild_var,\n  ShadowFiles = image_102_zerg_zbuild_var,\n  Constructions = {\n   {Percent = 0,\n    File = \"construction\",\n    Frame = 0},\n   {Percent = 1,\n    File = \"construction\",\n    Frame = 1},\n{Percent = 2,\nFile = \"construction\",\nFrame = 7},{Percent = 3,\nFile = \"construction\",\nFrame = 6},{Percent = 4,\nFile = \"construction\",\nFrame = 7},{Percent = 5,\nFile = \"construction\",\nFrame = 8},{Percent = 6,\nFile = \"construction\",\nFrame = 9},{Percent = 7,\nFile = \"construction\",\nFrame = 8},{Percent = 8,\nFile = \"construction\",\nFrame = 7},{Percent = 9,\nFile = \"construction\",\nFrame = 8},{Percent = 10,\nFile = \"construction\",\nFrame = 9},{Percent = 11,\nFile = \"construction\",\nFrame = 8},{Percent = 12,\nFile = \"construction\",\nFrame = 7},{Percent = 13,\nFile = \"construction\",\nFrame = 8},{Percent = 14,\nFile = \"construction\",\nFrame = 9},{Percent = 15,\nFile = \"construction\",\nFrame = 8},{Percent = 16,\nFile = \"construction\",\nFrame = 7},{Percent = 17,\nFile = \"construction\",\nFrame = 8},{Percent = 18,\nFile = \"construction\",\nFrame = 9},{Percent = 19,\nFile = \"construction\",\nFrame = 8},{Percent = 20,\nFile = \"construction\",\nFrame = 7},{Percent = 21,\nFile = \"construction\",\nFrame = 8},{Percent = 22,\nFile = \"construction\",\nFrame = 9},{Percent = 23,\nFile = \"construction\",\nFrame = 8},{Percent = 24,\nFile = \"construction\",\nFrame = 7},{Percent = 25,\nFile = \"construction\",\nFrame = 8},{Percent = 26,\nFile = \"construction\",\nFrame = 9},{Percent = 27,\nFile = \"construction\",\nFrame = 8},{Percent = 28,\nFile = \"construction\",\nFrame = 7},{Percent = 29,\nFile = \"construction\",\nFrame = 8},{Percent = 30,\nFile = \"construction\",\nFrame = 9},{Percent = 31,\nFile = \"construction\",\nFrame = 8},{Percent = 32,\nFile = \"construction\",\nFrame = 7},{Percent = 33,\nFile = \"construction\",\nFrame = 8},{Percent = 34,\nFile = \"construction\",\nFrame = 9},{Percent = 35,\nFile = \"construction\",\nFrame = 8},{Percent = 36,\nFile = \"construction\",\nFrame = 7},{Percent = 37,\nFile = \"construction\",\nFrame = 8},{Percent = 38,\nFile = \"construction\",\nFrame = 9},{Percent = 39,\nFile = \"construction\",\nFrame = 8},{Percent = 40,\nFile = \"construction\",\nFrame = 7},{Percent = 41,\nFile = \"construction\",\nFrame = 8},{Percent = 42,\nFile = \"construction\",\nFrame = 9},{Percent = 43,\nFile = \"construction\",\nFrame = 8},{Percent = 44,\nFile = \"construction\",\nFrame = 7},{Percent = 45,\nFile = \"construction\",\nFrame = 8},{Percent = 46,\nFile = \"construction\",\nFrame = 9},{Percent = 47,\nFile = \"construction\",\nFrame = 8},{Percent = 48,\nFile = \"construction\",\nFrame = 7},{Percent = 49,\nFile = \"construction\",\nFrame = 8},{Percent = 50,\nFile = \"construction\",\nFrame = 9},{Percent = 51,\nFile = \"construction\",\nFrame = 8},{Percent = 52,\nFile = \"construction\",\nFrame = 7},{Percent = 53,\nFile = \"construction\",\nFrame = 8},{Percent = 54,\nFile = \"construction\",\nFrame = 9},{Percent = 55,\nFile = \"construction\",\nFrame = 8},{Percent = 56,\nFile = \"construction\",\nFrame = 7},{Percent = 57,\nFile = \"construction\",\nFrame = 8},{Percent = 58,\nFile = \"construction\",\nFrame = 9},{Percent = 59,\nFile = \"construction\",\nFrame = 8},{Percent = 60,\nFile = \"construction\",\nFrame = 7},{Percent = 61,\nFile = \"construction\",\nFrame = 8},{Percent = 62,\nFile = \"construction\",\nFrame = 9},{Percent = 63,\nFile = \"construction\",\nFrame = 8},{Percent = 64,\nFile = \"construction\",\nFrame = 7},{Percent = 65,\nFile = \"construction\",\nFrame = 8},{Percent = 66,\nFile = \"construction\",\nFrame = 9},{Percent = 67,\nFile = \"construction\",\nFrame = 8},{Percent = 68,\nFile = \"construction\",\nFrame = 7},{Percent = 69,\nFile = \"construction\",\nFrame = 8},{Percent = 70,\nFile = \"construction\",\nFrame = 9},{Percent = 71,\nFile = \"construction\",\nFrame = 8},{Percent = 72,\nFile = \"construction\",\nFrame = 7},{Percent = 73,\nFile = \"construction\",\nFrame = 8},{Percent = 74,\nFile = \"construction\",\nFrame = 9},{Percent = 75,\nFile = \"construction\",\nFrame = 8},{Percent = 76,\nFile = \"construction\",\nFrame = 7},{Percent = 77,\nFile = \"construction\",\nFrame = 8},{Percent = 78,\nFile = \"construction\",\nFrame = 9},{Percent = 79,\nFile = \"construction\",\nFrame = 8},{Percent = 80,\nFile = \"construction\",\nFrame = 7},{Percent = 81,\nFile = \"construction\",\nFrame = 8},{Percent = 82,\nFile = \"construction\",\nFrame = 9},{Percent = 83,\nFile = \"construction\",\nFrame = 8},{Percent = 84,\nFile = \"construction\",\nFrame = 7},{Percent = 85,\nFile = \"construction\",\nFrame = 8},{Percent = 86,\nFile = \"construction\",\nFrame = 9},{Percent = 87,\nFile = \"construction\",\nFrame = 8},{Percent = 88,\nFile = \"construction\",\nFrame = 7},{Percent = 89,\nFile = \"construction\",\nFrame = 8},{Percent = 90,\nFile = \"construction\",\nFrame = 9},{Percent = 91,\nFile = \"construction\",\nFrame = 8},{Percent = 92,\nFile = \"construction\",\nFrame = 7},{Percent = 93,\nFile = \"construction\",\nFrame = 8},{Percent = 94,\nFile = \"construction\",\nFrame = 9},{Percent = 95,\nFile = \"construction\",\nFrame = 8},{Percent = 96,\nFile = \"construction\",\nFrame = 7},{Percent = 97,\nFile = \"construction\",\nFrame = 8},{Percent = 98,\nFile = \"construction\",\nFrame = 9},{Percent = 99,\nFile = \"construction\",\nFrame = 8},{Percent = 100,\nFile = \"construction\",\nFrame = 7},\n}\n})\n"
  },
  {
    "path": "scripts/zerg/icons.lua",
    "content": "--       _________ __                 __                               \n--      /   _____//  |_____________ _/  |______     ____  __ __  ______\n--      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n--      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ \\ \n--     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n--             \\/                  \\/          \\//_____/            \\/ \n--  ______________________                           ______________________\n--                        T H E   W A R   B E G I N S\n--         Stratagus - A free fantasy real time strategy game engine\n--\n--      icons.lua - Define the icons.\n--\n--      (c) Copyright 2005 by Jimmy Salmon\n--\n--      This program is free software; you can redistribute it and/or modify\n--      it under the terms of the GNU General Public License as published by\n--      the Free Software Foundation; either version 2 of the License, or\n--      (at your option) any later version.\n--  \n--      This program is distributed in the hope that it will be useful,\n--      but WITHOUT ANY WARRANTY; without even the implied warranty of\n--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n--      GNU General Public License for more details.\n--  \n--      You should have received a copy of the GNU General Public License\n--      along with this program; if not, write to the Free Software\n--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n--\n\nlocal zerg_icons = {\n  {\"icon-zerg-larva\", 35},\n  {\"icon-zerg-egg\", 36},\n  {\"icon-zerg-zergling\", 37},\n  {\"icon-zerg-hydralisk\", 38},\n  {\"icon-zerg-ultralisk\", 39},\n  {\"icon-zerg-broodling\", 40},\n  {\"icon-zerg-drone\", 41},\n  {\"icon-zerg-overlord\", 42},\n  {\"icon-zerg-mutalisk\", 43},\n  {\"icon-zerg-guardian\", 44},\n  {\"icon-zerg-queen\", 45},\n  {\"icon-zerg-defiler\", 46},\n  {\"icon-zerg-scourge\", 47},\n  {\"icon-zerg-ultralisk\", 48},\n  {\"icon-zerg-queen\", 49},\n  {\"icon-zerg-hatchery\", 131},\n  {\"icon-zerg-lair\", 132},\n  {\"icon-zerg-hive\", 133},\n  {\"icon-zerg-nydus-canal\", 134},\n  {\"icon-zerg-hydralisk-den\", 135},\n  {\"icon-zerg-defiler-mound\", 136},\n  {\"icon-zerg-greater-spire\", 137},\n  {\"icon-zerg-queens-nest\", 138},\n  {\"icon-zerg-evolution-chamber\", 139},\n  {\"icon-zerg-ultralisk-cavern\", 140},\n  {\"icon-zerg-spire\", 141},\n  {\"icon-zerg-spawning-pool\", 142},\n  {\"icon-zerg-creep-colony\", 143},\n  {\"icon-zerg-spore-colony\", 144},\n  {\"icon-zerg-sunken-colony\", 146},\n  {\"icon-zerg-overmind-with-shell\", 147},\n  {\"icon-zerg-overmind\", 148},\n  {\"icon-zerg-extractor\", 149},\n  {\"icon-zerg-mature-chrysalis\", 150},\n  {\"icon-zerg-cerebrate\", 151},\n  {\"icon-zerg-cerebrate-daggoth\", 152},\n  {\"icon-zerg-burrow-down\", 259},\n  {\"icon-zerg-burrow-up\", 260},\n  {\"icon-zerg-ventral-sacs\", 261},\n  {\"icon-zerg-antennae\", 262},\n  {\"icon-zerg-pneumatized-carapace\", 296},\n--  {\"icon-zerg-build\", 298},\n--  {\"icon-zerg-advanced-build\", 299},\n  {\"icon-zerg-evolve-adrenal-glands\", 264},\n  {\"icon-zerg-evolve-metabolic-boost\", 265},\n  {\"icon-zerg-upgrade-zerg-carapace\", 297},\n  {\"icon-zerg-upgrade-melee-attack\", 299},\n  {\"icon-zerg-upgrade-missle-attack\", 300},\n  {\"icon-zerg-upgrade-flyer-attack\", 301},\n  {\"icon-zerg-evolve-muscular-augments\", 266},\n  {\"icon-zerg-evolve-consume\", 302},\n  {\"icon-zerg-evolve-ensnare\", 267},\n  {\"icon-zerg-evolve-grooved-spines\", 268},\n  {\"icon-zerg-research-adrenal-glands\", 298},\n}\n\nlocal pos = table.getn(icons) + 1\n\nfor i = 1,table.getn(zerg_icons) do\n  icons[pos] = zerg_icons[i]\n  pos = pos + 1\nend\n\n\n"
  },
  {
    "path": "scripts/zerg/missiles.lua",
    "content": "--\n--  Missiles\n--\n\nDefineMissileType(\"missile-zerg-spit\", {\n  File = image_504_bullet_zspark_file, Size = image_504_bullet_zspark_size,\n  Frames = 8, DrawLevel = 50,\n  Class = \"missile-class-stay\", Sleep = 1, Speed = 4, Range = 0,\n})\n\n-- FIXME: Graphic not drawing in proper directions\nDefineMissileType(\"missile-zerg-mutalisk-glaive-wurm\", {\n  File = image_511_bullet_spores_file, Size = image_511_bullet_spores_size,\n  Frames = 10, DrawLevel = 50,\n  Class = \"missile-class-point-to-point\", Sleep = 1, Speed = 12, Range = 0,\n})\n\n"
  },
  {
    "path": "scripts/zerg/sound.lua",
    "content": "-- Advisor\n\nMakeSound(\"zerg-base-attacked\", \"zerg/units/advisor/base attacked.ogg\")\nMakeSound(\"zerg-units-attacked\", \"zerg/units/advisor/units attacked.ogg\")\nMakeSound(\"zerg-require-more-minerals\", \"zerg/units/advisor/require minerals.ogg\")\nMakeSound(\"zerg-require-more-gas\", \"zerg/units/advisor/require gas.ogg\")\nMakeSound(\"zerg-spawn-more-overlords\", \"zerg/units/advisor/spawn overlords.ogg\")\nMakeSound(\"zerg-require-more-energy\", \"zerg/units/advisor/not enough energy.ogg\")\nMakeSound(\"zerg-evolution-complete\", \"zerg/units/advisor/evolution complete.ogg\")\nMakeSound(\"zerg-nuclear-launch-detected\", \"zerg/units/advisor/nuclear launch.ogg\")\n\n-- drone\n\nMakeSound(\"zerg-drone-ready\", \"zerg/units/drone/ready.ogg\")\nMakeSound(\"zerg-drone-death\", \"zerg/units/drone/death/1.ogg\")\n\nMakeSound(\"zerg-drone-selected\",\n  {\"zerg/units/drone/selected/1.ogg\",\n  \"zerg/units/drone/selected/2.ogg\",\n  \"zerg/units/drone/selected/3.ogg\",\n  \"zerg/units/drone/selected/4.ogg\",\n  \"zerg/units/drone/selected/5.ogg\"})\n\nMakeSound(\"zerg-drone-pissed\",\n  {\"zerg/units/drone/pissed/1.ogg\",\n  \"zerg/units/drone/pissed/2.ogg\",\n  \"zerg/units/drone/pissed/3.ogg\",})\n\nMakeSound(\"zerg-drone-acknowledgement\",\n  {\"zerg/units/drone/acknowledgement/1.ogg\",\n  \"zerg/units/drone/acknowledgement/2.ogg\",\n  \"zerg/units/drone/acknowledgement/3.ogg\",\n  \"zerg/units/drone/acknowledgement/4.ogg\",\n  \"zerg/units/drone/acknowledgement/5.ogg\"})\n\nMakeSound(\"zerg-drone-gather\",\n\t{\"zerg/units/drone/min00.ogg\"})\n\n--hydralisk\n\nMakeSound(\"zerg-hydralisk-selected\",\n  {\"zerg/units/hydralisk/selected/1.ogg\",\n  \"zerg/units/hydralisk/selected/2.ogg\",\n  \"zerg/units/hydralisk/selected/3.ogg\"})\n\nMakeSound(\"zerg-hydralisk-pissed\",\n  {\"zerg/units/hydralisk/pissed/1.ogg\",\n  \"zerg/units/hydralisk/pissed/2.ogg\"})\n\nMakeSound(\"zerg-hydralisk-attack\",\n\t{\"zerg/units/hydralisk/fir00.ogg\"})\n\nMakeSound(\"zerg-hydralisk-acknowledgement\",\n  {\"zerg/units/hydralisk/acknowledgement/1.ogg\",\n  \"zerg/units/hydralisk/acknowledgement/2.ogg\",\n  \"zerg/units/hydralisk/acknowledgement/3.ogg\",\n  \"zerg/units/hydralisk/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-hydralisk-death\", \"zerg/units/hydralisk/death/1.ogg\")\n\nMakeSound(\"zerg-hydralisk-ready\", \"zerg/units/hydralisk/ready.ogg\")\n\n--zergling\n\nMakeSound(\"zerg-zergling-selected\",\n  {\"zerg/units/zergling/selected/1.ogg\",\n  \"zerg/units/zergling/selected/2.ogg\",\n  \"zerg/units/zergling/selected/3.ogg\",\n  \"zerg/units/zergling/selected/4.ogg\"})\n\nMakeSound(\"zerg-zergling-pissed\",\n  {\"zerg/units/zergling/pissed/1.ogg\",\n  \"zerg/units/zergling/pissed/2.ogg\",\n  \"zerg/units/zergling/pissed/3.ogg\"})\n\nMakeSound(\"zerg-zergling-acknowledgement\",\n  {\"zerg/units/zergling/acknowledgement/1.ogg\",\n  \"zerg/units/zergling/acknowledgement/2.ogg\",\n  \"zerg/units/zergling/acknowledgement/3.ogg\",\n  \"zerg/units/zergling/acknowledgement/4.ogg\"})\n\n\n-- FIXME Placeholder Zergling attack noise\nMakeSound(\"zerg-zergling-attack\", {\"zerg/units/hyfir00.ogg\"})\n\nMakeSound(\"zerg-zergling-death\", \"zerg/units/zergling/death/1.ogg\")\nMakeSound(\"zerg-zergling-ready\", \"zerg/units/zergling/ready.ogg\")\n\n--zerg ultralisk\n\nMakeSound(\"zerg-ultralisk-selected\",\n  {\"zerg/units/ultralisk/selected/1.ogg\",\n  \"zerg/units/ultralisk/selected/2.ogg\",\n  \"zerg/units/ultralisk/selected/3.ogg\"})\n\nMakeSound(\"zerg-ultralisk-pissed\",\n  {\"zerg/units/ultralisk/pissed/1.ogg\",\n  \"zerg/units/ultralisk/pissed/2.ogg\",\n  \"zerg/units/ultralisk/pissed/3.ogg\"})\n\nMakeSound(\"zerg-ultralisk-acknowledgement\",\n  {\"zerg/units/ultralisk/acknowledgement/1.ogg\",\n  \"zerg/units/ultralisk/acknowledgement/2.ogg\",\n  \"zerg/units/ultralisk/acknowledgement/3.ogg\",\n  \"zerg/units/ultralisk/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-ultralisk-hit\",\n  {\"zerg/units/ultralisk/hit00.ogg\",\n  \"zerg/units/ultralisk/hit01.ogg\"})\n\nMakeSound(\"zerg-ultralisk-attack\",\n  {\"zerg/units/ultralisk/att01.ogg\",\n  \"zerg/units/ultralisk/hit01.ogg\",\n  \"zerg/units/ultralisk/att02.ogg\"})\n\nMakeSound(\"zerg-ultralisk-death\", \"zerg/units/ultralisk/death/1.ogg\")\nMakeSound(\"zerg-ultralisk-ready\", \"zerg/units/ultralisk/ready.ogg\")\n\n--overlord\n\nMakeSound(\"zerg-overlord-selected\",\n  {\"zerg/units/overlord/selected/1.ogg\",\n  \"zerg/units/overlord/selected/2.ogg\",\n  \"zerg/units/overlord/selected/3.ogg\",\n  \"zerg/units/overlord/selected/4.ogg\"})\n\nMakeSound(\"zerg-overlord-pissed\",\n  {\"zerg/units/overlord/pissed/1.ogg\",\n  \"zerg/units/overlord/pissed/2.ogg\",\n  \"zerg/units/overlord/pissed/3.ogg\",\n  \"zerg/units/overlord/pissed/4.ogg\"})\n\nMakeSound(\"zerg-overlord-acknowledgement\",\n  {\"zerg/units/overlord/acknowledgement/1.ogg\",\n  \"zerg/units/overlord/acknowledgement/2.ogg\",\n  \"zerg/units/overlord/acknowledgement/3.ogg\",\n  \"zerg/units/overlord/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-overlord-death\", \"zerg/units/overlord/death/1.ogg\")\nMakeSound(\"zerg-overlord-ready\", \"zerg/units/overlord/ready.ogg\")\n\n--Broodling\n\nMakeSound(\"zerg-broodling-selected\",\n  {\"zerg/units/broodling/selected/1.ogg\",\n  \"zerg/units/broodling/selected/2.ogg\",\n  \"zerg/units/broodling/selected/3.ogg\",\n  \"zerg/units/broodling/selected/4.ogg\"})\n\nMakeSound(\"zerg-broodling-pissed\",\n  {\"zerg/units/broodling/pissed/1.ogg\",\n  \"zerg/units/broodling/pissed/2.ogg\",\n  \"zerg/units/broodling/pissed/3.ogg\",\n  \"zerg/units/broodling/pissed/4.ogg\"})\n\nMakeSound(\"zerg-broodling-acknowledgement\",\n  {\"zerg/units/broodling/acknowledgement/1.ogg\",\n  \"zerg/units/broodling/acknowledgement/2.ogg\",\n  \"zerg/units/broodling/acknowledgement/3.ogg\",\n  \"zerg/units/broodling/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-broodling-death\", \"zerg/units/broodling/death/1.ogg\")\nMakeSound(\"zerg-broodling-ready\", \"zerg/units/broodling/ready.ogg\")\n\n\n--defiler\n\nMakeSound(\"zerg-defiler-selected\",\n  {\"zerg/units/defiler/selected/1.ogg\",\n  \"zerg/units/defiler/selected/2.ogg\",\n  \"zerg/units/defiler/selected/3.ogg\",\n  \"zerg/units/defiler/selected/4.ogg\"})\n\nMakeSound(\"zerg-defiler-pissed\",\n  {\"zerg/units/defiler/pissed/1.ogg\",\n  \"zerg/units/defiler/pissed/2.ogg\",\n  \"zerg/units/defiler/pissed/3.ogg\",\n  \"zerg/units/defiler/pissed/4.ogg\"})\n\nMakeSound(\"zerg-defiler-acknowledgement\",\n  {\"zerg/units/defiler/acknowledgement/1.ogg\",\n  \"zerg/units/defiler/acknowledgement/2.ogg\",\n  \"zerg/units/defiler/acknowledgement/3.ogg\",\n  \"zerg/units/defiler/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-defiler-death\", \"zerg/units/defiler/death/1.ogg\")\nMakeSound(\"zerg-defiler-ready\", \"zerg/units/defiler/ready.ogg\")\n\n\n--egg\n\nMakeSound(\"zerg-egg-selected\",\n  {\"zerg/units/egg/selected/1.ogg\",\n  \"zerg/units/egg/selected/2.ogg\"})\n\nMakeSound(\"zerg-egg-pissed\",\n  {\"zerg/units/egg/pissed/1.ogg\"})\n\nMakeSound(\"zerg-egg-death\", \"zerg/units/egg/death/1.ogg\")\n\n--guardian\n\nMakeSound(\"zerg-guardian-selected\",\n  {\"zerg/units/guardian/selected/1.ogg\",\n  \"zerg/units/guardian/selected/2.ogg\",\n  \"zerg/units/guardian/selected/3.ogg\",\n  \"zerg/units/guardian/selected/4.ogg\"})\n\nMakeSound(\"zerg-guardian-pissed\",\n  {\"zerg/units/guardian/pissed/1.ogg\",\n  \"zerg/units/guardian/pissed/2.ogg\",\n  \"zerg/units/guardian/pissed/3.ogg\",\n  \"zerg/units/guardian/pissed/4.ogg\"})\n\nMakeSound(\"zerg-guardian-acknowledgement\",\n  {\"zerg/units/guardian/acknowledgement/1.ogg\",\n  \"zerg/units/guardian/acknowledgement/2.ogg\",\n  \"zerg/units/guardian/acknowledgement/3.ogg\",\n  \"zerg/units/guardian/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-guardian-death\", \"zerg/units/defiler/death/1.ogg\")\nMakeSound(\"zerg-guardian-ready\", \"zerg/units/defiler/ready.ogg\")\n\nMakeSound(\"zerg-guardian-attack\", \"zerg/units/guardian/fir00.ogg\")\nMakeSound(\"zerg-guardian-hit\", \"zerg/units/guardian/hit00.ogg\")\n\n\n--infested terran\n\nMakeSound(\"zerg-infested-terran-selected\",\n  {\"zerg/units/infested terran/selected/1.ogg\",\n  \"zerg/units/infested terran/selected/2.ogg\",\n  \"zerg/units/infested terran/selected/3.ogg\",\n  \"zerg/units/infested terran/selected/4.ogg\"})\n\nMakeSound(\"zerg-infested-terran-pissed\",\n  {\"zerg/units/infested terran/pissed/1.ogg\",\n  \"zerg/units/infested terran/pissed/2.ogg\",\n  \"zerg/units/infested terran/pissed/3.ogg\",\n  \"zerg/units/infested terran/pissed/4.ogg\"})\n\nMakeSound(\"zerg-infested-terran-acknowledgement\",\n  {\"zerg/units/infested terran/acknowledgement/1.ogg\",\n  \"zerg/units/infested terran/acknowledgement/2.ogg\",\n  \"zerg/units/infested terran/acknowledgement/3.ogg\",\n  \"zerg/units/infested terran/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-infested-terran-ready\", \"zerg/units/infested terran/ready.ogg\")\n\n\n--larva\n\nMakeSound(\"zerg-larva-selected\",\n  {\"zerg/units/larva/selected/1.ogg\"})\n\nMakeSound(\"zerg-larva-pissed\",\n  {\"zerg/units/larva/pissed/1.ogg\"})\n\nMakeSound(\"zerg-larva-death\", \"zerg/units/larva/death/1.ogg\")\n\n\n--mutalisk\n\nMakeSound(\"zerg-mutalisk-selected\",\n  {\"zerg/units/mutalisk/selected/1.ogg\",\n  \"zerg/units/mutalisk/selected/2.ogg\",\n  \"zerg/units/mutalisk/selected/3.ogg\",\n  \"zerg/units/mutalisk/selected/4.ogg\"})\n\nMakeSound(\"zerg-mutalisk-pissed\",\n  {\"zerg/units/mutalisk/pissed/1.ogg\",\n  \"zerg/units/mutalisk/pissed/2.ogg\",\n  \"zerg/units/mutalisk/pissed/3.ogg\",\n  \"zerg/units/mutalisk/pissed/4.ogg\"})\n\nMakeSound(\"zerg-mutalisk-acknowledgement\",\n  {\"zerg/units/mutalisk/acknowledgement/1.ogg\",\n  \"zerg/units/mutalisk/acknowledgement/2.ogg\",\n  \"zerg/units/mutalisk/acknowledgement/3.ogg\",\n  \"zerg/units/mutalisk/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-mutalisk-death\", \"zerg/units/mutalisk/death/1.ogg\")\nMakeSound(\"zerg-mutalisk-ready\", \"zerg/units/mutalisk/ready.ogg\")\nMakeSound(\"zerg-mutalisk-attack\", \"zerg/units/mutalisk/fir00.ogg\")\n\n--queen\n\nMakeSound(\"zerg-queen-selected\",\n  {\"zerg/units/queen/selected/1.ogg\",\n  \"zerg/units/queen/selected/2.ogg\",\n  \"zerg/units/queen/selected/3.ogg\",\n  \"zerg/units/queen/selected/4.ogg\"})\n\nMakeSound(\"zerg-queen-pissed\",\n  {\"zerg/units/queen/pissed/1.ogg\",\n  \"zerg/units/queen/pissed/2.ogg\",\n  \"zerg/units/queen/pissed/3.ogg\",\n  \"zerg/units/queen/pissed/4.ogg\"})\n\nMakeSound(\"zerg-queen-acknowledgement\",\n  {\"zerg/units/queen/acknowledgement/1.ogg\",\n  \"zerg/units/queen/acknowledgement/2.ogg\",\n  \"zerg/units/queen/acknowledgement/3.ogg\",\n  \"zerg/units/queen/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-queen-death\", \"zerg/units/queen/death/1.ogg\")\nMakeSound(\"zerg-queen-death-2\", \"zerg/units/queen/death/2.ogg\")\nMakeSound(\"zerg-queen-death-3\", \"zerg/units/queen/death/3.ogg\")\nMakeSound(\"zerg-queen-ready\", \"zerg/units/queen/ready.ogg\")\n\n\n--scourge\n\nMakeSound(\"zerg-scourge-selected\",\n  {\"zerg/units/scourge/selected/1.ogg\",\n  \"zerg/units/scourge/selected/2.ogg\"})\n\nMakeSound(\"zerg-scourge-pissed\",\n  {\"zerg/units/scourge/pissed/1.ogg\",\n  \"zerg/units/scourge/pissed/2.ogg\"})\n\nMakeSound(\"zerg-scourge-acknowledgement\",\n  {\"zerg/units/scourge/acknowledgement/1.ogg\",\n  \"zerg/units/scourge/acknowledgement/2.ogg\"})\n\nMakeSound(\"zerg-scourge-death\", \"zerg/units/scourge/death/1.ogg\")\nMakeSound(\"zerg-scourge-ready\", \"zerg/units/scourge/ready.ogg\")\nMakeSound(\"zerg-scourge-attack\", \"zerg/units/scourge/att00.ogg\")\nMakeSound(\"zerg-scourge-hit\", \"zerg/units/scourge/hit00.ogg\")\n\n\n--kerrigan\n\nMakeSound(\"zerg-kerrigan-selected\",\n  {\"zerg/units/kerrigan/selected/1.ogg\",\n  \"zerg/units/kerrigan/selected/2.ogg\",\n  \"zerg/units/kerrigan/selected/3.ogg\",\n  \"zerg/units/kerrigan/selected/4.ogg\"})\n\nMakeSound(\"zerg-kerrigan-pissed\",\n  {\"zerg/units/kerrigan/pissed/1.ogg\",\n  \"zerg/units/kerrigan/pissed/2.ogg\",\n  \"zerg/units/kerrigan/pissed/3.ogg\",\n  \"zerg/units/kerrigan/pissed/4.ogg\"})\n\nMakeSound(\"zerg-kerrigan-acknowledgement\",\n  {\"zerg/units/kerrigan/acknowledgement/1.ogg\",\n  \"zerg/units/kerrigan/acknowledgement/2.ogg\",\n  \"zerg/units/kerrigan/acknowledgement/3.ogg\",\n  \"zerg/units/kerrigan/acknowledgement/4.ogg\"})\n\nMakeSound(\"zerg-kerrigan-death\", \"zerg/units/defiler/death/1.ogg\")\n\n\n\n-- Zerg Buildings\n\nMakeSound(\"zerg-hatchery-selected\", \"zerg/units/hatchery selected.ogg\")\n\nMakeSound(\"zerg-building-ready\", \"zerg/units/morph complete.ogg\")\n\n\n\nMakeSound(\"zerg-building-blowup\", \"zerg/units/building death.ogg\")\n\nMakeSound(\"zerg-spawning-pool-selected\", \"zerg/units/spawning pool selected.ogg\")\nMakeSound(\"zerg-evolution-chamber-selected\", \"zerg/units/evolution chamber selected.ogg\")\nMakeSound(\"zerg-sunken-colony-selected\", \"zerg/units/sunken colony selected.ogg\")\nMakeSound(\"zerg-sunken-colony-attack\", \"zerg/units/lufir00.ogg\")\nMakeSound(\"zerg-sunken-colony-hit\", \"zerg/units/luhit00.ogg\")\nMakeSound(\"zerg-creep-colony-selected\", \"zerg/units/creep colony selected.ogg\")\nMakeSound(\"zerg-spore-colony-selected\", \"zerg/units/spore colony selected.ogg\")\nMakeSound(\"zerg-extractor-selected\", \"zerg/units/extractor selected.ogg\")\nMakeSound(\"zerg-defiler-mound-selected\", \"zerg/units/defiler mound selected.ogg\")\nMakeSound(\"zerg-queens-nest-selected\", \"zerg/units/queens nest selected.ogg\")\nMakeSound(\"zerg-nydus-canal-selected\", \"zerg/units/nydus canal selected.ogg\")\nMakeSound(\"zerg-ultralisk-cavern-selected\", \"zerg/units/ultralisk cavern selected.ogg\")\nMakeSound(\"zerg-hydralisk-den-selected\", \"zerg/units/hydralisk den selected.ogg\")\nMakeSound(\"zerg-spire-selected\", \"zerg/units/spire selected.ogg\")\nMakeSound(\"zerg-greater-spire-selected\", \"zerg/units/greater spire selected.ogg\")\n\n--Spells\n\nMakeSound(\"spell-consume\", \"zerg/units/defiler/consume.ogg\")\nMakeSound(\"spell-plague\", \"zerg/units/defiler/plague cast.ogg\")\nMakeSound(\"spell-ensnare\", \"zerg/units/queen/ensnare cast.ogg\")\nMakeSound(\"spell-parasite\", \"zerg/units/queen/parasite cast.ogg\")\n\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-creep-colony.lua",
    "content": "--\n-- unit-zerg-creep-colony\n--\n\n\nDefineAnimations(\"animations-zerg-creep-colony\", {\n  --[[ active overlay 108 ]]\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 3\", \"wait 2\",\n    \"frame 0\", \"wait 2\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-creep-colony\", {\n  Animations = \"animations-zerg-creep-colony\", Icon = \"icon-zerg-creep-colony\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-creep-colony-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n\t\n\nDefineUnitType(\"unit-zerg-spore-colony\", {})\nDefineUnitType(\"unit-zerg-sunken-colony\", {})\n\t\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-zerg-spore-colony\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-spore-colony\",\n  Key = \"s\", Hint = \"Mutate into ~!Spore Colony\",\n  ForUnit = {\"unit-zerg-creep-colony\"} } )\n\nDefineButton( { Pos = 8, Level = 0, Icon = \"icon-zerg-sunken-colony\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-sunken-colony\",\n  Key = \"u\", Hint = \"Mutate into S~!unken Colony\",\n  ForUnit = {\"unit-zerg-creep-colony\"} } )\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-defiler-mound.lua",
    "content": "--\n-- unit-zerg-defiler-mound\n--\n\n\nDefineAnimations(\"animations-zerg-defiler-mound\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\",\n    \"frame 0\", \"wait 2\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-defiler-mound\", {\n  Animations = \"animations-zerg-defiler-mound\", Icon = \"icon-zerg-defiler-mound\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-defiler-mound-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-defiler.lua",
    "content": "--\n-- unit-zerg-defiler\n--\n\n\nDefineAnimations(\"animations-zerg-defiler-death\", {\n  Death = {\n    \"unbreakable begin\", \"frame 0\", \"wait 50\", \"frame 1\", \"wait 50\",\n    \"frame 2\", \"wait 50\", \"frame 3\", \"wait 50\", \"frame 4\", \"wait 50\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-zerg-defiler-death\", {\n  Animations = \"animations-zerg-defiler-death\", Icon = \"icon-zerg-defiler\",\n  NumDirections = 1,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  SelectableByRectangle = false,\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-defiler\", {\n  Still = {\n    \"frame 0\", \"wait 3\", \"frame 17\", \"wait 3\", \"frame 34\", \"wait 3\",\n    \"frame 17\", \"wait 3\",\n  },\n  Move = {\"unbreakable begin\",\n    \"frame 0\", \"move 5\", \"wait 1\", \"frame 17\", \"move 4\", \"wait 1\",\n    \"frame 51\", \"move 5\", \"wait 1\", \"frame 68\", \"move 4\", \"wait 1\",\n    \"frame 85\", \"move 5\", \"wait 1\", \"frame 102\", \"move 4\", \"wait 1\",\n    \"frame 119\", \"move 5\", \"wait 1\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Death = {\"unbreakable begin\",\n    \"frame 136\", \"wait 2\", \"frame 153\", \"wait 2\", \"frame 170\", \"wait 2\",\n    \"frame 187\", \"wait 2\",\n    \"unbreakable end\", \"wait 1\",\n  },\n--[[ Burrow =\n  \"frame 204\", \"wait 1\", \"frame 221\", \"wait 1\", \"frame 238\", \"wait 1\",\n  \"frame 255\", \"wait 1\", \"frame 272\", \"wait 1\",\n]]\n})\n\nDefineUnitType(\"unit-zerg-defiler\", { Name = \"Hydralisk\",\n  Animations = \"animations-zerg-defiler\", Icon = \"icon-zerg-defiler\",\n  Speed = 10,\n  Mana = 200,\n  DrawLevel = 30,\n  Armor = 1, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  MaxAttackRange = 0,\n  Priority = 60,\n  Points = 50,\n  Demand = 2,\n  Corpse = \"unit-zerg-defiler-death\",\n  RegenerationRate = 1,\n  RightMouseAction = \"attack\",\n--  CanCastSpell = {\"d-s\"},\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-defiler-selected\",\n    \"acknowledge\", \"zerg-defiler-acknowledgement\",\n    \"ready\", \"zerg-defiler-ready\",\n    \"help\", \"zerg-units-attacked\",\n\t\"dead\", \"zerg-defiler-death\"} } )\n--[[\nDefineButton( { Pos = 9, Level = 0, Icon = \"icon-cancel\",\n  Action = \"cast-spell\", Value = \"d-s\",\n  Key = \"d\", Hint = \"Dark Swarm\",\n  ForUnit = {\"unit-zerg-defiler\"} } )\n--]]\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-drone.lua",
    "content": "--\n-- unit-zerg-drone\n--\n\n\nDefineAnimations(\"animations-zerg-drone\", {\n  Still = {\"frame 0\", \"wait 125\",},\n  Move = {\"unbreakable begin\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"wait 1\", \"move 4\", \"wait 1\",\n    \"move 4\", \"wait 1\", \"move 4\", \"unbreakable end\", \"wait 1\",},\n  Attack = {\"unbreakable begin\", \"sound zerg-drone-attack\",\n    \"frame 85\", \"wait 2\", \"frame 102\", \"wait 2\", \"frame 119\", \"wait 2\",\n    \"frame 136\", \"wait 2\", \"frame 85\", \"unbreakable end\", \"wait 1\",\n  },\n  Harvest_minerals = {\"unbreakable begin\", \"sound zerg-drone-attack\",\n    \"frame 85\", \"wait 2\", \"frame 102\", \"wait 2\", \"frame 119\", \"wait 2\",\n    \"frame 136\", \"wait 2\", \"frame 85\", \"unbreakable end\", \"wait 1\",\n  },\n  Repair = {\"unbreakable begin\", \"sound zerg-drone-attack\",\n    \"frame 85\", \"wait 2\", \"frame 102\", \"wait 2\", \"frame 119\", \"wait 2\",\n    \"frame 136\", \"wait 2\", \"frame 85\", \"unbreakable end\", \"wait 1\",\n  },\n  Death = {\"unbreakable begin\",\n    \"frame 170\", \"wait 2\", \"frame 187\", \"wait 2\", \"frame 204\", \"wait 2\",\n    \"frame 221\", \"wait 2\", \"frame 238\", \"wait 2\", \"frame 255\", \"wait 2\",\n    \"frame 272\", \"wait 2\", \"frame 289\", \"wait 2\", \"unbreakable end\", \"wait 1\",},\n})\n\n\nDefineUnitType(\"unit-zerg-drone\", {\n  Animations = \"animations-zerg-drone\", Icon = \"icon-zerg-drone\",\n  Speed = 10,\n  DrawLevel = 30,\n  BasicDamage = 5, PiercingDamage = 2, Missile = \"missile-zerg-spit\",\n  MaxAttackRange = 1,\n  Priority = 50,\n  RegenerationRate = 1,\n  Points = 30,\n  Demand = 1,\n  RightMouseAction = \"harvest\",\n  CanAttack = true, RepairRange = 0,\n  CanTargetLand = true,\n  Coward = true,\n  CanGatherResources = {\n   {\"file-when-loaded\", image_17_zerg_drone_file,\n    \"resource-id\", \"minerals\",\n    \"harvest-from-outside\",\n    \"resource-capacity\", 8,\n    \"wait-at-resource\", 150,\n    \"wait-at-depot\", 50},\n   {\"file-when-loaded\", image_17_zerg_drone_file,\n    \"resource-id\", \"gas\",\n    \"resource-capacity\", 8,\n    \"wait-at-resource\", 50,\n    \"wait-at-depot\", 50,}},\n  organic = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-drone-selected\",\n    \"acknowledge\", \"zerg-drone-acknowledgement\",\n    \"ready\", \"zerg-drone-ready\",\n    \"help\", \"zerg-units-attacked\",\n    \"dead\", \"zerg-drone-death\"} } )\n\n\n--\n-- Default\n--\nDefineButton( { Pos = 5, Level = 0, Icon = \"icon-gather\",\n  Action = \"harvest\",\n  Key = \"g\", Hint = \"~!Gather\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-zerg-build\",\n  Action = \"button\", Value = 1,\n  Key = \"b\", Hint = \"~!Basic Mutation\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n\nDefineButton( { Pos = 8, Level = 0, Icon = \"icon-zerg-advanced-build\",\n  Action = \"button\", Value = 2,\n  Key = \"v\", Hint = \"Ad~!vanced Mutation\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n\n\n--\n-- Build\n--\nDefineUnitType(\"unit-zerg-hatchery\", {})\nDefineUnitType(\"unit-zerg-creep-colony\", {})\nDefineUnitType(\"unit-zerg-extractor\", {})\nDefineUnitType(\"unit-zerg-spawning-pool\", {})\nDefineUnitType(\"unit-zerg-evolution-chamber\", {})\nDefineUnitType(\"unit-zerg-hydralisk-den\", {})\n\nDefineUnitType(\"unit-zerg-spire\", {})\nDefineUnitType(\"unit-zerg-queens-nest\", {})\nDefineUnitType(\"unit-zerg-nydus-canal\", {})\nDefineUnitType(\"unit-zerg-ultralisk-cavern\", {})\nDefineUnitType(\"unit-zerg-defiler-mound\", {})\n\nDefineButton( { Pos = 1, Level = 1, Icon = \"icon-zerg-hatchery\",\n  Action = \"build\", Value = \"unit-zerg-hatchery\",\n  Key = \"h\", Hint = \"Mutate into ~!Hatchery\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n\nDefineButton( { Pos = 2, Level = 1, Icon = \"icon-zerg-creep-colony\",\n  Action = \"build\", Value = \"unit-zerg-creep-colony\",\n  Key = \"c\", Hint = \"Mutate into ~!Creep Colony\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \nDefineButton( { Pos = 3, Level = 1, Icon = \"icon-zerg-extractor\",\n  Action = \"build\", Value = \"unit-zerg-extractor\",\n  Key = \"e\", Hint = \"Mutate into ~!Extractor\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \nDefineButton( { Pos = 4, Level = 1, Icon = \"icon-zerg-spawning-pool\",\n  Action = \"build\", Value = \"unit-zerg-spawning-pool\",\n  Key = \"s\", Hint = \"Mutate into ~!Spawning Pool\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \nDefineButton( { Pos = 5, Level = 1, Icon = \"icon-zerg-evolution-chamber\",\n  Action = \"build\", Value = \"unit-zerg-evolution-chamber\",\n  Key = \"v\", Hint = \"Mutate into E~!volution Chamber\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \nDefineButton( { Pos = 7, Level = 1, Icon = \"icon-zerg-hydralisk-den\",\n  Action = \"build\", Value = \"unit-zerg-hydralisk-den\",\n  Key = \"d\", Hint = \"Mutate into Hydralisk ~!Den\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \n\nDefineButton( { Pos = 1, Level = 2, Icon = \"icon-zerg-spire\",\n  Action = \"build\", Value = \"unit-zerg-spire\",\n  Key = \"s\", Hint = \"Mutate into ~!Spire\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n\nDefineButton( { Pos = 2, Level = 2, Icon = \"icon-zerg-queens-nest\",\n  Action = \"build\", Value = \"unit-zerg-queens-nest\",\n  Key = \"q\", Hint = \"Mutate into ~!Queen's Nest\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \nDefineButton( { Pos = 3, Level = 2, Icon = \"icon-zerg-nydus-canal\",\n  Action = \"build\", Value = \"unit-zerg-nydus-canal\",\n  Key = \"u\", Hint = \"Mutate into ~!Nydus Canal\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \nDefineButton( { Pos = 4, Level = 2, Icon = \"icon-zerg-ultralisk-cavern\",\n  Action = \"build\", Value = \"unit-zerg-ultralisk-cavern\",\n  Key = \"u\", Hint = \"Ultralisk Cavern\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \nDefineButton( { Pos = 5, Level = 2, Icon = \"icon-zerg-defiler-mound\",\n  Action = \"build\", Value = \"unit-zerg-defiler-mound\",\n  Key = \"u\", Hint = \"Mutate into ~!Defiler Mound\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n  \n\n  \nDefineButton( { Pos = 9, Level = 1, Icon = \"icon-cancel\",\n  Action = \"button\", Value = 0,\n  Key = \"\\27\", Hint = \"~<ESC~> - Cancel\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n\nDefineButton( { Pos = 9, Level = 2, Icon = \"icon-cancel\",\n  Action = \"button\", Value = 0,\n  Key = \"\\27\", Hint = \"~<ESC~> - Cancel\",\n  ForUnit = {\"unit-zerg-drone\"} } )\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-egg.lua",
    "content": "--\n--  unit-zerg-egg\n--\n\n\nDefineAnimations(\"animations-zerg-egg-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\",\n    \"frame 3\", \"wait 2\", \"frame 4\", \"wait 2\", \"frame 5\", \"wait 2\",\n    \"frame 6\", \"wait 2\", \"frame 7\", \"wait 2\", \"frame 8\", \"wait 2\",\n    \"frame 9\", \"wait 25\", \"frame 10\", \"wait 25\", \"frame 11\", \"wait 25\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-egg-death\", {\n  Animations = \"animations-zerg-egg-death\", Icon = \"icon-zerg-egg\",\n  NumDirections = 1,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  SelectableByRectangle = false,\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-egg\", {\n  Still = {\n    \"frame 20\", \"wait 2\", \"frame 21\", \"wait 2\", \"frame 22\", \"wait 2\",\n    \"frame 23\", \"wait 2\",\n    \"label 3E03\", \"frame 0\", \"wait 2\", \"frame 1\", \"wait 2\",\n    \"frame 3\", \"wait 2\", \"frame 4\", \"wait 2\", \"frame 4\", \"wait 2\",\n    \"frame 6\", \"wait 2\", \"frame 7\", \"wait 2\", \"frame 8\", \"wait 2\",\n    \"frame 9\", \"wait 2\", \"frame 10\", \"wait 2\", \"frame 11\", \"wait 2\",\n    \"goto 3E03\"\n  },\n})\n\nDefineUnitType(\"unit-zerg-egg\", { Name = \"Egg\",\n  DrawLevel = 30,\n  Animations = \"animations-zerg-egg\", Icon = \"icon-zerg-egg\",\n  Armor = 10, Missile = \"missile-none\",\n  Corpse = \"unit-zerg-egg-death\",\n} )"
  },
  {
    "path": "scripts/zerg/unit-zerg-evolution-chamber.lua",
    "content": "--\n-- unit-zerg-evolution-chamber\n--\n\n\nDefineAnimations(\"animations-zerg-evolution-chamber\", {\n  Still = {\n    \"frame 0\", \"random-wait 1 3\", \"label 4930\", \"frame 1\", \"wait 3\",\n    \"frame 2\", \"wait 3\", \"frame 0\", \"wait 3\", \"goto 4930\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-evolution-chamber\", {\n  Animations = \"animations-zerg-evolution-chamber\", Icon = \"icon-zerg-evolution-chamber\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-evolution-chamber-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n\nCUpgrade:New(\"upgrade-zerg-melee-attacks1\")\nCUpgrade:New(\"upgrade-zerg-melee-attacks2\")\nCUpgrade:New(\"upgrade-zerg-melee-attacks3\")\nCUpgrade:New(\"upgrade-zerg-missle-attacks1\")\nCUpgrade:New(\"upgrade-zerg-missle-attacks2\")\nCUpgrade:New(\"upgrade-zerg-missle-attacks3\")\nCUpgrade:New(\"upgrade-zerg-carapace1\")\nCUpgrade:New(\"upgrade-zerg-carapace2\")\nCUpgrade:New(\"upgrade-zerg-carapace3\")\n\n\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-melee-attack\",\n  Action = \"research\", Value = \"upgrade-zerg-melee-attacks1\",\n  Allowed = \"check-single-research\",\n  Key = \"w\", Hint = \"Upgrade Melee Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-melee-attack\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-melee-attacks2\",\n  Key = \"w\", Hint = \"Upgrade Melee Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-melee-attack\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-melee-attacks3\",\n  Key = \"w\", Hint = \"Upgrade Melee Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-missle-attack\",\n  Action = \"research\", Value = \"upgrade-zerg-missle-attacks1\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Missle Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-missle-attack\",\n  Action = \"research\", Value = \"upgrade-zerg-missle-attacks2\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Missle Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-missle-attack\",\n  Action = \"research\", Value = \"upgrade-zerg-missle-attacks3\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Missle Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-carapace1\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Carapace\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-carapace2\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Carapace\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-carapace3\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Carapace\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-extractor.lua",
    "content": "--\n-- unit-zerg-extractor\n--\n\n\nDefineAnimations(\"animations-zerg-extractor\", {\n  --[[ active overlay 109 ]]\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 3\", \"wait 2\",\n    \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 0\", \"wait 2\",\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 3\", \"wait 2\",\n    \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 0\", \"wait 2\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-extractor\", {\n  Animations = \"animations-zerg-extractor\", Icon = \"icon-zerg-extractor\",\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 20,\n  Points = 160,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-explosion\",\n  BuilderLost = true,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"ontop\", { Type = \"unit-resource-vespene-geyser\", ReplaceOnDie = true, ReplaceOnBuild = true} } },\n  GivesResource = \"gas\", CanHarvest = true,\n  Sounds = {\n    \"selected\", \"zerg-extractor-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-greater-spire.lua",
    "content": "--\n-- unit-zerg-greater-spire\n--\n\n\nDefineAnimations(\"animations-zerg-greater-spire\", {\n  Still = {\n    \"frame 0\", \"random-wait 1 5\", \"label 4E8C\", \"frame 0\", \"wait 2\",\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"goto 4E8C\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-greater-spire\", {\n  Animations = \"animations-zerg-greater-spire\", Icon = \"icon-zerg-greater-spire\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-spire-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n\n\nCUpgrade:New(\"upgrade-zerg-flyer-attacks1\")\nCUpgrade:New(\"upgrade-zerg-flyer-attacks2\")\nCUpgrade:New(\"upgrade-zerg-flyer-attacks3\")\nCUpgrade:New(\"upgrade-zerg-flyer-carapace1\")\nCUpgrade:New(\"upgrade-zerg-flyer-carapace2\")\nCUpgrade:New(\"upgrade-zerg-flyer-carapace3\")\n\n\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-flyer-attack\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-attacks1\",\n  Allowed = \"check-single-research\",\n  Key = \"w\", Hint = \"Upgrade Flyer Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-flyer-attack\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-attacks2\",\n  Key = \"w\", Hint = \"Upgrade Flyer Attacks\",\n  ForUnit = {\"unit-zerg-spire\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-flyer-attack\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-attacks3\",\n  Key = \"w\", Hint = \"Upgrade Flyer Attacks\",\n  ForUnit = {\"unit-zerg-spire\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-carapace1\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Flyer Carapace\",\n  ForUnit = {\"unit-zerg-spire\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-carapace2\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Flyer Carapace\",\n  ForUnit = {\"unit-zerg-spire\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-carapace3\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Flyer Carapace\",\n  ForUnit = {\"unit-zerg-spire\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-guardian.lua",
    "content": "--\n-- unit-zerg-guardian\n--\n\n\nDefineAnimations(\"animations-zerg-guardian-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 2\", --[[ active overlay 58 ]]\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-guardian-death\", {\n  Animations = \"animations-zerg-guardian-death\", Icon = \"icon-zerg-guardian\",\n  NumDirections = 1,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  SelectableByRectangle = false,\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-guardian\", {\n  Still = {\n    \"frame 0\", \"wait 2\", \"frame 17\", \"wait 2\", \"frame 34\", \"wait 2\",\n    \"frame 51\", \"wait 2\", \"frame 68\", \"wait 2\",\n  },\n  Move = {\n    \"unbreakable begin\",\n    \"frame 0\", \"move 4\", \"wait 1\", \"frame 17\", \"move 3\", \"wait 1\",\n    \"frame 34\", \"move 3\", \"wait 1\", \"frame 51\", \"move 3\", \"wait 1\",\n    \"frame 68\", \"move 3\", \"wait 1\", \"frame 0\", \"move 4\", \"wait 1\",\n    \"frame 17\", \"move 3\", \"wait 1\", \"frame 34\", \"move 3\", \"wait 1\",\n    \"frame 51\", \"move 3\", \"wait 1\", \"frame 68\", \"move 3\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Attack = {\"unbreakable begin\", \"attack\", \"sound zerg-guardian-attack\",\n    \"unbreakable end\", \"wait 1\",},\n  Death = {\"unbreakable begin\", \"sound zerg-guardian-death\",\n    --[[active overlay 41,0]] \"wait 1\", \"unbreakable end\", \"wait 1\",},\n})\n\n\nDefineUnitType(\"unit-zerg-guardian\", {\n  DrawLevel = 45,\n  Animations = \"animations-zerg-guardian\", Icon = \"icon-zerg-guardian\",\n  Speed = 14,\n  DrawLevel = 60,\n  Armor = 2, BasicDamage = 20, PiercingDamage = 16, Missile = \"missile-none\",\n  MaxAttackRange = 4,\n  Priority = 65,\n  Points = 150,\n  Demand = 2,\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetSea = true, CanTargetAir = true,\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-guardian-selected\",\n    \"acknowledge\", \"zerg-guardian-acknowledgement\",\n    \"ready\", \"zerg-guardian-ready\",\n    \"help\", \"zerg-units-attacked\",\n    \"dead\", \"zerg-guardian-death\"} } )\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-hatchery.lua",
    "content": "--\n-- unit-zerg-hatchery\n--\n\n\nDefineAnimations(\"animations-zerg-hatchery\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 3\", \"wait 4\",\n    \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 0\", \"wait 4\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\nDefineUnitType(\"unit-zerg-hatchery\", {\n  Animations = \"animations-zerg-hatchery\", Icon = \"icon-zerg-hatchery\",\n  OnEachSecond = (function (self)\n\tlocal timeout = GetUnitVariable(self, \"LarvaTimeout\")\n\tif (timeout <= 0) then\n\t   local larvacount = 0\n\t   local units = GetUnitsAroundUnit(self, 1)\n\t   local i\n\t   for i,unit in ipairs(units) do\n\t      if (GetUnitVariable(unit, \"Ident\") == \"unit-zerg-larva\") then\n\t\t larvacount = larvacount + 1\n\t      end\n\t   end\n\t   if larvacount < 3 then\n\t      local posx = GetUnitVariable(self, \"PosX\")\n\t      local posy = GetUnitVariable(self, \"PosY\")\n\t      CreateUnit(\"unit-zerg-larva\", GetUnitVariable(self, \"Player\"), {posx - 1, posy})\n\t   end\n\t   SetUnitVariable(self, \"LarvaTimeout\", 20)\n\telse\n\t   SetUnitVariable(self, \"LarvaTimeout\", timeout - 1)\n\tend\n  end),\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 0},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 35, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 8,\n  RegenerationRate = 1,\n--  ExplodeWhenKilled = \"missle-zerg-rubble-large\",\n--  Corpse = \"unit-zerg-rubble-large\",\n  BuilderLost = true,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \">\", Type = \"unit-resource-mineral-field\"} } },\n  CanStore = {\"gas\", \"minerals\"},\n  Sounds = {\n    \"selected\", \"zerg-hatchery-selected\",\n--    \"ready\", \"town-hall-ready\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n\n\nDefineUnitType(\"unit-zerg-lair\", {})\nDefineUnitType(\"unit-zerg-hive\", {})\nCUpgrade:New(\"upgrade-zerg-burrow\")\nCUpgrade:New(\"upgrade-zerg-ventral-sacs\")\nCUpgrade:New(\"upgrade-zerg-antennae\")\nCUpgrade:New(\"upgrade-zerg-pneumatized-carapace\")\n\n--DefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-larva\",\n--  Action = \"button\", Value = 1,\n--  Key = \"s\", Hint = \"~!Select Larva\",\n--  ForUnit = {\"unit-zerg-hatchery\", \"unit-zerg-lair\", \"unit-zerg-hive\"} } )\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-larva\",\n  Action = \"callback\", Value = (function(self)\n    local units = GetUnitsAroundUnit(self, 1)\n\tfor i,unit in ipairs(units) do\n\t  if (GetUnitVariable(unit, \"Ident\") == \"unit-zerg-larva\") then\n        SelectSingleUnit(unit)\n      end\n    end  \n  end),\n  Key = \"s\", Hint = \"~!Select Larva\",\n  ForUnit = {\"unit-zerg-hatchery\", \"unit-zerg-lair\", \"unit-zerg-hive\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-rally-point\",\n  Action = \"move\",\n  Key = \"r\", Hint = \"Set ~!Rally Point\",\n  ForUnit = {\"unit-zerg-hatchery\", \"unit-zerg-lair\", \"unit-zerg-hive\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-zerg-burrow-down\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-burrow\",\n  Key = \"b\", Hint = \"Evolve ~!Burrow\",\n  ForUnit = {\"unit-zerg-hatchery\", \"unit-zerg-lair\", \"unit-zerg-hive\"} } )\n\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-zerg-lair\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-lair\",\n  Key = \"l\", Hint = \"Mutate into ~!Lair\",\n  ForUnit = {\"unit-zerg-hatchery\"} } )\n\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-zerg-hive\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-hive\",\n  Key = \"h\", Hint = \"Mutate into ~!Hive\",\n  ForUnit = {\"unit-zerg-lair\"} } )\n\nDefineButton( { Pos = 4, Level = 0, Icon = \"icon-zerg-ventral-sacs\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-ventral-sacs\",\n  Key = \"v\", Hint = \"Evolve ~!Ventral Sacs\",\n  ForUnit = {\"unit-zerg-lair\", \"unit-zerg-hive\"} } )\n\nDefineButton( { Pos = 5, Level = 0, Icon = \"icon-zerg-antennae\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-antennae\",\n  Key = \"a\", Hint = \"Evolve ~!Antennae\",\n  ForUnit = {\"unit-zerg-lair\", \"unit-zerg-hive\"} } )\n\nDefineButton( { Pos = 6, Level = 0, Icon = \"icon-zerg-pneumatized-carapace\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-pneumatized-carapace\",\n  Key = \"p\", Hint = \"Evolve ~!Pneumatized Carapace\",\n  ForUnit = {\"unit-zerg-lair\", \"unit-zerg-hive\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-hive.lua",
    "content": "--\n-- unit-zerg-hive\n--\n\n\nDefineAnimations(\"animations-zerg-hive\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 3\", \"wait 4\",\n    \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 0\", \"wait 4\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-hive\", {\n  Animations = \"animations-zerg-hive\", Icon = \"icon-zerg-hive\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 0},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 35, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 8,\n  RegenerationRate = 1,\n--  ExplodeWhenKilled = \"missle-zerg-rubble-large\",\n--  Corpse = \"unit-zerg-rubble-large\",\n  BuilderLost = true,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \">\", Type = \"unit-resource-mineral-field\"} } },\n  CanStore = {\"gas\", \"minerals\"},\n  Sounds = {\n    \"selected\", \"zerg-hive-selected\",\n--    \"ready\", \"town-hall-ready\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-hydralisk-den.lua",
    "content": "--\n-- unit-zerg-hydralisk-den\n--\n\n\nDefineAnimations(\"animations-zerg-hydralisk-den\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 4\", \"frame 1\", \"wait 2\",\n    \"frame 0\", \"wait 4\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-hydralisk-den\", {\n  Animations = \"animations-zerg-hydralisk-den\", Icon = \"icon-zerg-hydralisk-den\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-hydralisk-den-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-hydralisk.lua",
    "content": "--\n-- unit-zerg-hydralisk\n--\n\n\nDefineAnimations(\"animations-zerg-hydralisk-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 50\", \"frame 1\", \"wait 50\", \"frame 2\", \"wait 50\",\n    \"frame 3\", \"wait 50\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-hydralisk-death\", {\n  Image = image_32_zerg_zhydeath,\n  Animations = \"animations-zerg-hydralisk-death\", Icon = \"icon-zerg-hydralisk\",\n  NumDirections = image_32_zerg_zhydeath_NumDirections,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  SelectableByRectangle = false,\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-hydralisk\", {\n  Still = {\n    \"label 3FBB\", \"frame 85\",\n    \"label 3FBE\", \"random-wait 63 75\",\n      \"random-goto 10 3FCC\", \"random-goto 50 3FF2\", \"goto 3FBE\",\n    \"label 3FCC\", \"frame 0\", \"wait 1\", \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\",\n      \"frame 51\", \"wait 25\", \"frame 34\", \"wait 1\", \"frame 17\", \"wait 1\",\n      \"frame 0\", \"wait 1\", \"goto 3FBB\",\n    \"label 3FF2\", \"random-goto 50 4023\", \"frame 102\", \"wait 1\", \"rotate -2\",\n      \"frame 119\", \"wait 1\", \"rotate -2\", \"frame 136\", \"wait 1\", \"rotate -2\",\n      \"frame 153\", \"wait 1\", \"rotate -2\", \"frame 170\", \"wait 1\", \"rotate -2\",\n      \"frame 187\", \"wait 1\", \"rotate -2\", \"goto 3FBB\",\n    \"label 4023\", \"frame 102\", \"wait 1\", \"rotate 2\",\n      \"frame 119\", \"wait 1\", \"rotate 2\", \"frame 136\", \"wait 1\", \"rotate 2\",\n      \"frame 153\", \"wait 1\", \"rotate 2\", \"frame 170\", \"wait 1\", \"rotate 2\",\n      \"frame 187\", \"wait 1\", \"rotate 2\", \"goto 3FBB\",\n  },\n  Move = {\n    \"unbreakable begin\",\n    \"move 3\", \"wait 1\", \"frame 102\", \"move 3\", \"wait 1\", \"frame 119\",\n    \"move 3\", \"wait 1\", \"frame 136\", \"move 7\", \"wait 1\", \"frame 153\",\n    \"move 6\", \"wait 1\", \"frame 170\", \"move 7\", \"wait 1\", \"frame 187\",\n    \"move 3\",\n    \"unbreakable end\", \"wait 1\", \"frame 85\",\n  },\n  Attack = {\n    \"frame 0\", \"wait 1\", \"unbreakable begin\",\n    \"frame 17\", \"wait 1\", \"frame 34\", \"wait 1\", \"frame 51\", \"wait 2\",\n    \"frame 68\", \"sound zerg-hydralisk-attack\", \"attack\", \"wait 1\", \"frame 51\",\n    \"unbreakable end\", \"wait 20\",\n  },\n  Death = {\n    \"unbreakable begin\",\n    \"exact-frame 204\", \"wait 2\", \"exact-frame 205\", \"wait 2\", \"exact-frame 206\", \"wait 2\",\n    \"exact-frame 207\", \"wait 2\", \"exact-frame 208\", \"wait 2\", \"exact-frame 209\", \"wait 2\",\n    \"exact-frame 210\", \"wait 2\", \"exact-frame 211\", \"wait 2\",\n    \"unbreakable end\", \"wait 1\",\n  },\n--[[ Burrow =\n    \"frame 212\", \"wait 1\", \"frame 229\", \"wait 1\", \"frame 246\", \"wait 1\",\n    \"frame 263\", \"wait 1\", \"frame 280\", \"wait 1\" ]]\n})\n\nDefineUnitType(\"unit-zerg-hydralisk\", { Name = \"Hydralisk\",\n  Animations = \"animations-zerg-hydralisk\", Icon = \"icon-zerg-hydralisk\",\n  Speed = 0,\n  DrawLevel = 40,\n  BoardSize = 2,\n  Armor = 2, BasicDamage = 10, PiercingDamage = 4, Missile = \"missile-zerg-spit\",\n  AnnoyComputerFactor = 50,\n  MaxAttackRange = 5,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  RegenerationRate = 1,\n  Corpse = \"unit-zerg-hydralisk-death\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  CanTargetAir = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-hydralisk-selected\",\n    \"acknowledge\", \"zerg-hydralisk-acknowledgement\",\n    \"ready\", \"zerg-hydralisk-ready\",\n    \"help\", \"zerg-units-attacked\",\n\t\"dead\", \"zerg-hydralisk-death\"} } )\n\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-lair.lua",
    "content": "--\n-- unit-zerg-lair\n--\n\n\nDefineAnimations(\"animations-zerg-lair\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 3\", \"wait 4\",\n    \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 0\", \"wait 4\",\n  },\n  Train = {\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-lair\", {\n  Animations = \"animations-zerg-lair\", Icon = \"icon-zerg-lair\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 0},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 35, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 8,\n  RegenerationRate = 1,\n--  ExplodeWhenKilled = \"missle-zerg-rubble-large\",\n--  Corpse = \"unit-zerg-rubble-large\",\n  BuilderLost = true,\n  VisibleUnderFog = true, \n  BuildingRules = { { \"distance\", { Distance = 3, DistanceType = \">\", Type = \"unit-resource-mineral-field\"} } },\n  CanStore = {\"gas\", \"minerals\"},\n  Sounds = {\n    \"selected\", \"zerg-lair-selected\",\n--    \"ready\", \"town-hall-ready\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-larva.lua",
    "content": "--\n--  unit-zerg-larva\n--\n\n\nDefineAnimations(\"animations-zerg-larva-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\",\n    \"frame 3\", \"wait 2\", \"frame 4\", \"wait 2\", \"frame 5\", \"wait 2\",\n    \"frame 6\", \"wait 25\", \"frame 7\", \"wait 25\", \"frame 8\", \"wait 25\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-larve-death\", {\n  Image = image_37_zerg_zladeath,\n  Animations = \"animations-zerg-larve-death\", Icon = \"icon-zerg-larva\",\n  NumDirections = image_37_zerg_zladeath_NumDirections,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  SelectableByRectangle = false,\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-larva\", {\n  Still = {\"frame 0\", \"wait 125\",},\n})\n\nDefineUnitType(\"unit-zerg-larva\", { Name = \"Larva\",\n  DrawLevel = 30,\n  Animations = \"animations-zerg-larva\", Icon = \"icon-zerg-larva\",\n  Armor = 10, Missile = \"missile-none\",\n  Corpse = \"unit-zerg-larva-death\",\n  SelectableByRectangle = true,\n} )\n\n-- larva\n\nDefineUnitType(\"unit-zerg-drone\", {})\nDefineUnitType(\"unit-zerg-zergling\", {})\nDefineUnitType(\"unit-zerg-hydralisk\", {})\nDefineUnitType(\"unit-zerg-ultralisk\", {})\nDefineUnitType(\"unit-zerg-overlord\", {})\nDefineUnitType(\"unit-zerg-queen\", {})\nDefineUnitType(\"unit-zerg-scourge\", {})\nDefineUnitType(\"unit-zerg-defiler\", {})\nDefineUnitType(\"unit-zerg-mutalisk\", {})\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-drone\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-drone\",\n  Key = \"d\", Hint = \"Build Drone\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-zergling\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-zergling\",\n  Key = \"z\", Hint = \"Zergling\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-zerg-overlord\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-overlord\",\n  Key = \"o\", Hint = \"Overlord\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n\nDefineButton( { Pos = 4, Level = 0, Icon = \"icon-zerg-hydralisk\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-hydralisk\",\n  Key = \"h\", Hint = \"Hydralisk\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n  \n DefineButton( { Pos = 5, Level = 0, Icon = \"icon-zerg-mutalisk\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-mutalisk\",\n  Key = \"m\", Hint = \"Mutalisk\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n  \nDefineButton( { Pos = 6, Level = 0, Icon = \"icon-zerg-scourge\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-scourge\",\n  Key = \"s\", Hint = \"Scourge\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n  \nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-zerg-queen\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-queen\",\n  Key = \"q\", Hint = \"Queen\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n  \nDefineButton( { Pos = 8, Level = 0, Icon = \"icon-zerg-ultralisk\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-ultralisk\",\n  Key = \"u\", Hint = \"Ultralisk\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n  \nDefineButton( { Pos = 9, Level = 0, Icon = \"icon-zerg-defiler\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-defiler\",\n  Key = \"d\", Hint = \"Defiler\",\n  ForUnit = {\"unit-zerg-larva\"} } )\n\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-mutalisk.lua",
    "content": "--\n-- unit-zerg-mutalisk\n--\n\n\nDefineAnimations(\"animations-zerg-mutalisk\", {\n  Still = {\n    \"frame 0\", \"wait 2\", \"frame 17\", \"wait 2\", \"frame 34\", \"wait 2\",\n    \"frame 51\", \"wait 2\", \"frame 68\", \"wait 2\",\n  },\n  Move = {\n    \"unbreakable begin\",\n    \"frame 0\", \"move 4\", \"wait 1\", \"frame 17\", \"move 3\", \"wait 1\",\n    \"frame 34\", \"move 3\", \"wait 1\", \"frame 51\", \"move 3\", \"wait 1\",\n    \"frame 68\", \"move 3\", \"wait 1\", \"frame 0\", \"move 4\", \"wait 1\",\n    \"frame 17\", \"move 3\", \"wait 1\", \"frame 34\", \"move 3\", \"wait 1\",\n    \"frame 51\", \"move 3\", \"wait 1\", \"frame 68\", \"move 3\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Attack = {\"unbreakable begin\", \"attack\", \"sound zerg-mutalisk-attack\",\n    \"unbreakable end\", \"wait 40\",},\n  Death = {\"unbreakable begin\", \"sound zerg-mutalisk-death\",\n    --[[active overlay 41,0]] \"wait 1\", \"unbreakable end\", \"wait 1\",},\n})\n\n\nDefineUnitType(\"unit-zerg-mutalisk\", {\n  DrawLevel = 45,\n  Animations = \"animations-zerg-mutalisk\", Icon = \"icon-zerg-mutalisk\",\n  Speed = 14,\n  DrawLevel = 60,\n  Armor = 5, BasicDamage = 0, PiercingDamage = 16, Missile = \"missile-zerg-mutalisk-glaive-wurm\",\n  AnnoyComputerFactor = 55,\n  MaxAttackRange = 4,\n  Priority = 65,\n  Points = 150,\n  Demand = 2,\n  ExplodeWhenKilled = \"missile-terran-explosion-small\",--FIXME:wrong explosion\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true, CanTargetSea = true, CanTargetAir = true,\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-mutalisk-selected\",\n    \"acknowledge\", \"zerg-mutalisk-acknowledgement\",\n    \"ready\", \"zerg-mutalisk-ready\",\n    \"help\", \"zerg-units-attacked\",\n    \"dead\", \"zerg-mutalisk-death\"} } )\n\nDefineUnitType(\"unit-zerg-guardian\", {})\n\n\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-zerg-guardian\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-guardian\",\n  Key = \"h\", Hint = \"Morph into Guardian\",\n  ForUnit = {\"unit-zerg-guardian\"} } )\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-nydus-canal.lua",
    "content": "--\n-- unit-zerg-nydus-canal\n--\n\n\nDefineAnimations(\"animations-zerg-nydus-canal\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\",\n    \"frame 0\", \"wait 2\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-nydus-canal\", {\n  Animations = \"animations-zerg-nydus-canal\", Icon = \"icon-zerg-nydus-canal\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-nydus-canal-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-overlord.lua",
    "content": "--\n-- unit-zerg-overlord\n--\n\n\nDefineAnimations(\"animations-zerg-overlord-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 2\", --[[ active overlay 58 ]]\n    \"wait 1\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-overlord-death\", {\n  Image = image_45_zerg_zovdeath,\n  Animations = \"animations-zerg-overlord-death\", Icon = \"icon-zerg-overlord\",\n  NumDirections = image_45_zerg_zovdeath_NumDirections,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {63, 63},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-overlord\", {\n  Still = {\n    \"frame 0\", \"wait 125\",\n  },\n  Move = {\n    \"frame 0\", \"wait 2\", \"frame 17\", \"wait 2\",\n    \"label 42D8\", \"unbreakable begin\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"frame 34\", \"move 2\", \"wait 2\", \"frame 51\", \"move 2\", \"wait 2\",\n    \"unbreakable end\", \"wait 1\", \"goto 42D8\",\n  },\n  Death = {\n    \"sound zerg-overlord-death\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-overlord\", { Name = \"Overlord\",\n  Animations = \"animations-zerg-overlord\", Icon = \"icon-zerg-overlord\",\n  RepairHp = 4,\n  Speed = 0,\n  DrawLevel = 45,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 45,\n  Points = 200,\n  Supply = 9,\n  DetectCloak = true,\n  CanTransport = {},\n  MaxOnBoard = 6,\n  Corpse = \"unit-zerg-overlord-death\",\n  SelectableByRectangle = true,\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  Sounds = {\n    \"selected\", \"zerg-overlord-selected\",\n    \"acknowledge\", \"zerg-overlord-acknowledgement\",\n    \"ready\", \"zerg-overlord-ready\",\n    \"help\", \"zerg-units-attacked\",\n    \"dead\", \"zerg-overlord-death\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-queen.lua",
    "content": "--\n-- unit-zerg-queen\n--\n\n\nDefineAnimations(\"animations-zerg-queen\", {\n  Still = {\n    \"frame 0\", \"wait 2\", \"frame 17\", \"wait 2\", \"frame 34\", \"wait 2\",\n    \"frame 51\", \"wait 2\", \"frame 68\", \"wait 2\",\n  },\n  Move = {\n    \"unbreakable begin\",\n    \"frame 0\", \"move 4\", \"wait 1\", \"frame 17\", \"move 3\", \"wait 1\",\n    \"frame 34\", \"move 3\", \"wait 1\", \"frame 51\", \"move 3\", \"wait 1\",\n    \"frame 68\", \"move 3\", \"wait 1\", \"frame 0\", \"move 4\", \"wait 1\",\n    \"frame 17\", \"move 3\", \"wait 1\", \"frame 34\", \"move 3\", \"wait 1\",\n    \"frame 51\", \"move 3\", \"wait 1\", \"frame 68\", \"move 3\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Attack = {\n    \"unbreakable begin\",\n    \"frame 85\", \"wait 1\", \"frame 102\", \"wait 1\", \"frame 119\", \"wait 1\",\n    \"frame 136\", \"sound zerg-queen-attack\", \"attack\", \"wait 1\",\n    \"frame 153\", \"wait 1\", \"frame 170\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Death = {\n    \"frame 0\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-queen\", {\n  Animations = \"animations-zerg-queen\", Icon = \"icon-zerg-queen\",\n  RepairHp = 1,\n  Speed = 4,\n  DrawLevel = 45,\n  Demand = 2,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 20, AnnoyComputerFactor = 45,\n  Points = 200,\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RegenerationRate = 1,\n  Sounds = {\n    \"selected\", \"zerg-queen-selected\",\n    \"acknowledge\", \"zerg-queen-acknowledgement\",\n    \"ready\", \"zerg-queen-ready\",\n    \"help\", \"zerg-units-attacked\",\n    \"dead\", \"zerg-queen-death\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-queens-nest.lua",
    "content": "--\n-- unit-zerg-queens-nest\n--\n\n\nDefineAnimations(\"animations-zerg-queens-nest\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 1\", \"wait 2\",\n    \"frame 0\", \"wait 2\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-queens-nest\", {\n  Animations = \"animations-zerg-queens-nest\", Icon = \"icon-zerg-queens-nest\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-queens-nest-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-scourge.lua",
    "content": "--\n-- unit-zerg-scourge\n--\n\n\nDefineAnimations(\"animations-zerg-scourge-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 50\", \"frame 1\", \"wait 50\", \"frame 2\", \"wait 50\",\n    \"frame 3\", \"wait 50\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-scourge-death\", { Name = \"Dead Scourge\",\n  Image = image_3_zerg_zavdeath,\n  Animations = \"animations-zerg-scourge-death\", Icon = \"icon-zerg-scourge\",\n  NumDirections = image_3_zerg_zavdeath_NumDirections,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  SelectableByRectangle = false,\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-scourge\", {\n  Still = {\n    \"frame 0\", \"wait 3\", \"frame 17\", \"wait 3\", \"frame 34\", \"wait 3\",\n    \"frame 51\", \"wait 3\", \"frame 68\", \"wait 3\",\n  },\n  Move = {\n    \"unbreakable begin\",\n    \"frame 0\", \"move 4\", \"wait 2\", \"frame 17\", \"move 3\", \"wait 2\",\n    \"frame 34\", \"move 3\", \"wait 2\", \"frame 51\", \"move 3\", \"wait 2\",\n    \"frame 68\", \"move 3\", \"wait 2\", \"frame 0\", \"move 4\", \"wait 2\",\n    \"frame 17\", \"move 3\", \"wait 2\", \"frame 34\", \"move 3\", \"wait 2\",\n    \"frame 51\", \"move 3\", \"wait 2\", \"frame 68\", \"move 3\", \"wait 1\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Attack = {\n    \"unbreakable begin\",\n    \"sound zerg-scourge-attack\", \"frame 0\", \"wait 1\", \"attack\",\n    \"unbreakable end\", \"wait 1\",\n  },\n  Death = {\n    \"unbreakable begin\", \"sound zerg-scourge-death\",\n    \"wait 1\", \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-scourge\", {\n  DrawLevel = 45,\n  Animations = \"animations-zerg-scourge\", Icon = \"icon-zerg-scourge\",\n  Speed = 14,\n  DrawLevel = 60,\n  Armor = 0, BasicDamage = 110, PiercingDamage = 16, Missile = \"missile-none\",\n  MaxAttackRange = 1,\n  Priority = 65,\n  Points = 150,\n  Demand = 1,\n  Corpse = \"unit-zerg-scourge-death\",\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = false, CanTargetSea = false, CanTargetAir = true,\n  AirUnit = true,\n  DetectCloak = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-scourge-selected\",\n    \"acknowledge\", \"zerg-scourge-acknowledgement\",\n    \"ready\", \"zerg-scourge-ready\",\n    \"help\", \"zerg-units-attacked\",\n    \"dead\", \"zerg-scourge-death\"} } )\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-spawning-pool.lua",
    "content": "--\n-- unit-zerg-spawning-pool\n--\n\n\nDefineAnimations(\"animations-zerg-spawning-pool\", {\n  Still = {\n    \"frame 0\", \"wait 2\", \"frame 2\", \"wait 2\", \"frame 3\", \"wait 2\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-spawning-pool\", {\n  Animations = \"animations-zerg-spawning-pool\", Icon = \"icon-zerg-spawning-pool\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 30, AnnoyComputerFactor = 35,\n  Points = 160,\n  RegenerationRate = 1,\n  BuilderLost = true,\n--  Corpse = \"unit-zerg-rubble-large\",\n  ExplodeWhenKilled = \"missile-none\",\n  VisibleUnderFog = true, \n  Sounds = {\n    \"selected\", \"zerg-spawning-pool-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n--[[\t\nCUpgrade:New(\"upgrade-zerg-zergling-speed\")\n\t\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-zergling-speed\",\n  Action = \"research\", Value = \"upgrade-zerg-zergling-speed\",\n  Allowed = \"check-single-research\",\n  Key = \"w\", Hint = \"Upgrade Zergling Speed\",\n  ForUnit = {\"unit-zerg-spawning-pool\"} } )\n\n--]]\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-spire.lua",
    "content": "--\n-- unit-zerg-spire\n--\n\n\nDefineAnimations(\"animations-zerg-spire\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 4\", \"frame 1\", \"wait 2\",\n    \"frame 0\", \"wait 4\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-spire\", {\n  Animations = \"animations-zerg-spire\", Icon = \"icon-zerg-spire\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  UpgradeTo = 100,\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-spire-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n\t\nCUpgrade:New(\"upgrade-zerg-greater-spire\")\n\t\nDefineButton( { Pos = 7, Level = 0, Icon = \"icon-zerg-greater-spire\",\n  Action = \"upgrade-to\", Value = \"unit-zerg-greater-spire\",\n  Key = \"w\", Hint = \"Mutate to Greater Spire\",\n  ForUnit = {\"unit-zerg-spire\"} } )\n\n\nCUpgrade:New(\"upgrade-zerg-flyer-attacks1\")\nCUpgrade:New(\"upgrade-zerg-flyer-attacks2\")\nCUpgrade:New(\"upgrade-zerg-flyer-attacks3\")\nCUpgrade:New(\"upgrade-zerg-flyer-carapace1\")\nCUpgrade:New(\"upgrade-zerg-flyer-carapace2\")\nCUpgrade:New(\"upgrade-zerg-flyer-carapace3\")\n\n\n\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-flyer-attack\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-attacks1\",\n  Allowed = \"check-single-research\",\n  Key = \"w\", Hint = \"Upgrade Flyer Attacks\",\n  ForUnit = {\"unit-zerg-evolution-chamber\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-flyer-attack\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-attacks2\",\n  Key = \"w\", Hint = \"Upgrade Flyer Attacks\",\n  ForUnit = {\"unit-zerg-spire\"} } )\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-zerg-upgrade-flyer-attack\",\n  Allowed = \"check-single-research\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-attacks3\",\n  Key = \"w\", Hint = \"Upgrade Flyer Attacks\",\n  ForUnit = {\"unit-zerg-spire\"} } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-carapace1\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Flyer Carapace\",\n  ForUnit = {\"unit-zerg-spire\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-carapace2\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Flyer Carapace\",\n  ForUnit = {\"unit-zerg-spire\"} } )\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-zerg-upgrade-zerg-carapace\",\n  Action = \"research\", Value = \"upgrade-zerg-flyer-carapace3\",\n  Allowed = \"check-single-research\",\n  Key = \"a\", Hint = \"Upgrade Flyer Carapace\",\n  ForUnit = {\"unit-zerg-spire\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-spore-colony.lua",
    "content": "--\n-- unit-zerg-spore-colony\n--\n\n\nDefineAnimations(\"animations-zerg-spore-colony\", {\n  Still = {\n    \"frame 0\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\",\n    \"frame 3\", \"wait 2\",\n  },\n  Attack = {\n    \"unbreakable begin\", \"sound zerg-spore-colony-attack\", \n    \"frame 0\", \"wait 1\", \"attack\",\n    \"unbreakable end\", \"wait 1\",\n  },  \n})\n\n\nDefineUnitType(\"unit-zerg-spore-colony\", {\n  Animations = \"animations-zerg-spore-colony\", Icon = \"icon-zerg-spore-colony\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 15, PiercingDamage = 5, Missile = \"missile-none\",\n  MaxAttackRange = 7,\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  BuilderLost = true,\n  RegenerationRate = 1,\n  CanAttack = true,\n  CanTargetAir = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-spore-colony-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-sunken-colony.lua",
    "content": "--\n-- unit-zerg-sunken-colony\n--\n\n\nDefineAnimations(\"animations-zerg-sunken-colony\", {\n  Still = {\n    \"frame 0\", \"wait 2\", \"frame 1\", \"wait 2\", \"frame 2\", \"wait 2\",\n  },\n  Attack = { --[[ frames 3-13, 14-23, 24-33 ]]\n    \"unbreakable begin\", \"sound zerg-sunken-colony-attack\", \n    \"frame 24\", \"wait 1\", \"frame 25\", \"wait 1\", \"frame 26\", \"wait 1\",\n    \"frame 27\", \"wait 1\", \"frame 28\", \"wait 1\", \"frame 29\", \"wait 1\",\n    \"frame 30\", \"wait 1\", \"frame 31\", \"wait 1\", \"frame 32\", \"wait 1\",\n    \"frame 33\", \"wait 1\", \"attack\", \"wait 6\",\n    \"frame 32\", \"wait 1\", \"frame 31\", \"wait 1\", \"frame 30\", \"wait 1\",\n    \"frame 29\", \"wait 1\", \"frame 28\", \"wait 1\", \"frame 27\", \"wait 1\",\n    \"frame 26\", \"wait 1\", \"frame 25\", \"wait 1\", \"frame 24\",\n    \"unbreakable end\", \"wait 5\", \"sound zerg-sunken-colony-hit\",  \"wait 20\",\n  },  \n})\n\n\nDefineUnitType(\"unit-zerg-sunken-colony\", {\n  Animations = \"animations-zerg-sunken-colony\", Icon = \"icon-zerg-sunken-colony\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  MaxAttackRange = 7,\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  BuilderLost = true,\n  RegenerationRate = 1,\n  CanAttack = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-sunken-colony-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-ultralisk-cavern.lua",
    "content": "--\n-- unit-zerg-ultralisk-cavern\n--\n\n\nDefineAnimations(\"animations-zerg-ultralisk-cavern\", {\n  Still = {\n    \"frame 1\", \"wait 2\", \"frame 2\", \"wait 4\", \"frame 1\", \"wait 2\",\n    \"frame 0\", \"wait 4\",\n  },\n  Train = {--[[FIXME: active overlay 276]]\n    \"frame 0\", \"wait 125\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-ultralisk-cavern\", {\n  Animations = \"animations-zerg-ultralisk-cavern\", Icon = \"icon-zerg-ultralisk-cavern\",\n  RepairHp = 4,\n  RepairCosts = {\"minerals\", 1, \"gas\", 1},\n  Construction = \"construction-zerg\",\n  Speed = 0,\n  DrawLevel = 30,\n  Armor = 20, BasicDamage = 20, PiercingDamage = 5, Missile = \"missile-none\",\n  Priority = 15, AnnoyComputerFactor = 20,\n  Points = 170,\n  --Corpse = \"unit-destroyed-3x3-place\",\n  ExplodeWhenKilled = \"missile-terran-explosion-large\",\n  RightMouseAction = \"attack\",\n  RegenerationRate = 1,\n  CanAttack = true,\n  BuilderLost = true,\n  CanTargetLand = true,\n  VisibleUnderFog = true,\n  Sounds = {\n    \"selected\", \"zerg-ultralisk-cavern-selected\",\n    \"ready\", \"zerg-building-ready\",\n    \"help\", \"zerg-base-attacked\",\n    \"dead\", \"zerg-building-blowup\"} } )\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-ultralisk.lua",
    "content": "--\n-- unit-zerg-ultralisk\n--\n\n\nDefineAnimations(\"animations-zerg-ultralisk-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 50\", \"frame 1\", \"wait 50\", \"frame 2\", \"wait 50\",\n    \"frame 3\", \"wait 50\", \"frame 4\", \"wait 50\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-ultralisk-death\", { Name = \"Dead Zergling\",\n  Image = image_53_zerg_zuldeath,\n  Animations = \"animations-zerg-ultralisk-death\", Icon = \"icon-zerg-ultralisk\",\n  NumDirections = image_53_zerg_zuldeath_NumDirections,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {63, 63},--FIXME: wrong boxsize\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-ultralisk\", {\n  Still = {\n    \"label 45F1\", \"frame 153\", \"goto 79BA\",\n    \"label 79BA\", \"wait 125\", \"goto 79BA\",\n    \"random-goto 50 4654\",\n    \"frame 153\", \"rotate -2\", \"wait 1\", \"frame 0\", \"rotate -2\", \"wait 1\",\n    \"frame 17\", \"rotate -2\", \"wait 1\", \"frame 34\", \"rotate -2\", \"wait 1\",\n    \"frame 51\", \"rotate -2\", \"wait 1\", \"frame 68\", \"rotate -2\", \"wait 1\",\n    \"frame 85\", \"rotate -2\", \"wait 1\", \"frame 102\", \"rotate -2\", \"wait 1\",\n    \"frame 119\", \"rotate -2\", \"wait 1\", \"goto 45F1\",\n    \"label 4654\", \"frame 153\", \"rotate 2\", \"wait 1\", \"frame 0\", \"rotate 2\", \"wait 1\",\n    \"frame 17\", \"rotate 2\", \"wait 1\", \"frame 34\", \"rotate 2\", \"wait 1\",\n    \"frame 51\", \"rotate 2\", \"wait 1\", \"frame 68\", \"rotate 2\", \"wait 1\",\n    \"frame 85\", \"rotate 2\", \"wait 1\", \"frame 102\", \"rotate 2\", \"wait 1\",\n    \"frame 119\", \"rotate 2\", \"wait 1\", \"goto 45F1\",\n  },\n  Move = {\n    \"unbreakable begin\",\n    \"move 3\", \"wait 1\", \"frame 0\", \"move 8\", \"wait 2\", \"frame 17\",\n    \"move 5\", \"wait 1\", \"frame 34\", \"move 4\", \"wait 1\", \"frame 51\",\n    \"move 4\", \"wait 2\", \"frame 68\", \"move 8\", \"wait 1\", \"frame 85\",\n    \"unbreakable end\", \"wait 1\",\n    \"unbreakable begin\",\n    \"move 8\", \"wait 1\", \"frame 102\", \"move 8\", \"wait 1\", \"frame 119\",\n    \"move 8\", \"wait 1\", \"frame 136\", \"move 8\",\n    \"unbreakable end\", \"wait 1\", \"frame 153\",\n  },\n  Attack = {\n    \"frame 238\", \"wait 1\",\n    \"unbreakable begin\",\n    \"sound zerg-ultralisk-attack\", \"wait 2\", \"frame 221\", \"wait 2\",\n    \"frame 204\", \"sound zerg-ultralisk-hit\", \"attack\", \"wait 2\",\n    \"frame 187\", \"wait 2\", \"frame 204\", \"wait 2\", \"frame 221\", \"wait 2\",\n    \"frame 238\", \"wait 2\",\n    \"unbreakable end\",\n  },\n  Death = {\n    \"unbreakable begin\",\n    \"frame 255\", \"wait 2\", \"frame 256\", \"wait 2\", \"frame 257\", \"wait 2\",\n    \"frame 258\", \"wait 2\", \"frame 259\", \"wait 2\", \"frame 260\", \"wait 2\",\n    \"frame 261\", \"wait 2\", \"frame 262\", \"wait 2\", \"frame 263\", \"wait 2\",\n    \"frame 264\", \"wait 2\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\nDefineUnitType(\"unit-zerg-ultralisk\", {\n  Animations = \"animations-zerg-ultralisk\", Icon = \"icon-zerg-ultralisk\",\n  Speed = 12,\n  DrawLevel = 40,\n  Armor = 3, BasicDamage = 20, PiercingDamage = 10, Missile = \"missile-none\",\n  AnnoyComputerFactor = 55,\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 30,\n  Demand = 6,\n  RegenerationRate = 1,\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  Corpse = \"unit-zerg-ultralisk-death\",\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-ultralisk-selected\",\n    \"acknowledge\", \"zerg-ultralisk-acknowledgement\",\n    \"ready\", \"zerg-ultralisk-ready\",\n    \"help\", \"zerg-units-attacked\",\n\t\"dead\", \"zerg-ultralisk-death\"} } )\n\n\n"
  },
  {
    "path": "scripts/zerg/unit-zerg-zergling.lua",
    "content": "--\n-- unit-zerg-zergling\n--\n\n\nDefineAnimations(\"animations-zerg-zergling-death\", {\n  Death = {\n    \"unbreakable begin\",\n    \"frame 0\", \"wait 50\", \"frame 1\", \"wait 50\", \"frame 2\", \"wait 50\",\n    \"frame 3\", \"wait 50\", \"frame 4\", \"wait 50\",\n    \"unbreakable end\", \"wait 1\",\n  },\n})\n\n\nDefineUnitType(\"unit-zerg-zergling-death\", { Name = \"Dead Zergling\",\n  Image = image_57_zerg_zzedeath,\n  Animations = \"animations-zerg-zergling-death\", Icon = \"icon-zerg-zergling\",\n  NumDirections = image_57_zerg_zzedeath_NumDirections,\n  HitPoints = 255,\n  DrawLevel = 30,\n  TileSize = {1, 1}, BoxSize = {31, 31},\n  SightRange = 1,\n  BasicDamage = 0, PiercingDamage = 0, Missile = \"missile-none\",\n  Priority = 0,\n  Type = \"land\",\n  Vanishes = true,\n  Sounds = {} } )\n\n\nDefineAnimations(\"animations-zerg-zergling\", {\n  Still = {\n    \"frame 85\", \"wait 125\",\n  },\n  Move = {\n    \"label jumpoff\", \"unbreakable begin\",\n    \"frame 102\", \"move 1\", \"wait 2\", \"frame 119\", \"move 7\",\n    \"unbreakable end\", \"wait 1\", \"goto fly\",\n\n    \"label runningstart\", \"unbreakable begin\",\n    \"if-var R >= 40 jumpoff\", -- 180 turn, accellerate from slow\n    \"if-var R <= -40 jumpoff\", -- 180 turn, accellerate from slow\n    \"frame 102\", \"move 1\", \"wait 1\", \"frame 119\", \"move 7\",\n    \"unbreakable end\", \"wait 1\",\n\n    \"label fly\", \"unbreakable begin\",\n    \"if-var R >= 40 jumpoff\", -- 180 turn, accellerate from slow\n    \"if-var R <= -40 jumpoff\", -- 180 turn, accellerate from slow\n    \"frame 136\", \"move 8\",\n    \"unbreakable end\", \"wait 1\",\n\n    \"label land\", \"unbreakable begin\",\n    \"if-var R >= 40 jumpoff\", -- 180 turn, accellerate from slow\n    \"if-var R <= -40 jumpoff\", -- 180 turn, accellerate from slow\n    \"frame 153\", \"move 4\", \"wait 1\", \"frame 170\", \"move 4\",\n    \"unbreakable end\", \"wait 1\",\n\n    \"wait crash\", \"unbreakable begin\",\n    \"if-var R >= 40 jumpoff\", -- 180 turn, accellerate from slow\n    \"if-var R <= -40 jumpoff\", -- 180 turn, accellerate from slow\n    \"frame 187\", \"move 6\", \"wait 1\", \"frame 187\", \"move 2\",\n    \"unbreakable end\", \"wait 1\",\n\n    \"goto runningstart\",\n  },\n  Attack = {\n    \"frame 0\", \"wait 1\",\n    \"unbreakable begin\", \"frame 17\", \"wait 1\", \"frame 34\",\n    \"sound zerg-zergling-attack\", \"attack\", \"wait 1\",\n    \"frame 51\", \"wait 1\", \"frame 68\", \"wait 1\",\n    \"unbreakable end\",\n  },\n  Death = {\n    \"unbreakable begin\",\n    \"sound zerg-zergling-death\", \"exact-frame 289\", \"wait 2\",\n    \"exact-frame 290\", \"wait 2\", \"exact-frame 291\", \"wait 2\",\n    \"exact-frame 292\", \"wait 2\", \"exact-frame 293\", \"wait 2\",\n    \"exact-frame 294\", \"wait 2\", \"exact-frame 295\", \"wait 2\",\n    \"unbreakable end\", \"wait 1\",\n  },\n--[[ Burrow = frame 204,221,238,255,272 ]]\n})\n\n\nDefineUnitType(\"unit-zerg-zergling\", {\n  Animations = \"animations-zerg-zergling\", Icon = \"icon-zerg-zergling\",\n  Speed = 10,\n  RotationSpeed = 40,\n  DrawLevel = 40,\n  Armor = 2, BasicDamage = 6, PiercingDamage = 3, Missile = \"missile-none\",\n  AnnoyComputerFactor = 50,\n  MaxAttackRange = 1,\n  Priority = 60,\n  Points = 50,\n  Demand = 1,\n  Corpse = \"unit-zerg-zergling-death\",\n  RegenerationRate = 1,\n  RightMouseAction = \"attack\",\n  CanAttack = true,\n  CanTargetLand = true,\n  SelectableByRectangle = true,\n  Sounds = {\n    \"selected\", \"zerg-zergling-selected\",\n    \"acknowledge\", \"zerg-zergling-acknowledgement\",\n    \"ready\", \"zerg-zergling-ready\",\n    \"help\", \"zerg-units-attacked\",\n\t\"dead\", \"zerg-zergling-death\",} } )\n\n"
  },
  {
    "path": "scripts/zerg/units.lua",
    "content": "Load(\"scripts/zerg/construction.lua\")\n\nLoad(\"scripts/zerg/unit-zerg-creep-colony.lua\")\nLoad(\"scripts/zerg/unit-zerg-defiler-mound.lua\")\nLoad(\"scripts/zerg/unit-zerg-evolution-chamber.lua\")\nLoad(\"scripts/zerg/unit-zerg-extractor.lua\")\nLoad(\"scripts/zerg/unit-zerg-greater-spire.lua\")\nLoad(\"scripts/zerg/unit-zerg-hatchery.lua\")\nLoad(\"scripts/zerg/unit-zerg-hive.lua\")\nLoad(\"scripts/zerg/unit-zerg-hydralisk-den.lua\")\nLoad(\"scripts/zerg/unit-zerg-lair.lua\")\nLoad(\"scripts/zerg/unit-zerg-nydus-canal.lua\")\nLoad(\"scripts/zerg/unit-zerg-queens-nest.lua\")\nLoad(\"scripts/zerg/unit-zerg-spawning-pool.lua\")\nLoad(\"scripts/zerg/unit-zerg-spire.lua\")\nLoad(\"scripts/zerg/unit-zerg-spore-colony.lua\")\nLoad(\"scripts/zerg/unit-zerg-sunken-colony.lua\")\nLoad(\"scripts/zerg/unit-zerg-ultralisk-cavern.lua\")\n\n--Load(\"scripts/zerg/unit-zerg-larva.lua\")\n\nLoad(\"scripts/zerg/unit-zerg-defiler.lua\")\nLoad(\"scripts/zerg/unit-zerg-drone.lua\")\nLoad(\"scripts/zerg/unit-zerg-egg.lua\")\nLoad(\"scripts/zerg/unit-zerg-guardian.lua\")\nLoad(\"scripts/zerg/unit-zerg-hydralisk.lua\")\nLoad(\"scripts/zerg/unit-zerg-mutalisk.lua\")\nLoad(\"scripts/zerg/unit-zerg-overlord.lua\")\nLoad(\"scripts/zerg/unit-zerg-queen.lua\")\nLoad(\"scripts/zerg/unit-zerg-scourge.lua\")\nLoad(\"scripts/zerg/unit-zerg-ultralisk.lua\")\nLoad(\"scripts/zerg/unit-zerg-zergling.lua\")\n\n\n--\n-- Buttons\n--\nDefineButton( { Pos = 1, Level = 0, Icon = \"icon-move\",\n  Action = \"move\",\n  Key = \"m\", Hint = \"~!Move\",\n  ForUnit = {\n    \"zerg-group\",\n\t\"unit-zerg-defiler\",\n    \"unit-zerg-drone\",\n    \"unit-zerg-guardian\",\n    \"unit-zerg-hydralisk\",\n\t\"unit-zerg-mutalisk\",\n\t\"unit-zerg-overlord\",\n\t\"unit-zerg-queen\",\n\t\"unit-zerg-scourge\",\n\t\"unit-zerg-ultralisk\",\n    \"unit-zerg-zergling\",\n  } } )\n\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-stop\",\n  Action = \"stop\",\n  Key = \"s\", Hint = \"~!Stop\",\n  ForUnit = {\n    \"zerg-group\",\n    \"unit-zerg-defiler\",\n    \"unit-zerg-drone\",\n    \"unit-zerg-guardian\",\n    \"unit-zerg-hydralisk\",\n    \"unit-zerg-mutalisk\",\n    \"unit-zerg-overlord\",\n    \"unit-zerg-queen\",\n    \"unit-zerg-scourge\",\n    \"unit-zerg-ultralisk\",\n    \"unit-zerg-zergling\",\n    \"unit-zerg-spore-colony\",\n    \"unit-zerg-sunken-colony\",\n  } } )\n\nDefineButton( { Pos = 3, Level = 0, Icon = \"icon-attack\",\n  Action = \"attack\",\n  Key = \"a\", Hint = \"~!Attack\",\n  ForUnit = {\n    \"zerg-group\",\n    \"unit-zerg-defiler\",\n    \"unit-zerg-drone\",\n    \"unit-zerg-guardian\",\n    \"unit-zerg-hydralisk\",\n    \"unit-zerg-mutalisk\",\n    \"unit-zerg-queen\",\n    \"unit-zerg-scourge\",\n    \"unit-zerg-ultralisk\",\n    \"unit-zerg-zergling\",\n    \"unit-zerg-spore-colony\",\n    \"unit-zerg-sunken-colony\",\n  } } )\n\nDefineButton( { Pos = 4, Level = 0, Icon = \"icon-patrol\",\n  Action = \"patrol\",\n  Key = \"p\", Hint = \"~!Patrol\",\n  ForUnit = {\n    \"zerg-group\",\n    \"unit-zerg-defiler\",\n    \"unit-zerg-guardian\",\n    \"unit-zerg-hydralisk\",\n    \"unit-zerg-mutalisk\",\n    \"unit-zerg-queen\",\n    \"unit-zerg-scourge\",\n    \"unit-zerg-ultralisk\",\n    \"unit-zerg-zergling\",\n  } } )\n\nDefineButton( { Pos = 5, Level = 0, Icon = \"icon-hold-position\",\n  Action = \"stand-ground\",\n  Key = \"h\", Hint = \"~!Hold Position\",\n  ForUnit = {\n    \"zerg-group\",\n    \"unit-zerg-defiler\",\n    \"unit-zerg-guardian\",\n    \"unit-zerg-hydralisk\",\n    \"unit-zerg-mutalisk\",\n    \"unit-zerg-queen\",\n    \"unit-zerg-scourge\",\n    \"unit-zerg-ultralisk\",\n    \"unit-zerg-zergling\",\n  } } )\n\n--[[\nDefineButton( { Pos = 2, Level = 0, Icon = \"icon-rally-point\",\n  Action = \"move\",\n  Key = \"r\", Hint = \"Set ~!Rally Point\",\n  ForUnit = { } } )\n]]\n\n\n--\n-- Allow\n--\nDefineAllow(\"unit-zerg-defiler\",            \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-larva\",              \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-drone\",              \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-egg\",                \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-guardian\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-hydralisk\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-mutalisk\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-overlord\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-queen\",              \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-scourge\",            \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-ultralisk\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-zergling\",           \"AAAAAAAAAAAAAAAA\")\n\nDefineAllow(\"unit-zerg-creep-colony\",       \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-defiler-mound\",      \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-evolution-chamber\",  \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-extractor\",          \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-greater-spire\",      \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-hatchery\",           \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-hive\",               \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-hydralisk-den\",      \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-lair\",               \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-nydus-canal\",        \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-queens-nest\",        \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-spawning-pool\",      \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-spire\",              \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-spore-colony\",       \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-sunken-colony\",      \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"unit-zerg-ultralisk-cavern\",   \"AAAAAAAAAAAAAAAA\")\n\n\n--DefineAllow(\"unit-zerg-rubble-large\",       \"AAAAAAAAAAAAAAAA\")\n\n"
  },
  {
    "path": "scripts/zerg/upgrade.lua",
    "content": "--\n--  Upgrades\n--\n\nlocal upgrades = {\n{ \"upgrade-zerg-melee-attacks1\", \"icon-zerg-upgrade-melee-attack\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-melee-attacks2\", \"icon-zerg-upgrade-melee-attack\",\n  {   200,   150,   150,     0,     0,     0,     0}},\n{ \"upgrade-zerg-melee-attacks3\", \"icon-zerg-upgrade-melee-attack\",\n  {   200,   200,   200,     0,     0,     0,     0}},\n  \n{ \"upgrade-zerg-missle-attacks1\", \"icon-zerg-upgrade-missle-attack\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-missle-attacks2\", \"icon-zerg-upgrade-missle-attack\",\n  {   200,   150,   150,     0,     0,     0,     0}},\n{ \"upgrade-zerg-missle-attacks3\", \"icon-zerg-upgrade-missle-attack\",\n  {   200,   200,   200,     0,     0,     0,     0}},\n  \n{ \"upgrade-zerg-carapace1\", \"icon-zerg-upgrade-zerg-carapace\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-carapace2\", \"icon-zerg-upgrade-zerg-carapace\",\n  {   200,   150,   150,     0,     0,     0,     0}},\n{ \"upgrade-zerg-carapace3\", \"icon-zerg-upgrade-zerg-carapace\",\n  {   200,   200,   200,     0,     0,     0,     0}},\n\n{ \"upgrade-zerg-flyer-attacks1\", \"icon-zerg-upgrade-flyer-attack\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-flyer-attacks2\", \"icon-zerg-upgrade-flyer-attack\",\n  {   200,   150,   150,     0,     0,     0,     0}},\n{ \"upgrade-zerg-flyer-attacks3\", \"icon-zerg-upgrade-flyer-attack\",\n  {   200,   200,   200,     0,     0,     0,     0}},\n  \n{ \"upgrade-zerg-flyer-carapace1\", \"icon-zerg-upgrade-zerg-carapace\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-flyer-carapace2\", \"icon-zerg-upgrade-zerg-carapace\",\n  {   200,   150,   150,     0,     0,     0,     0}},\n{ \"upgrade-zerg-flyer-carapace3\", \"icon-zerg-upgrade-zerg-carapace\",\n  {   200,   200,   200,     0,     0,     0,     0}},\n\n{ \"upgrade-zerg-burrow\", \"icon-zerg-burrow-down\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-ventral-sacs\", \"icon-zerg-ventral-sacs\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-antennae\", \"icon-zerg-antennae\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n{ \"upgrade-zerg-pneumatized-carapace\", \"icon-zerg-pneumatized-carapace\",\n  {   200,   100,   100,     0,     0,     0,     0}},\n}\n\nfor i = 1,table.getn(upgrades) do\n  u = CUpgrade:New(upgrades[i][1])\n  u.Icon = Icons[upgrades[i][2]]\n  for j = 1,table.getn(upgrades[1][3]) do\n    u.Costs[j - 1] = upgrades[i][3][j]\n  end\nend\n\n\n--\n--  Modifiers\n--\n\nDefineModifier(\"upgrade-zerg-melee-attacks1\",\n  {\"Level\", 1}, {\"PiercingDamage\", 2},\n  {\"apply-to\", \"unit-zerg-zergling\"}, {\"apply-to\", \"unit-zerg-ultralisk\"},\n  {\"apply-to\", \"unit-zerg-drone\"})\nDefineModifier(\"upgrade-zerg-melee-attacks2\",\n  {\"Level\", 2}, {\"PiercingDamage\", 3},\n  {\"apply-to\", \"unit-zerg-zergling\"}, {\"apply-to\", \"unit-zerg-ultralisk\"},\n  {\"apply-to\", \"unit-zerg-drone\"})\nDefineModifier(\"upgrade-zerg-melee-attacks3\",\n  {\"Level\", 3}, {\"PiercingDamage\", 4},\n  {\"apply-to\", \"unit-zerg-zergling\"}, {\"apply-to\", \"unit-zerg-ultralisk\"},\n  {\"apply-to\", \"unit-zerg-drone\"})\n  \nDefineModifier(\"upgrade-zerg-missle-attacks1\",\n  {\"Level\", 1}, {\"PiercingDamage\", 2},\n  {\"apply-to\", \"unit-zerg-hydralisk\"})\nDefineModifier(\"upgrade-zerg-missle-attacks2\",\n  {\"Level\", 2}, {\"PiercingDamage\", 3},\n  {\"apply-to\", \"unit-zerg-hydralisk\"})\nDefineModifier(\"upgrade-zerg-missle-attacks3\",\n  {\"Level\", 3}, {\"PiercingDamage\", 4},\n  {\"apply-to\", \"unit-zerg-hydralisk\"})\n  \nDefineModifier(\"upgrade-zerg-carapace1\",\n  {\"Level\", 1}, {\"Armor\", 2},\n  {\"apply-to\", \"unit-zerg-zergling\"}, {\"apply-to\", \"unit-zerg-ultralisk\"},\n  {\"apply-to\", \"unit-zerg-drone\"}, {\"apply-to\", \"unit-zerg-hydralisk\"})\nDefineModifier(\"upgrade-zerg-carapace2\",\n  {\"Level\", 2}, {\"Armor\", 3},\n  {\"apply-to\", \"unit-zerg-zergling\"}, {\"apply-to\", \"unit-zerg-ultralisk\"},\n  {\"apply-to\", \"unit-zerg-drone\"}, {\"apply-to\", \"unit-zerg-hydralisk\"})\nDefineModifier(\"upgrade-zerg-carapace3\",\n  {\"Level\", 3}, {\"Armor\", 4},\n  {\"apply-to\", \"unit-zerg-zergling\"}, {\"apply-to\", \"unit-zerg-ultralisk\"},\n  {\"apply-to\", \"unit-zerg-drone\"}, {\"apply-to\", \"unit-zerg-hydralisk\"})\n\nDefineModifier(\"upgrade-zerg-flyer-attacks1\",\n  {\"Level\", 1}, {\"PiercingDamage\", 2},\n  {\"apply-to\", \"unit-zerg-hydralisk\"})\nDefineModifier(\"upgrade-zerg-flyer-attacks2\",\n  {\"Level\", 2}, {\"PiercingDamage\", 3},\n  {\"apply-to\", \"unit-zerg-mutalisk\"})\nDefineModifier(\"upgrade-zerg-flyer-attacks3\",\n  {\"Level\", 3}, {\"PiercingDamage\", 4},\n  {\"apply-to\", \"unit-zerg-mutalisk\"})\n\nDefineModifier(\"upgrade-zerg-flyer-carapace1\",\n  {\"Level\", 1}, {\"Armor\", 2},\n  {\"apply-to\", \"unit-zerg-mutalisk\"})\nDefineModifier(\"upgrade-zerg-flyer-carapace2\",\n  {\"Level\", 2}, {\"Armor\", 3},\n  {\"apply-to\", \"unit-zerg-mutalisk\"})\nDefineModifier(\"upgrade-zerg-flyer-carapace3\",\n  {\"Level\", 3}, {\"Armor\", 4},\n  {\"apply-to\", \"unit-zerg-mutalisk\"})\n\n--\n--  Allow\n--\n\nDefineAllow(\"upgrade-zerg-melee-attacks1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-melee-attacks2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-melee-attacks3\", \"AAAAAAAAAAAAAAAA\")\n\nDefineAllow(\"upgrade-zerg-missle-attacks1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-missle-attacks2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-missle-attacks3\", \"AAAAAAAAAAAAAAAA\")\n\nDefineAllow(\"upgrade-zerg-carapace1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-carapace2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-carapace3\", \"AAAAAAAAAAAAAAAA\")\n\nDefineAllow(\"upgrade-zerg-flyer-carapace1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-flyer-carapace2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-flyer-carapace3\", \"AAAAAAAAAAAAAAAA\")\n\nDefineAllow(\"upgrade-zerg-flyer-attacks1\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-flyer-attacks2\", \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-flyer-attacks3\", \"AAAAAAAAAAAAAAAA\")\n\nDefineAllow(\"upgrade-zerg-burrow\",         \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-ventral-sacs\",   \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-antennae\",       \"AAAAAAAAAAAAAAAA\")\nDefineAllow(\"upgrade-zerg-pneumatized-carapace\", \"AAAAAAAAAAAAAAAA\")\n\n\n--\n--  Dependencies\n--\n\n-- upgrades\nDefineDependency(\"upgrade-zerg-melee-attacks2\",\n  {\"upgrade-zerg-melee-attacks1\"})\nDefineDependency(\"upgrade-zerg-melee-attacks3\",\n  {\"upgrade-zerg-melee-attacks2\"})\n  \nDefineDependency(\"upgrade-zerg-missle-attacks2\",\n  {\"upgrade-zerg-melee-attacks1\"})\nDefineDependency(\"upgrade-zerg-missle-attacks3\",\n  {\"upgrade-zerg-melee-attacks2\"})\n  \nDefineDependency(\"upgrade-zerg-carapace2\",\n  {\"upgrade-zerg-carapace1\"})\nDefineDependency(\"upgrade-zerg-carapace3\",\n  {\"upgrade-zerg-carapace2\"})\n\n\n-- units\nDefineDependency(\"unit-zerg-drone\",\n  {\"unit-zerg-hatchery\"}, \"or\", {\"unit-zerg-lair\"}, \"or\", {\"unit-zerg-hive\"})\nDefineDependency(\"unit-zerg-overlord\",\n  {\"unit-zerg-hatchery\"}, \"or\", {\"unit-zerg-lair\"}, \"or\", {\"unit-zerg-hive\"})\nDefineDependency(\"unit-zerg-zergling\",\n  {\"unit-zerg-spawning-pool\"})\nDefineDependency(\"unit-zerg-hydralisk\",\n  {\"unit-zerg-hydralisk-den\"})\nDefineDependency(\"unit-zerg-mutalisk\",\n  {\"unit-zerg-spire\"})\nDefineDependency(\"unit-zerg-scourge\",\n  {\"unit-zerg-spire\"})\nDefineDependency(\"unit-zerg-queen\",\n  {\"unit-zerg-queens-nest\"})\nDefineDependency(\"unit-zerg-defiler\",\n  {\"unit-zerg-defiler-mound\"})\nDefineDependency(\"unit-zerg-ultralisk\",\n  {\"unit-zerg-ultralisk-cavern\"})\nDefineDependency(\"unit-zerg-guardian\",\n  {\"unit-zerg-greater-spire\"})\n\n-- hatchery buildings\nDefineDependency(\"unit-zerg-evolution-chamber\",\n  {\"unit-zerg-hatchery\"}, \"or\", {\"unit-zerg-lair\"}, \"or\", {\"unit-zerg-hive\"})\nDefineDependency(\"unit-zerg-creep-colony\",\n  {\"unit-zerg-hatchery\"}, \"or\", {\"unit-zerg-lair\"}, \"or\", {\"unit-zerg-hive\"})\nDefineDependency(\"unit-zerg-spawning-pool\",\n  {\"unit-zerg-hatchery\"}, \"or\", {\"unit-zerg-lair\"}, \"or\", {\"unit-zerg-hive\"})\n\nDefineDependency(\"unit-zerg-spore-colony\",\n  {\"unit-zerg-creep-colony\", \"unit-zerg-evolution-chamber\"})\nDefineDependency(\"unit-zerg-sunken-colony\",\n  {\"unit-zerg-creep-colony\", \"unit-zerg-spawning-pool\"})\nDefineDependency(\"unit-zerg-hydralisk-den\",\n  {\"unit-zerg-spawning-pool\"})\n\n-- lair buildings\nDefineDependency(\"unit-zerg-lair\",\n  {\"unit-zerg-hatchery\", \"unit-zerg-spawning-pool\"})\n\nDefineDependency(\"unit-zerg-spire\",\n  {\"unit-zerg-lair\"}, \"or\", {\"unit-zerg-hive\"})\nDefineDependency(\"unit-zerg-queens-nest\",\n  {\"unit-zerg-lair\"}, \"or\", {\"unit-zerg-hive\"})\n\n-- hive buildings\nDefineDependency(\"unit-zerg-hive\",\n  {\"unit-zerg-lair\", \"unit-zerg-queens-nest\"})\n\nDefineDependency(\"unit-zerg-greater-spire\",\n  {\"unit-zerg-hive\", \"unit-zerg-spire\"})\nDefineDependency(\"unit-zerg-nydus-canal\",\n  {\"unit-zerg-hive\"})\nDefineDependency(\"unit-zerg-defiler-mound\",\n  {\"unit-zerg-hive\"})\nDefineDependency(\"unit-zerg-ultralisk-cavern\",\n  {\"unit-zerg-hive\"})\n\n"
  },
  {
    "path": "src/AbstractPalette.cpp",
    "content": "/*\n * AbstractPalette.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"AbstractPalette.h\"\n#include \"Palette.h\"\n#include \"Palette2D.h\"\n#include \"NoValidPaletteException.h\"\n\nusing namespace std;\n\nAbstractPalette::~AbstractPalette()\n{\n\n}\n\nbool AbstractPalette::write(const std::string &filename)\n{\n  bool result = true;\n\n  std::shared_ptr<DataChunk> dc_pal = createDataChunk();\n  result = dc_pal->write(filename);\n\n  return result;\n}\n\nbool AbstractPalette::read(const std::string &filename)\n{\n  bool result = true;\n\n  std::shared_ptr<DataChunk> dc_pal = make_shared<DataChunk>();\n  result = dc_pal->read(filename);\n  if(result)\n  {\n    load(dc_pal);\n  }\n\n  return result;\n}\n\nstd::shared_ptr<AbstractPalette> AbstractPalette::create(std::shared_ptr<DataChunk> rawPalette)\n{\n  if((rawPalette->getSize() == 256 * 3) || (rawPalette->getSize() == 256 * 3)) // RGBx/WPE size type\n  {\n    return make_shared<Palette>(rawPalette);\n  }\n  else if(!(rawPalette->getSize() % (256 * 3))) // PCX2D size type (size 3 and 4 are yet in the if statement)\n  {\n    return make_shared<Palette2D>(rawPalette);\n  }\n\n  // no valid palette\n  throw NoValidPaletteException(rawPalette->getSize());\n\n  // will never go here...\n  return nullptr;\n}\n"
  },
  {
    "path": "src/AbstractPalette.h",
    "content": "/*\n * AbstractPalette.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef ABSTRACTPALETTE_H\n#define ABSTRACTPALETTE_H\n\n// project\n#include \"DataChunk.h\"\n\n// system\n#include <memory>\n\nclass AbstractPalette\n{\npublic:\n  virtual ~AbstractPalette();\n\n  virtual std::shared_ptr<DataChunk> createDataChunk() = 0;\n\n  virtual void load(std::shared_ptr<DataChunk> rawPalette) = 0;\n\n  virtual bool write(const std::string &filename);\n\n  virtual bool read(const std::string &filename);\n\n  /**\n   * Creator function for the abstract factory design\n   */\n  static std::shared_ptr<AbstractPalette> create(std::shared_ptr<DataChunk> rawPalette);\n\nprotected:\n\n};\n\n#endif /* ABSTRACTPALETTE_H */\n"
  },
  {
    "path": "src/Breeze.cpp",
    "content": "/*\n * Breeze.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"Breeze.h\"\n#include \"FileUtil.h\"\n#include \"Logger.h\"\n#include \"StringUtil.h\"\n\n// System\n#include <stdio.h>\n#include <string.h>\n#include <fstream>\n#include <zlib.h>\n#include <optional>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Breeze\");\n\nBreeze::Breeze()\n{\n\n}\n\nBreeze::~Breeze()\n{\n  closeArchive();\n}\n\nBreeze::Breeze(const std::string &archiveName)\n{\n  openArchive(archiveName);\n}\n\nbool Breeze::openArchive(const std::string &archiveName)\n{\n  mArchiveName = archiveName;\n  return true;\n}\n\nvoid Breeze::closeArchive()\n{\n  mArchiveName.clear();\n}\n\nbool Breeze::extractFile(const std::string &archivedFile, const std::string &extractedName, bool compress)\n{\n  unsigned char *szEntryBuffer = nullptr;\n  size_t bufferLen = 0;\n  bool result = false;\n  FILE *file = nullptr;            // Disk file handle\n  gzFile gzfile = nullptr;         // Compressed file handle\n\n  if (extractMemory(archivedFile, &szEntryBuffer, &bufferLen))\n  {\n    CheckPath(extractedName);\n\n    if (compress)\n    {\n      gzfile = gzopen(extractedName.c_str(), \"wb9\");\n      if (gzfile)\n      {\n        int bytes_written = gzwrite(gzfile, szEntryBuffer, bufferLen);\n        gzclose(gzfile);\n        if (bytes_written != (int) bufferLen)\n        {\n          LOG4CXX_FATAL(logger, \"Wrong buffer len:\" + to_string(bytes_written) + \"!=\" + to_string(bufferLen));\n        }\n\n      }\n    }\n    else\n    {\n      file = fopen(extractedName.c_str(), \"wb\");\n      if (file)\n      {\n        size_t dwBytes = fwrite(szEntryBuffer, sizeof(char), bufferLen, file);\n        fclose(file);\n        if (dwBytes != bufferLen)\n        {\n          LOG4CXX_FATAL(logger, \"Wrong buffer len:\" + to_string(dwBytes) + \"!=\" + to_string(bufferLen));\n        }\n      }\n    }\n\n    free(szEntryBuffer);\n    result = true;\n  }\n\n  return result;\n}\n\nbool Breeze::extractMemory(const std::string &archivedFile, unsigned char **szEntryBufferPrt, size_t *bufferLen)\n{\n  FILE *f;\n  bool result = true;\n  unsigned char *szEntryBuffer = nullptr;\n\n  string archivedFilePath = mArchiveName + \"/\" + archivedFile;\n  replaceString(\"\\\\\", \"/\", archivedFilePath);\n\n  f = fopen(archivedFilePath.c_str(), \"r\");\n  if (f)\n  {\n    unsigned char szBuffer[0x10000];\n    size_t len = 0;\n    int i = 0;\n    size_t dwBytes = 1;\n\n    while (dwBytes > 0)\n    {\n      dwBytes = fread(szBuffer, sizeof(char), sizeof(szBuffer), f);\n      if (dwBytes > 0)\n      {\n        len = len + dwBytes;\n        szEntryBuffer = (unsigned char *) realloc(szEntryBuffer, len);\n        memcpy(szEntryBuffer + (i * sizeof(szBuffer)), szBuffer, dwBytes);\n      }\n    }\n    i++;\n    *bufferLen = len;\n  }\n  else\n  {\n    result = false;\n  }\n\n  *szEntryBufferPrt = szEntryBuffer;\n\n  return result;\n}\n\nstd::shared_ptr<std::istream> Breeze::extractStream(const std::string &archivedFile)\n{\n  string archivedFilePath = mArchiveName + \"/\" + archivedFile;\n  replaceString(\"\\\\\", \"/\", archivedFilePath);\n\n  auto stream = std::make_shared<std::ifstream>(archivedFilePath);\n\n  return std::shared_ptr<std::ifstream>(*stream ? std::move(stream) : nullptr);\n}\n\n"
  },
  {
    "path": "src/Breeze.h",
    "content": "/*\n * Breeze.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef BREEZE_H_\n#define BREEZE_H_\n\n#include \"Hurricane.h\"\n\n/**\n * This has the same interface as Hurricane but is\n * a dummy file provider to provide extracted files to the converters.\n */\nclass Breeze: public Hurricane\n{\npublic:\n  Breeze();\n  /**\n   * @param archiveName The folder where the extracted files are available (relative from that folder)\n   */\n  Breeze(const std::string &archiveName);\n  virtual ~Breeze();\n\n  bool openArchive(const std::string &archiveName);\n\n  void closeArchive();\n\n  /* In fact copy files and create all directories if not existing. Not really useful, just to provide data for converters.\n   *\n   * @param archivedFile is the source\n   * @param extractedName is the target\n   */\n  virtual bool extractFile(const std::string &archivedFile, const std::string &extractedName, bool compress);\n\n  /**\n   * Attention: This function malloc() bufferLen memory which you've to free yourself!\n   * Better use extractDataChunk()\n   */\n  virtual bool extractMemory(const std::string &archivedFile, unsigned char **szEntryBufferPrt, size_t *bufferLen);\n\n  virtual std::shared_ptr<std::istream> extractStream(const std::string &archivedFile);\n\nprivate:\n\n};\n\n#endif /* BREEZE_H_ */\n"
  },
  {
    "path": "src/Casc.cpp",
    "content": "/*\n * Casc.cpp\n *\n *      Author: Andreas Volz\n */\n#ifdef HAVE_CASC\n\n// Local\n#include \"Casc.h\"\n#include \"FileUtil.h\"\n\n// System\n#include \"CascLib.h\"\n#include <cstdio>\n#include <iostream>\n\nusing namespace std;\n\nCasc::Casc() :\n  mStorage(nullptr)\n{\n}\n\nCasc::Casc(const std::string &archiveName) :\n  mStorage(nullptr)\n{\n  openArchive(archiveName);\n}\n\nCasc::~Casc()\n{\n  closeArchive();\n}\n\nbool Casc::openArchive(const std::string &archiveName)\n{\n  bool result = true;\n\n  // close it in case it's still open\n  closeArchive();\n\n  if (!CascOpenStorage(archiveName.c_str(), 0, &mStorage))\n  {\n    result = false;\n  }\n  else\n  {\n    mArchiveName = archiveName;\n  }\n  return result;\n}\n\nvoid Casc::closeArchive()\n{\n  if (mStorage != nullptr)\n  {\n    CascCloseStorage(mStorage);\n    mArchiveName.clear();\n  }\n}\n\n// Not in class member to be not expose Casc to public header\nPCASC_FILE_SPAN_INFO GetFileSpanInfo(HANDLE hFile)\n{\n  PCASC_FILE_SPAN_INFO pSpans = NULL;\n  size_t cbLength = 0;\n\n  // Retrieve the full file info\n  CascGetFileInfo(hFile, CascFileSpanInfo, pSpans, cbLength, &cbLength);\n  if (cbLength != 0)\n  {\n    if ((pSpans = (PCASC_FILE_SPAN_INFO)(new BYTE[cbLength])) != NULL)\n    {\n      if (CascGetFileInfo(hFile, CascFileSpanInfo, pSpans, cbLength, NULL))\n        return pSpans;\n\n      // in case of error...\n      //free(pSpans); // TODO: this results in warning - not sure why\n      pSpans = NULL;\n    }\n  }\n\n  return pSpans;\n}\n\nbool Casc::extractMemory(const std::string &archivedFile,\n                         unsigned char **szEntryBufferPrt, size_t *bufferLen)\n{\n  HANDLE hFile = nullptr;\n  bool result = true;\n  unsigned char *szEntryBuffer = nullptr;\n\n  // Open a file in the storage\n  if (CascOpenFile(mStorage, archivedFile.c_str(), 0, 0, &hFile))\n  {\n    // Read the data from the file\n    char szBuffer[0x10000];\n    DWORD dwBytes = 1;\n\n    // quick check if file has valid info\n    // TODO: later more details to read out!\n    PCASC_FILE_SPAN_INFO cascFileInfo = GetFileSpanInfo(hFile);\n\n    if (cascFileInfo)\n    {\n      int i = 0;\n      size_t len = 0;\n\n      szEntryBuffer = (unsigned char *) malloc(sizeof(szBuffer)); // TODO: this might me useless and then free() could be avoid below\n      while (dwBytes > 0)\n      {\n        CascReadFile(hFile, szBuffer, sizeof(szBuffer), &dwBytes);\n        if (dwBytes > 0)\n        {\n          len = len + dwBytes;\n          szEntryBuffer = (unsigned char *) realloc(szEntryBuffer, len);\n          memcpy(szEntryBuffer + (i * sizeof(szBuffer)), szBuffer, dwBytes);\n\n        }\n        i++;\n      }\n\n      if (bufferLen != NULL)\n      {\n        *bufferLen = len;\n      }\n\n      if (hFile != nullptr)\n      {\n        CascCloseFile(hFile);\n      }\n    }\n    else\n    {\n      cout << \"*NOT* Extracting file (invalid info!): \" << archivedFile << endl;\n    }\n  }\n  else\n  {\n    cout << \"Error: CascOpenFile\" << endl;\n    result = false;\n    // in case of problem free what ever has been allocated\n    free(szEntryBuffer);\n    szEntryBuffer = nullptr;\n  }\n\n  *szEntryBufferPrt = szEntryBuffer;\n\n  return result;\n}\n\n// TODO 'compress' doesn't work!!\nbool Casc::extractFile(const std::string &archivedFile,\n                       const std::string &extractedName, bool compress)\n{\n  HANDLE hFile = NULL;\n  FILE *fileHandle = NULL;\n  bool result = true;\n\n  // Open a file in the storage\n  if (CascOpenFile(mStorage, archivedFile.c_str(), 0, 0, &hFile))\n  {\n    // Read the data from the file\n    char szBuffer[0x10000];\n    DWORD dwBytes = 1;\n\n    // quick check if file has valid info\n    // TODO: later more details to read out!\n    PCASC_FILE_SPAN_INFO cascFileInfo = GetFileSpanInfo(hFile);\n\n    if (cascFileInfo)\n    {\n      CheckPath(extractedName.c_str());\n      fileHandle = fopen(extractedName.c_str(), \"wb\");\n\n      while (dwBytes != 0)\n      {\n        CascReadFile(hFile, szBuffer, sizeof(szBuffer), &dwBytes);\n        if (dwBytes == 0)\n          break;\n\n        fwrite(szBuffer, 1, dwBytes, fileHandle);\n      }\n\n      if (fileHandle != NULL)\n      {\n        fclose(fileHandle);\n      }\n\n      if (hFile != NULL)\n      {\n        CascCloseFile(hFile);\n      }\n    }\n    else\n    {\n      cout << \"*NOT* Extracting file (invalid info!): \" << extractedName\n           << endl;\n    }\n  }\n  else\n  {\n    cout << \"Error: CascOpenFile\" << endl;\n    result = false;\n  }\n\n  return result;\n}\n\n#endif /* HAVE_CASC */\n"
  },
  {
    "path": "src/Casc.h",
    "content": "/*\n * Casc.h\n *\n *      Author: Andreas Volz\n */\n#ifdef HAVE_CASC\n\n#include \"Hurricane.h\"\n\n#ifndef CASC_H_\n#define CASC_H_\n\nclass Casc: public Hurricane\n{\npublic:\n  Casc();\n  Casc(const std::string &archiveName);\n  virtual ~Casc();\n\n  bool openArchive(const std::string &archiveName);\n  void closeArchive();\n\n  /**\n   * Extract file from CASC archive and create all directories if not existing\n   *\n   * @param TODO compress gzip compression -> NOT IMPLEMENTED\n   */\n  bool extractFile(const std::string &archivedFile, const std::string &extractedName, bool compress);\n\n  /**\n   * Attention: This function malloc() bufferLen memory which you've to free yourself!\n   * Better use extractDataChunk()\n   */\n  bool extractMemory(const std::string &archivedFile, unsigned char **szEntryBufferPrt, size_t *bufferLen);\n\nprivate:\n  void *mStorage;\n};\n\n\n#endif /* CASC_H_ */\n\n#endif /* HAVE_CASC */\n"
  },
  {
    "path": "src/Chk.cpp",
    "content": "/*\n * Chk.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include <luagen.h>\n#include \"Chk.h\"\n#include \"WorldMap.h\"\n#include \"endian.h\"\n#include \"Hurricane.h\"\n#include \"FileUtil.h\"\n#include \"Logger.h\"\n\n// system\n#include <cstring>\n#include <cstdint>\n#include <stdlib.h>\n#include <algorithm>\n#include <iostream>\n\n\n#ifdef DEBUG\n#define DebugLevel1(x) printf(x)\n#define DebugLevel2(x) printf(x)\n#define _C_ ,\n#else\n#define DebugLevel1(x)\n#define DebugLevel2(x)\n#define _C_\n#endif\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Chk\");\n\nstatic const char *TypeNames[] =\n{\n  \"nobody\", NULL, NULL, \"rescue-passive\", NULL, \"computer\", \"person\",\n  \"neutral\"\n};\nstatic const char *RaceNames[] =\n{ \"zerg\", \"terran\", \"protoss\", NULL, \"neutral\" };\n\nconstexpr int MinitileSubdivision = 4;\n\nChk::Chk(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane),\n  map(new WorldMap())\n{\n\n}\n\nChk::~Chk()\n{\n  FreeMap();\n}\n\nstatic char *chk_ptr;\t\t\t/// FIXME: docu\nstatic char *chk_endptr;\t\t\t/// FIXME: docu\n\nstatic int ChkReadHeader(char *header, int32_t *length)\n{\n  int32_t len;\n\n  if (chk_ptr >= chk_endptr)\n  {\n    return 0;\n  }\n  memcpy(header, chk_ptr, 4);\n  chk_ptr += 4;\n  memcpy(&len, chk_ptr, 4);\n  chk_ptr += 4;\n  *length = ConvertLE32(len);\n  return 1;\n}\n\n/**\n **  Read dword\n */\nstatic int ChkReadDWord(void)\n{\n  unsigned int temp_int;\n\n  memcpy(&temp_int, chk_ptr, 4);\n  chk_ptr += 4;\n  return ConvertLE32(temp_int);\n}\n\n/**\n **  Read word\n */\nstatic int ChkReadWord(void)\n{\n  unsigned short temp_short;\n\n  memcpy(&temp_short, chk_ptr, 2);\n  chk_ptr += 2;\n  return ConvertLE16(temp_short);\n}\n\n/**\n **  Read a byte from #chk_ptr.\n **\n **  @return  Next byte from #chk_ptr.\n */\nstatic inline int ChkReadByte(void)\n{\n  int c = *((unsigned char *) chk_ptr);\n  ++chk_ptr;\n  return c;\n}\n\nvoid Chk::setUnitNames(const std::vector<std::string> &unitNames)\n{\n  mUnitNames = unitNames;\n}\n\nvoid Chk::loadFromBuffer(unsigned char *chkdata, int len)\n{\n  char header[5];\n  int32_t length;\n\n  chk_ptr = (char *) chkdata;\n  chk_endptr = chk_ptr + len;\n  header[4] = '\\0';\n\n  while (ChkReadHeader(header, &length))\n  {\n\n    //\n    //\tSCM version\n    //\n    if (!memcmp(header, \"VER \", 4))\n    {\n      if (length == 2)\n      {\n        ChkReadWord();\n        continue;\n      }\n      DebugLevel1(\"Wrong VER  length\\n\");\n    }\n\n    //\n    //\tSCM version additional information\n    //\n    if (!memcmp(header, \"IVER\", 4))\n    {\n      if (length == 2)\n      {\n        ChkReadWord();\n        continue;\n      }\n      DebugLevel1(\"Wrong IVER length\\n\");\n    }\n\n    //\n    //\tSCM version additional information\n    //\n    if (!memcmp(header, \"IVE2\", 4))\n    {\n      if (length == 2)\n      {\n        ChkReadWord();\n        continue;\n      }\n      DebugLevel1(\"Wrong IVE2 length\\n\");\n    }\n\n    //\n    //\tVerification code\n    //\n    if (!memcmp(header, \"VCOD\", 4))\n    {\n      if (length == 1040)\n      {\n        chk_ptr += 1040;\n        continue;\n      }\n      DebugLevel1(\"Wrong VCOD length\\n\");\n    }\n\n    //\n    //\tSpecifies the owner of the player\n    //\n    if (!memcmp(header, \"IOWN\", 4))\n    {\n      if (length == 12)\n      {\n        chk_ptr += 12;\n        continue;\n      }\n      DebugLevel1(\"Wrong IOWN length\\n\");\n    }\n\n    //\n    //\tSpecifies the owner of the player, same as IOWN but with 0 added\n    //\n    if (!memcmp(header, \"OWNR\", 4))\n    {\n      if (length == 12)\n      {\n        for (int i = 0; i < 12; ++i)\n        {\n          int p = ChkReadByte();\n          map->PlayerType[i] = p;\n          if (p != 0 && p != 3 && p != 5 && p != 6 && p != 7)\n          {\n            DebugLevel1(\"Wrong OWNR type: %d\\n\" _C_ p);\n            map->PlayerType[i] = 0;\n          }\n        }\n        continue;\n      }\n      DebugLevel1(\"Wrong OWNR length\\n\");\n    }\n\n    //\n    //\tTerrain type\n    //\n    if (!memcmp(header, \"ERA \", 4))\n    {\n      if (length == 2)\n      {\n        int t;\n        const char *tilesets[] =\n        {\n          \"badlands\", \"platform\", \"install\", \"ashworld\", \"jungle\", \"desert\",\n          \"arctic\", \"twilight\"\n        };\n\n        t = ChkReadWord();\n        map->MapTerrainName = strdup(tilesets[t]);\n        continue;\n      }\n      DebugLevel1(\"Wrong ERA  length\\n\");\n    }\n\n    //\n    //\tDimensions\n    //\n    if (!memcmp(header, \"DIM \", 4))\n    {\n      if (length == 4)\n      {\n        map->MapWidth = ChkReadWord();\n        map->MapHeight = ChkReadWord();\n        continue;\n      }\n      DebugLevel1(\"Wrong DIM  length\\n\");\n    }\n\n    //\n    //\tIdentifies race of each player\n    //\n    if (!memcmp(header, \"SIDE\", 4))\n    {\n      if (length == 12)\n      {\n        int i;\n        int v;\n\n        for (i = 0; i < 12; ++i)\n        {\n          v = ChkReadByte();\n          if (v == 5)\n          {\n            // user selected race\n            v = 1;\n          }\n          if (v > 2 && v != 4 && v != 7)\n          {\n            DebugLevel1(\"Unknown race %d\\n\" _C_ v);\n            v = 0;\n          }\n          map->PlayerRace[i] = v;\n        }\n        continue;\n      }\n      DebugLevel1(\"Wrong SIDE length\\n\");\n    }\n\n    //\n    //\tGraphical tile map\n    //\n    if (!memcmp(header, \"MTXM\", 4))\n    {\n      if (length == map->MapWidth * map->MapHeight * 2)\n      {\n        map->Tiles = (int *) malloc(\n                       map->MapWidth * map->MapHeight * sizeof(int));\n        for (int h = 0; h < map->MapHeight; ++h)\n        {\n          for (int w = 0; w < map->MapWidth; ++w)\n          {\n            int v = ConvertLE16(\n                      ((unsigned short *)chk_ptr)[h * map->MapWidth + w]);\n            /*if (v > 10000) {\n             v = v;\n             }*/\n            map->Tiles[h * map->MapWidth + w] = v;\n          }\n        }\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong MTXM length\\n\");\n    }\n\n    //\n    //\tPlayer unit restrictions\n    //\n    if (!memcmp(header, \"PUNI\", 4))\n    {\n      if (length == 228 * 12 + 228 + 228 * 12)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong PUNI length\\n\");\n    }\n\n    //\n    //\tPlayer upgrade restrictions\n    //\n    if (!memcmp(header, \"UPGR\", 4))\n    {\n      if (length == 46 * 12 + 46 * 12 + 46 + 46 + 46 * 12)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong UPGR length\\n\");\n    }\n\n    //\n    //\tExtended upgrades\n    //\n    if (!memcmp(header, \"PUPx\", 4))\n    {\n      if (length == 61 * 12 + 61 * 12 + 61 + 61 + 61 * 12)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong PUPx length\\n\");\n    }\n\n    //\n    //\tPlayer technology restrictions\n    //\n    if (!memcmp(header, \"PTEC\", 4))\n    {\n      if (length == 24 * 12 + 24 * 12 + 24 + 24 + 24 * 12)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong PTEC length\\n\");\n    }\n\n    //\n    //\tExtended player technology restrictions\n    //\n    if (!memcmp(header, \"PTEx\", 4))\n    {\n      if (length == 44 * 12 + 44 * 12 + 44 + 44 + 44 * 12)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong PTEx length\\n\");\n    }\n\n    //\n    //\tUnits\n    //\n    if (!memcmp(header, \"UNIT\", 4))\n    {\n      if (length % 36 == 0)\n      {\n        while (length > 0)\n        {\n          Unit unit;\n\n          chk_ptr += 4;\t// unknown\n          unit.X = ChkReadWord();\t// x coordinate\n          unit.Y = ChkReadWord();\t// y coordinate\n          unit.Type = ChkReadWord();\t// unit type\n          chk_ptr += 2;\t// unknown\n          unit.Properties = ChkReadWord();\t// special properties flag\n          unit.ValidElements = ChkReadWord();\t// valid elements\n          unit.Player = ChkReadByte();\t// owner\n          unit.HitPointsPercent = ChkReadByte();\t// hit point %\n          unit.ShieldPointsPercent = ChkReadByte();\t// shield point %\n          unit.EnergyPointsPercent = ChkReadByte();\t// energy point %\n          unit.ResourceAmount = ChkReadDWord(); // resource amount\n          unit.NumUnitsIn = ChkReadWord();\t// num units in hanger\n          unit.StateFlags = ChkReadWord();\t// state flags\n          chk_ptr += 8;\t// unknown\n\n          length -= 36;\n\n          if (unit.Player == 11)\n          {\n            // neutral player\n            unit.Player = PlayerMax - 1;\n          }\n\n          unit.X /= 32;\n          unit.Y /= 32;\n\n//\t\t\t\t    type = UnitTypeByWcNum(t);\n//\t\t\t\t    x = (x - 32 * type->TileWidth / 2) / 32;\n//\t\t\t\t    y = (y - 32 * type->TileHeight / 2) / 32;\n\n          if (unit.Type == SC_StartLocation)\n          {\n            map->PlayerStart[unit.Player].X = unit.X;\n            map->PlayerStart[unit.Player].Y = unit.Y;\n          }\n          else\n          {\n            map->Units.push_back(unit);\n          }\n        }\n\n        continue;\n      }\n      DebugLevel1(\"Wrong UNIT length\\n\");\n    }\n\n    //\n    //\tExtended units\n    //\n    if (!memcmp(header, \"UNIx\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong UNIx length\\n\");\n    }\n\n    //\n    //\tIsometric tile mapping\n    //\n    if (!memcmp(header, \"ISOM\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong ISOM length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"TILE\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong TILE length\\n\");\n    }\n\n    //\n    //\tDoodad map used by the editor\n    //\n    if (!memcmp(header, \"DD2 \", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong DD2  length\\n\");\n    }\n\n    //\n    //\tThingys\n    //\n    if (!memcmp(header, \"THG2\", 4))\n    {\n      if (length % 10 == 0)\n      {\n        while (length > 0)\n        {\n          int n;\n\n          n = ChkReadWord();    // unit number of the thingy\n          ChkReadWord();    // x coordinate\n          ChkReadWord();    // y coordinate\n          ChkReadByte();   // player number of owner\n          ChkReadByte();\t// unknown\n          ChkReadWord();   // flags\n          length -= 10;\n\n          string thingyName = mUnitNames[n];\n\n          //cout << \"Thingy: \"  << thingyName << endl;\n\n//\t\t\t\t    unit = (char **)hash_find(TheMap.Tileset->ItemsHash, buf);\n#ifdef DEBUG\n//\t\t\t\t    if (!unit) {\n//\t\t\t\t\t\tfprintf(stderr,\"THG2 n=%d (%d,%d)\\n\",n,x,y);\n//\t\t\t\t\t\tcontinue;\n//\t\t\t\t    }\n#endif\n\n          // FIXME: remove\n//\t\t\t\t    type = UnitTypeByIdent(*unit);\n//\t\t\t\t    x = (x - 32 * type->TileWidth / 2) / 32;\n//\t\t\t\t    y = (y - 32 * type->TileHeight / 2) / 32;\n\n//\t\t\t\t    MakeUnitAndPlace(MapOffsetX + x, MapOffsetY + y, type, &Players[15]);\n        }\n        continue;\n      }\n      DebugLevel1(\"Wrong THG2 length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"MASK\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong MASK length\\n\");\n    }\n\n    //\n    //\tStrings\n    //\n    if (!memcmp(header, \"STR \", 4))\n    {\n      int i;\n      unsigned short num;\n      unsigned short s;\n      char *cptr = chk_ptr;\n\n      num = ChkReadWord();\n      for (i = 0; i < num; ++i)\n      {\n        s = ChkReadWord();\n\n        string str(cptr + s);\n\n        // replace incompatible line endings of multiline strings\n        // TODO: this might look ugle, but doesn't crash the LUA function at least\n        // TODO: need to find a good way when the GUI supports that... maybe remove all multible spaces...\n        str.erase(remove(str.begin(), str.end(), '\\r'), str.end());\n        str.erase(remove(str.begin(), str.end(), '\\n'), str.end());\n\n        map->Strings.push_back(str);\n      }\n      map->Description = strdup(\"none\");\n      chk_ptr += length - 2050;\n      continue;\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"UPRP\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong UPRP length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"UPUS\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong UPUS length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"MRGN\", 4))\n    {\n      if ((length / 20) * 20 == length)\n      {\n        while (length > 0)\n        {\n          Location location;\n          location.StartX = ChkReadDWord();\n          location.StartY = ChkReadDWord();\n          location.EndX = ChkReadDWord();\n          location.EndY = ChkReadDWord();\n          location.StringNumber = ChkReadWord();\n          location.Flags = ChkReadWord();\n          map->Locations.push_back(location);\n          length -= 20;\n        }\n        continue;\n      }\n      DebugLevel1(\"Wrong MRGN length\\n\");\n    }\n\n    //\n    //\tTriggers\n    //\n    if (!memcmp(header, \"TRIG\", 4))\n    {\n      if ((length / 2400) * 2400 == length)\n      {\n        int i;\n\n        while (length > 0)\n        {\n          Trigger trigger;\n          for (i = 0; i < 16; ++i)\n          {\n            trigger.TriggerConditions[i].Location = ChkReadDWord();\n            trigger.TriggerConditions[i].Group = ChkReadDWord();\n            trigger.TriggerConditions[i].QualifiedNumber = ChkReadDWord();\n            trigger.TriggerConditions[i].UnitType = ChkReadWord();\n            trigger.TriggerConditions[i].CompType = ChkReadByte();\n            trigger.TriggerConditions[i].Condition = ChkReadByte();\n            trigger.TriggerConditions[i].ResType = ChkReadByte();\n            trigger.TriggerConditions[i].Flags = ChkReadByte();\n            chk_ptr += 2;\n          }\n          for (i = 0; i < 64; ++i)\n          {\n            trigger.TriggerActions[i].Source = ChkReadDWord() - 1;\n            trigger.TriggerActions[i].TriggerNumber = ChkReadDWord();\n            trigger.TriggerActions[i].WavNumber = ChkReadDWord();\n            trigger.TriggerActions[i].Time = ChkReadDWord();\n            trigger.TriggerActions[i].FirstGroup = ChkReadDWord();\n            trigger.TriggerActions[i].SecondGroup = ChkReadDWord();\n            trigger.TriggerActions[i].Status = ChkReadWord();\n            trigger.TriggerActions[i].Action = ChkReadByte();\n            trigger.TriggerActions[i].NumUnits = ChkReadByte();\n            trigger.TriggerActions[i].ActionFlags = ChkReadByte();\n            chk_ptr += 3;\n          }\n          chk_ptr += 32;\n          map->Triggers.push_back(trigger);\n          length -= 2400;\n        }\n        continue;\n      }\n      DebugLevel1(\"Wrong TRIG length\\n\");\n    }\n\n    //\n    //\tMission briefing\n    //\n    if (!memcmp(header, \"MBRF\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong MBRF length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"SPRP\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong SPRP length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"FORC\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong FORC length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"WAV \", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong WAV  length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"UNIS\", 4))\n    {\n//\t\t    if (length==) {\n      if (1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong UNIS length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"UPGS\", 4))\n    {\n      if (length\n          == 46 * 1 + 46 * 2 + 46 * 2 + 46 * 2 + 46 * 2 + 46 * 2 + 46 * 2)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong UPGS length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"UPGx\", 4))\n    {\n      if (length\n          == 61 * 1 + 61 * 2 + 61 * 2 + 61 * 2 + 61 * 2 + 61 * 2 + 61 * 2 + 1)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong UPGx length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"TECS\", 4))\n    {\n      if (length == 24 * 1 + 24 * 2 + 24 * 2 + 24 * 2 + 24 * 2)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong TECS length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"TECx\", 4))\n    {\n      if (length == 44 * 1 + 44 * 2 + 44 * 2 + 44 * 2 + 44 * 2)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong TECx length\\n\");\n    }\n\n    //\n    //\n    //\n    if (!memcmp(header, \"SWNM\", 4))\n    {\n      if (length == 256 * 4)\n      {\n        chk_ptr += length;\n        continue;\n      }\n      DebugLevel1(\"Wrong SWNM length\\n\");\n    }\n\n    DebugLevel2(\"Unsupported Section: %4.4s\\n\" _C_ header);\n    chk_ptr += length;\n  }\n}\n\n/*----------------------------------------------------------------------------\n --  Variables\n ----------------------------------------------------------------------------*/\n\n#define VERSION \"1.0\"\n\n/*----------------------------------------------------------------------------\n --  Functions\n ----------------------------------------------------------------------------*/\n\nvoid Chk::SaveSMP(Storage storage)\n{\n  FILE *fd;\n\n  storage.setFilename(storage.getFilename() + \"smp\");\n\n  CheckPath(storage.getFullPath());\n\n  fd = fopen(storage.getFullPath().c_str(), \"wb\");\n\n  fprintf(fd, \"-- Stratagus Map Presentation\\n\");\n  fprintf(fd, \"-- File generated automatically from scmconvert V\" VERSION \"\\n\");\n  fprintf(fd, \"\\n\");\n\n  fprintf(fd, \"DefinePlayerTypes(\");\n  bool first = true;\n  for (int i = 0; i < PlayerMax; ++i)\n  {\n    if (TypeNames[map->PlayerType[i]])\n    {\n      if (first)\n      {\n        first = false;\n      }\n      else\n      {\n        fprintf(fd, \",\");\n      }\n      fprintf(fd, \"\\\"%s\\\"\", TypeNames[map->PlayerType[i]]);\n    }\n  }\n  fprintf(fd, \")\\n\");\n  fprintf(fd, \"PresentMap(\\\"%s\\\", %d, %d, %d, %d)\\n\", map->Description, 2,\n          map->MapWidth * MinitileSubdivision, map->MapHeight * MinitileSubdivision, 0);\n\n  fclose(fd);\n}\n\nvoid Chk::SaveTrigger(FILE *fd, Trigger *trigger)\n{\n  int i;\n  TriggerCondition *c;\n  TriggerAction *a;\n\n  // Conditions\n  for (i = 0; i < 16; ++i)\n  {\n    c = &trigger->TriggerConditions[i];\n    if (c->Condition == 0)\n    {\n      break;\n    }\n    switch (c->Condition)\n    {\n    case 1:\n      fprintf(fd, \"-- CountdownTimer(%d)\\n\", c->QualifiedNumber);\n      break;\n    case 2:\n      fprintf(fd, \"-- Command(%d, %d, %d)\\n\", c->Group, c->UnitType,\n              c->QualifiedNumber);\n      break;\n    case 3:\n      fprintf(fd, \"-- Bring(%d, %d, [%hu,%hu]-[%hu,%hu], %d)\\n\", c->Group,\n              c->UnitType, map->Locations[c->Location].StartX * MinitileSubdivision,\n              map->Locations[c->Location].StartY * MinitileSubdivision,\n              map->Locations[c->Location].EndX * MinitileSubdivision, map->Locations[c->Location].EndY * MinitileSubdivision,\n              c->QualifiedNumber);\n      break;\n    case 4:\n      fprintf(fd, \"-- Accumulate(%d, %d, %d)\\n\", c->Group, c->QualifiedNumber,\n              c->ResType);\n      break;\n    case 5:\n      fprintf(fd, \"-- Kill(%d, %d, %d)\\n\", c->Group, c->UnitType,\n              c->QualifiedNumber);\n      break;\n    case 6:\n      fprintf(fd, \"-- CommandMost(%d)\\n\", c->UnitType);\n      break;\n    case 7:\n      fprintf(fd, \"-- CommandMostAt(%d, [%hu,%hu]-[%hu,%hu])\\n\", c->UnitType,\n              map->Locations[c->Location].StartX * MinitileSubdivision,\n              map->Locations[c->Location].StartY * MinitileSubdivision,\n              map->Locations[c->Location].EndX * MinitileSubdivision, map->Locations[c->Location].EndY * MinitileSubdivision);\n      break;\n    case 8:\n      fprintf(fd, \"-- MostKills(%d)\\n\", c->UnitType);\n      break;\n    case 9:\n      fprintf(fd, \"-- HighestScore(%d)\\n\", c->ResType);\n      break;\n    case 10:\n      fprintf(fd, \"-- MostResources(%d)\\n\", c->ResType);\n      break;\n    case 11:\n      fprintf(fd, \"-- Switch(%d)\\n\", c->ResType);\n      break;\n    case 12:\n      fprintf(fd, \"-- ElapsedTime(%d)\\n\", c->QualifiedNumber);\n      break;\n    case 13:\n      fprintf(fd, \"-- MissionBriefing()\\n\");\n      break;\n    case 14:\n      fprintf(fd, \"-- Opponents(%d, %d)\\n\", c->Group, c->QualifiedNumber);\n      break;\n    case 15:\n      fprintf(fd, \"-- Deaths(%d, %d, %d)\\n\", c->Group, c->UnitType,\n              c->QualifiedNumber);\n      break;\n    case 16:\n      fprintf(fd, \"-- CommandLeast(%d)\\n\", c->UnitType);\n      break;\n    case 17:\n      fprintf(fd, \"-- CommandLeastAt(%d, [%hu,%hu]-[%hu,%hu])\\n\", c->UnitType,\n              map->Locations[c->Location].StartX * MinitileSubdivision,\n              map->Locations[c->Location].StartY * MinitileSubdivision,\n              map->Locations[c->Location].EndX * MinitileSubdivision, map->Locations[c->Location].EndY * MinitileSubdivision);\n      break;\n    case 18:\n      fprintf(fd, \"-- LeastKills(%d)\\n\", c->UnitType);\n      break;\n    case 19:\n      fprintf(fd, \"-- LowestScore(%d)\\n\", c->ResType);\n      break;\n    case 20:\n      fprintf(fd, \"-- LeastResources(%d)\\n\", c->ResType);\n      break;\n    case 21:\n      fprintf(fd, \"-- Score(%d, %d, %d)\\n\", c->Group, c->ResType,\n              c->QualifiedNumber);\n      break;\n    case 22:\n      fprintf(fd, \"-- Always()\\n\");\n      break;\n    case 23:\n      fprintf(fd, \"-- Never()\\n\");\n      break;\n    default:\n      fprintf(fd, \"-- Unhandled condition: %d\\n\", c->Condition);\n      break;\n    }\n  }\n\n  // Actions\n  for (i = 0; i < 64; ++i)\n  {\n    a = &trigger->TriggerActions[i];\n    if (a->Action == 0)\n    {\n      break;\n    }\n    switch (a->Action)\n    {\n    case 1:\n      fprintf(fd, \"--  ActionVictory()\\n\");\n      break;\n    case 2:\n      fprintf(fd, \"--  ActionDefeat()\\n\");\n      break;\n    case 3:\n      fprintf(fd, \"--  Preserve trigger\\n\");\n      break;\n    case 4:\n      fprintf(fd, \"--  Wait(%d)\\n\", a->Time);\n      break;\n    case 5:\n      fprintf(fd, \"--  Pause\\n\");\n      break;\n    case 6:\n      fprintf(fd, \"--  Unpause\\n\");\n      break;\n    case 7:\n      fprintf(fd,\n              \"--  Transmission(%s, %d, [%hu,%hu]-[%hu,%hu], %d, %d, %d, %d)\\n\",\n              map->Strings[a->TriggerNumber - 1].c_str(), a->Status,\n              map->Locations[a->Source].StartX * MinitileSubdivision, map->Locations[a->Source].StartY * MinitileSubdivision,\n              map->Locations[a->Source].EndX * MinitileSubdivision, map->Locations[a->Source].EndY * MinitileSubdivision,\n              a->Time, a->NumUnits, a->WavNumber, a->Time);\n      break;\n    case 8:\n      fprintf(fd, \"--  PlayWav(%d, %d)\\n\", a->WavNumber, a->Time);\n      break;\n    case 9:\n      fprintf(fd, \"--  TextMessage(%s)\\n\",\n              map->Strings[a->TriggerNumber - 1].c_str());\n      break;\n    case 10:\n      fprintf(fd, \"--  CenterMap(%hu, %hu)\\n\",\n              (map->Locations[a->Source].StartX * MinitileSubdivision + map->Locations[a->Source].EndX * MinitileSubdivision)\n              / 2 / 32,\n              (map->Locations[a->Source].StartY * MinitileSubdivision + map->Locations[a->Source].EndY * MinitileSubdivision)\n              / 2 / 32);\n      break;\n    case 12:\n      fprintf(fd, \"--  SetObjectives(%s)\\n\",\n              map->Strings[a->TriggerNumber - 1].c_str());\n      break;\n    case 26:\n      fprintf(fd, \"--  SetResources(%d, %d, %d, %d)\\n\", a->FirstGroup,\n              a->SecondGroup, a->NumUnits, a->Status);\n      break;\n    case 30:\n      fprintf(fd, \"--  Mute unit speech\\n\");\n      break;\n    case 31:\n      fprintf(fd, \"--  Unmute unit speech\\n\");\n      break;\n    default:\n      fprintf(fd, \"--  Unhandled action: %d\\n\", a->Action);\n      break;\n    }\n  }\n}\n\nvoid Chk::SaveSMS(Storage storage)\n{\n  FILE *fd;\n  int i;\n\n  storage.setFilename(storage.getFilename() + \"sms\");\n\n  CheckPath(storage.getFullPath());\n\n  fd = fopen(storage.getFullPath().c_str(), \"wb\");\n\n  fprintf(fd, \"-- Stratagus Map Setup\\n\");\n  fprintf(fd, \"-- File generated automatically from scmconvert V\" VERSION \"\\n\");\n  fprintf(fd, \"\\n\");\n\n  for (i = 0; i < PlayerMax; ++i)\n  {\n    if (map->PlayerType[i] == 0)\n    {\n      // inactive\n      continue;\n    }\n    fprintf(fd, \"SetStartView(%d, %d, %d)\\n\", i, map->PlayerStart[i].X * MinitileSubdivision,\n            map->PlayerStart[i].Y * MinitileSubdivision);\n    fprintf(fd, \"SetPlayerData(%d, \\\"Resources\\\", \\\"minerals\\\", %d)\\n\", i, 0);\n    fprintf(fd, \"SetPlayerData(%d, \\\"Resources\\\", \\\"gas\\\", %d)\\n\", i, 0);\n    fprintf(fd, \"SetPlayerData(%d, \\\"RaceName\\\", \\\"%s\\\")\\n\", i,\n            RaceNames[map->PlayerRace[i]]);\n  }\n\n  fprintf(fd, \"\\n\\n\");\n\n  fprintf(fd, \"LoadTileModels(\\\"luagen/tilesets/%s.lua\\\")\\n\",\n          map->MapTerrainName);\n\n  fprintf(fd, \"\\n\\n\");\n\n  // SetTile(t, x, y);\n  for (int h = 0; h < map->MapHeight; ++h)\n  {\n    for (int w = 0; w < map->MapWidth; ++w)\n    {\n      fprintf(fd, \"SetTile(%d, %d, %d)\\n\", map->Tiles[h * map->MapWidth + w], w * MinitileSubdivision,\n              h * MinitileSubdivision);\n    }\n  }\n\n  fprintf(fd, \"\\n\\n\");\n\n  // units\n  for (i = 0; i < (int) map->Units.size(); ++i)\n  {\n    string unitName = mUnitNames[map->Units[i].Type];\n\n    string lua_str = lg::line(\n                       lg::assign(\n                         \"unit\",\n                         lg::CreateUnit(unitName, (map->Units[i]).Player, Pos(map->Units[i].X * MinitileSubdivision, map->Units[i].Y * MinitileSubdivision)))\n                     );\n\n    fprintf(fd, \"%s\", lua_str.c_str()); // TODO: c++ this\n\n    if (map->Units[i].ResourceAmount)\n    {\n      fprintf(fd, \"SetResourcesHeld(unit, %d)\\n\", map->Units[i].ResourceAmount);\n    }\n  }\n\n  fprintf(fd, \"\\n\\n\");\n\n  for (i = 0; i < (int) map->Triggers.size(); ++i)\n  {\n    SaveTrigger(fd, (Trigger *) &map->Triggers[i]);\n  }\n\n  fprintf(fd, \"\\n\\n\");\n\n  /**\n   * This is some debug code that prints RapidStratagusIDE support as hook into each map\n   */\n  string if_rsi = lg::line(lg::function(\"if\", lg::compare(\"preferences.RapidStratagusIDE\", \"true\")) + \" then\");\n  if_rsi += lg::line(lg::function(\"Load\", lg::quote(\"RapidStratagusIDE/RSI_Functions.lua\")));\n  if_rsi += lg::line(lg::function(\"RSI_MapConfiguration\"));\n  if_rsi += lg::line(\"end\");\n  fprintf(fd, \"%s\\n\", if_rsi.c_str());\n  /******/\n\n  fprintf(fd, \"\\n\\n\");\n\n  fclose(fd);\n}\n\nvoid Chk::SaveMap(Storage storage)\n{\n  // if a map ends with a dot (.) then it adds .sms and .scp otherwise a dir with scenario.sms/scenario.smp\n  // TODO: if you give something unexpected to savedir - bye bye => rework later\n  if (storage.getFullPath().back() == '/')\n  {\n    storage.setFilename(storage.getFilename() + \"scenario.\");\n  }\n\n  SaveSMP(storage);\n\n  SaveSMS(storage);\n}\n\nvoid Chk::FreeMap()\n{\n  free(map->Description);\n  free(map->MapTerrainName);\n  free(map->Tiles);\n  delete map;\n}\n\nvoid Chk::ConvertChk(Storage storage, unsigned char *chkdata, int chklen)\n{\n  loadFromBuffer(chkdata, chklen);\n  SaveMap(storage);\n}\n\nbool Chk::convert(const std::string &arcfile, Storage storage)\n{\n  //char buf[1024];\n  bool result = false;\n\n  //Preferences &preferences = Preferences::getInstance();\n  //sprintf(buf, \"%s/%s\", preferences.getDestDir().c_str(), file.c_str());\n\n  shared_ptr<DataChunk> data = mHurricane->extractDataChunk(arcfile);\n  if (data)\n  {\n    ConvertChk(storage, data->getDataPointer(), data->getSize());\n\n    result = true;\n  }\n\n  return result;\n}\n\n"
  },
  {
    "path": "src/Chk.h",
    "content": "/*\n * Chk.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef CHK_H_\n#define CHK_H_\n\n// Local\n#include \"WorldMap.h\"\n#include \"Storage.h\"\n#include \"Converter.h\"\n\n// System\n#include <memory>\n\n// Forward declarations\nclass Hurricane;\n\n/**\n * For .chk files generate a combination of .smp and .sms file\n * The .smp and .sms files are Lua scripts and are executed by stargus/stratagus\n * The generated files describe the map, units, tiles, triggers - simply the map behavior\n *\n */\nclass Chk : public Converter\n{\npublic:\n  Chk(std::shared_ptr<Hurricane> hurricane);\n  virtual ~Chk();\n\n  void setUnitNames(const std::vector<std::string> &unitNames);\n\n  virtual bool convert(const std::string &arcfile, Storage storage);\n\nprivate:\n  /**\n   **\tLoad chk from buffer\n   **\n   **\t@param chkdata\tBuffer containing chk data\n   **\t@param len\tLength of chk buffer\n   **\t@param map\tThe map\n   */\n  void loadFromBuffer(unsigned char *chkdata, int len);\n  void ConvertChk(Storage storage, unsigned char *chkdata, int chklen);\n\n  void SaveMap(Storage storage);\n\n  void SaveSMS(Storage storage);\n  void SaveTrigger(FILE *fd, Trigger *trigger);\n  void SaveSMP(Storage storage);\n  void FreeMap();\n\n  WorldMap *map;\n  std::vector<std::string> mUnitNames;\n};\n\n#endif /* CHK_H_ */\n"
  },
  {
    "path": "src/Color.cpp",
    "content": "/*\n * Color.cpp\n *\n  *      Author: Andreas Volz\n */\n\n// project\n#include <Color.h>\n\n// system\n#include <algorithm>\n\nColor::Color() :\n  mRed(0),\n  mGreen(0),\n  mBlue(0),\n  mAlpha(0)\n{\n\n}\n\nColor::Color(const Color &color) :\n  mRed(color.mRed),\n  mGreen(color.mGreen),\n  mBlue(color.mBlue),\n  mAlpha(0)\n{\n\n}\n\nColor::Color(unsigned char red, unsigned char green, unsigned char blue) :\n  mRed(red),\n  mGreen(green),\n  mBlue(blue),\n  mAlpha(0)\n{\n\n}\n\nColor::Color(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha) :\n  mRed(red),\n  mGreen(green),\n  mBlue(blue),\n  mAlpha(alpha)\n{\n\n}\n\nColor::~Color()\n{\n\n}\n\nvoid Color::setRed(unsigned char color)\n{\n  mRed = color;\n}\n\nvoid Color::setGreen(unsigned char color)\n{\n  mGreen = color;\n}\n\nvoid Color::setBlue(unsigned char color)\n{\n  mBlue = color;\n}\n\nvoid Color::setAlpha(unsigned char color)\n{\n  mAlpha = color;\n}\n\nunsigned char Color::getRed() const\n{\n  return mRed;\n}\n\nunsigned char Color::getGreen() const\n{\n  return mGreen;\n}\n\nunsigned char Color::getBlue() const\n{\n  return mBlue;\n}\n\nunsigned char Color::getAlpha() const\n{\n  return mAlpha;\n}\n\nunsigned char Color::getBiggestColor() const\n{\n  return std::max(std::max(mRed, mGreen), mBlue);\n}\n\nColor Color::getBrighened() const\n{\n  double color_factor = getBiggestColor() / 255.0;\n\n  unsigned char bright_red = mRed / color_factor;\n  unsigned char bright_green = mGreen / color_factor;\n  unsigned char bright_blue = mBlue / color_factor;\n\n  Color bright_color(bright_red, bright_green, bright_blue);\n\n  return bright_color;\n}\n\nColor Color::blendAgainstReference(const Color &reference) const\n{\n  Color color_bright = getBrighened();\n\n  double alpha = 0;\n\n  // red biggest\n  if((getRed() > getGreen()) &\n     (getRed() > getBlue()))\n  {\n    alpha = (double) (getRed() - reference.getRed()) /\n            (double) (color_bright.getRed() - reference.getRed());\n\n  }\n  // green is biggest\n  else if((getGreen() > getRed()) &\n          (getGreen() > getBlue()))\n  {\n    alpha = (double) (getGreen() - reference.getGreen()) /\n            (double) (color_bright.getGreen() - reference.getGreen());\n  }\n  // blue is biggest\n  {\n    alpha = (double) (getBlue() - reference.getBlue()) /\n            (double) (color_bright.getBlue() - reference.getBlue());\n  }\n\n  unsigned char red = alpha * getRed() + (1 - alpha) * reference.getRed();\n  unsigned char green = alpha * getGreen() + (1 - alpha) * reference.getGreen();\n  unsigned char blue = alpha * getBlue() + (1 - alpha) * reference.getBlue();\n\n  Color color_result (red, green, blue, alpha * 255);\n\n  return color_result;\n}\n\nColor& Color::operator=(const Color& color)\n{\n  mRed = color.mRed;\n  mGreen = color.mGreen;\n  mBlue = color.mBlue;\n  mAlpha = color.mAlpha;\n\n  return *this;\n}\n\n\n\n"
  },
  {
    "path": "src/Color.h",
    "content": "/*\n * Color.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef COLOR_H\n#define COLOR_H\n\nclass Color\n{\npublic:\n  Color();\n  Color(const Color &color);\n  Color(unsigned char red, unsigned char green, unsigned char blue);\n  Color(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha);\n  virtual ~Color();\n\n  void setRed(unsigned char color);\n  void setGreen(unsigned char color);\n  void setBlue(unsigned char color);\n  void setAlpha(unsigned char color);\n\n  unsigned char getRed() const;\n  unsigned char getGreen() const;\n  unsigned char getBlue() const;\n  unsigned char getAlpha() const;\n\n  /**\n   * @return The same color but 100% brightened\n   */\n  Color getBrighened() const;\n\n  /**\n   * Blend the current color against a reference color (don't modify current color)\n   *\n   * @return The new blended color\n   */\n  Color blendAgainstReference(const Color &reference) const;\n\n  Color& operator=(const Color& color);\n\nprivate:\n  unsigned char getBiggestColor() const;\n\n  unsigned char mRed;\n  unsigned char mGreen;\n  unsigned char mBlue;\n  unsigned char mAlpha;\n};\n\n#endif /* COLOR_H */\n"
  },
  {
    "path": "src/Converter.cpp",
    "content": "/*\n * Converter.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"Converter.h\"\n\nConverter::Converter(std::shared_ptr<Hurricane> hurricane) :\n  mHurricane(hurricane)\n{\n\n}\n\nConverter::~Converter()\n{\n\n}\n\n"
  },
  {
    "path": "src/Converter.h",
    "content": "/*\n * Converter.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef CONVERTER_H_\n#define CONVERTER_H_\n\n// System\n#include <memory>\n#include <string>\n\n// Forward declarations\nclass Hurricane;\n\nclass Converter\n{\npublic:\n  Converter(std::shared_ptr<Hurricane> hurricane);\n  virtual ~Converter();\n\nprotected:\n  std::shared_ptr<Hurricane> mHurricane;\n};\n\n#endif /* ONVERTER_H_ */\n"
  },
  {
    "path": "src/DataChunk.cpp",
    "content": "/*\n * DataChunk.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"DataChunk.h\"\n#include \"Logger.h\"\n\n// System\n#include <stdlib.h>\n#include <string.h>\n#include <iostream>\n#include <fstream>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.DataChunk\");\n\nDataChunk::DataChunk() :\n  mData(nullptr), mSize(0)\n{\n\n}\n\nDataChunk::DataChunk(const DataChunk &datachunk) :\n  mData(nullptr), mSize(0)\n{\n  addData(datachunk.mData, datachunk.mSize);\n}\n\nDataChunk::DataChunk(unsigned char **data, const size_t size)\n{\n  mData = *data;\n  mSize = size;\n}\n\nDataChunk::~DataChunk()\n{\n  free(mData);\n  mData = nullptr;\n}\n\nvoid DataChunk::addData(unsigned char *data, const size_t size)\n{\n  mData = (unsigned char *) realloc(mData, mSize * sizeof(unsigned char) + size * sizeof(unsigned char));\n  memcpy(mData + mSize * sizeof(unsigned char), data, size);\n  mSize += size;\n}\n\nvoid DataChunk::replaceData(unsigned char *data, const size_t size, size_t pos)\n{\n  size_t new_size = pos * sizeof(unsigned char) + size * sizeof(unsigned char);\n  if (new_size > mSize)\n  {\n    mData = (unsigned char *) realloc(mData, new_size);\n    mSize = new_size;\n  }\n  memcpy(mData + pos * sizeof(unsigned char), data, size);\n}\n\nunsigned char *DataChunk::getDataPointer() const\n{\n  return mData;\n}\n\nsize_t DataChunk::getSize() const\n{\n  return mSize;\n}\n\nstd::vector<unsigned char> DataChunk::getUCharVector() const\n{\n  return std::vector<unsigned char>(mData, mData + mSize);\n}\n\nstd::vector<char> DataChunk::getCharVector() const\n{\n  return std::vector<char>(mData, mData + mSize);\n}\n\nbool DataChunk::write(const std::string &filename)\n{\n  bool result = true;\n\n  ofstream wf(filename, ios::out | ios::binary);\n\n  if (wf)\n  {\n    for (size_t i = 0; i < mSize; i++)\n    {\n      wf.write((char *) &mData[i], sizeof(unsigned char));\n    }\n    wf.close();\n  }\n  else\n  {\n    LOG4CXX_ERROR(logger, string(\"Couldn't write in: \") + filename);\n    result = false;\n  }\n\n  return result;\n}\n\nbool DataChunk::read(const std::string &filename)\n{\n  streampos size;\n  char *memblock;\n  bool result = false;\n\n  ifstream file(filename, ios::in|ios::binary|ios::ate);\n  if (file.is_open())\n  {\n    size = file.tellg();\n    memblock = new char [size];\n    file.seekg (0, ios::beg);\n    file.read(memblock, size);\n\n    if(file)\n    {\n      addData(reinterpret_cast<unsigned char*>(memblock), size);\n      result = true;\n    }\n    else\n    {\n      LOG4CXX_ERROR(logger, string(\"Couldn't read from: \") + filename);\n    }\n\n    file.close();\n\n    delete[] memblock;\n  }\n\n  return result;\n}\n\nunsigned char DataChunk::at(size_t pos)\n{\n  unsigned char ret = '\\0';\n\n  if (pos < mSize)\n  {\n    ret = mData[pos];\n  }\n  else\n  {\n    LOG4CXX_WARN(logger, \"'pos' bigger then data: \" + to_string(pos) + \" < \" + to_string(mSize));\n  }\n\n  return ret;\n}\n"
  },
  {
    "path": "src/DataChunk.h",
    "content": "/*\n * DataChunk.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef DATACHUNK_H_\n#define DATACHUNK_H_\n\n// Local\n\n\n// System\n#include <stdlib.h>\n#include <string>\n#include <vector>\n\nclass DataChunk\n{\npublic:\n  /**\n   * Create a new DataChunk with empty size\n   */\n  DataChunk();\n\n  /**\n   * Copy Constructor (full depth)\n   */\n  DataChunk(const DataChunk &datachunk);\n\n  /**\n   * Create a new DataChunk from existing data on heap and give DataChunk responsibility about freeing that memory\n   * (works like a smart pointer)\n   */\n  DataChunk(unsigned char **data, const size_t size);\n\n  virtual ~DataChunk();\n\n  /**\n   * Add a *copy* of the provided data to internal data structure. This doesn't replace the data but concatenates it.\n   */\n  void addData(unsigned char *data, const size_t size);\n\n  void replaceData(unsigned char *data, const size_t size, size_t pos);\n\n  /**\n   * @return a pointer to the raw data inside the DataChunk. Modifying the content changes the data itself.\n   */\n  unsigned char* getDataPointer() const;\n\n  /**\n   * @return a vector with a copy of the data\n   */\n  std::vector<unsigned char> getUCharVector() const;\n\n  /**\n   * @return a vector with a copy of the data\n   */\n  std::vector<char> getCharVector() const;\n\n  /**\n   * @return the number of elements in the container\n   */\n  size_t getSize() const;\n\n  /**\n   * Write the content as binary steam into filename\n   *\n   * @return true if succeed\n   */\n  bool write(const std::string &filename);\n\n  /**\n   * Read data from a file and use addData() to put it into the DataChunk\n   *\n   * @return true if succeed\n   */\n  bool read(const std::string &filename);\n\n  /**\n   * Access to a specific element\n   *\n   * @pos which element to access (if you give a size bigger then elements you get a log warning, buthing bad happens)\n   *\n   * @return the element to access\n   */\n  unsigned char at(size_t pos);\n\nprivate:\n  unsigned char *mData;\n  size_t mSize;\n};\n\n#endif /* DATACHUNK_H_ */\n"
  },
  {
    "path": "src/Dds.cpp",
    "content": "/*\n * Dds.cpp\n *\n *      Author: Andreas Volz\n */\n\n#ifdef HAVE_IMAGEMAGICKPP\n\n// Local\n#include \"Dds.h\"\n#include \"Hurricane.h\"\n#include \"FileUtil.h\"\n#include \"Preferences.h\"\n\n// System\n#include <Magick++.h>\n#include <memory>\n#include <iostream>\n\nusing namespace std;\nusing namespace Magick;\n\nDds::Dds(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane)\n{\n  // TODO: might be needed for Windows/OSX regarding docu...\n  //InitializeMagick(*argv);\n}\n\nDds::~Dds()\n{\n\n}\n\nbool Dds::convert(const std::string &arcfile, const std::string &file)\n{\n  bool result = true;\n\n  shared_ptr<DataChunk> data = mHurricane->extractDataChunk(arcfile);\n  if (data)\n  {\n    Blob blob(static_cast<void *>(data->getDataPointer()), data->getSize());\n    // Construct the image object. Seperating image construction from the\n    // the read operation ensures that a failure to read the image file\n    // doesn't render the image object useless.\n    Image image;\n    try\n    {\n      // Read a file into image object\n      image.read(blob);\n\n      Preferences &preferences = Preferences::getInstance();\n      string targetPath = preferences.getDestDir() + \"/\" + GRAPHICS_PATH + \"/\"\n                          + file;\n\n      // Write the image to a file\n      CheckPath(targetPath);\n      image.write(targetPath);\n    }\n    catch (Exception &error_)\n    {\n      cout << \"Caught exception: \" << error_.what() << endl;\n      return 1;\n    }\n  }\n\n  return result;\n}\n\n#endif /* HAVE_IMAGEMAGICKPP */\n"
  },
  {
    "path": "src/Dds.h",
    "content": "/*\n * Dds.h\n *\n *      Author: Andreas Volz\n */\n\n#ifdef HAVE_IMAGEMAGICKPP\n\n#ifndef DDS_H_\n#define DDS_H_\n\n// Local\n#include \"Converter.h\"\n\n// System\n#include <memory>\n\n// Forward declarations\nclass Hurricane;\n\nclass Dds: public Converter\n{\npublic:\n  Dds(std::shared_ptr<Hurricane> hurricane);\n  virtual ~Dds();\n\n  bool convert(const std::string &arcfile, const std::string &file);\n\nprivate:\n\n};\n\n#endif /* DDS_H_ */\n\n#endif /* HAVE_IMAGEMAGICKPP */\n"
  },
  {
    "path": "src/FileNotFoundException.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <string>\n#include \"FileNotFoundException.h\"\n\nusing namespace std;\n\nconst char *FileNotFoundException::what() const throw()\n{\n  static string s;\n  s = \"File not found: '\";\n  s += txt;\n  s += \"'.\";\n\n  return static_cast <const char *>(s.c_str());\n}\n"
  },
  {
    "path": "src/FileNotFoundException.h",
    "content": "#ifndef FILENOTFOUNDEXCEPTION_H\n#define FILENOTFOUNDEXCEPTION_H\n\n#include <exception>\n\nclass FileNotFoundException : public std::exception\n{\npublic:\n  FileNotFoundException(const std:: string &file) : txt(file) {}\n\n  const char *what() const throw();\n\nprivate:\n  const std::string &txt;\n};\n\n#endif // FILENOTFOUNDEXCEPTION_H\n"
  },
  {
    "path": "src/FileUtil.cpp",
    "content": "/*\n * FileUtil.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"FileUtil.h\"\n// system\n#include <sys/types.h>\n#include <sys/stat.h>\n\nusing namespace std;\n\nbool FileExists(const std::string &filename)\n{\n  struct stat buffer;\n  return stat(filename.c_str(), &buffer) == 0 ? true : false;\n}\n\nvoid CheckPath(const std::string &path)\n{\n  CheckPath(path.c_str());\n}\n\nvoid CheckPath(const char *path)\n{\n  char *cp = NULL;\n  char *s = NULL;\n\n  cp = platform::strdup(path);\n\n  s = strrchr(cp, '/');\n  if (s)\n  {\n    *s = '\\0';  // remove file\n    s = cp;\n    for (;;)\n    {\n      // make each path element\n      s = strchr(s, '/');\n      if (s)\n      {\n        *s = '\\0';\n      }\n\n      platform::mkdir(cp, 0777);\n\n      if (s)\n      {\n        *s++ = '/';\n      }\n      else\n      {\n        break;\n      }\n    }\n  }\n  free(cp);\n}\n"
  },
  {
    "path": "src/FileUtil.h",
    "content": "/*\n * FileUtil.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef FILEUTIL_H_\n#define FILEUTIL_H_\n\n// project\n#include \"platform.h\"\n\n// system\n#include <string>\n#include <stdlib.h>\n#include <string.h>\n\n/**\n * Check if path exists - DOESN'T create any directories/files\n */\nbool FileExists(const std::string &filename);\n\n/**\n *  Check if path exists, if not make all directories.\n */\nvoid CheckPath(const char *path);\n\n/**\n *  Check if path exists, if not make all directories.\n */\nvoid CheckPath(const std::string &path);\n\n#endif /* FILEUTIL_H_ */\n"
  },
  {
    "path": "src/Font.cpp",
    "content": "/*\n * Font.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include <Palette.h>\n#include <PngExporter.h>\n#include \"Font.h\"\n#include \"endian.h\"\n#include \"FileUtil.h\"\n#include \"Storm.h\"\n#include \"Preferences.h\"\n#include \"StringUtil.h\"\n#include \"Logger.h\"\n\n// C\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdint.h>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Font\");\n\nFont::Font(std::shared_ptr<Hurricane> hurricane) :\n  mHurricane(hurricane)\n{\n\n}\n\nFont::~Font()\n{\n\n}\n\n/**\n **  Convert a font to PNG image format.\n **\n **  @return true if everything is ok\n */\nbool Font::convert(const std::string &arcfile, Storage file)\n{\n  unsigned char *image;\n  int w;\n  int h;\n  bool result = true;\n\n  LOG4CXX_TRACE(logger, \"convert:\" + arcfile + \",\" + file);\n\n  shared_ptr<DataChunk> data = mHurricane->extractDataChunk(arcfile);\n  if (data && mPalette)\n  {\n    std::shared_ptr<DataChunk> datachunk = mPalette->createDataChunk();\n\n    image = Font::convertImage(data->getDataPointer(), &w, &h);\n\n    CheckPath(file.getFullPath());\n\n    DataChunk dc_image(&image, w * h);\n    PaletteImage palImage(dc_image, Size(w, h));\n\n    PngExporter::save(file.getFullPath(), palImage, mPalette, 255);\n  }\n\n  return result;\n}\n\nvoid Font::setPalette(std::shared_ptr<AbstractPalette> pal)\n{\n  mPalette = pal;\n}\n\ntypedef struct _FontHeader\n{\n  char name[5];\t//\t[0-4] Always is \"FONT\"\n  uint8_t lowIndex;\t//\tIndex of the first letter in file\n  uint8_t highIndex;\t//\tIndex of the last letter in file\n  uint8_t maxWidth;\t//\tMaximum width\n  uint8_t maxHeight;\t//\tMaximum height\n  //DWORD\tUnk1;\t\t//\tUnknown / Unused\n} FontHeader;\n\n// size of this header struct has to be 4xbyte!\ntypedef struct _FontLetterHeader\n{\n  uint8_t width;\t\t//\tWidth of the letter\n  uint8_t height;\t\t//\tHeight of the letter\n  uint8_t xOffset;\t//\tX Offset for the topleft corner of the letter.\n  uint8_t yOffset;\t//\tY Offset for the topleft corner of the letter.\n} FontLetterHeader;\n\nunsigned char *Font::convertImage(unsigned char *start, int *wp, int *hp)\n{\n  char buf[1024];\n  FontHeader header;\n  unsigned char *bp = nullptr;\n  unsigned char *image = nullptr;\n  unsigned char *dp = nullptr;\n  unsigned int *offsets = nullptr;\n  int image_width = 0;\n  int image_height = 0;\n\n  LOG4CXX_DEBUG(logger, \"convertImage\");\n\n  bp = start;\n\n  header.name[0] = FetchByte(bp);\n  header.name[1] = FetchByte(bp);\n  header.name[2] = FetchByte(bp);\n  header.name[3] = FetchByte(bp);\n  header.name[4] = '\\0';\n\n  header.lowIndex = FetchByte(bp);\n  header.highIndex = FetchByte(bp);\n  header.maxWidth = FetchByte(bp);\n  header.maxHeight = FetchByte(bp);\n\n  unsigned int letterCount = header.highIndex - header.lowIndex;\n\n  if (!strncmp(header.name, \"FONT\", 4))\n  {\n    sprintf(buf, \"li:%i / hi:%i / mw:%i / mh:%i\", header.lowIndex,\n            header.highIndex, header.maxWidth, header.maxHeight);\n    LOG4CXX_DEBUG(logger, string(\"FONT header found: \") + buf);\n\n    //bp += 2; // DWORD unused\n\n    image_width = header.maxWidth;\n    image_height = letterCount * header.maxHeight;\n    sprintf(buf, \"w:%i / h:%i\", image_width, image_height);\n    LOG4CXX_DEBUG(logger, string(\"Image size: \") + buf);\n\n    // calculate the offsets for each font letter header\n    offsets = (unsigned int *) malloc(letterCount * sizeof(FontLetterHeader));\n    for (unsigned int i = 0; i < letterCount; ++i)\n    {\n      offsets[i] = FetchLE32(bp);\n    }\n\n    // allocate the memory to fill with raw image data\n    image = (unsigned char *) malloc(image_width * image_height);\n    if (!image)\n    {\n      LOG4CXX_FATAL(logger, \"Can't allocate image memory\");\n    }\n\n    // Give image a transparent background\n    memset(image, 255, image_width * image_height);\n\n    // do this for all letters\n    for (unsigned int i = 0; i < letterCount; i++)\n    {\n      if (!offsets[i])\n      {\n        continue;\n      }\n\n      FontLetterHeader letter;\n\n      // set pointer to each letter header start...\n      bp = start + offsets[i];\n\n      letter.width = FetchByte(bp);\n      letter.height = FetchByte(bp);\n      letter.xOffset = FetchByte(bp);\n      letter.yOffset = FetchByte(bp);\n      sprintf(buf, \"%i# w:%i / h:%i / x:%i / y:%i\", i, letter.width,\n              letter.height, letter.xOffset, letter.yOffset);\n      LOG4CXX_DEBUG(logger, string(\"FontLetterRaw: \") + buf);\n\n      dp = image + letter.xOffset + letter.yOffset * header.maxWidth\n           + i * (header.maxWidth * header.maxHeight);\n      int w = 0;\n      int h = 0;\n\n      // copy all data from each letter and convert it\n      // who ever coded this algorithm didn't document it - but it seems to work!!\n      for (;;)\n      {\n        int ctrl;\n        ctrl = FetchByte(bp)\n               ;\n        w += (ctrl >> 3) & 0x1F;\n        if (w >= letter.width)\n        {\n          w -= letter.width;\n          ++h;\n          if (h >= letter.height)\n          {\n            break;\n          }\n        }\n        dp[h * header.maxWidth + w] = ctrl & 0x07;\n        ++w;\n        if (w >= letter.width)\n        {\n          w -= letter.width;\n          ++h;\n          if (h >= letter.height)\n          {\n            break;\n          }\n        }\n      }\n    }\n  }\n  else\n  {\n    LOG4CXX_WARN(logger, \"No Font Header found!\");\n  }\n\n  LOG4CXX_TRACE(logger, \"Exported font letter number: \" + to_string(letterCount));\n\n  *wp = header.maxWidth;\n  *hp = header.maxHeight * letterCount;\n\n  // free the offset memory as it's not longer used\n  free(offsets);\n\n  return image;\n}\n\n"
  },
  {
    "path": "src/Font.h",
    "content": "/*\n * Font.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef FONT_H\n#define FONT_H\n\n// Local\n#include \"Storage.h\"\n\n// System\n#include <memory>\n\n// Forward declarations\nclass Hurricane;\n\nclass Font\n{\npublic:\n  Font(std::shared_ptr<Hurricane> hurricane);\n  virtual ~Font();\n\n  bool convert(const std::string &arcfile, Storage file);\n\n  void setPalette(std::shared_ptr<AbstractPalette> pal);\n\nprivate:\n  /**\n   **  Convert font into raw image data\n   */\n  unsigned char* convertImage(unsigned char *start, int *wp, int *hp);\n\n  std::shared_ptr<Hurricane> mHurricane;\n  std::shared_ptr<AbstractPalette> mPalette;\n};\n\n#endif /* FONT_H */\n"
  },
  {
    "path": "src/Grp.cpp",
    "content": "/*\n * Grp.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include <PngExporter.h>\n#include \"Grp.h\"\n#include \"endian.h\"\n#include \"FileUtil.h\"\n#include \"Storm.h\"\n#include \"Logger.h\"\n\n// System\n#include <cstdio>\n#include <stdlib.h>\n#include <vector>\n#include <iostream>\n#include <fstream>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Grp\");\n\nGrp::Grp(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane),\n  mRGBA(false)\n{\n}\n\nGrp::Grp(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile) :\n  Converter(hurricane),\n  mRGBA(false)\n{\n  load(arcfile);\n}\n\nGrp::Grp(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile, std::shared_ptr<AbstractPalette> pal) :\n  Converter(hurricane),\n  mPal(pal),\n  mRGBA(false)\n{\n  load(arcfile);\n}\n\nGrp::~Grp()\n{\n\n}\n\nvoid Grp::setPalette(std::shared_ptr<AbstractPalette> pal)\n{\n  mPal = pal;\n\n  mGRPImage.SetColorPalette(pal);\n}\n\nvoid Grp::setRGBA(bool rgba)\n{\n  mRGBA = rgba;\n}\n\nbool Grp::getRGBA()\n{\n  return mRGBA;\n}\n\nbool Grp::load(const std::string &arcfile)\n{\n  //mArcfile = arcfile;\n\n  std::shared_ptr<DataChunk> dcGrp = mHurricane->extractDataChunk(arcfile);\n\n  std::vector<char> GrpVec = dcGrp->getCharVector();\n\n  if(dcGrp)\n  {\n    mGRPImage.LoadImage(&GrpVec, false);\n  }\n\n  return true;\n}\n\nbool Grp::save(Storage filename)\n{\n  bool result = true;\n\n  int IPR = 17;\n  int end_frame = mGRPImage.getNumberOfFrames();\n\n  // all IPR < 17 are buildings or similar and stratagus needs them in one image per row\n  if(end_frame < IPR)\n  {\n    IPR = 1;\n  }\n\n  mGRPImage.SaveStitchedPNG(filename.getFullPath(), 0, end_frame, IPR, mRGBA);\n\n  return result;\n}\n\nSize Grp::getTileSize()\n{\n  Size size (mGRPImage.getMaxImageWidth(), mGRPImage.getMaxImageHeight());\n  return size;\n}\n"
  },
  {
    "path": "src/Grp.h",
    "content": "/*\n * Grp.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef GRP_H\n#define GRP_H\n\n// Local\n#include \"Converter.h\"\n#include \"Palette.h\"\n#include \"Storage.h\"\n#include \"Size.h\"\n#include \"Palette2D.h\"\n#include \"libgrp/libgrp.hpp\"\n\n// System\n#include <string.h>\n#include <memory>\n\n/**\n *\n */\nclass Grp: public Converter\n{\npublic:\n  Grp(std::shared_ptr<Hurricane> hurricane);\n  Grp(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile);\n  Grp(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile, std::shared_ptr<AbstractPalette> pal);\n  virtual ~Grp();\n\n  /**\n   * Set if the Grp image is saved as 8-bit RGBA or palette PNG\n   * Default is palette PNG\n   */\n  void setRGBA(bool rgba);\n\n  bool getRGBA();\n\n  bool load(const std::string &arcfile);\n\n  /**\n   *  Convert a Grp graphic to PNG format\n   *\n   *  @param file Place to save the file on the drive (relative to game dir)\n   */\n  bool save(Storage filename);\n\n  void setPalette(std::shared_ptr<AbstractPalette> pal);\n\n  Size getTileSize();\n\nprotected: // TODO: maybe back to private after Widget redesign\n  std::shared_ptr<AbstractPalette> mPal;\n  GRPImage mGRPImage;\n  //std::string mArcfile;\n  bool mRGBA;\n  //int mTransparent;\n};\n\n#endif /* GRP_H */\n"
  },
  {
    "path": "src/Hurricane.cpp",
    "content": "/*\n * Hurricane.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"Hurricane.h\"\n\n// Sytsem\n#include <string>\n#include <sstream>\n#include <iostream>\n\nusing namespace std;\n\nHurricane::Hurricane()\n{\n\n}\n\nHurricane::~Hurricane()\n{\n\n}\n\nstd::shared_ptr<DataChunk> Hurricane::extractDataChunk(const std::string &archivedFile)\n{\n  size_t bufferLen = 0;\n  unsigned char *szEntryBufferPrt = nullptr;\n\n  if (extractMemory(archivedFile, &szEntryBufferPrt, &bufferLen))\n  {\n    shared_ptr<DataChunk> data = make_shared<DataChunk>(&szEntryBufferPrt,\n                                 bufferLen);\n    return data;\n  }\n\n  return nullptr;\n}\n\nstd::shared_ptr<std::istream> Hurricane::extractStream(const std::string &archivedFile)\n{\n  size_t bufferLen = 0;\n  unsigned char *szEntryBufferPrt = nullptr;\n\n  if (extractMemory(archivedFile, &szEntryBufferPrt, &bufferLen))\n  {\n    shared_ptr<stringstream> sstream = make_shared<stringstream>();\n\n    // write the memory into the stream\n    sstream->write(reinterpret_cast<char*>(szEntryBufferPrt), bufferLen);\n\n    // and then free the memory afterwards\n    free(szEntryBufferPrt);\n\n    return sstream;\n  }\n\n  return nullptr;\n}\n\nconst std::string &Hurricane::getArchiveName() const\n{\n  return mArchiveName;\n}\n"
  },
  {
    "path": "src/Hurricane.h",
    "content": "/*\n * Hurricane.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef HURRICANE_H_\n#define HURRICANE_H_\n\n// Local\n#include \"DataChunk.h\"\n\n// System\n#include <string>\n#include <memory>\n\n/**\n * This is the virtual base class for Bl*zz*rd data containers\n */\nclass Hurricane\n{\npublic:\n\tHurricane();\n\tHurricane(const std::string &archiveName);\n\tvirtual ~Hurricane();\n\n\tvirtual bool openArchive(const std::string &archiveName) = 0;\n\n\tvirtual void closeArchive() = 0;\n\n\t/**\n\t * Extract file from archive and create all directories if not existing\n\t *\n\t * @param compress if set true save file with gzip on drive. No special file extension is added automatic. (default: false)\n\t */\n  virtual bool extractFile(const std::string &archivedFile, const std::string &extractedName, bool compress = false) = 0;\n\n\t/**\n\t * Attention: This function malloc() bufferLen memory which you've to free yourself!\n\t * Better use extractDataChunk()\n\t */\n\tvirtual bool extractMemory(const std::string &archivedFile, unsigned char **szEntryBufferPrt, size_t *bufferLen) = 0;\n\n\t/**\n\t * Extract a file in memory\n\t * @return A shared_ptr with DataChunk to have responsibility of memory handling\n\t */\n\tvirtual std::shared_ptr<DataChunk> extractDataChunk(const std::string &archivedFile);\n\n\tvirtual std::shared_ptr<std::istream> extractStream(const std::string &archivedFile);\n\n\tvirtual const std::string &getArchiveName() const;\n\nprotected:\n\n\tstd::string mArchiveName;\n};\n\n#endif /* HURRICANE_H_ */\n"
  },
  {
    "path": "src/ImagesConverter.cpp",
    "content": "/*\n * ImagesConverter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"ImagesConverter.h\"\n#include \"Logger.h\"\n#include \"Preferences.h\"\n#include \"Storage.h\"\n#include \"luagen.h\"\n#include \"FileUtil.h\"\n#include \"dat/Image.h\"\n#include \"StringUtil.h\"\n#include \"Grp.h\"\n\n// system\n#include <iostream>\n#include <fstream>\n#include <string>\n\nusing namespace std;\nusing namespace dat;\n\nstatic Logger logger = Logger(\"startool.dat.ImagesConverter\");\n\nImagesConverter::ImagesConverter(std::shared_ptr<Hurricane> hurricane, DataHub &datahub) :\n    Converter(hurricane),\n    mDatahub(datahub)\n{\n\n}\n\nImagesConverter::~ImagesConverter()\n{\n\n}\n\nbool ImagesConverter::convert(std::map<std::string, std::shared_ptr<AbstractPalette>> &paletteMap)\n{\n  bool result = true;\n\n  Preferences &preferences = Preferences::getInstance();\n\n  Storage graphics;\n  graphics.setDataPath(preferences.getDestDir());\n  graphics.setDataType(\"graphics\");\n\n  Storage luagen;\n  luagen.setDataPath(preferences.getDestDir());\n  luagen.setDataType(\"luagen/images\");\n  CheckPath(luagen.getFullPath());\n\n  ofstream lua_include;\n  lua_include.open (luagen(\"luagen-images.lua\").getFullPath());\n  string lua_include_str;\n\n  for (unsigned int i = 0; i < mDatahub.images->grp()->size(); i++)\n  {\n    Image image(mDatahub, i);\n\n    string grp_name(image.grp_tbl().name1());\n    grp_name = to_lower(grp_name); // make lower case to match it always\n\n    LOG4CXX_TRACE(logger, \"image: \" + grp_name);\n\n    /* The following code splits a full GRP path/file into a logic of image type, subtype and subsubtype.\n     * The idea is to identify the logic which palette should be used to decode that specific GRP image.\n     */\n\n    string imageType;\n    string imageSubType;\n    string imageSubSubType;\n\n    // find first slash\n    size_t found = grp_name.find('\\\\');\n    if(found != string::npos)\n    {\n      imageType = grp_name.substr (0, found);\n      LOG4CXX_TRACE(logger, \"imageType: \" + imageType);\n\n      // find second slash\n      size_t found2 = grp_name.find('\\\\', found+1);\n      if(found2 != string::npos)\n      {\n        imageSubType = grp_name.substr (found+1, found2 - found-1);\n        LOG4CXX_TRACE(logger, \"imageSubType: \" + imageSubType);\n\n        // find third slash\n        size_t found3 = grp_name.find('\\\\', found2+1);\n        if(found3 != string::npos)\n        {\n          imageSubSubType = grp_name.substr (found2+1, found3 - found2-1);\n          LOG4CXX_TRACE(logger, \"imageSubSubType: \" + imageSubSubType);\n        }\n      }\n    }\n\n    string grp_arcfile =  \"unit\\\\\" + grp_name;\n\n    Grp grp(mHurricane, grp_arcfile);\n    std::shared_ptr<AbstractPalette> pal;\n    string remapping;\n\n    bool save_grp = true;\n\n    if (image.draw_function() == images_dat_t::DRAW_FUNCTION_ENUM_REMAPPING)\n    {\n      if(image.remapping() == images_dat_t::REMAPPING_ENUM_OFIRE)\n      {\n        remapping = \"ofire\";\n      }\n      else if(image.remapping() == images_dat_t::REMAPPING_ENUM_GFIRE)\n      {\n        remapping = \"gfire\";\n      }\n      else if(image.remapping() == images_dat_t::REMAPPING_ENUM_BFIRE)\n      {\n        remapping = \"bfire\";\n      }\n      else if(image.remapping() == images_dat_t::REMAPPING_ENUM_BEXPL)\n      {\n        remapping = \"bexpl\";\n      }\n      else // as default use ofire until I've a better idea....\n      {\n        remapping = \"ofire\";\n      }\n\n      pal = paletteMap.at(remapping);\n      grp.setPalette(pal);\n\n      grp.setRGBA(true);\n    }\n    else if (image.draw_function() == images_dat_t::DRAW_FUNCTION_ENUM_SHADOW)\n    {\n      // do not export shadows images as the stratagus engine has a better way to generate them\n      save_grp = false;\n    }\n    else // all other drawing functions until I identify a special case\n    {\n      string tileset;\n\n      if(imageType == \"thingy\" && imageSubType == \"tileset\" && !imageSubSubType.empty())\n      {\n        tileset = imageSubSubType;\n        pal = paletteMap.at(tileset);\n      }\n      else // in all other cases use the \"tunit\" palette\n      {\n        pal = paletteMap.at(\"tunit\");\n      }\n    }\n\n    // FIXME: some blacklisting until I know why it crash!\n    if(grp_name == \"thingy\\\\blackx.grp\")\n    {\n      save_grp = false;\n    }\n    // FIXME: some hard coded defaults to assign other palettes\n    // make this configurable or find out if this is in the data\n    else if(grp_name == \"terran\\\\tank.grp\")\n    {\n      // TODO: player color isn't available. But no problem visible for now.\n      // maybe need to add cunit palette before into tileset palette?\n      pal = paletteMap.at(\"badlands\");\n    }\n    else if(grp_name == \"neutral\\\\cbattle.grp\")\n    {\n      // TODO: player color isn't available. See how to fix this (or if this is needed for neutral)\n      pal = paletteMap.at(\"badlands\");\n    }\n    else if(grp_name == \"neutral\\\\ion.grp\")\n    {\n      pal = paletteMap.at(\"platform\");\n    }\n    else if(grp_name == \"neutral\\\\khyad01.grp\")\n    {\n      pal = paletteMap.at(\"jungle\");\n    }\n    else if(grp_name == \"neutral\\\\temple.grp\")\n    {\n      pal = paletteMap.at(\"jungle\");\n    }\n    else if(grp_name == \"neutral\\\\geyser.grp\")\n    {\n      /* FIXME: only the first frame is correct, but this looks ok as we use only this one in animation\n      frame 0 = \"badlands.wpe\" (default frame for all other tilesets)\n      frame 1 = \"platform.wpe\"\n      frame 2 = \"install.wpe\"\n      frame 3 = \"ashworld.wpe\"\n      */\n      pal = paletteMap.at(\"badlands\");\n    }\n\n    grp.setPalette(pal);\n\n    if(save_grp)\n    {\n      string grp_storage_file(grp_arcfile);\n      replaceString(\"\\\\\", \"/\", grp_storage_file);\n\n      // cut the file ending and lower case it\n      string grp_storage_file_base = to_lower(cutFileEnding(grp_storage_file, \".grp\"));\n\n      // if a remapping function is used for that Grp than save with specific name\n      if(!remapping.empty())\n      {\n        grp_storage_file_base += \"_\" + remapping;\n      }\n\n      Storage png_file = graphics(grp_storage_file_base + \".png\");\n\n      result = grp.save(png_file);\n\n      string image_id = image.getIDString();\n      string image_lua = image_id + \".lua\";\n\n      Storage lua_file_store(luagen(image_lua));\n\n      // only generate LUA file with the image properties in case it could be saved successful\n      if(result)\n      {\n        ofstream lua_file;\n        lua_file.open (lua_file_store.getFullPath());\n\n        Size tilesize = grp.getTileSize();\n\n        int NumDirections = 1;\n        if(image.gfx_turns() == true)\n        {\n          // it seems all animations which are calculated by gfx_turns have 32 directions\n          NumDirections = 32;\n        }\n\n        string unit_image_file(lg::assign(image_id + \"_file\", lg::quote(png_file.getRelativePath())));\n        lua_file << unit_image_file << endl;\n\n        string unit_image_size(lg::assign(image_id + \"_size\", lg::sizeTable(tilesize)));\n        lua_file << unit_image_size << endl;\n\n        string unit_image_NumDirections(lg::assign(image_id + \"_NumDirections\", to_string(NumDirections)));\n        lua_file << unit_image_NumDirections << endl;\n\n        string unit_image_table(\n            lg::table({lg::quote(\"file\"), image_id + \"_file\",\n            lg::quote(\"size\") , image_id + \"_size\"}));\n        string unit_image = lg::assign(image_id, unit_image_table);\n        lua_file << unit_image << endl;\n\n        string unit_image_table_var(\n            lg::table({lg::assign(\"File\", image_id + \"_file\"),\n            lg::assign(\"Size\" , image_id + \"_size\")}));\n        string unit_image_var = lg::assign(image_id + \"_var\", unit_image_table_var);\n        lua_file << unit_image_var << endl;\n\n        lua_file.close();\n\n        string grp_save_trace(to_string(i) +  \": \" + grp_name + \" : \" + grp_arcfile + \" => \" + grp_storage_file_base);\n        LOG4CXX_TRACE(logger, grp_save_trace);\n      }\n      // write the Load call even if Grp not present to preserve the SC base files\n      lua_include_str += lg::line(lg::function(\"Load\", lg::quote(lua_file_store.getRelativePath())));\n    }\n  }\n\n  lua_include << lua_include_str;\n  lua_include.close();\n\n  return result;\n}\n\n"
  },
  {
    "path": "src/ImagesConverter.h",
    "content": "/*\n * ImagesConverter.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef IMAGESCONVERTER_H\n#define IMAGESCONVERTER_H\n\n#include \"Converter.h\"\n#include \"dat/DataHub.h\"\n\nclass ImagesConverter: public Converter\n{\npublic:\n  ImagesConverter(std::shared_ptr<Hurricane> hurricane, dat::DataHub &datahub);\n  virtual ~ImagesConverter();\n\n  bool convert(std::map<std::string, std::shared_ptr<AbstractPalette>> &paletteMap);\n\nprivate:\n  dat::DataHub &mDatahub;\n};\n\n#endif /* IMAGESCONVERTER_H */\n"
  },
  {
    "path": "src/KaitaiConverter.cpp",
    "content": "/*\n * KaitaiConverter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"KaitaiConverter.h\"\n#include \"DataChunk.h\"\n#include \"Hurricane.h\"\n\n// system\n#include <iostream>\n\nusing namespace std;\n\nKaitaiConverter::KaitaiConverter(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane)\n{\n\n}\n\nKaitaiConverter::~KaitaiConverter()\n{\n\n}\n\n/*std::shared_ptr<kaitai::kstream> KaitaiConverter::getKaitaiStream(const std::string &file)\n{\n  std::shared_ptr<std::istream> stream = mHurricane->extractStream(file);\n\n  std::string s;\n  std::ostringstream os;\n  os<<stream->rdbuf();\n  s=os.str();\n\n  std::shared_ptr<kaitai::kstream> ks = make_shared<kaitai::kstream>(s);\n\n  return ks;\n}*/\n"
  },
  {
    "path": "src/KaitaiConverter.h",
    "content": "/*\n * KaitaiConverter.h\n *\n *      Author: Andreas\n */\n\n#ifndef KAITAICONVERTER_H\n#define KAITAICONVERTER_H\n\n// project\n#include \"Converter.h\"\n#include \"kaitai/kaitaistream.h\"\n\n//system\n#include <memory>\n\n/**\n * TODO: meaybe remove complete KaitaiConverter class layer...\n */\nclass KaitaiConverter: public Converter\n{\npublic:\n  KaitaiConverter(std::shared_ptr<Hurricane> hurricane);\n  virtual ~KaitaiConverter();\n\nprotected:\n  /**\n   * WARNING DEPRECATED!\n   * remove getKaitaiStream() complete and replace by logic in DataHub\n   */\n  //std::shared_ptr<kaitai::kstream> getKaitaiStream(const std::string &file);\n};\n\n#endif /* KAITAICONVERTER_H */\n"
  },
  {
    "path": "src/Logger.h",
    "content": "#ifndef LOGGER_H\n#define LOGGER_H\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#ifdef HAVE_LOG4CXX\n/* log4cxx */\n#include \"log4cxx/logger.h\"\n#include \"log4cxx/basicconfigurator.h\"\n#include \"log4cxx/propertyconfigurator.h\"\n#include \"log4cxx/helpers/exception.h\"\n\nclass Logger\n{\npublic:\n  Logger(const std::string &name) :\n    mLogger(log4cxx::Logger::getLogger(name)) {}\n\n  Logger(const std::wstring &name) :\n    mLogger(log4cxx::Logger::getLogger(name)) {}\n\n  /**\n   * Deactivate all logging in the application complete\n   */\n  void off()\n  {\n\t  log4cxx::BasicConfigurator::configure();\n    mLogger->setLevel(log4cxx::Level::getOff());\n  }\n\n  log4cxx::LoggerPtr operator = (const Logger &logger)\n  {\n    return mLogger;\n  }\n\n  log4cxx::LoggerPtr operator -> (void)\n  {\n    return mLogger;\n  }\n\nprivate:\n  log4cxx::LoggerPtr mLogger;\n};\n\n// print the calling function\n#define LOG_CUR_FUNC string(__func__)\n\n#else // no LOG4CXX available...\n\n#include <iostream>\n\n#ifdef HAVE_LOGGING\n// macros to log all and everything to stderr...\n#define LOGSTR \"[Logging] - \"\n#define LOG4CXX_TRACE(logger, expression) std::cerr << LOGSTR << \"TRACE \" << expression << std::endl;\n#define LOG4CXX_DEBUG(logger, expression) std::cerr << LOGSTR << \"DEBUG \" << expression << std::endl;\n#define LOG4CXX_INFO(logger, expression)  std::cerr << LOGSTR << \"INFO \"  << expression << std::endl;\n#define LOG4CXX_WARN(logger, expression)  std::cerr << LOGSTR << \"WARN \"  << expression << std::endl;\n#define LOG4CXX_ERROR(logger, expression) std::cerr << LOGSTR << \"ERROR \" << expression << std::endl;\n#define LOG4CXX_FATAL(logger, expression) std::cerr << LOGSTR << \"FATAL \" << expression << std::endl;\n#else\n// macros to log nothing...\n#define LOG4CXX_TRACE(logger, expression)\n#define LOG4CXX_DEBUG(logger, expression)\n#define LOG4CXX_INFO(logger, expression)\n#define LOG4CXX_WARN(logger, expression)\n#define LOG4CXX_ERROR(logger, expression)\n#define LOG4CXX_FATAL(logger, expression)\n#endif // LOG2NIX_ACTIVE\n\nclass Logger\n{\npublic:\n  Logger(const std::string &name)\n  {\n  }\n  Logger(const std::wstring &name)\n  {\n  }\n};\n\n#endif // HAVE_LOG4CXX\n\n#endif // LOGGER_H\n"
  },
  {
    "path": "src/NoValidPaletteException.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <string>\n#include \"NoValidPaletteException.h\"\n\nusing namespace std;\n\nconst char *NoValidPaletteException::what() const throw()\n{\n  static string s;\n  s = \"Palette size doesn't fit to RGB, or RGBx/WPE or PCX2D: \";\n  s += to_string(m_size);\n\n  return static_cast <const char *>(s.c_str());\n}\n"
  },
  {
    "path": "src/NoValidPaletteException.h",
    "content": "#ifndef NOVALIDPALETTEEXCEPTION_H\n#define NOVALIDPALETTEEXCEPTION_H\n\n#include <exception>\n\nclass NoValidPaletteException : public std::exception\n{\npublic:\n  NoValidPaletteException(const size_t size) : m_size(size) {}\n\n  const char *what() const throw();\n\nprivate:\n  const int m_size;\n};\n\n#endif // NOVALIDPALETTEEXCEPTION_H\n"
  },
  {
    "path": "src/Palette.cpp",
    "content": "/*\n * Palettes.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include <Palette.h>\n#include \"Logger.h\"\n#include \"NoValidPaletteException.h\"\n\n// system\n#include <iostream>\n#include <fstream>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Palette\");\n\nPalette::Palette()\n{\n\n}\n\n\nPalette::Palette(std::shared_ptr<DataChunk> rawPalette)\n{\n  load(rawPalette);\n}\n\nPalette::~Palette()\n{\n}\n\nvoid Palette::load(std::shared_ptr<DataChunk> rawPalette)\n{\n  if(rawPalette->getSize() == 256 * 4) // RGBx/WPE size type\n  {\n    for(unsigned int i = 0; i < rawPalette->getSize(); i += 4)\n    {\n      unsigned char red = rawPalette->at(i);\n      unsigned char green = rawPalette->at(i+1);\n      unsigned char blue = rawPalette->at(i+2);\n      // ignore the 4th component, as it is not used as alpha\n\n      Color rgb(red, green, blue);\n      at(i/4) = rgb;\n    }\n  }\n  else if(rawPalette->getSize() == 256 * 3) // RGB size type\n  {\n    for(unsigned int i = 0; i < rawPalette->getSize(); i += 3)\n    {\n      unsigned char red = rawPalette->at(i);\n      unsigned char green = rawPalette->at(i+1);\n      unsigned char blue = rawPalette->at(i+2);\n\n      Color rgb(red, green, blue);\n      at(i/3) = rgb;\n    }\n  }\n  else\n  {\n    throw NoValidPaletteException(rawPalette->getSize());\n  }\n}\n\nstd::shared_ptr<DataChunk> Palette::createDataChunk()\n{\n  std::shared_ptr<DataChunk> datachunk = make_shared<DataChunk>();\n\n  for(auto color_it = mColorPalette.begin(); color_it < mColorPalette.end(); color_it++)\n  {\n    Color &rgb = *color_it;\n    unsigned char red = rgb.getRed();\n    unsigned char green = rgb.getGreen();\n    unsigned char blue = rgb.getBlue();\n\n    datachunk->addData(&red, 1);\n    datachunk->addData(&green, 1);\n    datachunk->addData(&blue, 1);\n  }\n\n  return datachunk;\n}\n\nColor &Palette::at(unsigned int index)\n{\n  return mColorPalette.at(index);\n}\n"
  },
  {
    "path": "src/Palette.h",
    "content": "/*\n * Palettes.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PALETTE_H\n#define PALETTE_H\n\n// project\n#include \"Color.h\"\n#include \"Converter.h\"\n#include \"AbstractPalette.h\"\n\n// project\n#include <array>\n\n/**\n *\n */\nclass Palette : public AbstractPalette\n{\npublic:\n  Palette();\n\n  /**\n   * Create from a RGB or RGBx/WPE palette\n   */\n  Palette(std::shared_ptr<DataChunk> rawPalette);\n\n  virtual ~Palette();\n\n  /**\n   * Create a new DataChunk copy for (old) functions that need the data aligned in a big unsigned char*\n   * Pay attention of the std::shared_ptr nature:\n   *    If you directly call createDataChunk()->getDataPointer() without saving it before to a std::shared_ptr<DataChunk> it won't work!\n   */\n  std::shared_ptr<DataChunk> createDataChunk();\n\n  /**\n   * Property change of a color with r-value\n   */\n  Color &at(unsigned int index);\n\n  void load(std::shared_ptr<DataChunk> rawPalette);\n\nprivate:\n  std::array<Color, 256> mColorPalette;\n};\n\n#endif /* PALETTE_H */\n"
  },
  {
    "path": "src/Palette2D.cpp",
    "content": "/*\n * Palette2D.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Palette2D.h\"\n#include \"Logger.h\"\n#include \"NoValidPaletteException.h\"\n\n// system\n#include <fstream>\n#include <iostream>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Palette2D\");\n\nPalette2D::Palette2D(unsigned int size) :\n  mColorPalette2D(size)\n{\n\n}\n\nPalette2D::Palette2D(std::shared_ptr<DataChunk> rawPalette) :\n  mColorPalette2D(rawPalette->getSize()/256)\n{\n  /**\n   * For initial construction just check that the DataChunk is a multiple of 256*3 bytes\n   * which is an hint for a valid 2D palette.\n   */\n  if((rawPalette->getSize() % (256 * 3)))\n  {\n    throw NoValidPaletteException(rawPalette->getSize());\n  }\n\n  load(rawPalette);\n}\n\nPalette2D::~Palette2D()\n{\n\n}\n\nvoid Palette2D::load(std::shared_ptr<DataChunk> rawPalette)\n{\n  mColorPalette2D.clear();\n\n  unsigned int paletteSize = rawPalette->getSize() / (256*3);\n\n  for(unsigned int i = 0; i < paletteSize; i++)\n  {\n    shared_ptr<DataChunk> dc = make_shared<DataChunk>();\n\n    int start_read_pos = i * 256 *3;\n    int read_size = 256*3;\n    dc->addData(rawPalette->getDataPointer() + start_read_pos, read_size);\n\n    Palette pal(dc);\n\n    mColorPalette2D.push_back(pal);\n  }\n}\n\nstd::shared_ptr<DataChunk> Palette2D::createDataChunk()\n{\n  std::shared_ptr<DataChunk> datachunk = make_shared<DataChunk>();\n\n  for(Palette &pal : mColorPalette2D)\n  {\n    for(unsigned int i = 0; i < 256; i++)\n    {\n      unsigned char red = pal.at(i).getRed();\n      unsigned char green = pal.at(i).getGreen();\n      unsigned char blue = pal.at(i).getBlue();\n\n      datachunk->addData(&red, 1);\n      datachunk->addData(&green, 1);\n      datachunk->addData(&blue, 1);\n    }\n\n  }\n\n  return datachunk;\n}\n\nColor &Palette2D::at(unsigned int column, unsigned int row)\n{\n  auto &color_array = mColorPalette2D.at(row);\n  Color &color = color_array.at(column);\n\n  return color;\n}\n\nunsigned int Palette2D::getSize()\n{\n  return mColorPalette2D.size();\n}\n\n\n"
  },
  {
    "path": "src/Palette2D.h",
    "content": "/*\n * Palette2D.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PALETTE2D_H\n#define PALETTE2D_H\n\n// project\n#include \"Color.h\"\n#include \"Palette.h\"\n#include \"AbstractPalette.h\"\n\n// system\n#include <vector>\n#include <array>\n\nclass Palette2D  : public AbstractPalette\n{\npublic:\n  Palette2D(unsigned int size);\n\n  Palette2D(std::shared_ptr<DataChunk> rawPalette);\n\n  virtual ~Palette2D();\n\n  /**\n   * Create a new DataChunk copy for (old) functions that need the data aligned in a big unsigned char*\n   * Pay attention of the std::shared_ptr nature:\n   *    If you directly call createDataChunk()->getDataPointer() without saving it before to a std::shared_ptr<DataChunk> it won't work!\n   */\n  std::shared_ptr<DataChunk> createDataChunk();\n\n  /**\n   * Property change of a color with r-value\n   */\n  Color &at(unsigned int column, unsigned int row);\n\n  unsigned int getSize();\n\n  void load(std::shared_ptr<DataChunk> rawPalette);\n\nprivate:\n  std::vector<Palette> mColorPalette2D;\n};\n\n#endif /* PALETTE2D_H */\n"
  },
  {
    "path": "src/PaletteImage.cpp",
    "content": "/*\n * PaletteImage.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"PaletteImage.h\"\n\n// system\n#include <iostream>\n#include <math.h>\n\nusing namespace std;\n\nPaletteImage::PaletteImage(const DataChunk &datachunk, const Size &size) :\n  mData(datachunk.getDataPointer(), datachunk.getDataPointer()+datachunk.getSize()),\n  mSize(size)\n{\n\n}\n\nPaletteImage::PaletteImage(const Size &size) :\n  mData(size.getWidth() * size.getHeight(), 0),\n  mSize(size)\n{\n\n}\n\nPaletteImage::~PaletteImage()\n{\n\n}\n\nconst unsigned char* PaletteImage::getRawDataPointer() const\n{\n  return mData.data();\n}\n\nsize_t PaletteImage::positionToIndex(const Pos &pos) const\n{\n  size_t data_pos = 0;\n\n  // if pos is outside image return just 0 as fail safe\n  if((pos.getX() < mSize.getWidth()) || (pos.getY() < mSize.getHeight()) || (pos.getX() > 0) || (pos.getY() > 0))\n  {\n    data_pos = (pos.getY() * mSize.getWidth()) + pos.getX();\n  }\n\n  return data_pos;\n}\n\nconst Pos PaletteImage::indexToPosition(size_t index) const\n{\n  int y = 0;\n  int x = 0;\n\n  // if index is out of data size that return Pos(0, 0) as fail safe\n  if(index < mData.size())\n  {\n    y = index / mSize.getWidth();\n    x = index % mSize.getWidth();\n  }\n\n  return Pos(x, y);\n}\n\nconst Size PaletteImage::getSize() const\n{\n  return mSize;\n}\n\nunsigned char &PaletteImage::at(const Pos &pos)\n{\n  return at(positionToIndex(pos));\n}\n\nconst unsigned char &PaletteImage::at(const Pos &pos) const\n{\n  return at(positionToIndex(pos));\n}\n\nunsigned char &PaletteImage::at(size_t pos)\n{\n  return mData.at(pos);\n}\n\nconst unsigned char &PaletteImage::at(size_t pos) const\n{\n  return mData.at(pos);\n}\n\nvoid PaletteImage::fill(unsigned char color_index)\n{\n  for(unsigned int i = 0; i < mData.size(); i++)\n  {\n    mData.at(i) = color_index;\n  }\n}\n\nbool PaletteImage::operator== (const PaletteImage& image_cmp)\n{\n  // if the same object\n  if (this == &image_cmp)\n  {\n    return true;\n  }\n\n  // if the size isn't the same no content needs to be checked\n  if(image_cmp.getSize() != this->getSize())\n  {\n    return false;\n  }\n\n  // compare the content of the pixel data\n  if(image_cmp.mData == this->mData)\n  {\n    return true;\n  }\n\n  return false;\n}\n\n\n"
  },
  {
    "path": "src/PaletteImage.h",
    "content": "/*\n * PaletteImage.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PALETTEIMAGE_H\n#define PALETTEIMAGE_H\n\n// Project\n#include \"DataChunk.h\"\n#include \"Size.h\"\n#include \"Pos.h\"\n\n// System\n\n/**\n * A PaletteImage could hold a number of Integers of fixed size width*height that describe a Palette based image.\n * The Image itself needs always an associated Palette in one of the savers (e.g. PngExporter).\n */\nclass PaletteImage\n{\npublic:\n  /**\n   * Construct with specific size but zero data to fill byte by byte\n   * It allows random access to fill the elements with data as the internal vector is constructed at that size\n   */\n  PaletteImage(const Size &size);\n\n  /**\n   * Construct with specific size but fill in one chunk\n   */\n  PaletteImage(const DataChunk &datachunk, const Size &size);\n\n  virtual ~PaletteImage();\n\n  /**\n   * @return the internal std::vector<unsigned char> implementation. Handle carefully!!\n   */\n  virtual const unsigned char* getRawDataPointer() const;\n\n  virtual const Size getSize() const;\n\n  /**\n   * Get or set a pixel with palette index based on l-value or r-value (and provide a const variant)\n   * Just like a vector at() usage\n   */\n  virtual unsigned char &at(size_t pos);\n  virtual const unsigned char &at(size_t pos) const;\n\n  /**\n   * set or get a pixel based on l-value/r-value implementation (and provide a const variant)\n   */\n  virtual unsigned char &at(const Pos &pos);\n  virtual const unsigned char &at(const Pos &pos) const;\n\n  virtual const Pos indexToPosition(size_t index) const;\n\n  virtual size_t positionToIndex(const Pos &pos) const;\n\n  /**\n   * Fills the complete image with a specific index color from the Palette.\n   * This has no real use case in the Exporter just for easier testing the class.\n   */\n  virtual void fill(unsigned char color_index);\n\n  bool operator== (const PaletteImage& image_cmp);\n\nprivate:\n  std::vector<unsigned char> mData;\n  Size mSize;\n};\n\n//bool operator == (const PaletteImage& image1, const PaletteImage& image2);\n\n#endif /* PALETTEIMAGE_H */\n"
  },
  {
    "path": "src/Panel.cpp",
    "content": "/*\n * Panel.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"Panel.h\"\n#include \"FileUtil.h\"\n#include \"Preferences.h\"\n\n// System\n#include <png.h>\n#include <zlib.h>\n\nPanel::Panel()\n{\n\n}\n\nPanel::~Panel()\n{\n\n}\n\n/**\n * TODO: get an understanding why the former developer decided to generate images that high sophisticated\n */\nunsigned char *Panel::CreatePanel(int width, int height)\n{\n  unsigned char *buf;\n  int i, j;\n\n  buf = (unsigned char *) malloc(width * height * 4);\n  memset(buf, 0, width * height * 4);\n\n#define pixel2(i, j, r, g, b, a) \\\n\tbuf[(j) * width * 4 + (i) * 4 + 0] = r; \\\n\tbuf[(j) * width * 4 + (i) * 4 + 1] = g; \\\n\tbuf[(j) * width * 4 + (i) * 4 + 2] = b; \\\n\tbuf[(j) * width * 4 + (i) * 4 + 3] = a;\n\n#define pixel(i, j) \\\n\tpixel2((i), (j), 0x0, 0x8, 0x40, 0xff)\n\n  for (j = 1; j < height - 1; ++j)\n  {\n    for (i = 1; i < width - 1; ++i)\n    {\n      pixel2(i, j, 0x0, 0x8, 0x40, 0x80);\n    }\n  }\n  for (i = 3; i < width - 3; ++i)\n  {\n    pixel(i, 0);\n    pixel(i, height - 1);\n  }\n  for (i = 3; i < height - 3; ++i)\n  {\n    pixel(0, i);\n    pixel(width - 1, i);\n  }\n  // top left\n  pixel(1, 1);\n  pixel(2, 1);\n  pixel(1, 2);\n  // top right\n  pixel(width - 3, 1);\n  pixel(width - 2, 1);\n  pixel(width - 2, 2);\n  // bottom left\n  pixel(1, height - 3);\n  pixel(1, height - 2);\n  pixel(2, height - 2);\n  // bottom right\n  pixel(width - 3, height - 2);\n  pixel(width - 2, height - 2);\n  pixel(width - 2, height - 3);\n\n#undef pixel\n#undef pixel2\n\n  return buf;\n}\n\nint Panel::save(int width, int height)\n{\n  FILE *fp;\n  png_structp png_ptr;\n  png_infop info_ptr;\n  unsigned char **lines;\n  int i;\n  char name[256];\n  unsigned char *buf;\n\n  Preferences &preferences = Preferences::getInstance();\n  sprintf(name, \"%s/graphics/ui/panels/%dx%d.png\",\n          preferences.getDestDir().c_str(), width, height);\n  CheckPath(name);\n\n  if (!(fp = fopen(name, \"wb\")))\n  {\n    fprintf(stderr, \"%s:\", name);\n    perror(\"Can't open file\");\n    return 1;\n  }\n\n  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n  if (!png_ptr)\n  {\n    fclose(fp);\n    return 1;\n  }\n  info_ptr = png_create_info_struct(png_ptr);\n  if (!info_ptr)\n  {\n    png_destroy_write_struct(&png_ptr, NULL);\n    fclose(fp);\n    return 1;\n  }\n\n  if (setjmp(png_jmpbuf(png_ptr)))\n  {\n    // FIXME: must free buffers!!\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n    fclose(fp);\n    return 1;\n  }\n  png_init_io(png_ptr, fp);\n\n  // zlib parameters\n  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);\n\n  // prepare the file information\n  png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0,\n               PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n\n  buf = CreatePanel(width, height);\n\n  // write the file header information\n  png_write_info(png_ptr, info_ptr);  // write the file header information\n\n  // set transformation\n\n  // prepare image\n  lines = (unsigned char **) malloc(height * sizeof(*lines));\n  if (!lines)\n  {\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n    fclose(fp);\n    free(buf);\n    return 1;\n  }\n\n  for (i = 0; i < height; ++i)\n  {\n    lines[i] = buf + i * width * 4;\n  }\n\n  png_write_image(png_ptr, lines);\n  png_write_end(png_ptr, info_ptr);\n\n  png_destroy_write_struct(&png_ptr, &info_ptr);\n  fclose(fp);\n\n  free(lines);\n  free(buf);\n\n  return 0;\n}\n"
  },
  {
    "path": "src/Panel.h",
    "content": "/*\n * Panel.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PANEL_H_\n#define PANEL_H_\n\nclass Panel\n{\npublic:\n  Panel();\n  virtual ~Panel();\n\n  int save(int width, int height);\n\nprivate:\n  unsigned char* CreatePanel(int width, int height);\n};\n\n#endif /* PANEL_H_ */\n"
  },
  {
    "path": "src/Pcx.cpp",
    "content": "/*\n * Pcx.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include <PngExporter.h>\n#include \"endian.h\"\n#include \"Pcx.h\"\n#include \"Storm.h\"\n#include \"Hurricane.h\"\n#include \"Logger.h\"\n\n// System\n#include <stdlib.h>\n#include <string.h>\n#include <iostream>\n#include <fstream>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Pcx\");\n\nPcx::Pcx(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane), rawImage(0)\n{\n}\n\nPcx::Pcx(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile) :\n  Converter(hurricane), rawImage(0)\n{\n  load(arcfile);\n}\n\nPcx::~Pcx()\n{\n  free(rawImage);\n}\n\nbool Pcx::load(const std::string &arcfile)\n{\n  bool result = true;\n\n  mRawData = mHurricane->extractDataChunk(arcfile);\n  if (mRawData)\n  {\n    free(rawImage);\n    extractHeader();\n    extractImage();\n\n    LOG4CXX_TRACE(logger, \"load(): \" + arcfile);\n  }\n  else\n  {\n    result = false;\n  }\n\n  return result;\n}\n\nbool Pcx::savePNG(Storage storage)\n{\n  bool result = true;\n\n  if (mRawData)\n  {\n    PngExporter::saveRGB(storage.getFullPath(), *mPaletteImage, *mPalette, 0);\n  }\n  else\n  {\n    result = false;\n  }\n\n  return result;\n}\n\nstd::shared_ptr<Palette> Pcx::getPalette()\n{\n  return make_shared<Palette>(*mPalette);\n}\n\nSize Pcx::getSize()\n{\n  Size imageSize;\n\n  if(mPaletteImage)\n  {\n    imageSize = mPaletteImage->getSize();\n  }\n\n  return imageSize;\n}\n\nstd::shared_ptr<Palette> Pcx::mapIndexPalette(int length, int start, int index)\n{\n  std::shared_ptr<Palette> palette(mPalette);\n\n  if (mPaletteImage && palette)\n  {\n    for (int i = 0; i < length; i++)\n    {\n      int rel_index = i + (index * length);\n      int start_pal_dest = start + i;\n\n      unsigned char color_index = mPaletteImage->at(rel_index);\n\n      Color &image_color = mPalette->at(color_index);\n      palette->at(start_pal_dest) = image_color;\n    }\n  }\n\n  return palette;\n}\n\nstd::shared_ptr<Palette2D> Pcx::map2DPalette()\n{\n  std::shared_ptr<Palette2D> palette2D;\n\n  if (mPaletteImage && mPalette)\n  {\n    // check magic size of the special 2D palette format\n    if (mPaletteImage->getSize().getWidth() == 256)\n    {\n      palette2D = make_shared<Palette2D>(mPaletteImage->getSize().getHeight());\n\n      for (int x = 0; x < mPaletteImage->getSize().getWidth()-1; x++)\n      {\n        for (int y = 0; y < mPaletteImage->getSize().getHeight()-1; y++)\n        {\n          // FIXME: there was a bug in getPalettePixel() that y was decremented 1. After fixing it the output was ugly\n          // now I substract here y-1 before and now alpha graphics (e.g. fire) look fine. I've to check the algorithm later again\n          int y_mod = (y > 0) ? (y-1) : 0;\n\n          unsigned char color_index = mPaletteImage->at(Pos(x, y_mod));\n\n          if(color_index != 255)\n          {\n            Color image_color = mPalette->at(color_index);\n\n            palette2D->at(x, y) = image_color;\n          }\n          else\n          {\n            Color trans_color(0, 0, 0);\n            palette2D->at(x, y) = trans_color;\n          }\n        }\n      }\n    }\n  }\n\n  return palette2D;\n}\n\nvoid Pcx::extractHeader()\n{\n  if (mRawData)\n  {\n    struct PCXheader pcxh;\n\n    memcpy(&pcxh, mRawData->getDataPointer(), sizeof(struct PCXheader));\n    pcxh.Xmin = ConvertLE16(pcxh.Xmin);\n    pcxh.Ymin = ConvertLE16(pcxh.Ymin);\n    pcxh.Xmax = ConvertLE16(pcxh.Xmax);\n    pcxh.Ymax = ConvertLE16(pcxh.Ymax);\n    pcxh.BytesPerLine = ConvertLE16(pcxh.BytesPerLine);\n\n    int width = pcxh.Xmax - pcxh.Xmin + 1;\n    int height = pcxh.Ymax - pcxh.Ymin + 1;\n\n    mPaletteImage = make_shared<PaletteImage>(Size(width, height));\n  }\n}\n\nvoid Pcx::extractImage()\n{\n  int y;\n  int count;\n  unsigned char *dest = NULL;\n  unsigned char ch = 0;\n  unsigned char *imageParserPos = nullptr;\n  size_t pos = 0;\n\n  if (mRawData)\n  {\n    rawImage = (unsigned char *) malloc(mPaletteImage->getSize().getWidth() * mPaletteImage->getSize().getHeight());\n    imageParserPos = mRawData->getDataPointer() + sizeof(struct PCXheader);\n\n    for (y = 0; y < mPaletteImage->getSize().getHeight(); ++y)\n    {\n      count = 0;\n      dest = rawImage + y * mPaletteImage->getSize().getWidth();\n      for (int i = 0; i < mPaletteImage->getSize().getWidth(); ++i)\n      {\n        if (!count)\n        {\n          ch = *imageParserPos++;\n          if ((ch & 0xc0) == 0xc0)\n          {\n            count = ch & 0x3f;\n            ch = *imageParserPos++;\n          }\n          else\n          {\n            count = 1;\n          }\n        }\n        dest[i] = ch;\n        mPaletteImage->at(pos) = ch;\n        pos++;\n        --count;\n      }\n    }\n\n    // extract palette =>\n\n    mPalette = make_shared<Palette>();\n\n    do\n    {\n      ch = *imageParserPos++;\n    }\n    while (ch != 0x0c);   // search the 'magic ID' that shows the start of RGB information next\n\n    // copy RGB information to destination\n    for (int i = 0; i < RGB_SIZE; i += 3)\n    {\n      unsigned char red = *imageParserPos++;\n      unsigned char green = *imageParserPos++;\n      unsigned char blue = *imageParserPos++;\n\n      Color rgb(red, green, blue);\n\n      mPalette->at(i/3) = rgb;\n    }\n\n  }\n}\n\n"
  },
  {
    "path": "src/Pcx.h",
    "content": "/*\n * Pcx.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PCX_H\n#define PCX_H\n\n// Project\n#include \"Converter.h\"\n#include \"Palette.h\"\n#include \"Storage.h\"\n#include \"PaletteImage.h\"\n#include \"Palette2D.h\"\n\nclass Pcx : public Converter\n{\npublic:\n  Pcx(std::shared_ptr<Hurricane> hurricane);\n  Pcx(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile);\n  virtual ~Pcx();\n\n  bool load(const std::string &arcfile);\n\n  /**\n   *  Convert a PCX graphic to PNG format.\n   *  The PCX files is always saved with the original unmapped palette as mapping is\n   *  only relevant for GRP colors.\n   *\n   *  @param storage where to save the PNG image\n   */\n  bool savePNG(Storage storage);\n\n  /**\n   *\n   * @return get a copy of the unmodified original pcx palette information\n   */\n  std::shared_ptr<Palette> getPalette();\n\n  /**\n   * Map palette colors from one place in the image to a position in the color palette\n   *\n   * @param length the length of one color index\n   * @param start where to place the copy in the palette position\n   * @param index the color index\n   *\n   * @return a new created Palette with the applied mapping\n   */\n  std::shared_ptr<Palette> mapIndexPalette(int length, int start, int index);\n\n  /**\n   * * @return a new created Palette2D with the applied mapping\n   */\n  std::shared_ptr<Palette2D> map2DPalette();\n\n  Size getSize();\n\nprivate:\n  struct PCXheader\n  {\n    unsigned char Manufacturer;\n    unsigned char Version;\n    unsigned char Encoding;\n    unsigned char BitsPerPixel;\n    short Xmin, Ymin, Xmax, Ymax;\n    short HDpi, VDpi;\n    unsigned char Colormap[48];\n    unsigned char Reserved;\n    unsigned char NPlanes;\n    short BytesPerLine;\n    short PaletteInfo;\n    short HscreenSize;\n    short VscreenSize;\n    unsigned char Filler[54];\n  };\n\n  void extractHeader();\n\n  /**\n   *  Convert 8 bit pcx file to raw image\n   */\n  void extractImage();\n\n  std::shared_ptr<Palette> mPalette;\n  std::shared_ptr<DataChunk> mRawData;\n  std::shared_ptr<PaletteImage> mPaletteImage;\n  unsigned char *rawImage;\n  const int RGB_BYTE_SIZE = 3;\n  const int RGB_SIZE = 256 * RGB_BYTE_SIZE;\n};\n\n#endif /* PCX_H */\n"
  },
  {
    "path": "src/PngExporter.cpp",
    "content": "/*\n * Png.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"FileUtil.h\"\n#include \"PngExporter.h\"\n#include \"Logger.h\"\n\n// System\n#include <cstring>\n#include <stdlib.h>\n#include <zlib.h>\n#include <iostream>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.PngExporter\");\n\nPngExporter::PngExporter()\n{\n}\n\nPngExporter::~PngExporter()\n{\n\n}\n\nbool PngExporter::save(const std::string &name, PaletteImage &palImage,\n        std::shared_ptr<AbstractPalette> abs_palette, int transparent, bool rgba)\n{\n  bool result = false;\n\n\n  std::shared_ptr<Palette> palette = dynamic_pointer_cast<Palette>(abs_palette);\n  if(palette)\n  {\n    if(rgba)\n    {\n      result = PngExporter::saveRGBA(name, palImage, *palette, transparent);\n    }\n    else\n    {\n      result = PngExporter::saveRGB(name, palImage, *palette, transparent);\n    }\n  }\n  else\n  {\n    std::shared_ptr<Palette2D> palette2D = dynamic_pointer_cast<Palette2D>(abs_palette);\n    if(palette2D)\n    {\n      result = PngExporter::saveRGBA(name, palImage, *palette2D, transparent);\n    }\n  }\n\n  return result;\n}\n\nbool PngExporter::saveRGB(const std::string &name, PaletteImage &palImage, Palette &palette, int transparent)\n{\n  FILE *fp;\n  png_structp png_ptr;\n  png_infop info_ptr;\n  unsigned char **lines;\n  int i;\n\n  std::shared_ptr<DataChunk> palData = palette.createDataChunk();\n  unsigned char *pal = palData->getDataPointer();\n\n  const unsigned char *image = palImage.getRawDataPointer();\n\n  CheckPath(name);\n\n  if (!(fp = fopen(name.c_str(), \"wb\")))\n  {\n    printf(\"%s:\", name.c_str());\n    perror(\"Can't open file\");\n    fflush(stdout);\n    fflush(stderr);\n    return false;\n  }\n\n  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n  if (!png_ptr)\n  {\n    fclose(fp);\n    return false;\n  }\n  info_ptr = png_create_info_struct(png_ptr);\n  if (!info_ptr)\n  {\n    png_destroy_write_struct(&png_ptr, NULL);\n    fclose(fp);\n    return false;\n  }\n\n  if (setjmp(png_jmpbuf(png_ptr)))\n  {\n    free(lines);\n\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n    fclose(fp);\n    return false;\n  }\n  png_init_io(png_ptr, fp);\n\n  // zlib parameters\n  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);\n\n  // prepare the file information\n  png_set_IHDR(png_ptr, info_ptr, palImage.getSize().getWidth(), palImage.getSize().getHeight(), 8, PNG_COLOR_TYPE_PALETTE,\n               0, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n  png_set_invalid(png_ptr, info_ptr, PNG_INFO_PLTE);\n  png_set_PLTE(png_ptr, info_ptr, (png_colorp) pal, 256);\n\n  if (transparent != -1)\n  {\n    png_byte trans[256];\n\n    memset(trans, 0xFF, sizeof(trans));\n    trans[transparent] = 0x0;\n    png_set_tRNS(png_ptr, info_ptr, trans, 256, 0);\n  }\n\n  // write the file header information\n  png_write_info(png_ptr, info_ptr);\n\n  // prepare image\n  lines = (unsigned char **) malloc(palImage.getSize().getHeight() * sizeof(*lines));\n  if (!lines)\n  {\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n    fclose(fp);\n    return false;\n  }\n\n  for (i = 0; i < palImage.getSize().getHeight(); ++i)\n  {\n    const unsigned char *line = image + i * palImage.getSize().getWidth();\n    lines[i] = (unsigned char*) line;\n  }\n\n  png_write_image(png_ptr, lines);\n  png_write_end(png_ptr, info_ptr);\n\n  png_destroy_write_struct(&png_ptr, &info_ptr);\n  fclose(fp);\n\n  free(lines);\n\n  return true;\n}\n\n\nbool PngExporter::saveRGBA(const std::string &name, PaletteImage &palImage, Palette &palette, int transparent)\n{\n  FILE *fp;\n  png_structp png_ptr;\n  png_infop info_ptr;\n  png_bytep *row_pointers = NULL;\n  const int RGBA_BYTE_SIZE = 4;\n\n  CheckPath(name);\n\n  if (!(fp = fopen(name.c_str(), \"wb\")))\n  {\n    printf(\"%s:\", name.c_str());\n    perror(\"Can't open file\");\n    fflush(stdout);\n    fflush(stderr);\n    return false;\n  }\n\n  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n  if (!png_ptr)\n  {\n    fclose(fp);\n    return false;\n  }\n  info_ptr = png_create_info_struct(png_ptr);\n  if (!info_ptr)\n  {\n    png_destroy_write_struct(&png_ptr, NULL);\n    fclose(fp);\n    return false;\n  }\n\n  if (setjmp(png_jmpbuf(png_ptr)))\n  {\n    free(row_pointers);\n    row_pointers = NULL;\n\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n    fclose(fp);\n    return false;\n  }\n  png_init_io(png_ptr, fp);\n\n  // zlib parameters\n  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);\n\n  // prepare the file information\n  png_set_IHDR(png_ptr, info_ptr, palImage.getSize().getWidth(), palImage.getSize().getHeight(), 8, PNG_COLOR_TYPE_RGBA, 0, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n\n  // write the file header information\n  png_write_info(png_ptr, info_ptr);\n\n  row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * palImage.getSize().getHeight());\n\n  for (int h_pos = 0; h_pos < palImage.getSize().getHeight(); ++h_pos)\n  {\n    row_pointers[h_pos] = (unsigned char *) malloc(palImage.getSize().getWidth() * RGBA_BYTE_SIZE);\n\n    for (int w_pos = 0; w_pos < palImage.getSize().getWidth(); w_pos++)\n    {\n      unsigned char pal_pos = palImage.at(Pos(w_pos, h_pos));\n\n      Color color;\n\n      if (pal_pos != transparent)\n      {\n        color = palette.at(pal_pos);\n        color.setAlpha(255);\n      }\n\n      row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 0] = color.getRed();\n      row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 1] = color.getGreen();\n      row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 2] = color.getBlue();\n      row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 3] = color.getAlpha();\n    }\n\n  }\n\n  png_set_rows(png_ptr, info_ptr, row_pointers);\n  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);\n\n  png_destroy_write_struct(&png_ptr, &info_ptr);\n  fclose(fp);\n\n  if (NULL != row_pointers)\n  {\n    for (int h_pos = 0; h_pos < palImage.getSize().getHeight(); ++h_pos)\n    {\n      free(row_pointers[h_pos]);\n    }\n\n    free(row_pointers);\n    row_pointers = NULL;\n  }\n\n  return true;\n}\n\nbool PngExporter::saveRGBA(const std::string &name, PaletteImage &palImage, Palette2D &palette2d, int transparent)\n{\n  FILE *fp;\n  png_structp png_ptr;\n  png_infop info_ptr;\n  png_bytep *row_pointers = NULL;\n  const int RGBA_BYTE_SIZE = 4;\n  bool result = true;\n\n  CheckPath(name);\n\n  if (!(fp = fopen(name.c_str(), \"wb\")))\n  {\n    printf(\"%s:\", name.c_str());\n    perror(\"Can't open file\");\n    fflush(stdout);\n    fflush(stderr);\n    return false;\n  }\n\n  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n  if (!png_ptr)\n  {\n    fclose(fp);\n    return false;\n  }\n  info_ptr = png_create_info_struct(png_ptr);\n  if (!info_ptr)\n  {\n    png_destroy_write_struct(&png_ptr, NULL);\n    fclose(fp);\n    return false;\n  }\n\n  if (setjmp(png_jmpbuf(png_ptr)))\n  {\n    free(row_pointers);\n    row_pointers = NULL;\n\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n    fclose(fp);\n    return 1;\n  }\n  png_init_io(png_ptr, fp);\n\n  // zlib parameters\n  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);\n\n  // prepare the file information\n  png_set_IHDR(png_ptr, info_ptr, palImage.getSize().getWidth(), palImage.getSize().getHeight(), 8, PNG_COLOR_TYPE_RGBA, 0, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n\n  // write the file header information\n  png_write_info(png_ptr, info_ptr);\n\n  row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * palImage.getSize().getHeight());\n\n  /*\n   * Count how many lines are allocated in case of Exception cleanup later!\n   * This is only needed for Palette2D case as this one has dynamic size.\n   * If you export an GRP with the wrong Palette2D - Bang!\n   */\n  int h_pos_allocated = 0;\n\n  try\n  {\n    for (int h_pos = 0; h_pos < palImage.getSize().getHeight(); ++h_pos)\n    {\n      row_pointers[h_pos] = (unsigned char *) malloc(palImage.getSize().getWidth() * RGBA_BYTE_SIZE);\n      h_pos_allocated = h_pos;\n\n      for (int w_pos = 0; w_pos < palImage.getSize().getWidth(); w_pos++)\n      {\n        unsigned char pal_pos = palImage.at(Pos(w_pos, h_pos));\n\n        unsigned char pal_beneath = 0;// back palette id #0 (known in the palette format)\n        Color reference_beneath_color (0, 0, 0); // back palette id #0 (known in the palette format)\n\n        Color color_result;\n\n        if (pal_pos != transparent)\n        {\n          const Color &color_orig = palette2d.at(pal_beneath, pal_pos-1);\n\n          color_result = color_orig.blendAgainstReference(reference_beneath_color);\n        }\n\n        row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 0] = color_result.getRed();\n        row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 1] = color_result.getGreen();\n        row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 2] = color_result.getBlue();\n        row_pointers[h_pos][w_pos * RGBA_BYTE_SIZE + 3] = color_result.getAlpha();\n      }\n\n    }\n\n    png_set_rows(png_ptr, info_ptr, row_pointers);\n    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);\n  }\n  catch(std::out_of_range &ex)\n  {\n    LOG4CXX_ERROR(logger, ex.what());\n    LOG4CXX_ERROR(logger, \"This image couldn't be saved because index out of range error. Very often this happens because wrong palette is used for: \" + name);\n    result = false;\n  }\n\n  png_destroy_write_struct(&png_ptr, &info_ptr);\n  fclose(fp);\n\n  if (row_pointers != NULL)\n  {\n    for (int h_pos = 0; h_pos <= h_pos_allocated; ++h_pos)\n    {\n      free(row_pointers[h_pos]);\n    }\n\n    free(row_pointers);\n    row_pointers = NULL;\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "src/PngExporter.h",
    "content": "/*\n * Png.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PNG_H_\n#define PNG_H_\n\n// project\n#include \"PaletteImage.h\"\n#include \"Palette.h\"\n#include \"Palette2D.h\"\n\n// system\n#include <png.h>\n#include <string>\n\nclass PngExporter\n{\npublic:\n  PngExporter();\n  virtual ~PngExporter();\n\n  //TODO: un-static this in the design!\n\n  static bool save(const std::string &name, PaletteImage &palImage,\n        std::shared_ptr<AbstractPalette> abs_palette, int transparent, bool rgba = false);\n\n  /**\n   **  Save a png file with 8-bit colormap palette\n   **\n   **  @param name         File name\n   **  @param image        Graphic data\n   **  @param w            Graphic width\n   **  @param h            Graphic height\n   **  @param pal          Palette (256*3 colors/bytes)\n   **  @param transparent  Image uses transparency\n   */\n  static bool saveRGB(const std::string &name, PaletteImage &palImage,\n      Palette &palette, int transparent);\n\n  /**\n   **  Save a png file as 8-bit/color RGBA\n   **  Color information is collected from palette and converted to pixel RGBA information\n   **\n   **  @param name         File name\n   **  @param image        Graphic data\n   **  @param w            Graphic width\n   **  @param h            Graphic height\n   **  @param pal          Palette (256*3 colors/bytes)\n   **  @param transparent  Image uses transparency from from specific palette index\n   */\n  static bool saveRGBA(const std::string &name, PaletteImage &palImageh,\n      Palette &palette, int transparent);\n\n  static bool saveRGBA(const std::string &name, PaletteImage &palImageh,\n      Palette2D &palette2d, int transparent);\n\n};\n\n#endif /* PNG_H_ */\n"
  },
  {
    "path": "src/PortraitsConverter.cpp",
    "content": "/*\n * PortraitsConverter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"PortraitsConverter.h\"\n#include \"dat/Portrait.h\"\n#include \"Smacker.h\"\n#include \"StringUtil.h\"\n#include \"Preferences.h\"\n#include \"FileUtil.h\"\n#include \"platform.h\"\n#include \"luagen.h\"\n#include \"Logger.h\"\n\n// system\n#include <iostream>\n#include <fstream>\n#include <set>\n\nusing namespace std;\nusing namespace dat;\n\nstatic Logger mLogger = Logger(\"startool.dat.PortraitsConverter\");\n\nPortraitsConverter::PortraitsConverter(std::shared_ptr<Hurricane> hurricane, DataHub &datahub) :\n    Converter(hurricane),\n    mDatahub(datahub)\n{\n\n}\n\nPortraitsConverter::~PortraitsConverter()\n{\n\n}\n\nbool PortraitsConverter::convert()\n{\n  bool result = true;\n\n  Preferences &preferences = Preferences::getInstance();\n\n  Storage videos;\n  videos.setDataPath(preferences.getDestDir());\n  videos.setDataType(\"videos/portrait\");\n\n  Storage luagen;\n  luagen.setDataPath(preferences.getDestDir());\n  luagen.setDataType(\"luagen/portrait\");\n  CheckPath(luagen.getFullPath());\n\n  ofstream lua_include;\n  lua_include.open (luagen(\"luagen-portrait.lua\").getFullPath());\n  string lua_include_str;\n\n  for(unsigned int i = 0; i < mDatahub.portdata->video_idle()->size(); i++)\n  {\n    Portrait portrait(mDatahub, i);\n\n    string portrait_arcfile_idle(portrait.video_idle_tbl().name1());\n    string portrait_arcfile_talking(portrait.video_talking_tbl().name1());\n\n    string portrait_idle_id(portrait.getIDString(portrait_arcfile_idle));\n    string portrait_talking_id(portrait.getIDString(portrait_arcfile_talking));\n\n    // just to ensure the idle / talking consistency in the database\n    // this should also be the case otherwise something is broken\n    if(portrait_idle_id == portrait_talking_id)\n    {\n      Storage lua_file_store(luagen(\"portrait-\" + portrait_idle_id + \".lua\"));\n      ofstream lua_file;\n      lua_file.open (lua_file_store.getFullPath());\n\n      vector<string> portrait_list;\n\n      convertMngPortraits(portrait_arcfile_idle, portrait_list);\n      portrait_list.push_back(\"talking\"); // the stratagus API needs this as separator\n      convertMngPortraits(portrait_arcfile_talking, portrait_list);\n\n      string portraits_table = lg::assign(\"portrait_\" + portrait_idle_id ,lg::table(lg::paramsQuote(portrait_list)));\n\n      lua_include_str += lg::line(lg::function(\"Load\", lg::quote(lua_file_store.getRelativePath())));\n\n      lua_file << portraits_table;\n      lua_file.close();\n    }\n    else\n    {\n      LOG4CXX_FATAL(mLogger, \"portrait_idle_id != portrait_talking_id\");\n    }\n  }\n\n\n  lua_include << lua_include_str;\n  lua_include.close();\n\n  return result;\n}\n\nbool PortraitsConverter::convertMngPortraits(const std::string &arcfile, std::vector<std::string> &portrait_list)\n{\n  bool smk_available = true;\n  unsigned int smk_num = 0;\n\n  Preferences &preferences = Preferences::getInstance();\n\n  Storage videos;\n  videos.setDataPath(preferences.getDestDir());\n  videos.setDataType(\"videos/portrait\");\n\n  while(smk_available && smk_num <= 3)\n  {\n    Smacker video(mHurricane);\n\n    // build the name of the specific #smk file\n    string smk_arcfile(\"portrait\\\\\" + arcfile + to_string(smk_num) + \".smk\");\n\n    // target place where to store the file\n    string target_basename(arcfile + to_string(smk_num));\n    replaceString(\"\\\\\", \"/\", target_basename);\n    target_basename = to_lower(target_basename);\n\n    cout << \"Try export (last one may fail if less then three) \" << smk_arcfile << \" to \" << target_basename;\n\n    smk_available = video.convertMNG(smk_arcfile, videos(target_basename));\n\n    if(smk_available)\n    {\n      portrait_list.push_back(videos.getDataType() + \"/\" + target_basename + \".mng\");\n    }\n\n    printf(\"...%s\\n\", smk_available ? \"ok\" : \"nok\");\n    smk_num++;\n  }\n\n  return true;\n}\n"
  },
  {
    "path": "src/PortraitsConverter.h",
    "content": "/*\n * PortraitsConverter.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PORTRAITSCONVERTER_H\n#define PORTRAITSCONVERTER_H\n\n// project\n#include \"dat/DataHub.h\"\n#include \"Storage.h\"\n\n// system\n\nclass PortraitsConverter : public Converter\n{\npublic:\n  PortraitsConverter(std::shared_ptr<Hurricane> hurricane, dat::DataHub &datahub);\n  virtual ~PortraitsConverter();\n\n  bool convert();\n\nprivate:\n  /**\n   * check all smk files for a portrait, export them, convert to mng and save the raw name\n   * @param portrait_list The function fills this vector to later export to LUA\n   */\n  bool convertMngPortraits(const std::string &arcfile, std::vector<std::string> &portrait_list);\n\n\n  // if used more often put into a utils namespace...\n  /*template<typename T>\n  void removeDuplicates(std::vector<T>& vec)\n  {\n      std::sort(vec.begin(), vec.end());\n      vec.erase(std::unique(vec.begin(), vec.end()), vec.end());\n  }*/\n\n  dat::DataHub &mDatahub;\n};\n\n#endif /* PORTRAITSCONVERTER_H */\n"
  },
  {
    "path": "src/Pos.h",
    "content": "#ifndef POS_H\n#define POS_H\n\n#include <stdint.h>\n\n/*!\n * Trivial class which stores a Position in integer notation.\n */\n\nclass Pos\n{\npublic:\n  Pos ();\n  Pos (int inX, int inY);\n  Pos (const Pos& inPos);\n\n  ~Pos () {}\n\n  Pos& operator= (const Pos& inRHS);\n\n  bool operator== (const Pos& inPos) const;\n\n  bool isEmpty() const { return ((mX == 0) && (mY == 0));}\n\n  int getX ()  const {return mX;}\n  int getY() const {return mY;}\n\n  void setX(int x) {mX = x;}\n  void setY(int y) {mY = y;}\n\nprivate:\n  int mX, mY;\n};\n\ninline Pos::Pos ()\n    : mX (0), mY (0)\n{\n}\n\ninline Pos::Pos(int inX, int inY)\n    : mX (inX), mY(inY)\n{\n}\n\ninline Pos::Pos(const Pos& inPos)\n    : mX (inPos.mX), mY(inPos.mY)\n{\n}\n\ninline Pos& Pos::operator= (const Pos& inRHS)\n{\n  mX  = inRHS.mX;\n  mY = inRHS.mY;\n  return *this;\n}\n\ninline bool Pos::operator== (const Pos& inPos) const\n{\n  if (this == &inPos)  // The same object?\n    return true;\n\n  return (mX  == inPos.mX &&\n          mY == inPos.mY);\n}\n\n#endif // POS_H\n"
  },
  {
    "path": "src/Preferences.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n/* STD */\n#include <iostream>\n\n#include \"Preferences.h\"\n\nusing namespace std;\n\nPreferences &Preferences::getInstance()\n{\n  static Preferences instance;\n  return instance;\n}\n\nvoid Preferences::init()\n{\n  mVideoExtraction = false;\n  mDestDir = \"data\";\n}\n\nvoid Preferences::setVideoExtraction(bool video)\n{\n  mVideoExtraction = video;\n}\n\nbool Preferences::getVideoExtraction()\n{\n  return mVideoExtraction;\n}\n\nvoid Preferences::setSoundExtraction(bool sound)\n{\n  mSoundExtraction = sound;\n}\n\nbool Preferences::getSoundExtraction()\n{\n  return mSoundExtraction;\n}\n\nvoid Preferences::setArchiveDir(const std::string &dir)\n{\n  mArchiveDir = dir;\n}\n\nconst std::string Preferences::getArchiveDir()\n{\n  return mArchiveDir;\n}\n\nvoid Preferences::setDestDir(const std::string &dir)\n{\n  mDestDir = dir;\n}\n\nconst std::string Preferences::getDestDir()\n{\n  return mDestDir;\n}\n"
  },
  {
    "path": "src/Preferences.h",
    "content": "#ifndef PREFERENCES_H\n#define PREFERENCES_H\n\n#include <string>\n\n/**\n **\t\tPath to the unit graphics. (default=$DIR/graphics)\n */\n#define GRAPHICS_PATH\t\t\"graphics\"\n\nclass Preferences\n{\npublic: // Singleton\n  static Preferences& getInstance();\n\nprivate: // Singleton\n  Preferences()\n  {\n  }\n  ; // @suppress(\"Class members should be properly initialized\")\n  Preferences(const Preferences&);\n  //Preferences(Preferences&);\n  virtual ~Preferences()\n  {\n  }\n  //void operator = (const Preferences&);\n\npublic:\n  void init();\n\n  void setVideoExtraction(bool video);\n  bool getVideoExtraction();\n\n  void setSoundExtraction(bool sound);\n  bool getSoundExtraction();\n\n\n  void setArchiveDir(const std::string &dir);\n  const std::string getArchiveDir();\n\n  /**\n   **\t\tDestination directory of the data\n   */\n  void setDestDir(const std::string &dir);\n  const std::string getDestDir();\n\nprivate:\n  bool mVideoExtraction;\n  bool mSoundExtraction;\n  std::string mArchiveDir;\n  std::string mDestDir;\n};\n\n#endif // PREFERENCES_H\n"
  },
  {
    "path": "src/Scm.cpp",
    "content": "//       _________ __                 __\n//      /   _____//  |_____________ _/  |______     ____  __ __  ______\n//      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n//      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ |\n//     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n//             \\/                  \\/          \\//_____/            \\/\n//  ______________________                           ______________________\n//                        T H E   W A R   B E G I N S\n//         Stratagus - A free fantasy real time strategy game engine\n//\n/**@name Scm.cpp - The scm. */\n//\n//      (c) Copyright 2002-2007 by Jimmy Salmon\n//\n//      This program is free software; you can redistribute it and/or modify\n//      it under the terms of the GNU General Public License as published by\n//      the Free Software Foundation; version 2 dated June, 1991.\n//\n//      This program is distributed in the hope that it will be useful,\n//      but WITHOUT ANY WARRANTY; without even the implied warranty of\n//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//      GNU General Public License for more details.\n//\n//      You should have received a copy of the GNU General Public License\n//      along with this program; if not, write to the Free Software\n//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n//      02111-1307, USA.\n//\n//\t$Id$\n//@{\n// Lcoal\n#include \"Scm.h\"\n#include \"Chk.h\"\n#include \"Hurricane.h\"\n#include \"endian.h\"\n#include \"FileUtil.h\"\n#include \"Storm.h\"\n#include \"platform.h\"\n\n// System\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <string>\n#include <vector>\n#include <string>\n\nusing namespace std;\n\nScm::Scm(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane)\n{\n\n}\n\nScm::~Scm()\n{\n\n}\n\nbool Scm::convert(const std::string &arcfile, const std::vector<std::string> &unitNames, Storage storage)\n{\n  bool result = true;\n\n  string scm_path = storage.getFullPath() + \"scm\";\n\n  result = mHurricane->extractFile(arcfile, scm_path);\n  if (result)\n  {\n    // call the Chk converter with temp file...\n    shared_ptr<Storm> storm = make_shared<Storm>(scm_path);\n    Chk chk(storm);\n    chk.setUnitNames(unitNames);\n    result = chk.convert(\"staredit\\\\scenario.chk\", storage.getFullPath());\n\n    // delete the temporary .chk file -> below don't access 'breeze' any more!\n    platform::unlink(scm_path);\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "src/Scm.h",
    "content": "/*\n * scm.h\n *\n *      Author: Andreas Volz\n */\n#ifndef SCM_H_\n#define SCM_H_\n\n// Local\n#include \"Chk.h\"\n#include \"Converter.h\"\n#include \"Storage.h\"\n\n\n// System\n#include <cstring>\n#include <vector>\n#include <string>\n#include <memory>\n\n// Forward declarations\nclass Hurricane;\n\n/**\n * Map Container\n *\n * The .scm is MPQ encoded and will be decoded to a .ckk and then further processed by Chk class\n * At the end .scm is only useful with Storm\n */\nclass Scm : public Converter\n{\npublic:\n  Scm(std::shared_ptr<Hurricane> hurricane);\n  virtual ~Scm();\n\n  bool convert(const std::string &arcfile, const std::vector<std::string> &unitNames, Storage storage);\n\nprivate:\n\n};\n\n#endif /* SCM_H_ */\n"
  },
  {
    "path": "src/SfxConverter.cpp",
    "content": "/*\n * SfxConverter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"SfxConverter.h\"\n#include \"Storage.h\"\n#include \"Preferences.h\"\n#include \"FileUtil.h\"\n#include \"dat/Sfx.h\"\n#include \"Wav.h\"\n#include \"Logger.h\"\n#include \"StringUtil.h\"\n\n// system\n#include <iostream>\n#include <fstream>\n\nusing namespace std;\nusing namespace dat;\n\nstatic Logger logger = Logger(\"startool.dat.SfxConverter\");\n\n\nSfxConverter::SfxConverter(std::shared_ptr<Hurricane> hurricane, DataHub &datahub) :\n  Converter(hurricane),\n  mDatahub(datahub)\n{\n\n}\n\nSfxConverter::~SfxConverter()\n{\n\n}\n\nbool SfxConverter::convert()\n{\n  bool result = true;\n\n  Preferences &preferences = Preferences::getInstance();\n\n  Storage sounds;\n  sounds.setDataPath(preferences.getDestDir());\n  sounds.setDataType(\"sounds/unit\");\n\n  // start with i=1 as 0=none and couldn't be read\n  for(unsigned int i = 1; i < static_cast<unsigned int>(mDatahub.sfxdata->num_lines()); i++)\n  {\n    Sfx sfx(mDatahub, i);\n\n    string sound_id;\n\n    /*Storage lua_file_store(luagen(\"sound-\" + sound_id + \".lua\"));\n    ofstream lua_file;\n    lua_file.open (lua_file_store.getFullPath());*/\n\n    TblEntry sound_file = sfx.sound_file_tbl();\n\n    string sound_arcfile(\"sound\\\\\" + sound_file.name1());\n    string sound_file_base(sound_file.name1());\n    replaceString(\"\\\\\", \"/\", sound_file_base);\n    sound_file_base = cutFileEnding(to_lower(sound_file_base), \".wav\");\n\n    LOG4CXX_TRACE(logger, \"sound_arcfile: \" + sound_arcfile);\n    LOG4CXX_TRACE(logger, \"sound_file_base: \" + sound_file_base);\n\n    Wav wav(mHurricane);\n\n    bool case_func = wav.convert(sound_arcfile, sounds(sound_file_base));\n    printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n  }\n\n\n  return result;\n}\n"
  },
  {
    "path": "src/SfxConverter.h",
    "content": "/*\n * SfxConverter.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef SFXCONVERTER_H\n#define SFXCONVERTER_H\n\n// project\n#include \"dat/DataHub.h\"\n\nclass SfxConverter : public Converter\n{\npublic:\n  SfxConverter(std::shared_ptr<Hurricane> hurricane, dat::DataHub &datahub);\n  virtual ~SfxConverter();\n\n  bool convert();\n\nprivate:\n  dat::DataHub &mDatahub;\n};\n\n#endif /* SFXCONVERTER_H */\n"
  },
  {
    "path": "src/Size.h",
    "content": "#ifndef SIZE_H\n#define SIZE_H\n\n#include <stdint.h>\n\n/*!\n * Trivial class which stores a size in integer notation. \n */\n\nclass Size\n{\npublic:\n  Size ();\n  Size (int inWidth, int inHeight);\n  Size (const Size& inSize);\n\n  ~Size () {}\n\n  bool isEmpty() const { return ((mWidth == 0) && (mHeight == 0));}\n\n  int getWidth()  const {return mWidth;}\n\n  int getHeight() const {return mHeight;}\n\n  Size& operator= (const Size& inRHS);\n\n  Size& operator*= (const Size& inSize);\n\n  Size& operator* (const Size& inSize);\n\n  bool operator== (const Size& inSize) const;\n\n  bool operator!= (const Size& inSize) const;\n\nprivate:\n  int mWidth, mHeight;\n\n\n};\n\ninline Size::Size ()\n    : mWidth (0), mHeight (0)\n{\n}\n\ninline Size::Size(int inWidth, int inHeight)\n    : mWidth (inWidth), mHeight(inHeight)\n{\n}\n\ninline Size::Size(const Size& inSize)\n    : mWidth (inSize.mWidth), mHeight(inSize.mHeight)\n{\n}\n\ninline Size& Size::operator= (const Size& inRHS)\n{\n  mWidth  = inRHS.mWidth;\n  mHeight = inRHS.mHeight;\n  return *this;\n}\n\ninline bool Size::operator== (const Size& inSize) const\n{\n  // if the same object\n  if (this == &inSize)\n  {\n    return true;\n  }\n\n  return (mWidth  == inSize.mWidth &&\n          mHeight == inSize.mHeight);\n}\n\ninline bool Size::operator!= (const Size& inSize) const\n{\n  return !(inSize == *this);\n}\n\ninline Size& Size::operator*= (const Size& inSize)\n{\n  mWidth *= inSize.mWidth;\n  mHeight *= inSize.mHeight;\n\n  return *this;\n}\n\ninline Size operator* (const Size& s1, const Size& s2)\n{\n  return Size(s1.getWidth() * s2.getWidth(), s1.getHeight() * s2.getHeight());\n}\n\n#endif // SIZE_H\n"
  },
  {
    "path": "src/Smacker.cpp",
    "content": "/*\n * Video.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include <Smacker.h>\n#include \"Hurricane.h\"\n#include \"FileUtil.h\"\n#include \"platform.h\"\n#include \"Logger.h\"\n\n// System\n#include <iostream>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Smacker\");\n\nSmacker::Smacker(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane)\n{\n\n}\n\nSmacker::~Smacker()\n{\n\n}\n\nbool Smacker::convertOGV(const std::string &arcfile,  Storage storage)\n{\n  bool result = true;\n\n  string smk_file = storage.getFullPath() + \".smk\";\n  string ogv_file = storage.getFullPath() + \".ogv\";\n\n  result = mHurricane->extractFile(arcfile, smk_file, false);\n  if(result)\n  {\n    string ffmpeg_str =\n      string(\"ffmpeg -y -i \\\"\") + smk_file\n      + \"\\\" -codec:v libtheora -qscale:v 31 -codec:a libvorbis -qscale:a 15 -pix_fmt yuv420p \\\"\"\n      + ogv_file + \"\\\"\";\n\n    LOG4CXX_DEBUG(logger, ffmpeg_str);\n\n    // TODO: call it in a way we suppress the output to stdout\n    int sys_call = system(ffmpeg_str.c_str());\n    if (sys_call != 0)\n    {\n      result = false;\n    }\n\n    fs::remove(smk_file);\n  }\n\n  return result;\n}\n\nbool Smacker::convertMNG(const std::string &arcfile,  Storage storage)\n{\n  bool result = true;\n\n  string smk_file = storage.getFullPath() + \".smk\";\n  string png_path = storage.getFullPath() + \"_png/\";\n  string mng_file = storage.getFullPath() + \".mng\";\n\n  result = mHurricane->extractFile(arcfile, smk_file, false);\n  if(result)\n  {\n    CheckPath(png_path);\n\n    string ffmpeg_str =\n      string(\"ffmpeg -y -i \\\"\") + smk_file + \"\\\" -codec:v png -qscale:v 31 -pix_fmt yuv420p \\\"\" + png_path + \"\\\"image%05d.png\";\n      LOG4CXX_DEBUG(logger, ffmpeg_str);\n\n    // TODO: call it in a way we suppress the output to stdout\n    int sys_call = system(ffmpeg_str.c_str());\n    if (sys_call == 0)\n    {\n      if(result)\n      {\n        string mng_cmd = \"convert \\\"\" + png_path + \"image*.png\\\" -delay 4 \\\"\" + mng_file + \"\\\"\";\n        LOG4CXX_DEBUG(logger, mng_cmd);\n\n        result = callConvert(mng_cmd);\n      }\n    }\n    else\n    {\n      result = false;\n    }\n\n    fs::remove(smk_file);\n    fs::remove_all(png_path);\n  }\n\n  return result;\n}\n\nbool Smacker::callConvert(const std::string &cmd)\n{\n  bool result = true;\n\n  // try convert with ImageMagick 7+\n  string magic7_cmd(\"magick \" + cmd);\n  int sys_call = system(magic7_cmd.c_str());\n  if (sys_call != 0)\n  {\n    // try convert with ImageMagick <= 6\n    string magic6_cmd(cmd);\n    sys_call = system(magic6_cmd.c_str());\n    if (sys_call != 0)\n    {\n      // try convert with GraphicsMagick\n      string gm_cmd(\"gm \" + cmd);\n      sys_call = system(gm_cmd.c_str());\n      if (sys_call != 0)\n      {\n        result = false;\n      }\n    }\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "src/Smacker.h",
    "content": "/*\n * Video.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef VIDEO_H\n#define VIDEO_H\n\n// project\n#include \"Storage.h\"\n#include \"Converter.h\"\n\n// System\n#include <memory>\n\nclass Smacker : public Converter\n{\npublic:\n  Smacker(std::shared_ptr<Hurricane> hurricane);\n  virtual ~Smacker();\n\n  /**\n   *  Convert SMK video to OGV\n   */\n  bool convertOGV(const std::string &arcfile, Storage storage);\n\n  bool convertMNG(const std::string &arcfile,  Storage storage);\n\nprivate:\n  bool callConvert(const std::string &cmd);\n};\n\n#endif /* VIDEO_H */\n"
  },
  {
    "path": "src/Storage.cpp",
    "content": "/*\n * Storage.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Storage.h\"\n\n// system\n#include <iostream>\n\nusing namespace std;\n\nStorage::Storage()\n{\n\n}\n\nStorage::Storage(const char *filename) :\n  mFilename(filename)\n{\n\n}\n\nStorage::Storage(const std::string &filename) :\n  mFilename(filename)\n{\n\n}\n\nStorage::~Storage()\n{\n\n}\n\nconst std::string& Storage::getDataPath() const\n{\n  return mDataPath;\n}\n\nvoid Storage::setDataPath(const std::string &dataPath)\n{\n  this->mDataPath = dataPath;\n}\n\nconst std::string &Storage::getDataType() const\n{\n  return mDataType;\n}\n\nvoid Storage::setDataType(const std::string &dataType)\n{\n  this->mDataType = dataType;\n}\n\nconst std::string &Storage::getFilename() const\n{\n  return mFilename;\n}\n\nvoid Storage::setFilename(const std::string &filename)\n{\n  this->mFilename = filename;\n}\n\nstd::string Storage::getFullPath() const\n{\n  string path = getDataPath();\n\n  if(!path.empty())\n  {\n    path += \"/\";\n  }\n\n  path += getDataType();\n\n  if(!path.empty())\n  {\n    path += \"/\";\n  }\n\n  path += getFilename();\n\n  return path;\n}\n\nstd::string Storage::getRelativePath() const\n{\n  string path = getDataType();\n\n  if(!path.empty())\n  {\n    path += \"/\";\n  }\n\n  path += getFilename();\n\n  return path;\n}\n\nStorage Storage::operator()(std::string filename)\n{\n  Storage storage(*this);\n\n  storage.setFilename(filename);\n\n  return storage;\n}\n\nstd::string Storage::operator=(const Storage& storage)\n{\n  return getFullPath();\n}\n\nStorage::operator std::string() const\n{\n  return getFullPath();\n}\n\n\nstd::string operator+(const std::string &str, const Storage& storage)\n{\n  return str + storage.getFullPath();\n}\n\nstd::string operator+(const Storage& storage, const std::string &str)\n{\n  return storage.getFullPath() + str;\n}\n\nstd::string operator+(const char *str, const Storage& storage)\n{\n  return str + storage.getFullPath();\n}\n\nstd::string operator+(const Storage& storage, const char *str)\n{\n  return storage.getFullPath() + str;\n}\n"
  },
  {
    "path": "src/Storage.h",
    "content": "/*\n * Storage.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef STORAGE_H_\n#define STORAGE_H_\n\n#include <string>\n\nclass Storage\n{\npublic:\n  Storage();\n\n  Storage(const char *filename);\n\n  Storage(const std::string &filename);\n\n  virtual ~Storage();\n\n  const std::string& getDataPath() const;\n\n  void setDataPath(const std::string &dataPath);\n\n  const std::string& getDataType() const;\n\n  void setDataType(const std::string &dataType);\n\n  const std::string& getFilename() const;\n\n  void setFilename(const std::string &filename);\n\n  std::string getFullPath() const;\n\n  std::string getRelativePath() const;\n\n  Storage operator()(std::string filename);\n\n  std::string operator=(const Storage& storage);\n\n  operator std::string() const;\n\nprivate:\n  std::string mDataPath;\n  std::string mDataType;\n  std::string mFilename;\n\n};\n\nstd::string operator+(const std::string &str, const Storage& storage);\n\nstd::string operator+(const char *str, const Storage& storage);\n\nstd::string operator+(const Storage& storage, const std::string &str);\n\nstd::string operator+(const Storage& storage, const char *str);\n\n#endif /* STORAGE_H_ */\n"
  },
  {
    "path": "src/Storm.cpp",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#ifdef _MSC_VER\n#define DEBUG _DEBUG\n#define PATH_MAX _MAX_PATH\n#include <direct.h>\n#include <io.h>\n#else\n#include <limits.h>\n#include <unistd.h>\n#endif\n#include <ctype.h>\n#include <iostream>\n#include <zlib.h>\n#include <StormLib.h>\n\n#include \"Storm.h\"\n#include \"FileUtil.h\"\n\nusing namespace std;\n\nStorm::Storm() :\n  mMpqHandle(nullptr)\n{\n\n}\n\nStorm::Storm(const std::string &archiveName) :\n  mMpqHandle(nullptr)\n{\n  openArchive(archiveName);\n}\n\nStorm::~Storm()\n{\n  closeArchive();\n}\n\nbool Storm::openArchive(const std::string &archiveName)\n{\n  bool result = true;\n\n  // close it in case it's still open\n  closeArchive();\n\n  // Open an archive, e.g. \"d2music.mpq\"\n  if (!SFileOpenArchive(archiveName.c_str(), 0, STREAM_FLAG_READ_ONLY, &mMpqHandle))\n  {\n    result = false;\n  }\n  else\n  {\n    mArchiveName = archiveName;\n  }\n  return result;\n}\n\nvoid Storm::closeArchive()\n{\n  if (mMpqHandle != nullptr)\n  {\n    SFileCloseArchive(mMpqHandle);\n    mArchiveName.clear();\n  }\n}\n\nbool Storm::extractMemory(const std::string &archivedFile, unsigned char **szEntryBufferPrt, size_t *bufferLen)\n{\n  int nError = ERROR_SUCCESS;\n  unsigned char *szEntryBuffer = nullptr;\n  HANDLE hFile = nullptr;          // Archived file handle\n  bool result = true;\n\n  // Open a file in the archive, e.g. \"data\\global\\music\\Act1\\tristram.wav\"\n  if (nError == ERROR_SUCCESS)\n  {\n    if (!SFileOpenFileEx(mMpqHandle, archivedFile.c_str(), 0, &hFile))\n      nError = GetLastError();\n  }\n\n  int i = 0;\n  size_t len = 0;\n  // Read the file from the archive\n  if (nError == ERROR_SUCCESS)\n  {\n    char szBuffer[0x10000];\n\n    szEntryBuffer = (unsigned char *) malloc(sizeof(szBuffer)); // TODO: this might me useless and then free() could be avoid below\n    DWORD dwBytes = 1;\n\n    while (dwBytes > 0)\n    {\n      SFileReadFile(hFile, szBuffer, sizeof(szBuffer), &dwBytes, NULL);\n      if (dwBytes > 0)\n      {\n        len = len + dwBytes;\n        szEntryBuffer = (unsigned char *) realloc(szEntryBuffer, len);\n        memcpy(szEntryBuffer + (i * sizeof(szBuffer)), szBuffer, dwBytes);\n\n      }\n      i++;\n    }\n  }\n  if (bufferLen != NULL)\n  {\n    *bufferLen = len;\n  }\n\n  if (hFile != NULL)\n    SFileCloseFile(hFile);\n\n  if (nError != ERROR_SUCCESS)\n  {\n    result = false;\n    // in case of problem free what ever has been allocated\n    free(szEntryBuffer);\n    szEntryBuffer = nullptr;\n  }\n\n  *szEntryBufferPrt = szEntryBuffer;\n\n  return result;\n}\n\nbool Storm::extractFile(const std::string &archivedFile, const std::string &extractedName, bool compress)\n{\n  HANDLE hFile = nullptr;          // Archived file handle\n  FILE *file = nullptr;            // Disk file handle\n  gzFile gzfile = nullptr;         // Compressed file handle\n  int nError = ERROR_SUCCESS;\n  bool result = true;\n\n  // Open a file in the archive, e.g. \"data\\global\\music\\Act1\\tristram.wav\"\n  if (nError == ERROR_SUCCESS)\n  {\n    if (!SFileOpenFileEx(mMpqHandle, archivedFile.c_str(), 0, &hFile))\n      nError = GetLastError();\n  }\n\n  // Create the target file\n  if (nError == ERROR_SUCCESS)\n  {\n    CheckPath(extractedName);\n    if (compress)\n    {\n      gzfile = gzopen(extractedName.c_str(), \"wb9\");\n    }\n    else\n    {\n      file = fopen(extractedName.c_str(), \"wb\");\n    }\n  }\n\n  // Read the file from the archive\n  if (nError == ERROR_SUCCESS)\n  {\n    char szBuffer[0x10000];\n    DWORD dwBytes = 1;\n\n    while (dwBytes > 0)\n    {\n      SFileReadFile(hFile, szBuffer, sizeof(szBuffer), &dwBytes, NULL);\n      if (dwBytes > 0)\n      {\n        if (compress)\n        {\n          if(gzfile)\n          {\n            gzwrite(gzfile, szBuffer, dwBytes);\n          }\n        }\n        else\n        {\n          if(file)\n          {\n            fwrite(szBuffer, 1, dwBytes, file);\n          }\n        }\n      }\n    }\n  }\n\n  // Cleanup and exit\n  if (file != NULL)\n  {\n    fclose(file);\n  }\n  if (gzfile != NULL)\n  {\n    gzclose(gzfile);\n  }\n  if (hFile != NULL)\n    SFileCloseFile(hFile);\n\n  if (nError != ERROR_SUCCESS)\n    result = false;\n\n  return result;\n}\n\nunsigned int Storm::getRecordCount(const std::string &archivedFile, unsigned int recordsize)\n{\n  // TODO: implement\n  return 0;\n}\n\n"
  },
  {
    "path": "src/Storm.h",
    "content": "#ifndef STORM_H_\n#define STORM_H_\n\n// Local\n#include \"Hurricane.h\"\n#include \"DataChunk.h\"\n\n// System\n#include <stdint.h>\n#include <string>\n#include <memory>\n\nclass Storm: public Hurricane\n{\npublic:\n  Storm();\n  Storm(const std::string &archiveName);\n  virtual ~Storm();\n\n  bool openArchive(const std::string &archiveName);\n  void closeArchive();\n\n  /**\n   * Extract file from MPQ archive and create all directories if not existing\n   *\n   * @param archivedFile File/name identifier in MPQ archive to extract (e.g. game//icons.grp)\n   * @param extractedName File including path where it is extracted to (all folders will be created)\n   */\n  bool extractFile(const std::string &archivedFile, const std::string &extractedName, bool compress);\n\n  /**\n   * Attention: This function malloc() bufferLen memory which you've to free yourself!\n   * Better use extractDataChunk()\n   */\n  bool extractMemory(const std::string &archivedFile, unsigned char **szEntryBufferPrt, size_t *bufferLen);\n\n  unsigned int getRecordCount(const std::string &archivedFile, unsigned int recordsize);\n\nprivate:\n  void *mMpqHandle; // Open archive handle\n\n};\n\n#endif /* STORM_H_ */\n"
  },
  {
    "path": "src/StringUtil.cpp",
    "content": "/*\n * stringUtil.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"StringUtil.h\"\n#include \"Logger.h\"\n#include <algorithm>\n\n#include <iconv.h>\n#include <string.h>\n#include <stdlib.h>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.StringUtil\");\n\nint replaceString(const string &match, const string &replace, string &str)\n{\n  int i = 0;\n\n  if (str.find(match) == std::string::npos)\n    return false;\n\n  std::string::size_type start = 0;\n\n\n  while ((start = str.find(match)) != std::string::npos)\n  {\n    str.replace(start, match.size(), replace);\n\n    i++;\n  }\n\n  return i;\n}\n\nbool hasFileEnding(const std::string &filename, const std::string &ending)\n{\n  const size_t loc = filename.find(ending, filename.length() - ending.length());\n\n  if (loc != string::npos)\n  {\n    return true;\n  }\n\n  return false;\n}\n\nstd::string cutFileEnding(std::string filename, const std::string &ending)\n{\n  if (ending == \"\")\n  {\n    const size_t loc = filename.find_last_of('.', filename.length());\n\n    if (loc != string::npos)\n    {\n      filename.erase(loc);\n      return filename;\n    }\n  }\n  else\n  {\n    const size_t loc = filename.find(ending, filename.length() - ending.length());\n\n    if (loc != string::npos)\n    {\n      filename.erase(loc);\n      return filename;\n    }\n  }\n\n  return filename;\n}\n\nstd::string to_lower(std::string line)\n{\n  std::for_each(line.begin(), line.end(), [](char & c)\n  {\n      c = ::tolower(c);\n  });\n\n  return line;\n}\n\n// TODO: check if this helps to detect encoding https://github.com/freedesktop/uchardet\nchar *iconvISO2UTF8(char *iso)\n{\n  char buf[1024] = { '\\0' };\n  iconv_t iconvDesc = iconv_open(\"UTF-8//TRANSLIT//IGNORE\", \"ISO-8859-1\");\n\n  if (iconvDesc == (iconv_t) -1)\n  {\n    /* Something went wrong.  */\n    if (errno == EINVAL)\n    {\n      snprintf(buf, sizeof(buf), \"conversion from '%s' to '%s' not available\",\n               \"ISO-8859-1\", \"UTF-8\");\n      LOG4CXX_ERROR(logger, buf);\n    }\n    else\n    {\n      snprintf(buf, sizeof(buf), \"LibIcon initialization failure\");\n    }\n\n    return NULL;\n  }\n\n  size_t iconv_value;\n  char *utf8 = NULL;\n  size_t len = 0;\n  size_t utf8len = 0;\n  size_t utf8len_save = 0;\n  char *utf8start = NULL;\n\n\n  len = strlen(iso);\n  if (!len)\n  {\n    snprintf(buf, sizeof(buf), \"iconvISO2UTF8: input String is empty.\");\n    LOG4CXX_ERROR(logger, buf);\n    return NULL;\n  }\n\n  /* Assign enough space to put the UTF-8. */\n  utf8len = 2 * len;\n  utf8len_save = utf8len;\n  utf8 = (char *) calloc(utf8len + 1, sizeof(char));\n  if (!utf8)\n  {\n    snprintf(buf, sizeof(buf), \"iconvISO2UTF8: Calloc failed.\");\n    LOG4CXX_ERROR(logger, buf);\n    return NULL;\n  }\n  /* Keep track of the variables. */\n  utf8start = utf8;\n\n#ifdef _MSC_VER\n  iconv_value = iconv(iconvDesc, const_cast<const char**>(&iso), &len, &utf8, &utf8len);\n#else\n  iconv_value = iconv(iconvDesc, &iso, &len, &utf8, &utf8len);\n#endif\n  /* Handle failures. */\n  if (iconv_value == (size_t) -1)\n  {\n    switch (errno)\n    {\n    /* See \"man 3 iconv\" for an explanation. */\n    case EILSEQ:\n      snprintf(buf, sizeof(buf),\n               \"iconv failed: Invalid multibyte sequence, in string '%s', length %d, out string '%s', length %d\\n\",\n               iso, (int) len, utf8start, (int) utf8len);\n      LOG4CXX_ERROR(logger, buf);\n      break;\n    case EINVAL:\n      snprintf(buf, sizeof(buf),\n               \"iconv failed: Incomplete multibyte sequence, in string '%s', length %d, out string '%s', length %d\\n\",\n               iso, (int) len, utf8start, (int) utf8len);\n      LOG4CXX_ERROR(logger, buf);\n      break;\n    case E2BIG:\n      snprintf(buf, sizeof(buf),\n               \"iconv failed: No more room, in string '%s', length %d, out string '%s', length %d\\n\",\n               iso, (int) len, utf8start, (int) utf8len);\n      LOG4CXX_ERROR(logger, buf);\n      break;\n    default:\n      snprintf(buf, sizeof(buf),\n               \"iconv failed, in string '%s', length %d, out string '%s', length %d\\n\",\n               iso, (int) len, utf8start, (int) utf8len);\n      LOG4CXX_ERROR(logger, buf);\n    }\n    return NULL;\n  }\n\n  if (iconv_close(iconvDesc) != 0)\n  {\n    snprintf(buf, sizeof(buf), \"libicon close failed: %s\", strerror(errno));\n    LOG4CXX_ERROR(logger, buf);\n  }\n\n  utf8start[utf8len_save] ='\\0';\n  return utf8start;\n\n}\n"
  },
  {
    "path": "src/StringUtil.h",
    "content": "/*\n * stringUtil.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef STRINGUTIL_H_\n#define STRINGUTIL_H_\n\n// C++\n#include <sstream>\n#include <iomanip>\n#include <iostream>\n#include <vector>\n#include <string>\n#include <exception>\n\n// some functions that are very usefull for writing files\nbool hasFileEnding(const std::string &filename, const std::string &ending);\nstd::string cutFileEnding(std::string filename, const std::string &ending = \"\");\n\n/**\n * A helper function to return input string to lower case. Doesn't modify the input string.\n *\n * @return the lower case string variant\n */\nstd::string to_lower(std::string line);\n\n/**\n * An function to replace occurences of substrings in a bigger string. Very basic function without regex.\n * @param match This is the string that is matched to replace.\n * @param replace The string that replaces all found match strings.\n * @param str The string that is matched and replaced.\n *\n * @return number of replaced strings\n */\nint replaceString(const std::string &match, const std::string &replace, std::string &str);\n\n/**\n * A helper to convert text to UTF-8.\n *\n * @return a UTF-8 string that has to be free()d after usage\n */\nchar* iconvISO2UTF8(char *iso);\n\n/**\n * print Vector on std::cout\n */\ntemplate<typename T>\nvoid printVector(std::vector<T> iv)\n{\n  std::cout << \"[\";\n  for (unsigned i = 0; i < iv.size(); i++)\n  {\n    std::cout << iv[i];\n    if (i < iv.size() - 1)\n      std::cout << \",\";\n  }\n  std::cout << \"]\" << std::endl;\n}\n\ntemplate<class T>\nstd::string to_hex(const T &value)\n{\n  char hex_string[20];\n  sprintf(hex_string, \"0x%X\", value); //convert number to hex\n  return hex_string;\n}\n\n#endif /* STRINGUTIL_H_ */\n"
  },
  {
    "path": "src/UIConsole.cpp",
    "content": "/*\n * UIConsole.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"UIConsole.h\"\n#include \"Logger.h\"\n#include \"Hurricane.h\"\n#include \"platform.h\"\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.UIConsole\");\n\nUIConsole::UIConsole(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane)\n{\n\n}\n\nUIConsole::~UIConsole()\n{\n\n}\n\nbool UIConsole::convert(Storage pngfile, int left, int right)\n{\n  bool result = true;\n\n  string complete_file = pngfile.getFullPath() + \".png\";\n  string left_file = pngfile.getFullPath() + \"_left.png\";\n  string right_file = pngfile.getFullPath() + \"_right.png\";\n  string middle_file = pngfile.getFullPath() + \"_middle.png\";\n  string tmp_file = pngfile.getFullPath() + \"_tmp.png\";\n\n  // fix resolution for SC1, in case of Remastered this has to be an option\n  int width = 640;\n  int height = 480;\n  string wxh = to_string(width) + \"x\" + to_string(height);\n\n  int left_abs = width - left;\n  //echo $left_abs\n\n  //convert tconsole.png -crop ${width}x${height}-${left_abs}+0 tconsole_left.png\n  //convert tconsole.png -crop ${width}x${height}+${right}+0 tconsole_right.png\n\n  string convert_left_cmd = \"convert \\\"\" + complete_file + \"\\\" -crop \" + wxh + \"-\" + to_string(left_abs) + \"+0 \\\"\" + left_file + \"\\\"\";\n  string convert_right_cmd = \"convert \\\"\" + complete_file + \"\\\" -crop \" + wxh + \"+\" + to_string(right) + \"+0 \\\"\" + right_file + \"\\\"\";\n  LOG4CXX_DEBUG(logger, convert_left_cmd);\n  LOG4CXX_DEBUG(logger, convert_right_cmd);\n\n  if(result)\n  {\n    result = callConvert(convert_left_cmd);\n  }\n  if(result)\n  {\n    result = callConvert(convert_right_cmd);\n  }\n\n  int middle = right - left;\n  //echo $middle\n\n  int left_tmp = left_abs - middle;\n  int middle_abs = right - middle;\n  //echo $left_tmp\n\n  //convert tconsole.png -crop ${width}x${height}-${left_tmp}+0 tmp.png\n  //convert tmp.png -crop ${width}x${height}+${middle_abs}+0 tconsole_middle.png\n\n  string convert_tmp_cmd = \"convert \\\"\" + complete_file + \"\\\" -crop \" + wxh + \"-\" + to_string(left_tmp) + \"+0 \\\"\" + tmp_file + \"\\\"\";\n  string convert_middle_cmd = \"convert \\\"\" + tmp_file + \"\\\" -crop \" + wxh + \"+\" + to_string(middle_abs) + \"+0 \\\"\" + middle_file + \"\\\"\";\n  LOG4CXX_DEBUG(logger, convert_tmp_cmd);\n  LOG4CXX_DEBUG(logger, convert_middle_cmd);\n\n  if(result)\n  {\n    result = callConvert(convert_tmp_cmd);\n  }\n  if(result)\n  {\n    result = callConvert(convert_middle_cmd);\n  }\n\n\n  fs::remove(tmp_file);\n\n  return result;\n}\n\nbool UIConsole::callConvert(const std::string &cmd)\n{\n  bool result = true;\n\n  // try convert with ImageMagick 7+\n  string magic7_cmd(\"magick \" + cmd);\n  int sys_call = system(magic7_cmd.c_str());\n  if (sys_call != 0)\n  {\n    // try convert with ImageMagick <= 6\n    string magic6_cmd(cmd);\n    sys_call = system(magic6_cmd.c_str());\n    if (sys_call != 0)\n    {\n      // try convert with GraphicsMagick\n      string gm_cmd(\"gm \" + cmd);\n      sys_call = system(gm_cmd.c_str());\n      if (sys_call != 0)\n      {\n        result = false;\n      }\n    }\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "src/UIConsole.h",
    "content": "/*\n * UIConsole.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef UICONSOLE_H\n#define UICONSOLE_H\n\n// project\n#include \"Converter.h\"\n#include \"Storage.h\"\n\n// system\n#include <string>\n#include <memory>\n\n/**\n * Draft idea:\n * - get tconsole.pcx, pconsole.pcx, zconsole.pcx\n * - cut it somewhere in the middle\n * - define an area which is suited as copy fill area\n *   - or provide a contrib one\n * - generate three images\n * - use them in LUA to generate a dynamic width image\n * - or do this all in a script\n */\nclass UIConsole : public Converter\n{\npublic:\n  UIConsole(std::shared_ptr<Hurricane> hurricane);\n  virtual ~UIConsole();\n\n  bool convert(Storage pngfile, int left, int right);\n\nprivate:\n  bool callConvert(const std::string &cmd);\n};\n\n#endif /* UICONSOLE_H */\n"
  },
  {
    "path": "src/UnitsConverter.cpp",
    "content": "/*\n * UnitsExporter.cpp\n *\n *      Author: Andreas\n */\n\n// project\n#include \"UnitsConverter.h\"\n#include \"Preferences.h\"\n#include \"FileUtil.h\"\n#include \"Logger.h\"\n#include \"StringUtil.h\"\n#include \"Grp.h\"\n#include \"luagen.h\"\n#include \"dat/DataHub.h\"\n\n// system\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <algorithm>\n#include <nlohmann/json.hpp>\n\nusing namespace std;\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.UnitsConverter\");\n\nUnitsConverter::UnitsConverter(std::shared_ptr<Hurricane> hurricane, DataHub &datahub) :\n  Converter(hurricane),\n  mDatahub(datahub)\n{\n\n}\n\nUnitsConverter::~UnitsConverter()\n{\n\n}\n\nbool UnitsConverter::convert(json &unitsJson)\n{\n  bool result = true;\n\n  Preferences &preferences = Preferences::getInstance();\n\n  const int tilesize_pixel = 8; // size of a MiniTile in pixels\n  const int minitile_multi = 4; // number of MiniTiles in one MegaTile\n\n  Storage graphics;\n  graphics.setDataPath(preferences.getDestDir());\n  graphics.setDataType(\"graphics\");\n\n  Storage luagen;\n  luagen.setDataPath(preferences.getDestDir());\n  luagen.setDataType(\"luagen/units\");\n  CheckPath(luagen.getFullPath());\n\n  ofstream lua_include;\n  lua_include.open (luagen(\"luagen-units.lua\").getFullPath());\n  string lua_include_str;\n\n  /*ofstream lua_sounds;\n  lua_sounds.open (luagen(\"luagen-sounds.lua\").getFullPath());\n  string lua_lua_sounds_str;*/\n\n  // units.dat\n  for(auto &array : unitsJson)\n  {\n    string unit_name = array.at(\"name\");\n    int unit_id = array.at(\"id\");\n    bool extractor = true;\n    bool save_result = true;\n\n    LOG4CXX_TRACE(logger, string(\"Unit(\") + to_string(unit_id) + \")\");\n\n    try\n    {\n      extractor = array.at(\"extractor\");\n    }\n    catch (const nlohmann::detail::out_of_range &json_range)\n    {\n      extractor = true; // default behaviour TODO: maybe better write into JSON file and skip default\n    }\n\n    if(extractor)\n    {\n      Unit unit(mDatahub, unit_id, unit_name);\n\n      string grp_arcfile =  \"unit\\\\\" + unit.flingy_obj().sprite_obj().image_obj().grp_tbl().name1();\n\n      // for the LUA reference it's enough to use the idle name as we save only one LUA for idle+talking portrait\n      string unit_portraits;\n      try\n      {\n        string portrait_name = unit.portrait_obj().video_idle_tbl().name1();\n        string portrait_id = unit.portrait_obj().getIDString(portrait_name);\n        string portrait_lua = \"portrait_\" + portrait_id;\n        unit_portraits = lg::assign(\"Portrait\", portrait_lua);\n      }\n      catch (PropertyNotAvailableException &nex)\n      {\n        cout << nex.what() << endl;\n\n        // FIXME: just use the tadvisor as some fallback for now\n        unit_portraits = lg::assign(\"Portrait\", \"portrait_tadvisor\");\n      }\n\n      Storage lua_file_store(luagen(unit_name + \".lua\"));\n      ofstream lua_file;\n      lua_file.open (lua_file_store.getFullPath());\n\n      // generate sounds Lua -->\n\n      string makeLuaReadySounds = makeReadySounds(unit);\n      string makeLuaWhatSounds = makeWhatSounds(unit);\n      string makeLuaYesSounds = makeYesSounds(unit);\n      string makeLuaPissSounds = makePissSounds(unit);\n\n      vector<string> unit_LuaSounds;\n\n      // add Ready sounds direct to the unit\n      if(!makeLuaReadySounds.empty())\n      {\n        string unit_LuaSound_ready = lg::paramsQuote({\"ready\", unit_name + \"-sound-ready\"});\n        unit_LuaSounds.push_back(unit_LuaSound_ready);\n      }\n\n      // add Yes/Acknowledge sounds direct to the unit\n      if(!makeLuaYesSounds.empty())\n      {\n        string unit_LuaSound_acknowledge = lg::paramsQuote({\"acknowledge\", unit_name + \"-sound-yes\"});\n        unit_LuaSounds.push_back(unit_LuaSound_acknowledge);\n      }\n\n      // make a sound group from What...\n      vector<string> unit_LuaSelectedSounds;\n      if(!makeLuaWhatSounds.empty())\n      {\n        unit_LuaSelectedSounds.push_back(unit_name + \"-sound-what\");\n      }\n\n      // ...and Piss group\n      if(!makeLuaPissSounds.empty())\n      {\n        unit_LuaSelectedSounds.push_back(unit_name + \"-sound-piss\");\n      }\n\n      // create a what/piss sound group if both are existing...\n      string makeLuaSelectedSound;\n      // ... and add this sound group to unit Sounds\n      if(unit_LuaSelectedSounds.size() > 1)\n      {\n        string unit_LuaSound_selected = lg::paramsQuote({\"selected\", unit_name + \"-sound-selected\"});\n        unit_LuaSounds.push_back(unit_LuaSound_selected);\n\n        makeLuaSelectedSound = lg::function(\"MakeSoundGroup\", {lg::quote(unit_name + \"-sound-selected\"),\n                                                               lg::paramsQuote(unit_LuaSelectedSounds)});\n      }\n      else if (unit_LuaSelectedSounds.size() == 1) // ...otherwise assign it direct to selected\n      {\n        string unit_LuaSound_selected = lg::paramsQuote({\"selected\", unit_LuaSelectedSounds.at(0)});\n        unit_LuaSounds.push_back(unit_LuaSound_selected);\n      }\n\n      string unit_sounds = lg::assign(\"Sounds\", lg::table({lg::params(unit_LuaSounds)}));\n\n      // generate images and other properties Lua -->\n\n      string image_id = unit.flingy_obj().sprite_obj().image_obj().getIDString();\n      string image_lua = image_id;\n      string unit_image = lg::assign(\"Image\", image_lua);\n\n      string unit_hitpoints = lg::assign(\"HitPoints\", to_string(unit.hitpoints()));\n      string unit_name_translated = lg::assign(\"Name\", lg::quote(unit.name_tbl().name1()));\n\n      bool unit_building = unit.special_ability_flags()->building();\n      string unit_LuaBuilding =  lg::assign(\"Building\", lg::boolean(unit_building));\n\n      units_dat_t::unit_dimension_type_t *unit_dimension_tilesize = unit.unit_dimension();\n\n      int unit_width = unit_dimension_tilesize->left() + unit_dimension_tilesize->right();\n      int unit_height = unit_dimension_tilesize->up() + unit_dimension_tilesize->down();\n\n      double unit_tilesize_width = unit_width / (double) tilesize_pixel;\n      double unit_tilesize_height = unit_height / (double) tilesize_pixel;\n\n      int unit_boxsize_width = round(unit_tilesize_width * tilesize_pixel);\n      int unit_boxsize_height = round(unit_tilesize_height * tilesize_pixel);\n\n      // for all units which could move (all non-buildings) set a square size as optimization for stratagus\n      if(!unit_building)\n      {\n        unit_tilesize_width = unit_tilesize_height = round(sqrt(unit_tilesize_width * unit_tilesize_height));\n      }\n\n      // ensure minimal unit width\n      if(unit_tilesize_width < 1)\n      {\n        unit_tilesize_width = 1;\n      }\n\n      // ensure minimal unit height\n      if(unit_tilesize_height < 1)\n      {\n        unit_tilesize_height = 1;\n      }\n\n      string unit_LuaTileSize = lg::assign(\"TileSize\", lg::table({lg::integer(unit_tilesize_width), lg::integer(unit_tilesize_height)}));\n      string unit_LuaBoxSize = lg::assign(\"BoxSize\", lg::table({to_string(unit_boxsize_width), to_string(unit_boxsize_height)}));\n\n      // for now just give each unit a PersonalSpace of 1 around\n      string unit_LuaPersonalSpace = lg::assign(\"PersonalSpace\", lg::table({lg::integer(1), lg::integer(1)}));\n\n      int unit_sight_range = unit.sight_range() * minitile_multi;\n      string unit_computer_reaction_rangeStr (\"math.ceil(\" + to_string(unit_sight_range) + \" * ComputerReactionRangeFactor)\");\n      string unit_person_reaction_rangeStr (\"math.floor(\" + to_string(unit_sight_range) + \" * PersonReactionRangeFactor)\");\n\n      string unit_LuaSightRange = lg::assign(\"SightRange\", to_string(unit_sight_range));\n      string unit_LuaComputerReactionRange = lg::assign(\"ComputerReactionRange\", unit_computer_reaction_rangeStr);\n      string unit_LuaPersonReactionRange = lg::assign(\"PersonReactionRange\", unit_person_reaction_rangeStr);\n\n      // generate some standard shadow\n      Pos shadow_position = Pos(-7, -7);\n\n      // some basic flyer shadow support => to be improved\n      if(unit.elevation_level() >= 16)\n      {\n        shadow_position = Pos(15, 15);\n      }\n\n      string unit_shadow = lg::assign(\"Shadow\", lg::table({lg::quote(\"offset\"), lg::posTable(shadow_position), lg::quote(\"scale\"), \"1\"}));\n\n      // generate a dummy animation as fallback to not crash\n      string unit_animations = lg::assign(\"Animations\", lg::quote(\"animations-dummy-still\"));\n\n      // generate a dummy icon as fallback to not crash\n      string unit_icon = lg::assign(\"Icon\", lg::quote(\"icon-terran-command-center\"));\n\n      string unit_LuaNumDirections = lg::assign(\"NumDirections\", image_lua + \"_NumDirections\");\n\n      string unit_LuaType(lg::assign(\"Type\", lg::quote(\"land\"))); // land is fallback\n      string unit_LuaLandUnit(lg::assign(\"LandUnit\", lg::boolean(true))); // LandUnit=true is fallback\n\n      bool unit_flyer = unit.special_ability_flags()->flyer();\n      string unit_LuaFlyer =  lg::assign(\"AirUnit\", lg::boolean(unit_flyer));\n      if(unit_flyer)\n      {\n        unit_LuaType = lg::assign(\"Type\", lg::quote(\"fly\"));\n        unit_LuaLandUnit = lg::assign(\"LandUnit\", lg::boolean(false));\n      }\n\n      bool unit_organic = unit.special_ability_flags()->organic();\n      string unit_LuaOrganic =  lg::assign(\"organic\", lg::boolean(unit_organic));\n\n      int unit_build_time = ((double)unit.build_time() / 24.0) * 6.0; // SC time is 1/24 sec and *6 is stratagus magic\n      int unit_minaral_costs = unit.mineral_cost();\n      int unit_vespene_costs = unit.vespene_cost();\n\n      string unit_LuaCosts =  lg::assign(\"Costs\", lg::table({lg::quote(\"time\"), to_string(unit_build_time),\n                                                             lg::quote(\"minerals\"), to_string(unit_minaral_costs),\n                                                             lg::quote(\"gas\"), to_string(unit_vespene_costs)\n                                                            }));\n\n      // FIXME: just make everything able to move as test\n      //string unit_LuaSpeed = lg::assign(\"Speed\", \"10\");\n\n      string unit_defintion = lg::DefineUnitType(unit_name,\n                                                {lg::line(unit_name_translated),\n                                                 lg::line(unit_image),\n                                                 lg::line(unit_shadow),\n                                                 lg::line(unit_icon),\n                                                 lg::line(unit_animations),\n                                                 lg::line(unit_portraits),\n                                                 lg::line(unit_hitpoints),\n                                                 lg::line(unit_LuaTileSize),\n                                                 lg::line( unit_LuaBoxSize),\n                                                 lg::line(unit_LuaSightRange),\n                                                 lg::line(unit_LuaComputerReactionRange),\n                                                 lg::line(unit_LuaPersonReactionRange),\n                                                 lg::line(unit_LuaNumDirections),\n                                                 lg::line(unit_LuaFlyer),\n                                                 lg::line(unit_LuaType),\n                                                 lg::line(unit_LuaBuilding),\n                                                 lg::line(unit_LuaOrganic),\n                                                 lg::line(unit_LuaLandUnit),\n                                                 lg::line(unit_LuaCosts),\n                                                 lg::line(unit_LuaPersonalSpace),\n                                                 lg::line(unit_sounds)\n                                                });\n\n      lua_include_str += lg::line(lg::function(\"Load\", lg::quote(lua_file_store.getRelativePath())));\n\n      lua_file << unit_defintion << endl;\n\n\n      // write all the Lua sound functions\n      if(!makeLuaReadySounds.empty())\n      {\n        lua_file <<  makeLuaReadySounds << endl;\n      }\n\n      if(!makeLuaWhatSounds.empty())\n      {\n        lua_file <<  makeLuaWhatSounds << endl;\n      }\n\n      if(!makeLuaYesSounds.empty())\n      {\n        lua_file <<  makeLuaYesSounds << endl;\n      }\n\n      if(!makeLuaPissSounds.empty())\n      {\n        lua_file <<  makeLuaPissSounds << endl;\n      }\n\n      if(!makeLuaSelectedSound.empty())\n      {\n        lua_file <<  makeLuaSelectedSound << endl;\n      }\n\n      lua_file.close();\n    }\n\n    printf(\"...%s\\n\", save_result ? \"ok\" : \"nok\");\n  }\n\n  lua_include << lua_include_str;\n  lua_include.close();\n\n  //lua_sounds.close();\n\n  return result;\n}\n\nstd::string UnitsConverter::makeReadySounds(Unit &unit)\n{\n  string make_sound;\n\n  try\n  {\n    TblEntry unit_ready_sound_tbl_entry = unit.ready_sound_obj().sound_file_tbl();\n\n    string unit_sound_ready_id = unit.getIDString() + \"-sound-ready\";\n\n    string unit_ready_sound = unit_ready_sound_tbl_entry.name1();\n\n    cout << \"Ready Sound: \" << unit_ready_sound  << endl;\n\n    string sound_file_base(unit_ready_sound);\n    replaceString(\"\\\\\", \"/\", sound_file_base);\n    sound_file_base = cutFileEnding(to_lower(sound_file_base), \".wav\");\n    string sound_file_ogg = \"sounds/unit/\" + sound_file_base + \".ogg\";\n\n    make_sound = lg::function(\"MakeSound\", {lg::quote(unit_sound_ready_id), lg::table({lg::quote(sound_file_ogg)})});\n  }\n  catch(PropertyNotAvailableException &nex)\n  {\n    cout << \"no Ready sound: \" << nex.what() << endl;\n  }\n\n  return make_sound;\n}\n\nstd::string UnitsConverter::makeWhatSounds(Unit &unit)\n{\n  string make_sound;\n\n  try\n  {\n    vector<Sfx> sfx_vec = unit.what_sound_obj();\n    vector<string> what_sound_vec;\n\n    if(!sfx_vec.empty())\n    {\n      string unit_sound_ready_id = unit.getIDString() + \"-sound-what\";\n\n      for (auto sfx : sfx_vec)\n      {\n        TblEntry unit_what_sound_tbl_entry = sfx.sound_file_tbl();\n\n        string unit_what_sound = unit_what_sound_tbl_entry.name1();\n\n        cout << \"What Sound: \" << unit_what_sound  << endl;\n\n        string sound_file_base(unit_what_sound);\n        replaceString(\"\\\\\", \"/\", sound_file_base);\n        sound_file_base = cutFileEnding(to_lower(sound_file_base), \".wav\");\n        string sound_file_ogg = \"sounds/unit/\" + sound_file_base + \".ogg\";\n\n        what_sound_vec.push_back(sound_file_ogg);\n      }\n\n      string unit_LuaWhatSoundParams = lg::paramsQuote(what_sound_vec);\n\n      make_sound = lg::function(\"MakeSound\", {lg::quote(unit_sound_ready_id), lg::table(unit_LuaWhatSoundParams)});\n    }\n  }\n  catch(PropertyNotAvailableException &nex)\n  {\n    cout << \"no What sound: \" << nex.what() << endl;\n  }\n\n  return make_sound;\n}\n\nstd::string UnitsConverter::makeYesSounds(Unit &unit)\n{\n  string make_sound;\n\n  try\n  {\n    vector<Sfx> sfx_vec = unit.yes_sound_obj();\n    vector<string> yes_sound_vec;\n\n    if(!sfx_vec.empty())\n    {\n      string unit_yes_ready_id = unit.getIDString() + \"-sound-yes\";\n\n      for (auto sfx : sfx_vec)\n      {\n        TblEntry unit_yes_sound_tbl_entry = sfx.sound_file_tbl();\n\n        string unit_yes_sound = unit_yes_sound_tbl_entry.name1();\n\n        cout << \"Yes Sound: \" << unit_yes_sound  << endl;\n\n        string sound_file_base(unit_yes_sound);\n        replaceString(\"\\\\\", \"/\", sound_file_base);\n        sound_file_base = cutFileEnding(to_lower(sound_file_base), \".wav\");\n        string sound_file_ogg = \"sounds/unit/\" + sound_file_base + \".ogg\";\n\n        yes_sound_vec.push_back(sound_file_ogg);\n      }\n\n      string unit_LuaYesSoundParams = lg::paramsQuote(yes_sound_vec);\n\n      make_sound = lg::function(\"MakeSound\", {lg::quote(unit_yes_ready_id), lg::table(unit_LuaYesSoundParams)});\n    }\n  }\n  catch(PropertyNotAvailableException &nex)\n  {\n    cout << \"no Yes sound: \" << nex.what() << endl;\n  }\n\n  return make_sound;\n}\n\nstd::string UnitsConverter::makePissSounds(Unit &unit)\n{\n  string make_sound;\n\n  try\n  {\n    vector<Sfx> sfx_vec = unit.piss_sound_obj();\n    vector<string> piss_sound_vec;\n\n    if(!sfx_vec.empty())\n    {\n      string unit_sound_piss_id = unit.getIDString() + \"-sound-piss\";\n\n      for (auto sfx : sfx_vec)\n      {\n        TblEntry unit_piss_sound_tbl_entry = sfx.sound_file_tbl();\n\n        string unit_piss_sound = unit_piss_sound_tbl_entry.name1();\n\n        cout << \"Piss Sound: \" << unit_piss_sound  << endl;\n\n        string sound_file_base(unit_piss_sound);\n        replaceString(\"\\\\\", \"/\", sound_file_base);\n        sound_file_base = cutFileEnding(to_lower(sound_file_base), \".wav\");\n        string sound_file_ogg = \"sounds/unit/\" + sound_file_base + \".ogg\";\n\n        piss_sound_vec.push_back(sound_file_ogg);\n      }\n\n      string unit_LuaPissSoundParams = lg::paramsQuote(piss_sound_vec);\n\n      make_sound = lg::function(\"MakeSound\", {lg::quote(unit_sound_piss_id), lg::table(unit_LuaPissSoundParams)});\n    }\n  }\n  catch(PropertyNotAvailableException &nex)\n  {\n    cout << \"no Piss sound: \" << nex.what() << endl;\n  }\n\n  return make_sound;\n}\n\nstd::string UnitsConverter::makeHelpSounds(Unit &unit)\n{\n  return \"\";\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/UnitsConverter.h",
    "content": "/*\n * UnitsExporter.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef UNITSEXPORTER_H\n#define UNITSEXPORTER_H\n\n// project\n#include \"dat/DataHub.h\"\n#include \"Storage.h\"\n#include \"dat/Unit.h\"\n\n// system\n\nnamespace dat\n{\n\n/**\n * Walk through the tree of Units in the dat architecture and convert what is referenced\n */\nclass UnitsConverter : public Converter\n{\npublic:\n  UnitsConverter(std::shared_ptr<Hurricane> hurricane, DataHub &datahub);\n  virtual ~UnitsConverter();\n\n  bool convert(json &unitsJson);\n\nprivate:\n  std::string makeReadySounds(Unit &unit);\n  std::string makeWhatSounds(Unit &unit);\n  std::string makeYesSounds(Unit &unit);\n  std::string makePissSounds(Unit &unit);\n  std::string makeHelpSounds(Unit &unit);\n\n  DataHub &mDatahub;\n};\n\n} /* namespace dat */\n\n#endif /* UNITSEXPORTER_H */\n"
  },
  {
    "path": "src/Wav.cpp",
    "content": "/*\n * Wav.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Wav.h\"\n#include \"Hurricane.h\"\n#include \"platform.h\"\n#include \"Logger.h\"\n#include \"FileUtil.h\"\n\n// system\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.Wav\");\n\nWav::Wav(std::shared_ptr<Hurricane> hurricane) :\n  Converter(hurricane)\n{\n}\n\nWav::Wav(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile) :\n  Converter(hurricane)\n{\n\n}\n\nWav::~Wav()\n{\n\n}\n\nbool Wav::convert(const std::string &arcfile,  Storage storage)\n{\n  bool result = true;\n\n  string wav_file = storage.getFullPath() + \".wav\";\n  string ogg_file = storage.getFullPath() + \".ogg\";\n\n  CheckPath(wav_file);\n  result = mHurricane->extractFile(arcfile, wav_file, false);\n\n  string ffmpeg_str =\n    string(\"ffmpeg -y -i \\\"\") + wav_file\n    + \"\\\" -acodec libvorbis  \\\"\"\n    + ogg_file + \"\\\"\";\n\n  //cout << \"video: \" << ffmpeg_str << endl;\n\n  // TODO: call it in a way we suppress the output to stdout\n  int sys_call = system(ffmpeg_str.c_str());\n  if (sys_call != 0)\n  {\n    result = false;\n  }\n\n  fs::remove(wav_file);\n\n  return result;\n}\n"
  },
  {
    "path": "src/Wav.h",
    "content": "/*\n * Wav.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef WAV_H\n#define WAV_H\n\n// project\n#include \"Converter.h\"\n#include \"Storage.h\"\n\n// system\n#include <string>\n\nclass Wav : public Converter\n{\npublic:\n  Wav(std::shared_ptr<Hurricane> hurricane);\n  Wav(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile);\n  virtual ~Wav();\n\n  /**\n   * storage the file basename without any file extension to let the converter the flexibility to add own extension\n   */\n  bool convert(const std::string &arcfile, Storage storage);\n\nprivate:\n\n};\n\n#endif /* WAV_H*/\n"
  },
  {
    "path": "src/Widgets.cpp",
    "content": "/*\n * Widget.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include <Palette.h>\n#include <PngExporter.h>\n#include \"Widgets.h\"\n#include \"Storm.h\"\n#include \"Preferences.h\"\n#include \"FileUtil.h\"\n#include \"pacman.h\"\n\n// system\n#include <fstream>\n#include <iostream>\n\nusing namespace std;\n\nWidgets::Widgets(std::shared_ptr<Hurricane> hurricane) :\n  Grp(hurricane)\n{\n\n}\n\nWidgets::~Widgets()\n{\n\n}\n\nbool Widgets::convert(const std::string &arcfile, Storage filename, json &frameExtractJson)\n{\n  bool result = true;\n\n  std::shared_ptr<DataChunk> dcGrp = mHurricane->extractDataChunk(arcfile);\n\n  std::vector<char> GrpVec = dcGrp->getCharVector();\n\n  mGRPImage.LoadImage(&GrpVec, true); // true: no duplicate widgets needed\n\n  CheckPath(filename.getFullPath());\n\n  if(dcGrp)\n  {\n    //cout << frameExtractJson << endl; // prints json object to screen\n\n    //vector<string> frameSingleNames;\n\n    for(auto &array : frameExtractJson)\n    {\n      //int frame_id = array.at(\"frame\");\n      string name = array.at(\"name\");\n      nlohmann::json frameArray = array.at(\"frame\");\n\n      int frameStitching = 0;\n      vector<int> stitchedFrames;\n      for(auto frame : frameArray)\n      {\n        //cout << \"frame: \" << frame << endl;\n        stitchedFrames.push_back(frame);\n        frameStitching++;\n      }\n\n      if(frameStitching == 1)\n      {\n        //frameSingleNames.push_back(name);\n        mGRPImage.SaveSinglePNG(filename.getFullPath() + \"/\" + name, *stitchedFrames.begin(), *stitchedFrames.begin()+1, true);\n      }\n      else if(frameStitching > 1)\n      {\n        mGRPImage.SaveStitchedPNG(filename.getFullPath() + \"/\" + name, stitchedFrames, 0, true);\n      }\n      else\n      {\n        cerr << \"something wrong with frame array!\" << endl;\n      }\n    }\n\n    //mGRPImage.SaveSinglePNG(filename.getFullPath(), frameSingleNames, 0, mGRPImage.getNumberOfFrames(), true);\n  }\n\n  return result;\n}\n\n\n\n"
  },
  {
    "path": "src/Widgets.h",
    "content": "/*\n * Widget.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef WIDGETS_H_\n#define WIDGETS_H_\n\n#include \"Grp.h\"\n#include \"Palette.h\"\n\n// system\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nclass Widgets: public Grp\n{\npublic:\n  Widgets(std::shared_ptr<Hurricane> hurricane);\n  virtual ~Widgets();\n\n  /**\n   * Convert a widget from data container as several PNG files\n   */\n  bool convert(const std::string &arcfile, Storage filename, json &frameExtractJson);\n\nprivate:\n\n};\n\n#endif /* WIDGETS_H_ */\n"
  },
  {
    "path": "src/WorldMap.cpp",
    "content": "/*\n * WorldMap.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"WorldMap.h\"\n"
  },
  {
    "path": "src/WorldMap.h",
    "content": "/*\n * WorldMap.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef WORLDMAP_H_\n#define WORLDMAP_H_\n\n// C++\n#include <cstring>\n#include <cstdint>\n#include <cstdlib>\n#include <vector>\n#include <string>\n\n#define SC_IsUnitMineral(x) ((x) == 176 || (x) == 177 || (x) == 178)  /// sc unit mineral\n#define SC_UnitGeyser\t    188\t    /// sc unit geyser\n#define SC_TerranSCV\t    7\t    /// terran scv\n#define SC_ZergDrone\t    41\t    /// zerg drone\n#define SC_ProtossProbe\t    64\t    /// protoss probe\n#define SC_TerranCommandCenter\t106 /// terran command center\n#define SC_ZergHatchery\t    131\t    /// zerg hatchery\n#define SC_ProtossNexus\t    154\t    /// protoss nexus\n#define SC_StartLocation\t214\t    /// sc start location\n\n#define PlayerMax 16\n\n#define SettingsPresetMapDefault  -1  /// Special: Use map supplied\n#define SettingsNumUnitsMapDefault  SettingsPresetMapDefault\n#define SettingsNumUnits1    0\n\nclass Unit\n{\npublic:\n  Unit() :\n    X(0),\n    Y(0),\n    Type(0),\n    Properties(0),\n    ValidElements(0),\n    Player(0),\n    HitPointsPercent(0),\n    ShieldPointsPercent(0),\n    EnergyPointsPercent(0),\n    ResourceAmount(0),\n    NumUnitsIn(0),\n    StateFlags(0)\n  {\n\n  }\n\n  ~Unit()\n  {\n\n  }\n\n\n  unsigned short X;\n  unsigned short Y;\n  unsigned short Type;\n  unsigned short Properties;\n  unsigned short ValidElements;\n  unsigned char Player;\n  unsigned char HitPointsPercent;\n  unsigned char ShieldPointsPercent;\n  unsigned char EnergyPointsPercent;\n  unsigned int ResourceAmount;\n  unsigned short NumUnitsIn;\n  unsigned char StateFlags;\n};\n\ntypedef struct Location\n{\n  unsigned int StartX;\n  unsigned int StartY;\n  unsigned int EndX;\n  unsigned int EndY;\n  unsigned short StringNumber;\n  union {\n    unsigned short Flags;\n    struct {\n      unsigned LowElevation:1;\n      unsigned MediumElevation:1;\n      unsigned HighElevation:1;\n      unsigned LowAir:1;\n      unsigned MediumAir:1;\n      unsigned HighAir:1;\n    };\n  };\n} Location;\n\ntypedef struct TriggerCondition\n{\n  unsigned int Location;\n  unsigned int Group;\n  unsigned int QualifiedNumber;\n  unsigned short UnitType;\n  unsigned char CompType;\n  unsigned char Condition;\n  unsigned char ResType;\n  unsigned char Flags;\n} TriggerCondition;\n\ntypedef struct TriggerAction\n{\n  unsigned int Source;\n  unsigned int TriggerNumber;\n  unsigned int WavNumber;\n  unsigned int Time;\n  unsigned int FirstGroup;\n  unsigned int SecondGroup;\n  unsigned short Status;\n  unsigned char Action;\n  unsigned char NumUnits;\n  unsigned char ActionFlags;\n} TriggerAction;\n\ntypedef struct Trigger\n{\n  TriggerCondition TriggerConditions[16];\n  TriggerAction TriggerActions[64];\n} Trigger;\n\ntypedef struct WorldMap\n{\n  int MapWidth;\n  int MapHeight;\n  char *MapTerrainName;\n  char *Description;\n  int PlayerRace[PlayerMax];\n  int PlayerType[PlayerMax];\n  int *Tiles;\n  struct\n  {\n    int X;\n    int Y;\n  } PlayerStart[PlayerMax];\n  std::vector<Location> Locations;\n  std::vector<Trigger> Triggers;\n  std::vector<Unit> Units;\n  std::vector<std::string> Strings;\n\n  WorldMap() :\n      MapWidth(0), MapHeight(0), MapTerrainName(NULL), Description(NULL), Tiles(\n          NULL)\n  {\n    memset(PlayerRace, 0, sizeof(PlayerRace));\n    memset(PlayerType, 0, sizeof(PlayerType));\n    memset(PlayerStart, 0, sizeof(PlayerStart));\n  }\n} WorldMap;\n\n#endif /* WORLDMAP_H_ */\n\n// Local Variables:\n// c-basic-offset: 2\n// End:\n"
  },
  {
    "path": "src/dat/DataHub.cpp",
    "content": "/*\n * DataHub.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"Logger.h\"\n#include \"luagen.h\"\n#include \"DataHub.h\"\n#include \"StringUtil.h\"\n#include \"Grp.h\"\n#include \"Unit.h\"\n#include \"Preferences.h\"\n#include \"FileUtil.h\"\n#include \"Hurricane.h\"\n\n// System\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.DataHub\");\n\nDataHub::DataHub(std::shared_ptr<Hurricane> hurricane) :\n  KaitaiConverter(hurricane)\n{\n  init_units_dat();\n\n  init_orders_dat();\n\n  init_weapons_dat();\n\n  init_flingy_dat();\n\n  init_sprites_dat();\n\n  init_images_dat();\n\n  init_sfxdata_dat();\n\n  init_portdata_dat();\n\n  init_upgrades_dat();\n\n  init_techdata_dat();\n\n  init_mapdata_dat();\n\n  init_stat_txt_tbl();\n\n  init_images_tbl();\n\n  init_sfxdata_tbl();\n\n  init_portdata_tbl();\n\n  init_mapdata_tbl();\n\n  init_iscript_bin();\n}\n\nDataHub::~DataHub()\n{\n}\n\nvoid DataHub::init_units_dat()\n{\n  string sc_arr_units_dat = \"arr\\\\units.dat\";\n\n  m_units_stream = mHurricane->extractStream(sc_arr_units_dat);\n  m_units_ks = make_shared<kaitai::kstream>(&*m_units_stream);\n\n  units = make_shared<units_dat_t>(m_units_ks.get());\n}\n\nvoid DataHub::init_orders_dat()\n{\n  string sc_arr_orders_dat = \"arr\\\\orders.dat\";\n\n  m_orders_stream = mHurricane->extractStream(sc_arr_orders_dat);\n\n  m_orders_ks = make_shared<kaitai::kstream>(&*m_orders_stream);\n\n  orders = make_shared<orders_dat_t>(m_orders_ks.get());\n}\n\nvoid DataHub::init_weapons_dat()\n{\n  string sc_arr_weapons_dat = \"arr\\\\weapons.dat\";\n\n  m_weapons_stream = mHurricane->extractStream(sc_arr_weapons_dat);\n  m_weapons_ks = make_shared<kaitai::kstream>(&*m_weapons_stream);\n\n  weapons = make_shared<weapons_dat_t>(m_weapons_ks.get());\n}\n\nvoid DataHub::init_flingy_dat()\n{\n  string sc_arr_flingy_dat = \"arr\\\\flingy.dat\";\n\n  m_flingy_stream = mHurricane->extractStream(sc_arr_flingy_dat);\n  m_flingy_ks = make_shared<kaitai::kstream>(&*m_flingy_stream);\n\n  flingy = make_shared<flingy_dat_t>(m_flingy_ks.get());\n}\n\nvoid DataHub::init_sprites_dat()\n{\n  string sc_arr_sprites_dat = \"arr\\\\sprites.dat\";\n\n  m_sprites_stream = mHurricane->extractStream(sc_arr_sprites_dat);\n  m_sprites_ks = make_shared<kaitai::kstream>(&*m_sprites_stream);\n\n  sprites = make_shared<sprites_dat_t>(m_sprites_ks.get());\n}\n\nvoid DataHub::init_images_dat()\n{\n  string sc_arr_images_dat = \"arr\\\\images.dat\";\n\n  m_images_stream = mHurricane->extractStream(sc_arr_images_dat);\n  m_images_ks = make_shared<kaitai::kstream>(&*m_images_stream);\n\n  images = make_shared<images_dat_t>(m_images_ks.get());\n}\n\nvoid DataHub::init_sfxdata_dat()\n{\n  string sc_arr_sfxdata_dat = \"arr\\\\sfxdata.dat\";\n\n  m_sfxdata_stream = mHurricane->extractStream(sc_arr_sfxdata_dat);\n  m_sfxdata_ks = make_shared<kaitai::kstream>(&*m_sfxdata_stream);\n\n  sfxdata = make_shared<sfxdata_dat_t>(m_sfxdata_ks.get());\n}\n\nvoid DataHub::init_portdata_dat()\n{\n  string sc_arr_portdata_dat = \"arr\\\\portdata.dat\";\n\n  m_portdata_stream = mHurricane->extractStream(sc_arr_portdata_dat);\n  m_portdata_ks = make_shared<kaitai::kstream>(&*m_portdata_stream);\n\n  portdata = make_shared<portdata_dat_t>(m_portdata_ks.get());\n}\n\nvoid DataHub::init_upgrades_dat()\n{\n  string sc_arr_upgrades_dat = \"arr\\\\upgrades.dat\";\n\n  m_upgrades_stream = mHurricane->extractStream(sc_arr_upgrades_dat);\n  m_upgrades_ks = make_shared<kaitai::kstream>(&*m_upgrades_stream);\n\n  upgrades = make_shared<upgrades_dat_t>(m_upgrades_ks.get());\n}\n\nvoid DataHub::init_techdata_dat()\n{\n  string sc_arr_techdata_dat = \"arr\\\\techdata.dat\";\n\n  m_techdata_stream = mHurricane->extractStream(sc_arr_techdata_dat);\n  m_techdata_ks = make_shared<kaitai::kstream>(&*m_techdata_stream);\n\n  techdata = make_shared<techdata_dat_t>(m_techdata_ks.get());\n}\n\nvoid DataHub::init_mapdata_dat()\n{\n  string sc_arr_mapdata_dat = \"arr\\\\mapdata.dat\";\n\n  m_mapdata_stream = mHurricane->extractStream(sc_arr_mapdata_dat);\n  m_mapdata_ks = make_shared<kaitai::kstream>(&*m_mapdata_stream);\n\n  mapdata = make_shared<mapdata_dat_t>(m_mapdata_ks.get());\n}\n\nvoid DataHub::init_stat_txt_tbl()\n{\n  string sc_rez_stat_txt_tbl = \"rez\\\\stat_txt.tbl\";\n\n  std::shared_ptr<std::istream> tbl_stream = mHurricane->extractStream(sc_rez_stat_txt_tbl);\n  std::shared_ptr<kaitai::kstream> stat_txt_ks = make_shared<kaitai::kstream>(&*tbl_stream);\n\n  Tbl stat_txt;\n  /*std::vector<TblEntry>*/\n  stat_txt_tbl_vec = stat_txt.convertFromStream(stat_txt_ks);\n\n  /*int vec_pos = 0;\n\n  // This below splits the big string vector to smaller ones per type. I found later that regarding the data index one\n  // big file is easier to handle. But maybe I change my mind later to enable this again...\n\n  stat_txt_units_tbl_vec.resize(units->flingy()->size());\n  std::copy(stat_txt_tbl_vec.begin() + vec_pos, stat_txt_tbl_vec.begin() + units->flingy()->size(), stat_txt_units_tbl_vec.begin());\n  vec_pos += units->flingy()->size();\n\n  stat_txt_weapons_tbl_vec.resize(weapons->label()->size());\n  std::copy(stat_txt_tbl_vec.begin() + vec_pos, stat_txt_tbl_vec.begin() + vec_pos + weapons->label()->size(), stat_txt_weapons_tbl_vec.begin());\n  vec_pos += weapons->label()->size();\n\n  stat_txt_error_messages_tbl_vec.resize(weapons->error_message()->size());\n  std::copy(stat_txt_tbl_vec.begin() + vec_pos, stat_txt_tbl_vec.begin() + vec_pos + weapons->error_message()->size(), stat_txt_error_messages_tbl_vec.begin());\n  vec_pos += weapons->error_message()->size();\n\n  stat_txt_upgrades_tbl_vec.resize(upgrades->label()->size());\n  std::copy(stat_txt_tbl_vec.begin() + vec_pos, stat_txt_tbl_vec.begin() + vec_pos + upgrades->label()->size(), stat_txt_upgrades_tbl_vec.begin());\n  vec_pos += upgrades->label()->size();\n\n  stat_txt_orders_tbl_vec.resize(orders->label()->size());\n  std::copy(stat_txt_tbl_vec.begin() + vec_pos, stat_txt_tbl_vec.begin() + vec_pos + orders->label()->size(), stat_txt_orders_tbl_vec.begin());\n  vec_pos += orders->label()->size();\n\n  stat_txt_techdata_tbl_vec.resize(techdata->label()->size());\n  std::copy(stat_txt_tbl_vec.begin() + vec_pos, stat_txt_tbl_vec.begin() + vec_pos + techdata->label()->size(), stat_txt_techdata_tbl_vec.begin());\n  vec_pos += techdata->label()->size();*/\n}\n\nvoid DataHub::init_images_tbl()\n{\n  string sc_arr_images_tbl = \"arr\\\\images.tbl\";\n\n  std::shared_ptr<std::istream> tbl_stream = mHurricane->extractStream(sc_arr_images_tbl);\n  std::shared_ptr<kaitai::kstream> images_tbl_ks = make_shared<kaitai::kstream>(&*tbl_stream);\n\n  Tbl images_tbl;\n  images_tbl_vec = images_tbl.convertFromStream(images_tbl_ks);\n}\n\nvoid DataHub::init_sfxdata_tbl()\n{\n  string sc_arr_sfxdata_tbl = \"arr\\\\sfxdata.tbl\";\n\n  std::shared_ptr<std::istream> tbl_stream = mHurricane->extractStream(sc_arr_sfxdata_tbl);\n  std::shared_ptr<kaitai::kstream> sfxdata_tbl_ks = make_shared<kaitai::kstream>(&*tbl_stream);\n\n  Tbl sfxdata_tbl;\n  sfxdata_tbl_vec = sfxdata_tbl.convertFromStream(sfxdata_tbl_ks);\n}\n\nvoid DataHub::init_portdata_tbl()\n{\n  string sc_arr_portdata_tbl = \"arr\\\\portdata.tbl\";\n\n  std::shared_ptr<std::istream> tbl_stream = mHurricane->extractStream(sc_arr_portdata_tbl);\n  std::shared_ptr<kaitai::kstream> portdata_tbl_ks = make_shared<kaitai::kstream>(&*tbl_stream);\n\n  Tbl portdata_tbl;\n  portdata_tbl_vec = portdata_tbl.convertFromStream(portdata_tbl_ks);\n}\n\nvoid DataHub::init_mapdata_tbl()\n{\n  string sc_arr_mapdata_tbl = \"arr\\\\mapdata.tbl\";\n\n  std::shared_ptr<std::istream> tbl_stream = mHurricane->extractStream(sc_arr_mapdata_tbl);\n  std::shared_ptr<kaitai::kstream> mapdata_tbl_ks = make_shared<kaitai::kstream>(&*tbl_stream);\n\n  Tbl mapdata_tbl;\n  mapdata_tbl_vec = mapdata_tbl.convertFromStream(mapdata_tbl_ks);\n}\n\nvoid DataHub::init_iscript_bin()\n{\n  string sc_iscript_bin = \"scripts\\\\iscript.bin\";\n\n  m_iscript_stream = mHurricane->extractStream(sc_iscript_bin);\n  m_iscript_ks = make_shared<kaitai::kstream>(&*m_iscript_stream);\n\n  iscript = make_shared<iscript_bin_t>(m_iscript_ks.get());\n\n  /* This code creates a map to access the iscripts by image ID */\n  for(unsigned int i = 0; i < iscript->entree_offsets()->size(); i++)\n  {\n    auto entree_offset = iscript->entree_offsets()->at(i);\n\n    uint16_t iscript_id = entree_offset->iscript_id();\n\n    m_iscriptImageEntreeMap[iscript_id] = i;\n  }\n}\n\nuint16_t DataHub::getIScriptImage(uint16_t index)\n{\n  return m_iscriptImageEntreeMap.at(index);\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/DataHub.h",
    "content": "/*\n * DataHub.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef DATAHUB_H\n#define DATAHUB_H\n\n// project\n#include \"KaitaiConverter.h\"\n#include \"Palette.h\"\n#include \"Palette2D.h\"\n#include \"Tbl.h\"\n\n#include \"kaitai/units_dat.h\"\n#include \"kaitai/weapons_dat.h\"\n#include \"kaitai/flingy_dat.h\"\n#include \"kaitai/sprites_dat.h\"\n#include \"kaitai/images_dat.h\"\n#include \"kaitai/sfxdata_dat.h\"\n#include \"kaitai/portdata_dat.h\"\n#include \"kaitai/upgrades_dat.h\"\n#include \"kaitai/orders_dat.h\"\n#include \"kaitai/techdata_dat.h\"\n#include \"kaitai/mapdata_dat.h\"\n#include \"kaitai/iscript_bin.h\"\n\n// System\n#include <nlohmann/json.hpp>\n#include <map>\n\nusing json = nlohmann::json;\n\nnamespace dat\n{\n\n/**\n * The DataHub parses the complete data structures inside those files:\n * - arr\\\\units.dat\n * - arr\\\\orders.dat\n * - arr\\\\weapons.dat\n * - arr\\\\flingy.dat\n * - arr\\\\sprites.dat\n * - arr\\\\images.dat\n * - arr\\\\sfxdata.dat\n * - arr\\\\portdata.dat\n * - arr\\\\upgrades.dat\n * - arr\\\\techdata.dat\n * - arr\\\\mapdata.dat\n * - arr\\\\images.tbl\n * - arr\\\\sfxdata.tbl\n * - arr\\\\portdata.tbl\n * - arr\\\\mapdata.tbl\n * - rez\\\\stat_txt.tbl\n *\n * As those data has have depends on each other they're all parsed together in one run. After being parsed\n * to Kaitai data structures they could be accessed from outside.\n *\n * The Kaitai parsed objects in this class are by intension public. There's no benefit in putting dozen silly\n * getter around them. The alternative to put them private means to implement every parser logic\n * inside this class or friend them all.\n *\n * So the design decision is just to let them public and the outside accessing function should only read them!\n * If I ever put this stuff to a general purpose library this design might change.\n *\n *  \"with great power comes great responsibility\" - (Spiderman)\n */\nclass DataHub : public KaitaiConverter\n{\npublic:\n  DataHub(std::shared_ptr<Hurricane> hurricane);\n  virtual ~DataHub();\n\n  uint16_t getIScriptImage(uint16_t index);\n\n  // Kaitai parsed objects\n  std::shared_ptr<units_dat_t> units;\n  std::shared_ptr<orders_dat_t> orders;\n  std::shared_ptr<weapons_dat_t> weapons;\n  std::shared_ptr<flingy_dat_t> flingy;\n  std::shared_ptr<sprites_dat_t> sprites;\n  std::shared_ptr<images_dat_t> images;\n  std::shared_ptr<sfxdata_dat_t> sfxdata;\n  std::shared_ptr<portdata_dat_t> portdata;\n  std::shared_ptr<upgrades_dat_t> upgrades;\n  std::shared_ptr<techdata_dat_t> techdata;\n  std::shared_ptr<mapdata_dat_t> mapdata;\n  std::shared_ptr<iscript_bin_t> iscript;\n\n  // kaitai parsed Tbl vectors\n  std::vector<TblEntry> stat_txt_tbl_vec;\n  /*std::vector<TblEntry> stat_txt_units_tbl_vec;\n  std::vector<TblEntry> stat_txt_weapons_tbl_vec;\n  std::vector<TblEntry> stat_txt_error_messages_tbl_vec;\n  std::vector<TblEntry> stat_txt_upgrades_tbl_vec;\n  std::vector<TblEntry> stat_txt_orders_tbl_vec;\n  std::vector<TblEntry> stat_txt_techdata_tbl_vec;*/\n\n  std::vector<TblEntry> images_tbl_vec;\n  std::vector<TblEntry> sfxdata_tbl_vec;\n  std::vector<TblEntry> portdata_tbl_vec;\n  std::vector<TblEntry> mapdata_tbl_vec;\n\nprivate:\n  // units.dat\n  void init_units_dat();\n\n  // orders.dat\n  void init_orders_dat();\n\n  // weapons.dat\n  void init_weapons_dat();\n\n  // flingy.dat\n  void init_flingy_dat();\n\n  // sprites.dat\n  void init_sprites_dat();\n\n  // images.dat\n  void init_images_dat();\n\n  // sfxdata.dat\n  void init_sfxdata_dat();\n\n  // portdata.dat\n  void init_portdata_dat();\n\n  // upgrades.dat\n  void init_upgrades_dat();\n\n  // techdata.dat\n  void init_techdata_dat();\n\n  // mapdata.dat\n  void init_mapdata_dat();\n\n  // stat_txt.tbl\n  void init_stat_txt_tbl();\n\n  // images.tbl\n  void init_images_tbl();\n\n  // sfxdata.tbl\n  void init_sfxdata_tbl();\n\n  // portdata.tbl\n  void init_portdata_tbl();\n\n  // mapdata.tbl\n  void init_mapdata_tbl();\n\n  // iscript.bin\n  void init_iscript_bin();\n\n  std::shared_ptr<std::istream> m_units_stream;\n  std::shared_ptr<std::istream> m_orders_stream;\n  std::shared_ptr<std::istream> m_weapons_stream;\n  std::shared_ptr<std::istream> m_flingy_stream;\n  std::shared_ptr<std::istream> m_sprites_stream;\n  std::shared_ptr<std::istream> m_images_stream;\n  std::shared_ptr<std::istream> m_sfxdata_stream;\n  std::shared_ptr<std::istream> m_portdata_stream;\n  std::shared_ptr<std::istream> m_upgrades_stream;\n  std::shared_ptr<std::istream> m_techdata_stream;\n  std::shared_ptr<std::istream> m_mapdata_stream;\n  std::shared_ptr<std::istream> m_iscript_stream;\n\n  std::shared_ptr<kaitai::kstream> m_units_ks;\n  std::shared_ptr<kaitai::kstream> m_orders_ks;\n  std::shared_ptr<kaitai::kstream> m_weapons_ks;\n  std::shared_ptr<kaitai::kstream> m_flingy_ks;\n  std::shared_ptr<kaitai::kstream> m_sprites_ks;\n  std::shared_ptr<kaitai::kstream> m_images_ks;\n  std::shared_ptr<kaitai::kstream> m_sfxdata_ks;\n  std::shared_ptr<kaitai::kstream> m_portdata_ks;\n  std::shared_ptr<kaitai::kstream> m_upgrades_ks;\n  std::shared_ptr<kaitai::kstream> m_techdata_ks;\n  std::shared_ptr<kaitai::kstream> m_mapdata_ks;\n  std::shared_ptr<kaitai::kstream> m_iscript_ks;\n\n  std::map<uint16_t, uint16_t> m_iscriptImageEntreeMap;\n};\n\n} /* namespace dat */\n\n#endif /* DATAHUB_H */\n"
  },
  {
    "path": "src/dat/Flingy.cpp",
    "content": "/*\n * Flingy.cpp\n *\n *      Author: Andreas\n */\n\n#include \"Flingy.h\"\n#include \"Logger.h\"\n\nusing namespace std;\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.Flingy\");\n\nFlingy::Flingy(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n\n}\n\nFlingy::~Flingy()\n{\n\n}\n\nuint16_t Flingy::sprite()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.flingy->sprite()->at(mId);\n}\n\nSprite Flingy::sprite_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Sprite(mDatahub, sprite());\n}\n\nuint32_t Flingy::speed()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.flingy->speed()->at(mId);\n}\n\nuint16_t Flingy::acceleration()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.flingy->acceleration()->at(mId);\n}\n\nuint32_t Flingy::halt_distance()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.flingy->halt_distance()->at(mId);\n}\n\nuint8_t Flingy::turn_radius()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.flingy->turn_radius()->at(mId);\n}\n\nuint8_t Flingy::unused()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.flingy->unused()->at(mId);\n}\n\nuint8_t Flingy::movement_control()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.flingy->movement_control()->at(mId);\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Flingy.h",
    "content": "/*\n * Flingy.h\n *\n *      Author: andreas\n */\n\n#ifndef FLINGY_H\n#define FLINGY_H\n\n// project\n#include \"ObjectAccess.h\"\n#include \"Sprite.h\"\n\nnamespace dat\n{\n\nclass Flingy : public ObjectAccess\n{\npublic:\n  Flingy(DataHub &datahub, unsigned int id);\n  virtual ~Flingy();\n\n  uint16_t sprite();\n  Sprite sprite_obj();\n\n  uint32_t speed();\n\n  uint16_t acceleration();\n\n  uint32_t halt_distance();\n\n  uint8_t turn_radius();\n\n  uint8_t unused();\n\n  uint8_t movement_control();\n\nprivate:\n\n};\n\n} /* namespace dat */\n\n#endif /* FLINGY_H */\n"
  },
  {
    "path": "src/dat/IScript.cpp",
    "content": "/*\n * IScript.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"IScript.h\"\n#include \"Logger.h\"\n\n// system\n#include <iostream>\n#include <iterator>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.dat.IScript\");\n\nnamespace dat\n{\n\nIScript::IScript(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, datahub.getIScriptImage(id))\n{\n}\n\nIScript::~IScript()\n{\n}\n\n\n\nstd::vector<iscript_bin_t::opcode_type_t*> IScript::getAnimationScript(IScript::AnimationType animationType)\n{\n  return getAnimationScript(static_cast<unsigned int>(animationType));\n}\n\nstd::vector<iscript_bin_t::opcode_type_t*> IScript::getAnimationScript(unsigned int animationType)\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \":\" + to_string(animationType) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  iscript_bin_t::scpe_type_t* scpe = mDatahub.iscript->scpe()->at(mId);\n\n  std::vector<iscript_bin_t::scpe_content_type_t*>* scpe_content_vec = scpe->scpe_content();\n\n  // calculate the offset hash list per iscript (TODO: maybe cache this?)\n  unordered_set<uint16_t> scpe_offset_table;\n  for(auto scpe_content : *scpe_content_vec)\n  {\n    scpe_offset_table.insert(scpe_content->scpe_opcode_offset());\n  }\n\n  iscript_bin_t::scpe_content_type_t* scpe_content = scpe_content_vec->at(animationType);\n  opcode_list_type_t* opcode_list_type = scpe_content->scpe_opcode_list();\n\n  // if kaitai animation script object is null give a empty vector back (TODO: maybe change design)\n  if(!opcode_list_type)\n  {\n    return std::vector<iscript_bin_t::opcode_type_t*>();\n  }\n  // else... parse the object....\n\n  std::vector<kaitai::kstruct*>* opcode_vec_ks = opcode_list_type->read_list(scpe_offset_table);\n\n  std::vector<iscript_bin_t::opcode_type_t*> opcode_vec(opcode_vec_ks->size());\n\n  std::transform(opcode_vec_ks->begin(), opcode_vec_ks->end(), opcode_vec.begin(),\n                 [](auto ptr) {return static_cast<iscript_bin_t::opcode_type_t*>(ptr); });\n\n  return opcode_vec;\n}\n\nint8_t IScript::getAnimationCount()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  return mDatahub.iscript->scpe()->at(mId)->num_scpe_content();\n}\n\nbool IScript::is_format_bw()\n{\n  return !mDatahub.iscript->version_tag();\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/IScript.h",
    "content": "/*\n * IScript.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef ISCRIPT_H\n#define ISCRIPT_H\n\n// project\n#include \"ObjectAccess.h\"\n\nnamespace dat\n{\n\nclass IScript: public ObjectAccess\n{\npublic:\n  IScript(DataHub &datahub, unsigned int id);\n  virtual ~IScript();\n\n  enum AnimationType\n    {\n      Init, // Initial animation\n      Death, // Death animation\n      GndAttkInit, // Initial ground attack animation\n      AirAttkInit, // Initial air attack animation\n      Unused1, // Unknown/unused animation\n      GndAttkRpt, // Repeated ground attack animation\n      AirAttkRpt, // Repeated air attack animation\n      CastSpell, // Spell casting animation\n      GndAttkToIdle, // Animation for returning to an idle state after a ground attack\n      AirAttkToIdle, // Animation for returning to an idle state after an air attack\n      Unused2, // Unknown/unused animation\n      Walking, // Walking/moving animation\n      WalkingToIdle, // Animation for returning to an idle state after walking/moving\n      SpecialState1, // Some sort of category of special animations, in some cases an in-transit animation, sometimes used for special orders, sometimes having to do with the animation when something finishes morphing, or the first stage of a construction animation\n      SpecialState2, // Some sort of category of special animations, in some cases a burrowed animation, sometimes used for special orders, sometimes having to do with the animation when canceling a morph, or the second stage of a construction animation\n      AlmostBuilt, // An animation for one part of the building process\n      Built, // Final animation before finishing being built\n      Landing, // Landing animation\n      LiftOff, // Lifting off animation\n      IsWorking, // Animation for when researching an upgrade/technology or training/building units and some other animations for some sort of work being done\n      WorkingToIdle, // Animation for returning to an idle state after IsWorking\n      WarpIn, // Warping in animation\n      Unused3, // Unknown/unused animation\n      StarEditInit, // Previously called InitTurret, this is actually an alternate initial animation for StarEdit a.k.a. the Campaign Editor\n      Disable, // Animation for becoming disabled, either through the \"Set Doodad State\" trigger action or by not being in the psi field of any pylons\n      Burrow, // Burrowing animation\n      UnBurrow, // Unburrowing animation\n      Enable // Animation for becoming enabled, either through the \"Set Doodad State\" trigger action or by being in the psi field of a pylon\n    };\n\n  std::vector<iscript_bin_t::opcode_type_t*> getAnimationScript(IScript::AnimationType animationType);\n\n  std::vector<iscript_bin_t::opcode_type_t*> getAnimationScript(unsigned int animationType);\n\n  int8_t getAnimationCount();\n\n  /**\n   * @return true in case the iscript format is broodwar. (Nothing to do as the parser detects and handles the format itself)\n   */\n  bool is_format_bw();\n\nprivate:\n\n};\n\n} /* namespace dat */\n\n#endif /* ISCRIPT_H */\n"
  },
  {
    "path": "src/dat/Image.cpp",
    "content": "/*\n * Image.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"Image.h\"\n#include \"Logger.h\"\n#include \"platform.h\"\n#include \"StringUtil.h\"\n\nusing namespace std;\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.Image\");\n\nImage::Image(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nImage::~Image()\n{\n\n}\n\nuint32_t Image::grp()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return  mDatahub.images->grp()->at(mId);\n}\n\nTblEntry Image::grp_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images_tbl_vec.at(grp()-1);\n}\n\nbool Image::gfx_turns()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->gfx_turns()->at(mId);\n}\n\nbool Image::clickable()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->clickable()->at(mId);\n}\n\nbool Image::use_full_iscript()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->use_full_iscript()->at(mId);\n}\n\nbool Image::draw_if_cloaked()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->draw_if_cloaked()->at(mId);\n}\n\nimages_dat_t::draw_function_enum_t Image::draw_function()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->draw_function()->at(mId);\n}\n\nimages_dat_t::remapping_enum_t Image::remapping()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->remapping()->at(mId);\n}\n\nuint32_t Image::iscript()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->iscript()->at(mId);\n}\n\nIScript Image::iscript_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return IScript(mDatahub, iscript());\n}\n\nuint32_t Image::shield_overlay()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->shield_overlay()->at(mId);\n}\n\nTblEntry Image::shield_overlay_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint32_t overlay = shield_overlay();\n\n  if(overlay == Image::overlay_none)\n    {\n      throw PropertyNotAvailableException(mId, \"shield_overlay_tbl\");\n    }\n\n  return  mDatahub.images_tbl_vec.at(overlay);\n}\n\nuint32_t Image::attack_overlay()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->attack_overlay()->at(mId);\n}\n\nTblEntry Image::attack_overlay_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint32_t overlay = attack_overlay();\n\n  if(overlay == Image::overlay_none)\n    {\n      throw PropertyNotAvailableException(mId, \"attack_overlay_tbl\");\n    }\n\n  return  mDatahub.images_tbl_vec.at(overlay);\n}\n\nuint32_t Image::damage_overlay()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->damage_overlay()->at(mId);\n}\n\nTblEntry Image::damage_overlay_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint32_t overlay = damage_overlay();\n\n  if(overlay == Image::overlay_none)\n    {\n      throw PropertyNotAvailableException(mId, \"damage_overlay_tbl\");\n    }\n\n  return  mDatahub.images_tbl_vec.at(overlay);\n}\n\nuint32_t Image::special_overlay()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->special_overlay()->at(mId);\n}\n\nTblEntry Image::special_overlay_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint32_t overlay = special_overlay();\n\n  if(overlay == Image::overlay_none)\n    {\n      throw PropertyNotAvailableException(mId, \"special_overlay_tbl\");\n    }\n\n  return  mDatahub.images_tbl_vec.at(overlay);\n}\n\nuint32_t Image::landing_dust_overlay()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->landing_dust_overlay()->at(mId);\n}\n\nTblEntry Image::landing_dust_overlay_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint32_t overlay = landing_dust_overlay();\n\n  if(overlay == Image::overlay_none)\n    {\n      throw PropertyNotAvailableException(mId, \"landing_dust_overlay_tbl\");\n    }\n\n  return  mDatahub.images_tbl_vec.at(overlay);\n}\n\nuint32_t Image::lift_off_dust_overlay()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.images->lift_off_dust_overlay()->at(mId);\n}\n\nTblEntry Image::lift_off_dust_overlay_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint32_t overlay = lift_off_dust_overlay();\n\n  if(overlay == Image::overlay_none)\n    {\n      throw PropertyNotAvailableException(mId, \"lift_off_dust_overlay_tbl\");\n    }\n\n  return  mDatahub.images_tbl_vec.at(overlay);\n}\n\nstd::string Image::getIDString()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  string image_name(\"image_\" + to_string(mId) + \"_\" + grp_tbl().name1());\n  replaceString(\"\\\\\", \"_\", image_name);\n  //fs::path p(image_name);\n\n  image_name = to_lower(cutFileEnding(image_name));\n  //cout << \"image_name: \" << image_name << endl;\n\n  return image_name;\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Image.h",
    "content": "/*\n * Image.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef IMAGE_H\n#define IMAGE_H\n\n// project\n#include \"ObjectAccess.h\"\n#include \"PropertyNotAvailableException.h\"\n#include \"IScript.h\"\n\nnamespace dat\n{\n\n/**\n * Wrapper interface for Kaitai parser images_dat.ksy, but with easier access in the game logic.\n * New functions are added on need as wrapper functions. The function names should stay the same\n * and documentation in only mandatory if needed to understand the difference.\n *\n */\nclass Image : public ObjectAccess\n{\npublic:\n  Image(DataHub &datahub, unsigned int id);\n  virtual ~Image();\n\n  uint32_t grp();\n  TblEntry grp_tbl();\n\n  bool gfx_turns();\n\n  bool clickable();\n\n  bool use_full_iscript();\n\n  bool draw_if_cloaked();\n\n  images_dat_t::draw_function_enum_t draw_function();\n\n  images_dat_t::remapping_enum_t remapping();\n\n  uint32_t iscript();\n  IScript iscript_obj();\n\n  uint32_t shield_overlay();\n  TblEntry shield_overlay_tbl();\n\n  uint32_t attack_overlay();\n  TblEntry attack_overlay_tbl();\n\n  uint32_t damage_overlay();\n  TblEntry damage_overlay_tbl();\n\n  uint32_t special_overlay();\n  TblEntry special_overlay_tbl();\n\n  uint32_t landing_dust_overlay();\n  TblEntry landing_dust_overlay_tbl();\n\n  uint32_t lift_off_dust_overlay();\n  TblEntry lift_off_dust_overlay_tbl();\n\n  /***/\n  std::string getIDString();\n\n  static const int overlay_none = 0;\n\nprivate:\n\n};\n\n} /* namespace dat */\n\n#endif /* IMAGE_H */\n"
  },
  {
    "path": "src/dat/ObjectAccess.h",
    "content": "/*\n * ObjectAccess.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef OBJECTACCESS_H\n#define OBJECTACCESS_H\n\n// project\n#include \"DataHub.h\"\n\nnamespace dat\n{\n\nclass ObjectAccess\n{\npublic:\n  ObjectAccess(DataHub &datahub, unsigned int id) : mDatahub(datahub), mId(id) {}\n  virtual ~ObjectAccess() {}\n\n  virtual unsigned int id() {return mId;}\n\n  //virtual std::string id_string() = 0;\n\nprotected:\n  DataHub &mDatahub;\n  unsigned int mId;\n};\n\n} /* namespace dat */\n\n#endif /* OBJECTACCESS_H */\n"
  },
  {
    "path": "src/dat/Order.cpp",
    "content": "/*\n * Order.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Order.h\"\n#include \"Logger.h\"\n\nstatic Logger logger = Logger(\"startool.dat.Order\");\n\nusing namespace std;\n\nnamespace dat\n{\n\nOrder::Order(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nOrder::~Order()\n{\n\n}\n\nuint16_t Order::label()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->label()->at(mId);\n}\n\nTblEntry Order::label_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.stat_txt_tbl_vec.at(label());\n}\n\nbool Order::use_weapon_targeting()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->use_weapon_targeting()->at(mId);\n}\n\nuint8_t Order::unknown2()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown2()->at(mId);\n}\n\nuint8_t Order::unknown3()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown3()->at(mId);\n}\n\nuint8_t Order::unknown4()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown4()->at(mId);\n}\n\nuint8_t Order::unknown5()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown5()->at(mId);\n}\n\nuint8_t Order::interruptible()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->interruptible()->at(mId);\n}\n\nuint8_t Order::unknown7()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown7()->at(mId);\n}\n\nuint8_t Order::queueable()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->queueable()->at(mId);\n}\n\nuint8_t Order::unknown9()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown9()->at(mId);\n}\n\nuint8_t Order::unknown10()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown10()->at(mId);\n}\n\nuint8_t Order::unknown11()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown11()->at(mId);\n}\n\nuint8_t Order::unknown12()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown12()->at(mId);\n}\n\nuint8_t Order::targeting()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->targeting()->at(mId);\n}\n\nWeapon Order::targeting_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  uint8_t targeting_id = targeting();\n\n  // strange logic in the data. If the weapon links to a index bigger than weapon then it's 'none'\n  if(targeting_id >= mDatahub.weapons->label()->size())\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: targeting_obj > size\"));\n    throw PropertyNotAvailableException(mId, \"targeting_obj\");\n  }\n\n  return Weapon(mDatahub, targeting_id);\n}\n\nuint8_t Order::energy()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->energy()->at(mId);\n}\n\nTechdata Order::energy_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  uint8_t energy_id = energy();\n\n  // strange logic in the data. If the weapon links to a index bigger than weapon then it's 'none'\n  if(energy_id >= mDatahub.techdata->label()->size())\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: energy_obj > size\"));\n    throw PropertyNotAvailableException(mId, \"energy_obj\");\n  }\n\n  return Techdata(mDatahub, energy_id);\n}\n\nuint8_t Order::animation()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->animation()->at(mId);\n}\n\nuint8_t Order::highlight()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->highlight()->at(mId);\n}\n\nuint8_t Order::unknown17()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->unknown17()->at(mId);\n}\n\nuint8_t Order::obscured_order()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.orders->obscured_order()->at(mId);\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Order.h",
    "content": "/*\n * Order.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef ORDER_H\n#define ORDER_H\n\n// project\n#include \"ObjectAccess.h\"\n#include \"Weapon.h\"\n#include \"Techdata.h\"\n\nnamespace dat\n{\n\nclass Order : public ObjectAccess\n{\npublic:\n  Order(DataHub &datahub, unsigned int id);\n  virtual ~Order();\n\n  uint16_t label();\n  TblEntry label_tbl();\n\n  bool use_weapon_targeting();\n\n  uint8_t unknown2();\n\n  uint8_t unknown3();\n\n  uint8_t unknown4();\n\n  uint8_t unknown5();\n\n  uint8_t interruptible();\n\n  uint8_t unknown7();\n\n  uint8_t queueable();\n\n  uint8_t unknown9();\n\n  uint8_t unknown10();\n\n  uint8_t unknown11();\n\n  uint8_t unknown12();\n\n  uint8_t targeting();\n  Weapon targeting_obj();\n\n  uint8_t energy();\n  Techdata energy_obj();\n\n  uint8_t animation();\n\n  uint8_t highlight();\n\n  uint8_t unknown17();\n\n  uint8_t obscured_order();\n\n  // TODO: the recursive object return logic doesn't work here as this ends in a endless loop\n  //Order obscured_order_obj();\n\n};\n\n} /* namespace dat */\n\n#endif /* ORDER_H */\n"
  },
  {
    "path": "src/dat/Portrait.cpp",
    "content": "/*\n * Portrait.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"Portrait.h\"\n#include \"Logger.h\"\n#include \"StringUtil.h\"\n#include \"platform.h\"\n\nusing namespace std;\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.Portrait\");\n\nPortrait::Portrait(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nPortrait::~Portrait()\n{\n\n}\n\nuint32_t Portrait::video_idle()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata->video_idle()->at(mId);\n}\n\nTblEntry Portrait::video_idle_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata_tbl_vec.at(video_idle() - 1);\n}\n\nuint32_t Portrait::video_talking()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata->video_talking()->at(mId);\n}\n\nTblEntry Portrait::video_talking_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata_tbl_vec.at(video_talking() - 1);\n}\n\nuint8_t Portrait::change_idle()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata->change_idle()->at(mId);\n}\n\nuint8_t Portrait::change_talking()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata->change_talking()->at(mId);\n}\n\nuint8_t Portrait::unknown1_idle()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata->unknown1_idle()->at(mId);\n}\n\nuint8_t Portrait::unknown1_talking()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.portdata->unknown1_talking()->at(mId);\n}\n\nstd::string Portrait::getIDString(const std::string &portrait)\n{\n  string portrait_name(portrait);\n  replaceString(\"\\\\\", \"/\", portrait_name);\n  fs::path p(portrait_name);\n\n  portrait_name = to_lower(p.parent_path().string());\n  //cout << \"portrait_name: \" << portrait_name << endl;\n\n  return portrait_name;\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Portrait.h",
    "content": "/*\n * Portrait.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PORTRAIT_H\n#define PORTRAIT_H\n\n#include \"ObjectAccess.h\"\n\nnamespace dat\n{\n\nclass Portrait : public ObjectAccess\n{\npublic:\n  Portrait(DataHub &datahub, unsigned int id);\n  virtual ~Portrait();\n\n  uint32_t video_idle();\n  TblEntry video_idle_tbl();\n\n  uint32_t video_talking();\n  TblEntry video_talking_tbl();\n\n  uint8_t change_idle();\n\n  uint8_t change_talking();\n\n  uint8_t unknown1_idle();\n\n  uint8_t unknown1_talking();\n\n  std::string getIDString(const std::string &portrait);\n\nprivate:\n\n};\n\n} /* namespace dat */\n\n#endif /* PORTRAIT_H */\n"
  },
  {
    "path": "src/dat/PropertyNotAvailableException.cpp",
    "content": "/*\n * PropertyNotAvailableException.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"PropertyNotAvailableException.h\"\n\nusing namespace std;\n\nnamespace dat {\n\nconst char *PropertyNotAvailableException::what() const throw()\n{\n  static string s;\n  s = \"Property '\";\n  s += m_property;\n  s += \"' not existing for parent: \";\n  s += to_string(m_parent_id);\n\n  return static_cast <const char *>(s.c_str());\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/PropertyNotAvailableException.h",
    "content": "/*\n * PropertyNotAvailableException.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PROPERTYNOTAVAILABLEEXCEPTION_H\n#define PROPERTYNOTAVAILABLEEXCEPTION_H\n\n#include <string>\n\nnamespace dat {\n\n/**\n * This Exception is thrown if a property isn't available for a specific item, but requested by the caller\n */\nclass PropertyNotAvailableException : public std::exception\n{\npublic:\n  PropertyNotAvailableException(int parent_id, const std::string &property) :\n    m_parent_id(parent_id),\n    m_property(property)\n  {}\n\n  virtual ~PropertyNotAvailableException() throw() {}\n\n  const char *what() const throw();\n\nprivate:\n  int m_parent_id;\n  std::string m_property;\n};\n\n} /* namespace dat */\n\n#endif /* PROPERTYNOTAVAILABLEEXCEPTION_H */\n"
  },
  {
    "path": "src/dat/Sfx.cpp",
    "content": "/*\n * Sound.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Sfx.h\"\n#include \"Logger.h\"\n\nusing namespace std;\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.Sound\");\n\nSfx::Sfx(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nSfx::~Sfx()\n{\n\n}\n\nuint32_t Sfx::sound_file()\n{\n  return mDatahub.sfxdata->sound_file()->at(mId);\n}\n\nTblEntry Sfx::sound_file_tbl()\n{\n  return mDatahub.sfxdata_tbl_vec.at(sound_file()-1);\n}\n\nuint8_t Sfx::unknown1()\n{\n  return mDatahub.sfxdata->unknown1()->at(mId);\n}\n\nuint8_t Sfx::unknown2()\n{\n  return mDatahub.sfxdata->unknown2()->at(mId);\n}\n\nuint8_t Sfx::unknown3()\n{\n  return mDatahub.sfxdata->unknown3()->at(mId);\n}\n\nuint8_t Sfx::unknown4()\n{\n  return mDatahub.sfxdata->unknown4()->at(mId);\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Sfx.h",
    "content": "/*\n * Sound.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef SFX_H\n#define SFX_H\n\n// project\n#include \"ObjectAccess.h\"\n\n//system\n#include <memory>\n\nnamespace dat\n{\n\nclass Sfx : public ObjectAccess\n{\npublic:\n  Sfx(DataHub &datahub, unsigned int id);\n  virtual ~Sfx();\n\n  uint32_t sound_file();\n\n  TblEntry sound_file_tbl();\n\n  uint8_t unknown1();\n\n  uint8_t unknown2();\n\n  uint8_t unknown3();\n\n  uint8_t unknown4();\n\nprivate:\n\n};\n\n} /* namespace dat */\n\n#endif /* SFX_H */\n"
  },
  {
    "path": "src/dat/Sprite.cpp",
    "content": "/*\n * Sprite.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"Sprite.h\"\n#include \"Logger.h\"\n\nusing namespace std;\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.Sprite\");\n\nSprite::Sprite(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nSprite::~Sprite()\n{\n\n}\n\nuint16_t Sprite::image()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t image_id = 0;\n\n  /*\n   * The data deep dive shows that there're some unused units which request a sprite/image\n   * which is available first in Broodwar for this Sprite. I could only assume that this is an error.\n   * Therefore this is just mapped to 0. No problem as such units are never used in the normal game.\n   * This is just to draw the unit in test code.\n   */\n  if (mId < mDatahub.sprites->image()->size())\n  {\n    image_id = mDatahub.sprites->image()->at(mId);\n    LOG4CXX_TRACE(logger, string(\"image(\") + to_string(image_id) + \")\");\n  }\n  else\n  {\n    LOG4CXX_TRACE(logger, string(\"not found image->at(\") + to_string(mId) + \") mapped to 0\");\n  }\n\n  return image_id;\n}\n\nImage Sprite::image_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Image(mDatahub, image());\n}\n\nuint8_t Sprite::health_bar()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t health_bar = 0;\n\n  try\n  {\n    // This property is only available from unit index 130 to num_lines\n    health_bar = mDatahub.sprites->health_bar()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: health_bar(\") + to_string(health_bar) + \")\");\n    throw PropertyNotAvailableException(mId, \"health_bar\");\n  }\n\n  return health_bar;\n}\n\nuint8_t Sprite::unknown2()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint8_t unknown2 = 0;\n\n  /*\n   * The data deep dive shows that there're some unused units which request a unknown property\n   * which is available first in Broodwar for this Sprite. I could only assume that this is an error.\n   * Therefore this is just mapped to 0. No problem as such units are never used in the normal game.\n   */\n  if (mId < mDatahub.sprites->unknown2()->size())\n  {\n    unknown2 = mDatahub.sprites->unknown2()->at(mId);\n    LOG4CXX_TRACE(logger, string(\"unknown2(\") + to_string(unknown2) + \")\");\n  }\n  else\n  {\n    LOG4CXX_TRACE(logger, string(\"not found unknown2->at(\") + to_string(mId) + \") mapped to 0\");\n  }\n\n  return unknown2;\n}\n\nbool Sprite::is_visible()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint8_t is_visible = 1;\n\n  /*\n   * The data deep dive shows that there're some unused units which request a unknown property\n   * which is available first in Broodwar for this Sprite. I could only assume that this is an error.\n   * Therefore this is just mapped to 0. No problem as such units are never used in the normal game.\n   * We map it to 1 to let this units draw for test cases.\n   */\n  if (mId < mDatahub.sprites->is_visible()->size())\n  {\n    is_visible = mDatahub.sprites->is_visible()->at(mId);\n    LOG4CXX_TRACE(logger, string(\"is_visible(\") + to_string(is_visible) + \")\");\n  }\n  else\n  {\n    LOG4CXX_TRACE(logger, string(\"not found is_visible->at(\") + to_string(mId) + \") mapped to 1\");\n  }\n\n  return is_visible;\n}\n\nuint8_t Sprite::select_circle_image_size()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t select_circle_image_size = 0;\n\n  try\n  {\n    // This property is only available from unit index 130 to num_lines\n    select_circle_image_size = mDatahub.sprites->select_circle_image_size()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: select_circle_image_size(\") + to_string(select_circle_image_size) + \")\");\n    throw PropertyNotAvailableException(mId, \"select_circle_image_size\");\n  }\n\n  return select_circle_image_size;\n}\n\nuint8_t Sprite::select_circle_vertical_pos()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t select_circle_vertical_pos = 0;\n\n  try\n  {\n    // This property is only available from unit index 130 to num_lines\n    select_circle_vertical_pos = mDatahub.sprites->select_circle_vertical_pos()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: select_circle_vertical_pos(\") + to_string(select_circle_vertical_pos) + \")\");\n    throw PropertyNotAvailableException(mId, \"select_circle_vertical_pos\");\n  }\n\n  return select_circle_vertical_pos;\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Sprite.h",
    "content": "/*\n * Sprite.h\n *\n *      Author: Andreas\n */\n\n#ifndef SPRITE_H\n#define SPRITE_H\n\n// project\n#include \"ObjectAccess.h\"\n#include \"Image.h\"\n#include \"PropertyNotAvailableException.h\"\n\nnamespace dat\n{\n\nclass Sprite : public ObjectAccess\n{\npublic:\n  Sprite(DataHub &datahub, unsigned int id);\n  virtual ~Sprite();\n\n  uint16_t image();\n  Image image_obj();\n\n  uint8_t health_bar();\n\n  uint8_t unknown2();\n\n  bool is_visible();\n\n  uint8_t select_circle_image_size();\n\n  uint8_t select_circle_vertical_pos();\n\nprivate:\n\n};\n\n} /* namespace dat */\n\n#endif /* SPRITE_H */\n"
  },
  {
    "path": "src/dat/Tbl.cpp",
    "content": "/*\n * Tbl.cpp\n *\n *      Author: Andreas Volz\n */\n\n// Local\n#include \"Hurricane.h\"\n#include \"StringUtil.h\"\n#include \"Tbl.h\"\n#include \"Logger.h\"\n\n// System\n#include <iostream>\n#include <fstream>\n#include <string>\n\nusing namespace std;\n\nnamespace dat {\n\nstatic Logger logger = Logger(\"startool.DataHub.Tbl\");\n\n// this is a very local debug print concept. But for this use case of sequence character debugging perfect...\nint no_printf(const char *format, ...)\n{\n  return 0;\n}\n//#define dbg_printf printf\n#define dbg_printf no_printf\n\nTbl::Tbl()\n{\n\n}\n\nTbl::~Tbl()\n{\n\n}\n\n/**\n * TODO: this is just a raw format parser. Not yet decided what to do with the format\n * a debug output looks like this if you uncomment the printf() below. The format isn't yet complete\n * understood. But somehow there're shortcuts and a marker which char should be highlighted in the GUI...\n * r<EOT>Pa<ETX>r<SOH>asit entwickeln<LF>(Für Königin)<NULL>\n */\nvector<TblEntry> Tbl::convertFromStream(std::shared_ptr<kaitai::kstream> ks)\n{\n  file_tbl_t file_tbl = file_tbl_t(ks.get());\n\n  std::vector<file_tbl_t::tbl_entry_t *> *file_tbl_entry_vec = file_tbl.tbl_entries();\n\n  unsigned int i = 0;\n  vector<TblEntry> tbl_entry_vec;\n  for (vector<file_tbl_t::tbl_entry_t *>::iterator file_tbl_entry_it =\n         file_tbl_entry_vec->begin();\n       file_tbl_entry_it != file_tbl_entry_vec->end(); file_tbl_entry_it++)\n  {\n    file_tbl_t::tbl_entry_t *file_entry = *file_tbl_entry_it;\n\n    std::vector<uint8_t> *entry_char_vec = file_entry->entry();\n\n    dbg_printf(\"%d:\", i);\n\n    //\"#entry: \" << entry_char_vec->size() << endl;\n\n    //uint8_t last_control = 0;\n\n    std::string name1;\n    std::string name2;\n    std::string name3;\n    int shortcut_pos = -1;\n    std::string shortcut;\n\n    string entry_str_tmp;\n    unsigned int null_counter = 0;\n    bool etx = false;\n    for (unsigned int n = 0; n < entry_char_vec->size(); n++)\n    {\n      uint8_t entry_char = entry_char_vec->at(n);\n\n      // ASCII control characters + special chars\n      if ((entry_char >= 0 && entry_char <= 31) || entry_char == 127\n          || entry_char == 0x2a)\n      {\n        switch (entry_char)\n        {\n        case 0x0: // ' '\n          dbg_printf(\"<NULL>\");\n          if (n == 1) // first char is shortcut special case\n          {\n            uint8_t last = entry_char_vec->at(n - 1);\n            // TODO: special handling of ESC key if I ever come to this point...\n            if (last != 0x1B) // !Escape\n            {\n              shortcut = last;\n              entry_str_tmp.clear();\n            }\n          }\n          else\n          {\n            if (null_counter == 0)\n            {\n              name1 = entry_str_tmp;\n              entry_str_tmp.clear();\n            }\n            else if (null_counter == 1)\n            {\n              name2 = entry_str_tmp;\n              entry_str_tmp.clear();\n            }\n            else if (null_counter == 2)\n            {\n              name3 = entry_str_tmp;\n              entry_str_tmp.clear();\n            }\n            null_counter++;\n          }\n          break;\n        case 0x0a: // Line Feed\n          dbg_printf(\"<LF>\");\n          entry_str_tmp += \" \";\n          break;\n        case 0x01: // Start of Heading\n          dbg_printf(\"<SOH>\");\n          if (!etx) // <ETX><SOH> is a special case\n          {\n            shortcut = entry_char_vec->at(n - 1);\n            entry_str_tmp.clear();\n          }\n          break;\n        case 0x02: // Start of Text\n          dbg_printf(\"<STX>\");\n          shortcut = entry_char_vec->at(n - 1);\n          entry_str_tmp.clear();\n          break;\n        case 0x03: // End of Text\n          dbg_printf(\"<ETX>\");\n          if (n == 1) // first char is shortcut special case\n          {\n            shortcut = entry_char_vec->at(n - 1);\n            entry_str_tmp.clear();\n          }\n          else\n          {\n            shortcut_pos = entry_str_tmp.length();\n            etx = true;\n          }\n          break;\n        case 0x4: // End of Transmission, diamonds card suit\n          dbg_printf(\"<EOT>\");\n          if (n > 0)\n          {\n            shortcut = entry_char_vec->at(n - 1);\n            entry_str_tmp.clear();\n          }\n          break;\n        case 0x6: // Acknowledgement, spade card suit\n          dbg_printf(\"<ACK>\");\n          break;\n        case 0x7: // Bell\n          dbg_printf(\"<BEL>\");\n          break;\n        case 0x1B: // Escape\n          dbg_printf(\"<ESC>\");\n          break;\n        case 0x2a: // '*'\n          dbg_printf(\"<ASTERISK>\");\n          entry_str_tmp += entry_char;\n          break;\n        default:\n          dbg_printf(\"<unhandled>: %x\", entry_char);\n          break;\n        }\n\n        //last_control = entry_char;\n      }\n      // printable ASCII characters\n      else if (entry_char >= 32 && entry_char <= 126)\n      {\n        dbg_printf(\"%c\", entry_char);\n        entry_str_tmp += entry_char;\n      }\n      // printable extended ASCII characters\n      else if (entry_char >= 120 && entry_char <= 255)\n      {\n        char inBuf[2];\n        inBuf[0] = (char) entry_char;\n        inBuf[1] = '\\0';\n\n        char *utf8 = iconvISO2UTF8(inBuf);\n        if (utf8)\n        {\n          dbg_printf(\"%s\", utf8);\n\n          entry_str_tmp += utf8;\n          free(utf8);\n        }\n        else\n        {\n          LOG4CXX_ERROR(logger, \"No UTF-8 conversation possible!\");\n        }\n      }\n      else\n      {\n        LOG4CXX_ERROR(logger, \"ASCII characters > 255 should not be possible!\");\n      }\n    }\n    dbg_printf(\"\\n\");\n\n    // fix trailing characters\n    if (shortcut == \" \")\n    {\n      shortcut = \"\";\n    }\n\n    removeDoubleSpaces(name1);\n    removeDoubleSpaces(name2);\n    removeDoubleSpaces(name3);\n\n    // access the tbl_entry members direct for now as this is a friend class.\n    // maybe I change this design later, but for now it's ok\n    TblEntry tbl_entry;\n    tbl_entry.m_name1 = name1;\n    tbl_entry.m_name2 = name2;\n    tbl_entry.m_name3 = name3;\n    tbl_entry.m_shortcut = shortcut;\n    tbl_entry.m_shortcut_pos = shortcut_pos;\n\n\n    dbg_printf(\"tbl_entry.name(): %s\\n\", tbl_entry.name1().c_str());\n    dbg_printf(\"tbl_entry.category1(): %s\\n\", tbl_entry.name2().c_str());\n    dbg_printf(\"tbl_entry.category2(): %s\\n\", tbl_entry.name3().c_str());\n    dbg_printf(\"tbl_entry.shortcut(): %s\\n\", tbl_entry.shortcut().c_str());\n    dbg_printf(\"tbl_entry.shortcut_pos(): %d\\n\", tbl_entry.shortcut_pos());\n\n    i++;\n\n\n    tbl_entry_vec.push_back(tbl_entry);\n  }\n\n  return tbl_entry_vec;\n}\n\nvoid Tbl::removeDoubleSpaces(std::string &str)\n{\n  size_t pos;\n  while ((pos = str.find(\"  \")) != std::string::npos)\n  {\n    str = str.replace(pos, 2, \" \");\n  }\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Tbl.h",
    "content": "/*\n * Tbl.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef TBL_H\n#define TBL_H\n\n// Local\n#include \"kaitai/file_tbl.h\"\n#include \"TblEntry.h\"\n\n// System\n#include <memory>\n\nnamespace dat {\n\n\n\nclass Tbl\n{\npublic:\n  Tbl();\n  virtual ~Tbl();\n\n  std::vector<TblEntry> convertFromStream(std::shared_ptr<kaitai::kstream> ks);\n\nprivate:\n  void removeDoubleSpaces(std::string &str);\n};\n\n} /* namespace dat */\n\n#endif /* TBL_H */\n"
  },
  {
    "path": "src/dat/TblEntry.cpp",
    "content": "/*\n * TblEntry.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"TblEntry.h\"\n#include \"Logger.h\"\n\n// system\n#include <string>\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.dat.TblEntry\");\n\nnamespace dat\n{\n\nTblEntry::TblEntry()\n{\n  m_shortcut_pos = -1;\n  m_shortcut = ' ';\n}\n\nTblEntry::~TblEntry()\n{\n\n}\n\nstd::string TblEntry::name1()\n{\n  LOG4CXX_TRACE(logger, LOG_CUR_FUNC + \"()=\" + m_name1);\n  return m_name1;\n}\n\nstd::string TblEntry::name2()\n{\n  LOG4CXX_TRACE(logger, LOG_CUR_FUNC + \"()=\" + m_name2);\n  return m_name2;\n}\n\nstd::string TblEntry::name3()\n{\n  LOG4CXX_TRACE(logger, LOG_CUR_FUNC + \"()=\" + m_name3);\n  return m_name3;\n}\n\nint TblEntry::shortcut_pos()\n{\n  LOG4CXX_TRACE(logger, LOG_CUR_FUNC + \"()=\" + to_string(m_shortcut_pos));\n  return m_shortcut_pos;\n}\n\nstd::string TblEntry::shortcut()\n{\n  LOG4CXX_TRACE(logger, LOG_CUR_FUNC + \"()=\" + m_shortcut);\n  return m_shortcut;\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/TblEntry.h",
    "content": "/*\n * TblEntry.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef TBLENTRY_H\n#define TBLENTRY_H\n\n// system\n#include <string>\n\nnamespace dat\n{\n\nclass TblEntry\n{\npublic:\n  TblEntry();\n  virtual ~TblEntry();\n\n  std::string name1();\n  std::string name2();\n  std::string name3();\n  int shortcut_pos();\n  std::string shortcut();\n\n\nprivate:\n  std::string m_name1;\n  std::string m_name2;\n  std::string m_name3;\n  int m_shortcut_pos;\n  std::string m_shortcut;\n\n  friend class Tbl;\n};\n\n} /* namespace dat */\n\n#endif /* TBLENTRY_H */\n"
  },
  {
    "path": "src/dat/Techdata.cpp",
    "content": "/*\n * Techdata.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"Techdata.h\"\n#include \"Logger.h\"\n#include \"PropertyNotAvailableException.h\"\n\nstatic Logger logger = Logger(\"startool.dat.Techdata\");\n\nusing namespace std;\n\nnamespace dat\n{\n\nTechdata::Techdata(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nTechdata::~Techdata()\n{\n\n}\n\nuint16_t Techdata::mineral_cost()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->mineral_cost()->at(mId);\n}\n\nuint16_t Techdata::vespene_cost()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->vespene_cost()->at(mId);\n}\n\nuint16_t Techdata::research_time()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->research_time()->at(mId);\n}\n\nuint16_t Techdata::energy_required()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->energy_required()->at(mId);\n}\n\nuint32_t Techdata::unknown4()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->unknown4()->at(mId);\n}\n\nuint16_t Techdata::icon()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->icon()->at(mId);\n}\n\nuint16_t Techdata::label()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->label()->at(mId);\n}\n\nTblEntry Techdata::label_tbl()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  if(label() == Techdata::label_none)\n  {\n    throw PropertyNotAvailableException(mId, \"label_tbl\");\n  }\n\n  return mDatahub.stat_txt_tbl_vec.at(label()-1);\n}\n\nuint8_t Techdata::race()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->race()->at(mId);\n}\n\nuint8_t Techdata::unused()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->unused()->at(mId);\n}\n\nbool Techdata::broodwar_flag()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.techdata->broodwar_flag()->at(mId);\n}\n\nbool Techdata::has_broodwar_flag()\n{\n  return mDatahub.techdata->has_broodwar_flag();\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Techdata.h",
    "content": "/*\n * Techdata.h\n *\n *      Author: Andreas\n */\n\n#ifndef TECHDATA_H\n#define TECHDATA_H\n\n#include \"ObjectAccess.h\"\n\nnamespace dat\n{\n\nclass Techdata : public ObjectAccess\n{\npublic:\n  Techdata(DataHub &datahub, unsigned int id);\n  virtual ~Techdata();\n\n  uint16_t mineral_cost();\n\n  uint16_t vespene_cost();\n\n  uint16_t research_time();\n\n  uint16_t energy_required();\n\n  uint32_t unknown4();\n\n  uint16_t icon();\n\n  uint16_t label();\n  TblEntry label_tbl();\n\n  uint8_t race();\n\n  uint8_t unused();\n\n  bool broodwar_flag();\n\n  bool has_broodwar_flag();\n\n  /* constants */\n  static const int label_none = 0;\n};\n\n} /* namespace dat */\n\n#endif /* TECHDATA_H */\n"
  },
  {
    "path": "src/dat/Unit.cpp",
    "content": "/*\n * Unit.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Unit.h\"\n#include \"Logger.h\"\n\n// system\n#include <iostream>\n\nusing namespace std;\n\n\n\nnamespace dat\n{\n\nstatic Logger logger = Logger(\"startool.dat.Unit\");\n\nUnit::Unit(DataHub &datahub, unsigned int id, const std::string &identString) :\n  ObjectAccess(datahub, id),\n  mIdentString(identString)\n{\n}\n\nUnit::~Unit()\n{\n}\n\nstd::string Unit::getIDString()\n{\n  // trace at least the id string that we know where we are\n  LOG4CXX_TRACE(logger,  mIdentString + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mIdentString;\n}\n\nTblEntry Unit::name_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.stat_txt_tbl_vec.at(mId);\n}\n\nuint8_t Unit::flingy()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->flingy()->at(mId);\n}\n\nFlingy Unit::flingy_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Flingy(mDatahub, flingy());\n}\n\nuint16_t Unit::subunit1()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->subunit1()->at(mId);\n}\n\nUnit Unit::subunit1_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t subunit_id = subunit1();\n\n  if(subunit_id == Unit::subunit_none)\n  {\n    throw PropertyNotAvailableException(mId, \"subunit1_obj\");\n  }\n\n  return Unit(mDatahub, subunit_id, \"<subunit2>\");\n}\n\nuint16_t Unit::subunit2()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->subunit2()->at(mId);\n}\n\nUnit Unit::subunit2_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t subunit_id = subunit2();\n\n  if(subunit_id == Unit::subunit_none)\n  {\n    throw PropertyNotAvailableException(mId, \"subunit2_obj\");\n  }\n\n  return Unit(mDatahub, subunit_id, \"<subunit2>\");\n}\n\nuint16_t Unit::infestation()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t infestation = 0;\n\n  try\n  {\n    // only for units of ID 106-201 (buildings)\n    infestation = mDatahub.units->infestation()->at(mId-106);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_DEBUG(logger, string(\"Exception: infestation(\") + to_string(infestation) + \")\");\n    throw PropertyNotAvailableException(mId, \"infestation\");\n  }\n\n  return infestation;\n}\n\nUnit Unit::infestation_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t infestation_id = infestation();\n\n  if(infestation_id == Unit::infestation_none)\n  {\n    throw PropertyNotAvailableException(mId, \"infestation_obj\");\n  }\n\n  return Unit(mDatahub, infestation_id, \"<infestation>\");\n}\n\nuint32_t Unit::construction_animation()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->construction_animation()->at(mId);\n}\n\nImage Unit::construction_animation_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  uint32_t construction_animation_id = construction_animation();\n\n  if(construction_animation_id == Unit::construction_none)\n  {\n    throw PropertyNotAvailableException(mId, \"construction_animation_obj\");\n  }\n\n  return Image(mDatahub, construction_animation_id);\n}\n\nuint8_t Unit::unit_direction()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->unit_direction()->at(mId);\n}\n\nuint8_t Unit::shield_enable()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->shield_enable()->at(mId);\n}\n\nuint16_t Unit::shield_amount()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->shield_amount()->at(mId);\n}\n\nuint32_t Unit::hitpoints()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->hit_points()->at(mId)->hitpoints();\n}\n\nuint8_t Unit::elevation_level()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->elevation_level()->at(mId);\n}\n\nuint8_t Unit::unknown()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->unknown()->at(mId);\n}\n\nuint8_t Unit::rank()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->rank()->at(mId);\n}\n\nuint8_t Unit::ai_computer_idle()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->ai_computer_idle()->at(mId);\n}\n\nOrder Unit::ai_computer_idle_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Order(mDatahub, ai_computer_idle());\n}\n\nuint8_t Unit::ai_human_idle()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->ai_human_idle()->at(mId);\n}\n\nOrder Unit::ai_human_idle_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Order(mDatahub, ai_human_idle());\n}\n\nuint8_t Unit::ai_return_to_idle()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->ai_return_to_idle()->at(mId);\n}\n\nOrder Unit::ai_return_to_idle_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Order(mDatahub, ai_return_to_idle());\n}\n\nuint8_t Unit::ai_attack_unit()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->ai_attack_unit()->at(mId);\n}\n\nOrder Unit::ai_attack_unit_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Order(mDatahub, ai_attack_unit());\n}\n\nuint8_t Unit::ai_attack_move()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->ai_attack_move()->at(mId);\n}\n\nOrder Unit::ai_attack_move_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Order(mDatahub, ai_attack_move());\n}\n\nuint8_t Unit::ground_weapon()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->ground_weapon()->at(mId);\n}\n\nWeapon Unit::ground_weapon_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  uint8_t ground_weapon_id = mDatahub.units->ground_weapon()->at(mId);\n\n  // strange logic in the data. If the weapon links to a index bigger than weapon then it's 'none'\n  if(ground_weapon_id >= mDatahub.weapons->label()->size())\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: ground_weapon_obj > size\"));\n    throw PropertyNotAvailableException(mId, \"ground_weapon_obj\");\n  }\n\n  return Weapon(mDatahub, ground_weapon_id);\n}\n\nuint8_t Unit::max_ground_hits()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->max_ground_hits()->at(mId);\n}\n\nuint8_t Unit::air_weapon()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->air_weapon()->at(mId);\n}\n\nWeapon Unit::air_weapon_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  uint8_t air_weapon_id = mDatahub.units->air_weapon()->at(mId);\n\n  // strange logic in the data. If the weapon links to a index bigger than weapon then it's 'none'\n  if(air_weapon_id >= mDatahub.weapons->label()->size())\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: air_weapon_obj > size\"));\n    throw PropertyNotAvailableException(mId, \"air_weapon_obj\");\n  }\n\n  return Weapon(mDatahub, air_weapon_id);\n}\n\nuint8_t Unit::max_air_hits()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->max_air_hits()->at(mId);\n}\n\nuint8_t Unit::ai_internal()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->ai_internal()->at(mId);\n}\n\nunits_dat_t::special_ability_flags_type_t* Unit::special_ability_flags()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->special_ability_flags()->at(mId);\n}\n\nuint8_t Unit::target_acquisition_range()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->target_acquisition_range()->at(mId);\n}\n\nuint8_t Unit::sight_range()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->sight_range()->at(mId);\n}\n\nuint8_t Unit::armor_upgrade()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->armor_upgrade()->at(mId);\n}\n\nunits_dat_t::unit_size_enum_t Unit::unit_size()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->unit_size()->at(mId);\n}\n\nuint8_t Unit::armor()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->armor()->at(mId);\n}\n\nunits_dat_t::right_click_action_enum_t Unit::right_click_action()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->right_click_action()->at(mId);\n}\n\nuint16_t Unit::ready_sound()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t ready_sound = 0;\n\n  try\n  {\n    // only unit IDs < 106 have ready_sound\n    ready_sound = mDatahub.units->ready_sound()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: ready_sound(\") + to_string(ready_sound) + \")\");\n    throw PropertyNotAvailableException(mId, \"ready_sound\");\n  }\n\n  return ready_sound;\n}\n\nSfx Unit::ready_sound_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t ready_sound_id = ready_sound();\n\n  if(ready_sound_id == Unit::sound_none)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: ready_sound_obj(\") + to_string(ready_sound_id) + \")\");\n    throw PropertyNotAvailableException(mId, \"ready_sound_obj\");\n  }\n\n  Sfx sfx(mDatahub, ready_sound_id);\n\n  return sfx;\n}\n\nuint16_t Unit::what_sound_start()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->what_sound_start()->at(mId);\n}\n\nuint16_t Unit::what_sound_end()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->what_sound_end()->at(mId);\n}\n\nstd::vector<Sfx> Unit::what_sound_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  std::vector<Sfx> sfx_vector;\n\n  uint16_t what_sound_start_id = what_sound_start();\n  uint16_t what_sound_end_id = what_sound_end();\n\n  if((what_sound_start_id || what_sound_end_id) == Unit::sound_none)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: what_sound_obj(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"what_sound_obj\");\n  }\n\n  for(unsigned int i = what_sound_start_id; i <= what_sound_end_id; i++)\n  {\n    Sfx sfx(mDatahub, i);\n    sfx_vector.push_back(sfx);\n  }\n\n  return sfx_vector;\n}\n\nuint16_t Unit::piss_sound_start()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t piss_sound_start = 0;\n\n  try\n  {\n    // only unit IDs < 106 have piss_sound_start\n    piss_sound_start = mDatahub.units->piss_sound_start()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: piss_sound_start(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"piss_sound_start\");\n  }\n\n  return piss_sound_start;\n}\n\nuint16_t Unit::piss_sound_end()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t piss_sound_end = 0;\n\n  try\n  {\n    // only unit IDs < 106 have piss_sound_end\n    piss_sound_end = mDatahub.units->piss_sound_end()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: piss_sound_end(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"piss_sound_end\");\n  }\n\n  return piss_sound_end;\n}\n\nstd::vector<Sfx> Unit::piss_sound_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  std::vector<Sfx> sfx_vector;\n\n  uint16_t piss_sound_start_id = piss_sound_start();\n  uint16_t piss_sound_end_id = piss_sound_end();\n\n  if((piss_sound_start_id || piss_sound_end_id) == Unit::sound_none)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: piss_sound_obj(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"piss_sound_obj\");\n  }\n\n  for(unsigned int i = piss_sound_start_id; i <= piss_sound_end_id; i++)\n  {\n    Sfx sfx(mDatahub, i);\n    sfx_vector.push_back(sfx);\n  }\n\n  return sfx_vector;\n}\n\nuint16_t Unit::yes_sound_start()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t yes_sound_start = 0;\n\n  try\n  {\n    // only unit IDs < 106 have yes_sound_start\n    yes_sound_start = mDatahub.units->yes_sound_start()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: piss_sound_start(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"yes_sound_start\");\n  }\n\n  return yes_sound_start;\n}\n\nuint16_t Unit::yes_sound_end()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t yes_sound_end = 0;\n\n  try\n  {\n    // only unit IDs < 106 have yes_sound_end\n    yes_sound_end = mDatahub.units->yes_sound_end()->at(mId);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: yes_sound_end(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"yes_sound_end\");\n  }\n\n  return yes_sound_end;\n}\n\nstd::vector<Sfx> Unit::yes_sound_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  std::vector<Sfx> sfx_vector;\n\n  uint16_t yes_sound_start_id = yes_sound_start();\n  uint16_t yes_sound_end_id = yes_sound_end();\n\n  if((yes_sound_start_id || yes_sound_end_id) == Unit::sound_none)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: yes_sound_obj(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"yes_sound_obj\");\n  }\n\n  for(unsigned int i = yes_sound_start_id; i <= yes_sound_end_id; i++)\n  {\n    Sfx sfx(mDatahub, i);\n    sfx_vector.push_back(sfx);\n  }\n\n  return sfx_vector;\n}\n\nunits_dat_t::staredit_placement_box_type_t* Unit::staredit_placement_box()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->staredit_placement_box()->at(mId);\n}\n\nunits_dat_t::addon_position_type_t* Unit::addon_position()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  units_dat_t::addon_position_type_t* addon = nullptr;\n\n  try\n  {\n    // Exists only for units of ID 106-201 (buildings)\n    addon = mDatahub.units->addon_position()->at(mId-106);\n  }\n  catch (const std::out_of_range& oor)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: addon_position(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"addon_position\");\n  }\n\n  return addon;\n}\n\nunits_dat_t::unit_dimension_type_t *Unit::unit_dimension()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->unit_dimension()->at(mId);\n}\n\nuint16_t Unit::portrait()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->portrait()->at(mId);\n}\n\nPortrait Unit::portrait_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  uint16_t portrait_id = portrait();\n\n  if (portrait_id == Unit::portrait_none)\n  {\n    LOG4CXX_TRACE(logger, string(\"Exception: portrait_obj(\") + to_string(mId) + \")\");\n    throw PropertyNotAvailableException(mId, \"portrait_obj\");\n  }\n\n  Portrait portrait(mDatahub, portrait_id);\n\n  return portrait;\n}\n\n\nuint16_t Unit::mineral_cost()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->mineral_cost()->at(mId);\n}\n\nuint16_t Unit::vespene_cost()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->vespene_cost()->at(mId);\n}\n\n\nuint16_t Unit::build_time()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->build_time()->at(mId);\n}\n\nuint16_t Unit::requirements()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->requirements()->at(mId);\n}\n\nunits_dat_t::staredit_group_flags_type_t* Unit::staredit_group_flags()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->staredit_group_flags()->at(mId);\n}\n\nuint8_t Unit::supply_required()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->supply_required()->at(mId);\n}\n\nuint8_t Unit::space_provided()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->space_provided()->at(mId);\n}\n\nuint16_t Unit::build_score()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->build_score()->at(mId);\n}\n\nuint16_t Unit::destroy_score()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->destroy_score()->at(mId);\n}\n\n// TODO: a unit_map_string_string_tbl() might be helpful...\nuint16_t Unit::unit_map_string()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->unit_map_string()->at(mId);\n}\n\nuint8_t Unit::broodwar_flag()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->broodwar_flag()->at(mId);\n}\n\nunits_dat_t::staredit_availability_flags_type_t* Unit::staredit_availability_flags()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.units->staredit_availability_flags()->at(mId);\n}\n\nbool Unit::is_format_bw()\n{\n  return mDatahub.units->is_format_bw();\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Unit.h",
    "content": "/*\n * Unit.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef UNIT_H\n#define UNIT_H\n\n// project\n#include \"Flingy.h\"\n#include \"ObjectAccess.h\"\n#include \"Portrait.h\"\n#include \"Sfx.h\"\n#include \"PropertyNotAvailableException.h\"\n#include \"Weapon.h\"\n#include \"Order.h\"\n\nnamespace dat\n{\n\nclass Unit : public ObjectAccess\n{\npublic:\n  Unit(DataHub &datahub, unsigned int id, const std::string &identString);\n  virtual ~Unit();\n\n  TblEntry name_tbl();\n\n  uint8_t flingy();\n  Flingy flingy_obj();\n\n  uint16_t subunit1();\n  Unit subunit1_obj();\n\n  uint16_t subunit2();\n  Unit subunit2_obj();\n\n  uint16_t infestation();\n  Unit infestation_obj();\n\n  uint32_t construction_animation();\n  Image construction_animation_obj();\n\n  uint8_t unit_direction();\n\n  uint8_t shield_enable();\n\n  uint16_t shield_amount();\n\n  uint32_t hitpoints();\n\n  uint8_t elevation_level();\n\n  uint8_t unknown();\n\n  uint8_t rank();\n\n  uint8_t ai_computer_idle();\n  Order ai_computer_idle_obj();\n\n  uint8_t ai_human_idle();\n  Order ai_human_idle_obj();\n\n  uint8_t ai_return_to_idle();\n  Order ai_return_to_idle_obj();\n\n  uint8_t ai_attack_unit();\n  Order ai_attack_unit_obj();\n\n  uint8_t ai_attack_move();\n  Order ai_attack_move_obj();\n\n  uint8_t ground_weapon();\n  Weapon ground_weapon_obj();\n\n  uint8_t max_ground_hits();\n\n  uint8_t air_weapon();\n  Weapon air_weapon_obj();\n\n  uint8_t max_air_hits();\n\n  uint8_t ai_internal();\n\n  units_dat_t::special_ability_flags_type_t* special_ability_flags();\n\n  uint8_t target_acquisition_range();\n\n  uint8_t sight_range();\n\n  uint8_t armor_upgrade();\n\n  units_dat_t::unit_size_enum_t unit_size();\n\n  uint8_t armor();\n\n  units_dat_t::right_click_action_enum_t right_click_action();\n\n  uint16_t ready_sound();\n\n  Sfx ready_sound_obj();\n\n  uint16_t what_sound_start();\n\n  uint16_t what_sound_end();\n\n  std::vector<Sfx> what_sound_obj();\n\n  uint16_t piss_sound_start();\n\n  uint16_t piss_sound_end();\n\n  std::vector<Sfx> piss_sound_obj();\n\n  uint16_t yes_sound_start();\n\n  uint16_t yes_sound_end();\n\n  std::vector<Sfx> yes_sound_obj();\n\n  units_dat_t::staredit_placement_box_type_t* staredit_placement_box();\n\n  units_dat_t::addon_position_type_t* addon_position();\n\n  units_dat_t::unit_dimension_type_t *unit_dimension();\n\n  uint16_t portrait();\n\n  Portrait portrait_obj();\n\n  uint16_t mineral_cost();\n\n  uint16_t vespene_cost();\n\n  uint16_t build_time();\n\n  uint16_t requirements();\n\n  units_dat_t::staredit_group_flags_type_t* staredit_group_flags();\n\n  uint8_t supply_required();\n\n  uint8_t space_provided();\n\n  uint16_t build_score();\n\n  uint16_t destroy_score();\n\n  uint16_t unit_map_string();\n\n  uint8_t broodwar_flag();\n\n  units_dat_t::staredit_availability_flags_type_t* staredit_availability_flags();\n\n  bool is_format_bw();\n\n  std::string getIDString();\n\n  /* constants */\n  static const int portrait_none = 65535;\n  static const int sound_none = 0;\n  static const int construction_none = 0;\n  static const int subunit_none = 228;\n  static const int infestation_none = 228;\n\nprivate:\n  std::string mIdentString;\n};\n\n} /* namespace dat */\n\n#endif /* UNIT_H */\n"
  },
  {
    "path": "src/dat/Upgrade.cpp",
    "content": "/*\n * Upgrade.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"Upgrade.h\"\n#include \"Logger.h\"\n#include \"PropertyNotAvailableException.h\"\n\nstatic Logger logger = Logger(\"startool.dat.Upgrade\");\n\nusing namespace std;\n\nnamespace dat\n{\n\nUpgrade::Upgrade(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nUpgrade::~Upgrade()\n{\n\n}\n\nuint16_t Upgrade::mineral_cost_base()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->mineral_cost_base()->at(mId);\n}\n\nuint16_t Upgrade::mineral_cost_factor()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->mineral_cost_factor()->at(mId);\n}\n\nuint16_t Upgrade::vespene_cost_base()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->vespene_cost_base()->at(mId);\n}\n\nuint16_t Upgrade::vespene_cost_factor()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->vespene_cost_factor()->at(mId);\n}\n\nuint16_t Upgrade::research_time_base()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->research_time_base()->at(mId);\n}\n\nuint16_t Upgrade::research_time_factor()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->research_time_factor()->at(mId);\n}\n\nuint16_t Upgrade::unknown6()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->unknown6()->at(mId);\n}\n\nuint16_t Upgrade::icon()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->icon()->at(mId);\n}\n\nuint16_t Upgrade::label()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->label()->at(mId);\n}\n\nTblEntry Upgrade::label_tbl()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  if(label() == Upgrade::label_none)\n  {\n    throw PropertyNotAvailableException(mId, \"label_tbl\");\n  }\n\n  return mDatahub.stat_txt_tbl_vec.at(label()-1);\n}\n\nuint8_t Upgrade::race()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->race()->at(mId);\n}\n\nuint8_t Upgrade::max_repeats()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->max_repeats()->at(mId);\n}\n\nbool Upgrade::broodwar_flags()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.upgrades->broodwar_flags()->at(mId);\n}\n\nbool Upgrade::has_broodwar_flag()\n{\n  return mDatahub.upgrades->has_broodwar_flag();\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Upgrade.h",
    "content": "/*\n * Upgrade.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef UPGRADE_H\n#define UPGRADE_H\n\n#include \"ObjectAccess.h\"\n\nnamespace dat\n{\n\nclass Upgrade : public ObjectAccess\n{\npublic:\n  Upgrade(DataHub &datahub, unsigned int id);\n  virtual ~Upgrade();\n\n  uint16_t mineral_cost_base();\n\n  uint16_t mineral_cost_factor();\n\n  uint16_t vespene_cost_base();\n\n  uint16_t vespene_cost_factor();\n\n  uint16_t research_time_base();\n\n  uint16_t research_time_factor();\n\n  uint16_t unknown6();\n\n  uint16_t icon();\n\n  uint16_t label();\n  TblEntry label_tbl();\n\n  uint8_t race();\n\n  uint8_t max_repeats();\n\n  bool broodwar_flags();\n\n  bool has_broodwar_flag();\n\n  static const int label_none = 0;\n};\n\n} /* namespace dat */\n\n#endif /* UPGRADE_H */\n"
  },
  {
    "path": "src/dat/Weapon.cpp",
    "content": "/*\n * Weapon.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"Weapon.h\"\n#include \"Logger.h\"\n\nusing namespace std;\n\nstatic Logger logger = Logger(\"startool.dat.Weapon\");\n\nnamespace dat\n{\n\nWeapon::Weapon(DataHub &datahub, unsigned int id) :\n  ObjectAccess(datahub, id)\n{\n\n}\n\nWeapon::~Weapon()\n{\n\n}\n\nuint16_t Weapon::label()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->label()->at(mId);\n}\n\nTblEntry Weapon::label_tbl()\n{\n  LOG4CXX_TRACE(logger, to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  if(label() == Weapon::label_none)\n  {\n    throw PropertyNotAvailableException(mId, \"label_tbl\");\n  }\n\n  return mDatahub.stat_txt_tbl_vec.at(label()-1);\n}\n\nuint32_t Weapon::graphics()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->graphics()->at(mId);\n}\n\nFlingy Weapon::graphics_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n\n  uint32_t graphics_id = graphics();\n\n\n  if(graphics_id == Weapon::graphics_none)\n  {\n    throw PropertyNotAvailableException(mId, \"graphics_obj\");\n  }\n\n  return Flingy(mDatahub, graphics());\n}\n\nuint8_t Weapon::explosion()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->explosion()->at(mId);\n}\n\nuint16_t Weapon::target_flags()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->target_flags()->at(mId);\n}\n\nuint32_t Weapon::minimum_range()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->minimum_range()->at(mId);\n}\n\nuint32_t Weapon::maximum_range()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->maximum_range()->at(mId);\n}\n\nuint8_t Weapon::damage_upgrade()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->damage_upgrade()->at(mId);\n}\n\nUpgrade Weapon::damage_upgrade_obj()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return Upgrade(mDatahub, damage_upgrade());\n}\n\nuint8_t Weapon::weapon_type()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->weapon_type()->at(mId);\n}\n\nuint8_t Weapon::weapon_behaviour()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->weapon_behaviour()->at(mId);\n}\n\nuint8_t Weapon::remove_after()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->remove_after()->at(mId);\n}\n\nuint8_t Weapon::explosive_type()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->explosive_type()->at(mId);\n}\n\nuint16_t Weapon::inner_splash_range()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->inner_splash_range()->at(mId);\n}\n\nuint16_t Weapon::medium_splash_range()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->medium_splash_range()->at(mId);\n}\n\nuint16_t Weapon::outer_splash_range()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->outer_splash_range()->at(mId);\n}\n\nuint16_t Weapon::damage_amount()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->damage_amount()->at(mId);\n}\n\nuint16_t Weapon::damage_bonus()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->damage_amount()->at(mId);\n}\n\nuint8_t Weapon::weapon_cooldown()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->weapon_cooldown()->at(mId);\n}\n\nuint8_t Weapon::damage_factor()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->damage_factor()->at(mId);\n}\n\nuint8_t Weapon::attack_angle()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->attack_angle()->at(mId);\n}\n\nuint8_t Weapon::launch_spin()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->launch_spin()->at(mId);\n}\n\nuint8_t Weapon::x_offset()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->x_offset()->at(mId);\n}\n\n\nuint8_t Weapon::y_offset()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->y_offset()->at(mId);\n}\n\nuint16_t Weapon::error_message()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->error_message()->at(mId);\n}\n\nTblEntry Weapon::error_message_tbl()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.stat_txt_tbl_vec.at(error_message());\n}\n\nuint16_t Weapon::icon()\n{\n  LOG4CXX_TRACE(logger,  to_string(mId) + \"=>\" + LOG_CUR_FUNC + \"()\");\n  return mDatahub.weapons->icon()->at(mId);\n}\n\n\n} /* namespace dat */\n"
  },
  {
    "path": "src/dat/Weapon.h",
    "content": "/*\n * Weapon.h\n *\n  *      Author: Andreas Volz\n */\n\n#ifndef WEAPON_H\n#define WEAPON_H\n\n#include \"DataHub.h\"\n#include \"ObjectAccess.h\"\n#include \"PropertyNotAvailableException.h\"\n#include \"Flingy.h\"\n#include \"Upgrade.h\"\n\nnamespace dat\n{\n\nclass Weapon : public ObjectAccess\n{\npublic:\n  Weapon(DataHub &datahub, unsigned int id);\n  virtual ~Weapon();\n\n  uint16_t label();\n  TblEntry label_tbl();\n\n  uint32_t graphics();\n  Flingy graphics_obj();\n\n  // TODO: make enum as return\n  uint8_t explosion();\n\n  uint16_t target_flags();\n\n  uint32_t minimum_range();\n\n  uint32_t maximum_range();\n\n  uint8_t damage_upgrade();\n  Upgrade damage_upgrade_obj();\n\n  uint8_t weapon_type();\n\n  // TODO: make enum as return\n  uint8_t weapon_behaviour();\n\n  uint8_t remove_after();\n\n  // TODO: make enum as return\n  uint8_t explosive_type();\n\n  uint16_t inner_splash_range();\n\n  uint16_t medium_splash_range();\n\n  uint16_t outer_splash_range();\n\n  uint16_t damage_amount();\n\n  uint16_t damage_bonus();\n\n  uint8_t weapon_cooldown();\n\n  uint8_t damage_factor();\n\n  uint8_t attack_angle();\n\n  uint8_t launch_spin();\n\n  uint8_t x_offset();\n\n  uint8_t y_offset();\n\n  uint16_t error_message();\n\n  TblEntry error_message_tbl();\n\n  uint16_t icon();\n\n  /* constants */\n\n  static const int graphics_none = 0;\n  static const int label_none = 0;\n\nprivate:\n\n};\n\n} /* namespace dat */\n\n#endif /* WEAPON_H */\n"
  },
  {
    "path": "src/dat/meson.build",
    "content": "startool_dat_sources = files(\n\t'DataHub.cpp',\n\t'Unit.cpp',\n\t'Flingy.cpp',\n\t'Sprite.cpp',\n\t'Image.cpp',\n\t'Tbl.cpp',\n\t'TblEntry.cpp',\n\t'Portrait.cpp',\n\t'Sfx.cpp',\n\t'Weapon.cpp',\n\t'PropertyNotAvailableException.cpp',\n\t'Order.cpp',\n\t'Techdata.cpp',\n\t'Upgrade.cpp',\n\t'IScript.cpp'\n)\n\n"
  },
  {
    "path": "src/endian.h",
    "content": "//       _________ __                 __\n//      /   _____//  |_____________ _/  |______     ____  __ __  ______\n//      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n//      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ |\n//     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n//             \\/                  \\/          \\//_____/            \\/\n//  ______________________                           ______________________\n//                        T H E   W A R   B E G I N S\n//         Stratagus - A free fantasy real time strategy game engine\n//\n/**@name wartool.h */\n//\n//      (c) Copyright 1998-2004 by Lutz Sammer\n//\n//      This program is free software; you can redistribute it and/or modify\n//      it under the terms of the GNU General Public License as published by\n//      the Free Software Foundation; only version 2 of the License.\n//\n//      This program is distributed in the hope that it will be useful,\n//      but WITHOUT ANY WARRANTY; without even the implied warranty of\n//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//      GNU General Public License for more details.\n//\n//      You should have received a copy of the GNU General Public License\n//      along with this program; if not, write to the Free Software\n//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n//      02111-1307, USA.\n//\n#ifndef __WENDIAN_H__\n#define __WENDIAN_H__\n\n#ifdef __aarch64__\n#ifdef __AARCH64EB__\n# define __BYTE_ORDER __BIG_ENDIAN\n#define __BIG_ENDIAN__ 4321\n#else\n# define __BYTE_ORDER __LITTLE_ENDIAN\n#define __LITTLE_ENDIAN__ 1234\n#endif\n#endif\n\n// From SDL_byteorder.h\n#if  defined(__i386__) || defined(__ia64__) || defined(_MSC_VER) || \\\n    (defined(__alpha__) || defined(__alpha)) || \\\n     defined(__arm__) || \\\n    (defined(__mips__) && defined(__MIPSEL__)) || \\\n     defined(__SYMBIAN32__) || \\\n     defined(__x86_64__) || \\\n     defined(__LITTLE_ENDIAN__)\n#ifdef __cplusplus\nstatic inline unsigned short FetchLE16(unsigned char *&p)\n{\n  unsigned short s = *(unsigned short*) p;\n  p += 2;\n  return s;\n}\nstatic inline unsigned int FetchLE32(unsigned char *&p)\n{\n  unsigned int s = *(unsigned int*) p;\n  p += 4;\n  return s;\n}\n#else\n#define FetchLE16(p) (*((unsigned short*)(p))); p += 2\n#define FetchLE32(p) (*((unsigned int*)(p))); p += 4\n#endif\n#define AccessLE16(p) (*((unsigned short*)(p)))\n#define AccessLE32(p) (*((unsigned int*)(p)))\n#define ConvertLE16(v) (v)\n#define ConvertLE32(v) (v)\n#else\nstatic inline unsigned short Swap16(unsigned short D) {\n\treturn ((D << 8) | (D >> 8));\n}\nstatic inline unsigned int Swap32(unsigned int D) {\n\treturn ((D << 24) | ((D << 8) & 0x00FF0000) | ((D >> 8) & 0x0000FF00) | (D >> 24));\n}\n#define FetchLE16(p) Swap16(*((unsigned short*)(p))); p += 2\n#define FetchLE32(p) Swap32(*((unsigned int*)(p))); p += 4\n#define AccessLE16(p) Swap16((*((unsigned short*)(p))))\n#define AccessLE32(p) Swap32(*((unsigned int*)(p)))\n#define ConvertLE16(v) Swap16(v)\n#define ConvertLE32(v) Swap32(v)\n#endif\n\n#define FetchByte(p) (*((unsigned char*)(p))); ++p\n\n#endif /* __WENDIAN_H__ */\n"
  },
  {
    "path": "src/kaitai/custom_decoder.h",
    "content": "#ifndef KAITAI_CUSTOM_DECODER_H\n#define KAITAI_CUSTOM_DECODER_H\n\n#include <string>\n\nnamespace kaitai {\n\nclass custom_decoder {\npublic:\n    virtual ~custom_decoder() {};\n    virtual std::string decode(std::string src) = 0;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "src/kaitai/exceptions.h",
    "content": "#ifndef KAITAI_EXCEPTIONS_H\n#define KAITAI_EXCEPTIONS_H\n\n#include <kaitai/kaitaistream.h>\n\n#include <string>\n#include <stdexcept>\n\n// We need to use \"noexcept\" in virtual destructor of our exceptions\n// subclasses. Different compilers have different ideas on how to\n// achieve that: C++98 compilers prefer `throw()`, C++11 and later\n// use `noexcept`. We define KS_NOEXCEPT macro for that.\n\n#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)\n#define KS_NOEXCEPT noexcept\n#else\n#define KS_NOEXCEPT throw()\n#endif\n\nnamespace kaitai {\n\n/**\n * Common ancestor for all error originating from Kaitai Struct usage.\n * Stores KSY source path, pointing to an element supposedly guilty of\n * an error.\n */\nclass kstruct_error: public std::runtime_error {\npublic:\n    kstruct_error(const std::string what, const std::string src_path):\n        std::runtime_error(src_path + \": \" + what),\n        m_src_path(src_path)\n    {\n    }\n\n    virtual ~kstruct_error() KS_NOEXCEPT {};\n\nprotected:\n    const std::string m_src_path;\n};\n\n/**\n * Error that occurs when default endianness should be decided with\n * a switch, but nothing matches (although using endianness expression\n * implies that there should be some positive result).\n */\nclass undecided_endianness_error: public kstruct_error {\npublic:\n    undecided_endianness_error(const std::string src_path):\n        kstruct_error(\"unable to decide on endianness for a type\", src_path)\n    {\n    }\n\n    virtual ~undecided_endianness_error() KS_NOEXCEPT {};\n};\n\n/**\n * Common ancestor for all validation failures. Stores pointer to\n * KaitaiStream IO object which was involved in an error.\n */\nclass validation_failed_error: public kstruct_error {\npublic:\n    validation_failed_error(const std::string what, kstream* io, const std::string src_path):\n        kstruct_error(\"at pos \" + kstream::to_string(io->pos()) + \": validation failed: \" + what, src_path),\n        m_io(io)\n    {\n    }\n\n// \"at pos #{io.pos}: validation failed: #{msg}\"\n\n    virtual ~validation_failed_error() KS_NOEXCEPT {};\n\nprotected:\n    kstream* m_io;\n};\n\n/**\n * Signals validation failure: we required \"actual\" value to be equal to\n * \"expected\", but it turned out that it's not.\n */\ntemplate<typename T>\nclass validation_not_equal_error: public validation_failed_error {\npublic:\n    validation_not_equal_error<T>(const T& expected, const T& actual, kstream* io, const std::string src_path):\n        validation_failed_error(\"not equal\", io, src_path),\n        m_expected(expected),\n        m_actual(actual)\n    {\n    }\n\n    // \"not equal, expected #{expected.inspect}, but got #{actual.inspect}\"\n\n    virtual ~validation_not_equal_error<T>() KS_NOEXCEPT {};\n\nprotected:\n    const T& m_expected;\n    const T& m_actual;\n};\n\n/**\n * Signals validation failure: we required \"actual\" value to be greater\n * than or equal to \"min\", but it turned out that it's not.\n */\ntemplate<typename T>\nclass validation_less_than_error: public validation_failed_error {\npublic:\n    validation_less_than_error<T>(const T& min, const T& actual, kstream* io, const std::string src_path):\n        validation_failed_error(\"not in range\", io, src_path),\n        m_min(min),\n        m_actual(actual)\n    {\n    }\n\n    // \"not in range, min #{min.inspect}, but got #{actual.inspect}\"\n\n    virtual ~validation_less_than_error<T>() KS_NOEXCEPT {};\n\nprotected:\n    const T& m_min;\n    const T& m_actual;\n};\n\n/**\n * Signals validation failure: we required \"actual\" value to be less\n * than or equal to \"max\", but it turned out that it's not.\n */\ntemplate<typename T>\nclass validation_greater_than_error: public validation_failed_error {\npublic:\n    validation_greater_than_error<T>(const T& max, const T& actual, kstream* io, const std::string src_path):\n        validation_failed_error(\"not in range\", io, src_path),\n        m_max(max),\n        m_actual(actual)\n    {\n    }\n\n    // \"not in range, max #{max.inspect}, but got #{actual.inspect}\"\n\n    virtual ~validation_greater_than_error<T>() KS_NOEXCEPT {};\n\nprotected:\n    const T& m_max;\n    const T& m_actual;\n};\n\n/**\n * Signals validation failure: we required \"actual\" value to be from\n * the list, but it turned out that it's not.\n */\ntemplate<typename T>\nclass validation_not_any_of_error: public validation_failed_error {\npublic:\n    validation_not_any_of_error<T>(const T& actual, kstream* io, const std::string src_path):\n        validation_failed_error(\"not any of the list\", io, src_path),\n        m_actual(actual)\n    {\n    }\n\n    // \"not any of the list, got #{actual.inspect}\"\n\n    virtual ~validation_not_any_of_error<T>() KS_NOEXCEPT {};\n\nprotected:\n    const T& m_actual;\n};\n\n/**\n * Signals validation failure: we required \"actual\" value to match\n * the expression, but it turned out that it doesn't.\n */\ntemplate<typename T>\nclass validation_expr_error: public validation_failed_error {\npublic:\n    validation_expr_error<T>(const T& actual, kstream* io, const std::string src_path):\n        validation_failed_error(\"not matching the expression\", io, src_path),\n        m_actual(actual)\n    {\n    }\n\n    // \"not matching the expression, got #{actual.inspect}\"\n\n    virtual ~validation_expr_error<T>() KS_NOEXCEPT {};\n\nprotected:\n    const T& m_actual;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "src/kaitai/file_tbl.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"file_tbl.h\"\n\nfile_tbl_t::file_tbl_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, file_tbl_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_ofs_files = 0;\n    m_tbl_entries = 0;\n    f_tbl_entries = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid file_tbl_t::_read() {\n    m_num_offsets = m__io->read_u2le();\n    m_ofs_files = new std::vector<uint16_t>();\n    const int l_ofs_files = num_offsets();\n    for (int i = 0; i < l_ofs_files; i++) {\n        m_ofs_files->push_back(m__io->read_u2le());\n    }\n}\n\nfile_tbl_t::~file_tbl_t() {\n    _clean_up();\n}\n\nvoid file_tbl_t::_clean_up() {\n    if (m_ofs_files) {\n        delete m_ofs_files; m_ofs_files = 0;\n    }\n    if (f_tbl_entries) {\n        if (m_tbl_entries) {\n            for (std::vector<tbl_entry_t*>::iterator it = m_tbl_entries->begin(); it != m_tbl_entries->end(); ++it) {\n                delete *it;\n            }\n            delete m_tbl_entries; m_tbl_entries = 0;\n        }\n    }\n}\n\nfile_tbl_t::tbl_entry_t::tbl_entry_t(uint16_t p_i, kaitai::kstream* p__io, file_tbl_t* p__parent, file_tbl_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_i = p_i;\n    m_entry = 0;\n    f_len = false;\n    f_dyn_end = false;\n    f_entry = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid file_tbl_t::tbl_entry_t::_read() {\n}\n\nfile_tbl_t::tbl_entry_t::~tbl_entry_t() {\n    _clean_up();\n}\n\nvoid file_tbl_t::tbl_entry_t::_clean_up() {\n    if (f_entry) {\n        if (m_entry) {\n            delete m_entry; m_entry = 0;\n        }\n    }\n}\n\nint32_t file_tbl_t::tbl_entry_t::len() {\n    if (f_len)\n        return m_len;\n    m_len = (_parent()->ofs_files()->at((i() + 1)) - _parent()->ofs_files()->at(i()));\n    f_len = true;\n    return m_len;\n}\n\nint32_t file_tbl_t::tbl_entry_t::dyn_end() {\n    if (f_dyn_end)\n        return m_dyn_end;\n    m_dyn_end = (((i() + 1) < _parent()->num_offsets()) ? (len()) : ((_io()->size() - _parent()->ofs_files()->at(i()))));\n    f_dyn_end = true;\n    return m_dyn_end;\n}\n\nstd::vector<uint8_t>* file_tbl_t::tbl_entry_t::entry() {\n    if (f_entry)\n        return m_entry;\n    std::streampos _pos = m__io->pos();\n    m__io->seek(_parent()->ofs_files()->at(i()));\n    m_entry = new std::vector<uint8_t>();\n    const int l_entry = dyn_end();\n    for (int i = 0; i < l_entry; i++) {\n        m_entry->push_back(m__io->read_u1());\n    }\n    m__io->seek(_pos);\n    f_entry = true;\n    return m_entry;\n}\n\nstd::vector<file_tbl_t::tbl_entry_t*>* file_tbl_t::tbl_entries() {\n    if (f_tbl_entries)\n        return m_tbl_entries;\n    m_tbl_entries = new std::vector<tbl_entry_t*>();\n    const int l_tbl_entries = num_offsets();\n    for (int i = 0; i < l_tbl_entries; i++) {\n        m_tbl_entries->push_back(new tbl_entry_t(i, m__io, this, m__root));\n    }\n    f_tbl_entries = true;\n    return m_tbl_entries;\n}\n"
  },
  {
    "path": "src/kaitai/file_tbl.h",
    "content": "#ifndef FILE_TBL_H_\n#define FILE_TBL_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass file_tbl_t : public kaitai::kstruct {\n\npublic:\n    class tbl_entry_t;\n\n    file_tbl_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, file_tbl_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~file_tbl_t();\n\n    class tbl_entry_t : public kaitai::kstruct {\n\n    public:\n\n        tbl_entry_t(uint16_t p_i, kaitai::kstream* p__io, file_tbl_t* p__parent = 0, file_tbl_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~tbl_entry_t();\n\n    private:\n        bool f_len;\n        int32_t m_len;\n\n    public:\n        int32_t len();\n\n    private:\n        bool f_dyn_end;\n        int32_t m_dyn_end;\n\n    public:\n        int32_t dyn_end();\n\n    private:\n        bool f_entry;\n        std::vector<uint8_t>* m_entry;\n\n    public:\n        std::vector<uint8_t>* entry();\n\n    private:\n        uint16_t m_i;\n        file_tbl_t* m__root;\n        file_tbl_t* m__parent;\n\n    public:\n        uint16_t i() const { return m_i; }\n        file_tbl_t* _root() const { return m__root; }\n        file_tbl_t* _parent() const { return m__parent; }\n    };\n\nprivate:\n    bool f_tbl_entries;\n    std::vector<tbl_entry_t*>* m_tbl_entries;\n\npublic:\n    std::vector<tbl_entry_t*>* tbl_entries();\n\nprivate:\n    uint16_t m_num_offsets;\n    std::vector<uint16_t>* m_ofs_files;\n    file_tbl_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n    uint16_t num_offsets() const { return m_num_offsets; }\n    std::vector<uint16_t>* ofs_files() const { return m_ofs_files; }\n    file_tbl_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // FILE_TBL_H_\n"
  },
  {
    "path": "src/kaitai/file_tbl.ksy",
    "content": "meta:\n  id: file_tbl\n  endian: le\n  encoding: ASCII\n  \nseq:\n  - id: num_offsets\n    type: u2\n  # Just read offsets normally\n  - id: ofs_files\n    type: u2\n    repeat: expr\n    repeat-expr: num_offsets\ninstances:\n  tbl_entries:\n    type: tbl_entry(_index)\n    repeat: expr\n    repeat-expr: num_offsets\ntypes:\n  tbl_entry:\n    params:\n      - id: i\n        type: u2\n    instances:\n      len:\n        value: '_parent.ofs_files[i + 1] - _parent.ofs_files[i]'\n      dyn_end:\n        value: 'i + 1 < _parent.num_offsets ? len : _io.size - _parent.ofs_files[i]'\n      entry:\n        pos: _parent.ofs_files[i]\n        type: u1\n        repeat: expr\n        repeat-expr: dyn_end"
  },
  {
    "path": "src/kaitai/flingy_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"flingy_dat.h\"\n\nflingy_dat_t::flingy_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, flingy_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_sprite = 0;\n    m_speed = 0;\n    m_acceleration = 0;\n    m_halt_distance = 0;\n    m_turn_radius = 0;\n    m_unused = 0;\n    m_movement_control = 0;\n    f_num_lines = false;\n    f_record_size = false;\n    f_file_size = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid flingy_dat_t::_read() {\n    m_sprite = new std::vector<uint16_t>();\n    const int l_sprite = num_lines();\n    for (int i = 0; i < l_sprite; i++) {\n        m_sprite->push_back(m__io->read_u2le());\n    }\n    m_speed = new std::vector<uint32_t>();\n    const int l_speed = num_lines();\n    for (int i = 0; i < l_speed; i++) {\n        m_speed->push_back(m__io->read_u4le());\n    }\n    m_acceleration = new std::vector<uint16_t>();\n    const int l_acceleration = num_lines();\n    for (int i = 0; i < l_acceleration; i++) {\n        m_acceleration->push_back(m__io->read_u2le());\n    }\n    m_halt_distance = new std::vector<uint32_t>();\n    const int l_halt_distance = num_lines();\n    for (int i = 0; i < l_halt_distance; i++) {\n        m_halt_distance->push_back(m__io->read_u4le());\n    }\n    m_turn_radius = new std::vector<uint8_t>();\n    const int l_turn_radius = num_lines();\n    for (int i = 0; i < l_turn_radius; i++) {\n        m_turn_radius->push_back(m__io->read_u1());\n    }\n    m_unused = new std::vector<uint8_t>();\n    const int l_unused = num_lines();\n    for (int i = 0; i < l_unused; i++) {\n        m_unused->push_back(m__io->read_u1());\n    }\n    m_movement_control = new std::vector<uint8_t>();\n    const int l_movement_control = num_lines();\n    for (int i = 0; i < l_movement_control; i++) {\n        m_movement_control->push_back(m__io->read_u1());\n    }\n}\n\nflingy_dat_t::~flingy_dat_t() {\n    _clean_up();\n}\n\nvoid flingy_dat_t::_clean_up() {\n    if (m_sprite) {\n        delete m_sprite; m_sprite = 0;\n    }\n    if (m_speed) {\n        delete m_speed; m_speed = 0;\n    }\n    if (m_acceleration) {\n        delete m_acceleration; m_acceleration = 0;\n    }\n    if (m_halt_distance) {\n        delete m_halt_distance; m_halt_distance = 0;\n    }\n    if (m_turn_radius) {\n        delete m_turn_radius; m_turn_radius = 0;\n    }\n    if (m_unused) {\n        delete m_unused; m_unused = 0;\n    }\n    if (m_movement_control) {\n        delete m_movement_control; m_movement_control = 0;\n    }\n}\n\nint32_t flingy_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = (file_size() / record_size());\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nint8_t flingy_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 15;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint32_t flingy_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n"
  },
  {
    "path": "src/kaitai/flingy_dat.h",
    "content": "#ifndef FLINGY_DAT_H_\n#define FLINGY_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass flingy_dat_t : public kaitai::kstruct {\n\npublic:\n\n    flingy_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, flingy_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~flingy_dat_t();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    std::vector<uint16_t>* m_sprite;\n    std::vector<uint32_t>* m_speed;\n    std::vector<uint16_t>* m_acceleration;\n    std::vector<uint32_t>* m_halt_distance;\n    std::vector<uint8_t>* m_turn_radius;\n    std::vector<uint8_t>* m_unused;\n    std::vector<uint8_t>* m_movement_control;\n    flingy_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * The sprites.dat entry corresponding to the flingy.dat entry. [pointer to sprites.dat]\n     */\n    std::vector<uint16_t>* sprite() const { return m_sprite; }\n\n    /**\n     * Maximum speed at which the sprite will move. Measured in pixels-per-frame, but written as \"Speed*(320/3)\" (rounded up, it's weird, but that's how it works). Works ONLY if \"Move Control\" is set to \"Flingy.dat Control\".\n     */\n    std::vector<uint32_t>* speed() const { return m_speed; }\n\n    /**\n     * How fast the sprite speeds up or slows down. Added to or subtracted from current speed until it reaches the Top Speed or 0. Measured in pixels-per-frame.  Works ONLY if \"Move Control\" is set to \"Flingy.dat Control\".\n     */\n    std::vector<uint16_t>* acceleration() const { return m_acceleration; }\n\n    /**\n     * Distance from its destination at which the sprite will begin to deccelerate from its Top Speed to a complete halt. Measured in pixels*256.\n     */\n    std::vector<uint32_t>* halt_distance() const { return m_halt_distance; }\n\n    /**\n     * The distance the sprite requires to \"wipe around\" to turn to another direction. Works ONLY if \"Move Control\" is set to \"Flingy.dat Control\".\n     */\n    std::vector<uint8_t>* turn_radius() const { return m_turn_radius; }\n\n    /**\n     * Unused.\n     */\n    std::vector<uint8_t>* unused() const { return m_unused; }\n\n    /**\n     * Indicates the mechanism that is used to control the movement of the flingy.dat entry. \"Flingy.dat Control\" makes use of the Acceleration, Speed, Turn Style and Turn Radius properties, i.e. the values in this editor will be used. \"Iscript.bin Control\" ignores these properties and follows only the Iscript opcode sequence. \"Partially Mobile/Weapon\" is used for various weapons sprites, not completely understood.\n     */\n    std::vector<uint8_t>* movement_control() const { return m_movement_control; }\n    flingy_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // FLINGY_DAT_H_\n"
  },
  {
    "path": "src/kaitai/flingy_dat.ksy",
    "content": "meta:\n  id: flingy_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: sprite\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The sprites.dat entry corresponding to the flingy.dat entry. [pointer to sprites.dat]\n\n  - id: speed\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Maximum speed at which the sprite will move. Measured in pixels-per-frame, but written as \"Speed*(320/3)\" (rounded up, it's weird, but that's how it works). Works ONLY if \"Move Control\" is set to \"Flingy.dat Control\".\n\n  - id: acceleration\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      How fast the sprite speeds up or slows down. Added to or subtracted from current speed until it reaches the Top Speed or 0. Measured in pixels-per-frame.  Works ONLY if \"Move Control\" is set to \"Flingy.dat Control\".\n\n  - id: halt_distance\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Distance from its destination at which the sprite will begin to deccelerate from its Top Speed to a complete halt. Measured in pixels*256.\n\n  - id: turn_radius\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The distance the sprite requires to \"wipe around\" to turn to another direction. Works ONLY if \"Move Control\" is set to \"Flingy.dat Control\".\n\n  - id: unused\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Unused.\n\n  - id: movement_control\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Indicates the mechanism that is used to control the movement of the flingy.dat entry. \"Flingy.dat Control\" makes use of the Acceleration, Speed, Turn Style and Turn Radius properties, i.e. the values in this editor will be used. \"Iscript.bin Control\" ignores these properties and follows only the Iscript opcode sequence. \"Partially Mobile/Weapon\" is used for various weapons sprites, not completely understood.\n\ninstances:\n  num_lines:\n    value: file_size / record_size\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 15\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  file_size:\n    value: '_io.size'\n"
  },
  {
    "path": "src/kaitai/images_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"images_dat.h\"\n\nimages_dat_t::images_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, images_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_grp = 0;\n    m_gfx_turns = 0;\n    m_clickable = 0;\n    m_use_full_iscript = 0;\n    m_draw_if_cloaked = 0;\n    m_draw_function = 0;\n    m_remapping = 0;\n    m_iscript = 0;\n    m_shield_overlay = 0;\n    m_attack_overlay = 0;\n    m_damage_overlay = 0;\n    m_special_overlay = 0;\n    m_landing_dust_overlay = 0;\n    m_lift_off_dust_overlay = 0;\n    f_num_lines = false;\n    f_record_size = false;\n    f_file_size = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid images_dat_t::_read() {\n    m_grp = new std::vector<uint32_t>();\n    const int l_grp = num_lines();\n    for (int i = 0; i < l_grp; i++) {\n        m_grp->push_back(m__io->read_u4le());\n    }\n    m_gfx_turns = new std::vector<uint8_t>();\n    const int l_gfx_turns = num_lines();\n    for (int i = 0; i < l_gfx_turns; i++) {\n        m_gfx_turns->push_back(m__io->read_u1());\n    }\n    m_clickable = new std::vector<uint8_t>();\n    const int l_clickable = num_lines();\n    for (int i = 0; i < l_clickable; i++) {\n        m_clickable->push_back(m__io->read_u1());\n    }\n    m_use_full_iscript = new std::vector<uint8_t>();\n    const int l_use_full_iscript = num_lines();\n    for (int i = 0; i < l_use_full_iscript; i++) {\n        m_use_full_iscript->push_back(m__io->read_u1());\n    }\n    m_draw_if_cloaked = new std::vector<uint8_t>();\n    const int l_draw_if_cloaked = num_lines();\n    for (int i = 0; i < l_draw_if_cloaked; i++) {\n        m_draw_if_cloaked->push_back(m__io->read_u1());\n    }\n    m_draw_function = new std::vector<draw_function_enum_t>();\n    const int l_draw_function = num_lines();\n    for (int i = 0; i < l_draw_function; i++) {\n        m_draw_function->push_back(static_cast<images_dat_t::draw_function_enum_t>(m__io->read_u1()));\n    }\n    m_remapping = new std::vector<remapping_enum_t>();\n    const int l_remapping = num_lines();\n    for (int i = 0; i < l_remapping; i++) {\n        m_remapping->push_back(static_cast<images_dat_t::remapping_enum_t>(m__io->read_u1()));\n    }\n    m_iscript = new std::vector<uint32_t>();\n    const int l_iscript = num_lines();\n    for (int i = 0; i < l_iscript; i++) {\n        m_iscript->push_back(m__io->read_u4le());\n    }\n    m_shield_overlay = new std::vector<uint32_t>();\n    const int l_shield_overlay = num_lines();\n    for (int i = 0; i < l_shield_overlay; i++) {\n        m_shield_overlay->push_back(m__io->read_u4le());\n    }\n    m_attack_overlay = new std::vector<uint32_t>();\n    const int l_attack_overlay = num_lines();\n    for (int i = 0; i < l_attack_overlay; i++) {\n        m_attack_overlay->push_back(m__io->read_u4le());\n    }\n    m_damage_overlay = new std::vector<uint32_t>();\n    const int l_damage_overlay = num_lines();\n    for (int i = 0; i < l_damage_overlay; i++) {\n        m_damage_overlay->push_back(m__io->read_u4le());\n    }\n    m_special_overlay = new std::vector<uint32_t>();\n    const int l_special_overlay = num_lines();\n    for (int i = 0; i < l_special_overlay; i++) {\n        m_special_overlay->push_back(m__io->read_u4le());\n    }\n    m_landing_dust_overlay = new std::vector<uint32_t>();\n    const int l_landing_dust_overlay = num_lines();\n    for (int i = 0; i < l_landing_dust_overlay; i++) {\n        m_landing_dust_overlay->push_back(m__io->read_u4le());\n    }\n    m_lift_off_dust_overlay = new std::vector<uint32_t>();\n    const int l_lift_off_dust_overlay = num_lines();\n    for (int i = 0; i < l_lift_off_dust_overlay; i++) {\n        m_lift_off_dust_overlay->push_back(m__io->read_u4le());\n    }\n}\n\nimages_dat_t::~images_dat_t() {\n    _clean_up();\n}\n\nvoid images_dat_t::_clean_up() {\n    if (m_grp) {\n        delete m_grp; m_grp = 0;\n    }\n    if (m_gfx_turns) {\n        delete m_gfx_turns; m_gfx_turns = 0;\n    }\n    if (m_clickable) {\n        delete m_clickable; m_clickable = 0;\n    }\n    if (m_use_full_iscript) {\n        delete m_use_full_iscript; m_use_full_iscript = 0;\n    }\n    if (m_draw_if_cloaked) {\n        delete m_draw_if_cloaked; m_draw_if_cloaked = 0;\n    }\n    if (m_draw_function) {\n        delete m_draw_function; m_draw_function = 0;\n    }\n    if (m_remapping) {\n        delete m_remapping; m_remapping = 0;\n    }\n    if (m_iscript) {\n        delete m_iscript; m_iscript = 0;\n    }\n    if (m_shield_overlay) {\n        delete m_shield_overlay; m_shield_overlay = 0;\n    }\n    if (m_attack_overlay) {\n        delete m_attack_overlay; m_attack_overlay = 0;\n    }\n    if (m_damage_overlay) {\n        delete m_damage_overlay; m_damage_overlay = 0;\n    }\n    if (m_special_overlay) {\n        delete m_special_overlay; m_special_overlay = 0;\n    }\n    if (m_landing_dust_overlay) {\n        delete m_landing_dust_overlay; m_landing_dust_overlay = 0;\n    }\n    if (m_lift_off_dust_overlay) {\n        delete m_lift_off_dust_overlay; m_lift_off_dust_overlay = 0;\n    }\n}\n\nint32_t images_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = (file_size() / record_size());\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nint8_t images_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 38;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint32_t images_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n"
  },
  {
    "path": "src/kaitai/images_dat.h",
    "content": "#ifndef IMAGES_DAT_H_\n#define IMAGES_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass images_dat_t : public kaitai::kstruct {\n\npublic:\n\n    enum draw_function_enum_t {\n        DRAW_FUNCTION_ENUM_NORMAL = 0,\n        DRAW_FUNCTION_ENUM_NO_HALLUCINATION = 1,\n        DRAW_FUNCTION_ENUM_NON_VISION_CLOAKING = 2,\n        DRAW_FUNCTION_ENUM_NON_VISION_CLOAKED = 3,\n        DRAW_FUNCTION_ENUM_NON_VISION_UNCLOAKING = 4,\n        DRAW_FUNCTION_ENUM_VISION_CLOAKING = 5,\n        DRAW_FUNCTION_ENUM_VISION_CLOAKED = 6,\n        DRAW_FUNCTION_ENUM_VISION_UNCLOAKING = 7,\n        DRAW_FUNCTION_ENUM_EMP_SHOCKWAVE = 8,\n        DRAW_FUNCTION_ENUM_REMAPPING = 9,\n        DRAW_FUNCTION_ENUM_SHADOW = 10,\n        DRAW_FUNCTION_ENUM_HP_BAR = 11,\n        DRAW_FUNCTION_ENUM_WARP_TEXTURE = 12,\n        DRAW_FUNCTION_ENUM_SEL_CIRCLE_REMAPPING = 13,\n        DRAW_FUNCTION_ENUM_PLAYER_COLOR = 14,\n        DRAW_FUNCTION_ENUM_UPDATE_RECT = 15,\n        DRAW_FUNCTION_ENUM_HALLUCINATION = 16,\n        DRAW_FUNCTION_ENUM_WARP_FLASH = 17\n    };\n\n    enum remapping_enum_t {\n        REMAPPING_ENUM_NO_REMAPPING = 0,\n        REMAPPING_ENUM_OFIRE = 1,\n        REMAPPING_ENUM_GFIRE = 2,\n        REMAPPING_ENUM_BFIRE = 3,\n        REMAPPING_ENUM_BEXPL = 4,\n        REMAPPING_ENUM_SPECIAL = 5,\n        REMAPPING_ENUM_UNKNOWN1 = 6,\n        REMAPPING_ENUM_UNKNOWN2 = 7,\n        REMAPPING_ENUM_UNKNOWN3 = 8,\n        REMAPPING_ENUM_UNKNOWN4 = 9\n    };\n\n    images_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, images_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~images_dat_t();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    std::vector<uint32_t>* m_grp;\n    std::vector<uint8_t>* m_gfx_turns;\n    std::vector<uint8_t>* m_clickable;\n    std::vector<uint8_t>* m_use_full_iscript;\n    std::vector<uint8_t>* m_draw_if_cloaked;\n    std::vector<draw_function_enum_t>* m_draw_function;\n    std::vector<remapping_enum_t>* m_remapping;\n    std::vector<uint32_t>* m_iscript;\n    std::vector<uint32_t>* m_shield_overlay;\n    std::vector<uint32_t>* m_attack_overlay;\n    std::vector<uint32_t>* m_damage_overlay;\n    std::vector<uint32_t>* m_special_overlay;\n    std::vector<uint32_t>* m_landing_dust_overlay;\n    std::vector<uint32_t>* m_lift_off_dust_overlay;\n    images_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * Indicates the GRP graphics used by the current images.dat entry. If the value exceeds the number of lines in images.tbl, SC won't load. [pointer to images.tbl, -1 based]\n     */\n    std::vector<uint32_t>* grp() const { return m_grp; }\n\n    /**\n     * Determines if the game engine dynamically adds up to 16 frames and/or mirror them during animations, depending on what direction the sprite is facing. Unchecked, makes the sprite follow its Iscript animation with exactly the frame numbers contained in it.\n     */\n    std::vector<uint8_t>* gfx_turns() const { return m_gfx_turns; }\n\n    /**\n     * Determines if the graphics can be selected using the mouse cursor. Also determines the presence (or lack of) the cursor selection graphics. DOES NOT make the unit not at all selectable - it is still possible using the selection box.\n     */\n    std::vector<uint8_t>* clickable() const { return m_clickable; }\n\n    /**\n     * Allows running for Iscript animations other than the Initial and Death animations. Unchecked, prevents the sprite movement, attack, spellcasting etc. If the Movement Control for the corresponding flingy.dat entry is set to \"Flingy.dat Control\", the sprite movement WILL take place, but without any animation.\n     */\n    std::vector<uint8_t>* use_full_iscript() const { return m_use_full_iscript; }\n\n    /**\n     * Makes the image appear/disappear when cloacked.\n     */\n    std::vector<uint8_t>* draw_if_cloaked() const { return m_draw_if_cloaked; }\n\n    /**\n     * The drawing function used for the image. This property has rather various effects and not all options works with all entries so expect crashes. It can produce very interesting effects though, especially spell-related.\n     * 0 - normal\\n\n     * 1 - doesn't draw hallucination\\n\n     * 2 - non-vision cloaking\\n\n     * 3 - non-vision cloaked\\n\n     * 4 - non-vision uncloaking\\n\n     * 5 - vision cloaking\\n\n     * 6 - vision cloaked\\n\n     * 7 - vision uncloaking\\n\n     * 8 - EMP shockwave\\n\n     * 9 - uses remapping\\n\n     * 10 - shadow\\n\n     * 11 - HP bar\\n\n     * 12 - warp texture\\n\n     * 13 - selection circle remapping\\n\n     * 14 - draw original player color (used for flags -- player color stored in coloring data)\\n\n     * 15 - draw update rect\\n\n     * 16 - hallucination\\n\n     * 17 - warp flash\\n\n     */\n    std::vector<draw_function_enum_t>* draw_function() const { return m_draw_function; }\n\n    /**\n     * An additional remapping \"palette\" that is to be used. Each tileset has its own files responsible for remapping. Used only if the Draw property is set to \"9-Use Remapping\". Values 8 and 9 produce a weird effect and most probably are a result of an error in Starcraft.\n     * If 'draw_function' is 9:\n     * 0 = No remapping\\n\n     * 1 = ofire.pcx (Orange)\\n\n     * 2 = gfire.pcx (Green)\\n\n     * 3 = bfire.pcx (Blue)\\n\n     * 4 = bexpl.pcx (Blue2)\\n\n     * 5 = Special (Own cloak)\\n\n     * 6 = (crash)\\n\n     * 7 = (crash)\\n\n     * 8 = Unk8 (?)\\n\n     * 9 = Unk9 (?)\\n\n     */\n    std::vector<remapping_enum_t>* remapping() const { return m_remapping; }\n\n    /**\n     * Indicates the animation ID in the Iscript.bin file used to manage the animation of the current entry's GRP graphics. [pointer to Iscript.bin]\n     */\n    std::vector<uint32_t>* iscript() const { return m_iscript; }\n\n    /**\n     * Overlay used to place the Images.dat entry #424 (\"Shield Overlay\"), if the unit has shields and is hit. [pointer to images.tbl]\n     */\n    std::vector<uint32_t>* shield_overlay() const { return m_shield_overlay; }\n\n    /**\n     * This one usually controls a part of the attack animation. Except for the Bunker (which is hardcoded), the use of this property is not specific, but removing it will hang the game if unit's Iscript animation calls for the overlay with the opcodes: 0xD(imgoluselo), 0xE(imguluselo) or 0x15(sproluselo).[pointer to a LOG\\LOL\\LOX\\LOA file in images.tbl]\n     */\n    std::vector<uint32_t>* attack_overlay() const { return m_attack_overlay; }\n\n    /**\n     * The \"Flames/Bleeding\" overlay control, dependent on the current HP value. If the number of frames of the used GRP file is higher than the number of frames of the overlay, the game will crash.[pointer to a LOF file in images.tbl]\n     */\n    std::vector<uint32_t>* damage_overlay() const { return m_damage_overlay; }\n\n    /**\n     * This one is used for various purposes: for \"Resource Miners\", it controls where they \"hold\" the resources;for the gas-containers, it controls the placement of the smoke graphics (iscript connection via the \"creategasoverlays\" (0x38) opcode); for the base-turret units, it controls the placement of the turret (also \"imgoluselo\" connection); for the Battlecruiser, it is the location of the Yamato Gun graphics.[pointer to a LOS\\LOL\\LOO\\LOA\\LOB file in images.tbl]\n     */\n    std::vector<uint32_t>* special_overlay() const { return m_special_overlay; }\n\n    /**\n     * Complementary to \"Lift-off Dust\", this one controls the placement of the landing dust. Some units (Dropship,Science Vessel) originally had this one too, but the idea was abandoned.Also used for the \"2 in 1 Egg\" zerg units, to determine the location where to put the 2 spawned units.[pointer to a LOB\\LOU file in images.tbl]\n     */\n    std::vector<uint32_t>* landing_dust_overlay() const { return m_landing_dust_overlay; }\n\n    /**\n     * Complementary to \"Landing Dust\", this one controls the placement of the lifting-off dust. Some units (Dropship, Science Vessel) originally had this too, but the idea was abandoned. [pointer to a LOD file in images.tbl]\n     */\n    std::vector<uint32_t>* lift_off_dust_overlay() const { return m_lift_off_dust_overlay; }\n    images_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // IMAGES_DAT_H_\n"
  },
  {
    "path": "src/kaitai/images_dat.ksy",
    "content": "meta:\n  id: images_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: grp\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Indicates the GRP graphics used by the current images.dat entry. If the value exceeds the number of lines in images.tbl, SC won't load. [pointer to images.tbl, -1 based]\n\n  - id: gfx_turns\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Determines if the game engine dynamically adds up to 16 frames and/or mirror them during animations, depending on what direction the sprite is facing. Unchecked, makes the sprite follow its Iscript animation with exactly the frame numbers contained in it.\n\n  - id: clickable\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Determines if the graphics can be selected using the mouse cursor. Also determines the presence (or lack of) the cursor selection graphics. DOES NOT make the unit not at all selectable - it is still possible using the selection box.\n\n  - id: use_full_iscript\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Allows running for Iscript animations other than the Initial and Death animations. Unchecked, prevents the sprite movement, attack, spellcasting etc. If the Movement Control for the corresponding flingy.dat entry is set to \"Flingy.dat Control\", the sprite movement WILL take place, but without any animation.\n\n  - id: draw_if_cloaked\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Makes the image appear/disappear when cloacked.\n\n  - id: draw_function\n    type: u1\n    enum: draw_function_enum\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The drawing function used for the image. This property has rather various effects and not all options works with all entries so expect crashes. It can produce very interesting effects though, especially spell-related.\n      0 - normal\\n\n      1 - doesn't draw hallucination\\n\n      2 - non-vision cloaking\\n\n      3 - non-vision cloaked\\n\n      4 - non-vision uncloaking\\n\n      5 - vision cloaking\\n\n      6 - vision cloaked\\n\n      7 - vision uncloaking\\n\n      8 - EMP shockwave\\n\n      9 - uses remapping\\n\n      10 - shadow\\n\n      11 - HP bar\\n\n      12 - warp texture\\n\n      13 - selection circle remapping\\n\n      14 - draw original player color (used for flags -- player color stored in coloring data)\\n\n      15 - draw update rect\\n\n      16 - hallucination\\n\n      17 - warp flash\\n\n\n  - id: remapping\n    type: u1\n    enum: remapping_enum\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      An additional remapping \"palette\" that is to be used. Each tileset has its own files responsible for remapping. Used only if the Draw property is set to \"9-Use Remapping\". Values 8 and 9 produce a weird effect and most probably are a result of an error in Starcraft.\n      If 'draw_function' is 9:\n      0 = No remapping\\n\n      1 = ofire.pcx (Orange)\\n\n      2 = gfire.pcx (Green)\\n\n      3 = bfire.pcx (Blue)\\n\n      4 = bexpl.pcx (Blue2)\\n\n      5 = Special (Own cloak)\\n\n      6 = (crash)\\n\n      7 = (crash)\\n\n      8 = Unk8 (?)\\n\n      9 = Unk9 (?)\\n\n\n  - id: iscript\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Indicates the animation ID in the Iscript.bin file used to manage the animation of the current entry's GRP graphics. [pointer to Iscript.bin]\n\n  - id: shield_overlay\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Overlay used to place the Images.dat entry #424 (\"Shield Overlay\"), if the unit has shields and is hit. [pointer to images.tbl]\n\n  - id: attack_overlay\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      This one usually controls a part of the attack animation. Except for the Bunker (which is hardcoded), the use of this property is not specific, but removing it will hang the game if unit's Iscript animation calls for the overlay with the opcodes: 0xD(imgoluselo), 0xE(imguluselo) or 0x15(sproluselo).[pointer to a LOG\\LOL\\LOX\\LOA file in images.tbl]\n\n  - id: damage_overlay\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The \"Flames/Bleeding\" overlay control, dependent on the current HP value. If the number of frames of the used GRP file is higher than the number of frames of the overlay, the game will crash.[pointer to a LOF file in images.tbl]\n\n  - id: special_overlay\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      This one is used for various purposes: for \"Resource Miners\", it controls where they \"hold\" the resources;for the gas-containers, it controls the placement of the smoke graphics (iscript connection via the \"creategasoverlays\" (0x38) opcode); for the base-turret units, it controls the placement of the turret (also \"imgoluselo\" connection); for the Battlecruiser, it is the location of the Yamato Gun graphics.[pointer to a LOS\\LOL\\LOO\\LOA\\LOB file in images.tbl]\n\n  - id: landing_dust_overlay\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Complementary to \"Lift-off Dust\", this one controls the placement of the landing dust. Some units (Dropship,Science Vessel) originally had this one too, but the idea was abandoned.Also used for the \"2 in 1 Egg\" zerg units, to determine the location where to put the 2 spawned units.[pointer to a LOB\\LOU file in images.tbl]\n\n  - id: lift_off_dust_overlay\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Complementary to \"Landing Dust\", this one controls the placement of the lifting-off dust. Some units (Dropship, Science Vessel) originally had this too, but the idea was abandoned. [pointer to a LOD file in images.tbl]\n\ninstances:\n  num_lines:\n    value: file_size / record_size\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 38\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  file_size:\n    value: '_io.size'\n    \nenums:\n  draw_function_enum:\n    0: normal\n    1: no_hallucination\n    2: non_vision_cloaking\n    3: non_vision_cloaked\n    4: non_vision_uncloaking\n    5: vision_cloaking\n    6: vision_cloaked\n    7: vision_uncloaking\n    8: emp_shockwave\n    9: remapping\n    10: shadow\n    11: hp_bar\n    12: warp_texture\n    13: sel_circle_remapping\n    14: player_color\n    15: update_rect\n    16: hallucination\n    17: warp_flash\n\n  remapping_enum:\n    0: no_remapping\n    1: ofire\n    2: gfire\n    3: bfire\n    4: bexpl\n    5: special\n    6: unknown1\n    7: unknown2\n    8: unknown3\n    9: unknown4\n\n"
  },
  {
    "path": "src/kaitai/iscript_bin.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"iscript_bin.h\"\n\niscript_bin_t::iscript_bin_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_entree_offsets = 0;\n    m_scpe = 0;\n    f_version_tag = false;\n    f_entree_table_pos = false;\n    f_entree_offsets = false;\n    f_scpe = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::_read() {\n    m_first_word = m__io->read_u2le();\n}\n\niscript_bin_t::~iscript_bin_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::_clean_up() {\n    if (f_version_tag) {\n    }\n    if (f_entree_offsets) {\n        if (m_entree_offsets) {\n            for (std::vector<entree_offset_type_t*>::iterator it = m_entree_offsets->begin(); it != m_entree_offsets->end(); ++it) {\n                delete *it;\n            }\n            delete m_entree_offsets; m_entree_offsets = 0;\n        }\n    }\n    if (f_scpe) {\n        if (m_scpe) {\n            for (std::vector<scpe_type_t*>::iterator it = m_scpe->begin(); it != m_scpe->end(); ++it) {\n                delete *it;\n            }\n            delete m_scpe; m_scpe = 0;\n        }\n    }\n}\n\niscript_bin_t::scpe_content_type_t::scpe_content_type_t(kaitai::kstream* p__io, iscript_bin_t::scpe_type_t* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_scpe_opcode_list = 0;\n    f_scpe_opcode_list = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::scpe_content_type_t::_read() {\n    m_scpe_opcode_offset = m__io->read_u2le();\n}\n\niscript_bin_t::scpe_content_type_t::~scpe_content_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::scpe_content_type_t::_clean_up() {\n    if (f_scpe_opcode_list && !n_scpe_opcode_list) {\n        if (m_scpe_opcode_list) {\n            delete m_scpe_opcode_list; m_scpe_opcode_list = 0;\n        }\n    }\n}\n\nopcode_list_type_t* iscript_bin_t::scpe_content_type_t::scpe_opcode_list() {\n    if (f_scpe_opcode_list)\n        return m_scpe_opcode_list;\n    n_scpe_opcode_list = true;\n    if (scpe_opcode_offset() != 0) {\n        n_scpe_opcode_list = false;\n        std::streampos _pos = m__io->pos();\n        m__io->seek(scpe_opcode_offset());\n        m_scpe_opcode_list = new opcode_list_type_t(_parent(), _root(), m__io);\n        m__io->seek(_pos);\n        f_scpe_opcode_list = true;\n    }\n    return m_scpe_opcode_list;\n}\n\niscript_bin_t::trgtrangecondjmp_type_t::trgtrangecondjmp_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::trgtrangecondjmp_type_t::_read() {\n    m_distance = m__io->read_u2le();\n    m_labelname = m__io->read_u2le();\n}\n\niscript_bin_t::trgtrangecondjmp_type_t::~trgtrangecondjmp_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::trgtrangecondjmp_type_t::_clean_up() {\n}\n\niscript_bin_t::u1_type_t::u1_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::u1_type_t::_read() {\n    m_value = m__io->read_u1();\n}\n\niscript_bin_t::u1_type_t::~u1_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::u1_type_t::_clean_up() {\n}\n\niscript_bin_t::playsounds_type_t::playsounds_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_sound = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::playsounds_type_t::_read() {\n    m_number_sounds = m__io->read_u1();\n    m_sound = new std::vector<uint16_t>();\n    const int l_sound = number_sounds();\n    for (int i = 0; i < l_sound; i++) {\n        m_sound->push_back(m__io->read_u2le());\n    }\n}\n\niscript_bin_t::playsounds_type_t::~playsounds_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::playsounds_type_t::_clean_up() {\n    if (m_sound) {\n        delete m_sound; m_sound = 0;\n    }\n}\n\niscript_bin_t::randcondjmp_type_t::randcondjmp_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::randcondjmp_type_t::_read() {\n    m_randchance = m__io->read_u1();\n    m_labelname = m__io->read_u2le();\n}\n\niscript_bin_t::randcondjmp_type_t::~randcondjmp_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::randcondjmp_type_t::_clean_up() {\n}\n\niscript_bin_t::empty_type_t::empty_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::empty_type_t::_read() {\n}\n\niscript_bin_t::empty_type_t::~empty_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::empty_type_t::_clean_up() {\n}\n\niscript_bin_t::pos_type_t::pos_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::pos_type_t::_read() {\n    m_x = m__io->read_u1();\n    m_y = m__io->read_u1();\n}\n\niscript_bin_t::pos_type_t::~pos_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::pos_type_t::_clean_up() {\n}\n\niscript_bin_t::sprl_type_t::sprl_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_pos = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::sprl_type_t::_read() {\n    m_sprite = m__io->read_u2le();\n    m_pos = new pos_type_t(m__io, this, m__root);\n}\n\niscript_bin_t::sprl_type_t::~sprl_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::sprl_type_t::_clean_up() {\n    if (m_pos) {\n        delete m_pos; m_pos = 0;\n    }\n}\n\niscript_bin_t::opcode_type_t::opcode_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::opcode_type_t::_read() {\n    m_code = static_cast<iscript_bin_t::opcode_t>(m__io->read_u1());\n    switch (code()) {\n    case iscript_bin_t::OPCODE_TURN1CWISE: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_IMGOLORIG: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_UNKNOWN_3E: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SIGORDER: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_ENGFRAME: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_TURNCCWISE: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_UNKNOWN_2D: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_END: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_PLAYFRAM: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_TMPRMGRAPHICSTART: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_IMGULNEXTID: {\n        m_args = new pos_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_PLAYSNDBTWN: {\n        m_args = new playsndbtwn_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_UNKNOWN_0C: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_ENGSET: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SWITCHUL: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_TRGTARCCONDJMP: {\n        m_args = new trgcondjmp_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SETFLIPSTATE: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SETPOS: {\n        m_args = new pos_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_IMGOLUSELO: {\n        m_args = new imgl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_LOWSPRUL: {\n        m_args = new sprl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_TURNRAND: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_DOMISSILEDMG: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_HIGHSPROL: {\n        m_args = new sprl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SETFLSPEED: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_USEWEAPON: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_WARPOVERLAY: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_GOTOREPEATATTK: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_UFLUNSTABLE: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_ORDERDONE: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_TRGTRANGECONDJMP: {\n        m_args = new trgtrangecondjmp_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_RETURN: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_CASTSPELL: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_FOLLOWMAINGRAPHIC: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_RANDCONDJMP: {\n        m_args = new randcondjmp_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_NOBRKCODEEND: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_CALL: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_NOBRKCODESTART: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_WAIT: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SPROL: {\n        m_args = new sprl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_TMPRMGRAPHICEND: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_CREATEGASOVERLAYS: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SETFLDIRECT: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_PWRUPCONDJMP: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SETHORPOS: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SPRULUSELO: {\n        m_args = new sprl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SPRUL: {\n        m_args = new sprl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_GRDSPROL: {\n        m_args = new sprl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_MOVE: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_GOTO: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_IMGUL: {\n        m_args = new imgl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_PLAYFRAMTILE: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_ATTKSHIFTPROJ: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_LIFTOFFCONDJMP: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_IMGOL: {\n        m_args = new imgl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_IMGULUSELO: {\n        m_args = new imgl_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_ATTACK: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_ATTACKMELEE: {\n        m_args = new playsounds_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SPROLUSELO: {\n        m_args = new sprov_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_PLAYSNDRAND: {\n        m_args = new playsounds_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_IGNOREREST: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_PLAYSND: {\n        m_args = new u2_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_UNKNOWN_43: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SETVERTPOS: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_DOGRDDAMAGE: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_WAITRAND: {\n        m_args = new waitrand_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_TURNCWISE: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_CURDIRECTCONDJMP: {\n        m_args = new trgcondjmp_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_SETSPAWNFRAME: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    case iscript_bin_t::OPCODE_ATTACKWITH: {\n        m_args = new u1_type_t(m__io, this, m__root);\n        break;\n    }\n    default: {\n        m_args = new empty_type_t(m__io, this, m__root);\n        break;\n    }\n    }\n}\n\niscript_bin_t::opcode_type_t::~opcode_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::opcode_type_t::_clean_up() {\n    if (m_args) {\n        delete m_args; m_args = 0;\n    }\n}\n\niscript_bin_t::trgcondjmp_type_t::trgcondjmp_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::trgcondjmp_type_t::_read() {\n    m_angle1 = m__io->read_u2le();\n    m_angle2 = m__io->read_u2le();\n    m_labelname = m__io->read_u2le();\n}\n\niscript_bin_t::trgcondjmp_type_t::~trgcondjmp_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::trgcondjmp_type_t::_clean_up() {\n}\n\niscript_bin_t::entree_offset_type_t::entree_offset_type_t(kaitai::kstream* p__io, iscript_bin_t* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::entree_offset_type_t::_read() {\n    m_iscript_id = m__io->read_u2le();\n    m_offset = m__io->read_u2le();\n}\n\niscript_bin_t::entree_offset_type_t::~entree_offset_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::entree_offset_type_t::_clean_up() {\n}\n\niscript_bin_t::scpe_type_t::scpe_type_t(uint16_t p_i, kaitai::kstream* p__io, iscript_bin_t* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_i = p_i;\n    m_scpe_header = 0;\n    m_scpe_content = 0;\n    f_scpe_header = false;\n    f_num_scpe_content = false;\n    f_scpe_content = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::scpe_type_t::_read() {\n}\n\niscript_bin_t::scpe_type_t::~scpe_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::scpe_type_t::_clean_up() {\n    if (f_scpe_header) {\n        if (m_scpe_header) {\n            delete m_scpe_header; m_scpe_header = 0;\n        }\n    }\n    if (f_scpe_content) {\n        if (m_scpe_content) {\n            for (std::vector<scpe_content_type_t*>::iterator it = m_scpe_content->begin(); it != m_scpe_content->end(); ++it) {\n                delete *it;\n            }\n            delete m_scpe_content; m_scpe_content = 0;\n        }\n    }\n}\n\niscript_bin_t::scpe_header_type_t* iscript_bin_t::scpe_type_t::scpe_header() {\n    if (f_scpe_header)\n        return m_scpe_header;\n    std::streampos _pos = m__io->pos();\n    m__io->seek(_parent()->entree_offsets()->at(i())->offset());\n    m_scpe_header = new scpe_header_type_t(m__io, this, m__root);\n    m__io->seek(_pos);\n    f_scpe_header = true;\n    return m_scpe_header;\n}\n\nint8_t iscript_bin_t::scpe_type_t::num_scpe_content() {\n    if (f_num_scpe_content)\n        return m_num_scpe_content;\n    m_num_scpe_content = ((scpe_header()->scpe_content_type() == 0) ? (2) : (((scpe_header()->scpe_content_type() == 1) ? (2) : (((scpe_header()->scpe_content_type() == 2) ? (4) : (((scpe_header()->scpe_content_type() == 12) ? (14) : (((scpe_header()->scpe_content_type() == 13) ? (14) : (((scpe_header()->scpe_content_type() == 14) ? (15) : (((scpe_header()->scpe_content_type() == 15) ? (15) : (((scpe_header()->scpe_content_type() == 20) ? (21) : (((scpe_header()->scpe_content_type() == 21) ? (21) : (((scpe_header()->scpe_content_type() == 23) ? (23) : (((scpe_header()->scpe_content_type() == 24) ? (25) : (((scpe_header()->scpe_content_type() == 26) ? (27) : (((scpe_header()->scpe_content_type() == 27) ? (27) : (((scpe_header()->scpe_content_type() == 28) ? (27) : (((scpe_header()->scpe_content_type() == 29) ? (27) : (0))))))))))))))))))))))))))))));\n    f_num_scpe_content = true;\n    return m_num_scpe_content;\n}\n\nstd::vector<iscript_bin_t::scpe_content_type_t*>* iscript_bin_t::scpe_type_t::scpe_content() {\n    if (f_scpe_content)\n        return m_scpe_content;\n    std::streampos _pos = m__io->pos();\n    m__io->seek((_parent()->entree_offsets()->at(i())->offset() + 8));\n    m_scpe_content = new std::vector<scpe_content_type_t*>();\n    const int l_scpe_content = num_scpe_content();\n    for (int i = 0; i < l_scpe_content; i++) {\n        m_scpe_content->push_back(new scpe_content_type_t(m__io, this, m__root));\n    }\n    m__io->seek(_pos);\n    f_scpe_content = true;\n    return m_scpe_content;\n}\n\niscript_bin_t::playsndbtwn_type_t::playsndbtwn_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::playsndbtwn_type_t::_read() {\n    m_firstsound = m__io->read_u2le();\n    m_lastsound = m__io->read_u2le();\n}\n\niscript_bin_t::playsndbtwn_type_t::~playsndbtwn_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::playsndbtwn_type_t::_clean_up() {\n}\n\niscript_bin_t::imgl_type_t::imgl_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_pos = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::imgl_type_t::_read() {\n    m_image = m__io->read_u2le();\n    m_pos = new pos_type_t(m__io, this, m__root);\n}\n\niscript_bin_t::imgl_type_t::~imgl_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::imgl_type_t::_clean_up() {\n    if (m_pos) {\n        delete m_pos; m_pos = 0;\n    }\n}\n\niscript_bin_t::waitrand_type_t::waitrand_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::waitrand_type_t::_read() {\n    m_ticks1 = m__io->read_u1();\n    m_ticks2 = m__io->read_u1();\n}\n\niscript_bin_t::waitrand_type_t::~waitrand_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::waitrand_type_t::_clean_up() {\n}\n\niscript_bin_t::sprov_type_t::sprov_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::sprov_type_t::_read() {\n    m_sprite = m__io->read_u2le();\n    m_overlay = m__io->read_u1();\n}\n\niscript_bin_t::sprov_type_t::~sprov_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::sprov_type_t::_clean_up() {\n}\n\niscript_bin_t::scpe_header_type_t::scpe_header_type_t(kaitai::kstream* p__io, iscript_bin_t::scpe_type_t* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::scpe_header_type_t::_read() {\n    m_scpe_magic = m__io->read_u4le();\n    m_scpe_content_type = m__io->read_u1();\n    m_padding = m__io->read_bytes(3);\n}\n\niscript_bin_t::scpe_header_type_t::~scpe_header_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::scpe_header_type_t::_clean_up() {\n}\n\niscript_bin_t::u2_type_t::u2_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, iscript_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid iscript_bin_t::u2_type_t::_read() {\n    m_value = m__io->read_u2le();\n}\n\niscript_bin_t::u2_type_t::~u2_type_t() {\n    _clean_up();\n}\n\nvoid iscript_bin_t::u2_type_t::_clean_up() {\n}\n\nuint32_t iscript_bin_t::version_tag() {\n    if (f_version_tag)\n        return m_version_tag;\n    std::streampos _pos = m__io->pos();\n    m__io->seek(2);\n    m_version_tag = m__io->read_u4le();\n    m__io->seek(_pos);\n    f_version_tag = true;\n    return m_version_tag;\n}\n\nuint16_t iscript_bin_t::entree_table_pos() {\n    if (f_entree_table_pos)\n        return m_entree_table_pos;\n    m_entree_table_pos = ((version_tag() == 0) ? (first_word()) : (0));\n    f_entree_table_pos = true;\n    return m_entree_table_pos;\n}\n\nstd::vector<iscript_bin_t::entree_offset_type_t*>* iscript_bin_t::entree_offsets() {\n    if (f_entree_offsets)\n        return m_entree_offsets;\n    std::streampos _pos = m__io->pos();\n    m__io->seek(entree_table_pos());\n    m_entree_offsets = new std::vector<entree_offset_type_t*>();\n    {\n        int i = 0;\n        entree_offset_type_t* _;\n        do {\n            _ = new entree_offset_type_t(m__io, this, m__root);\n            m_entree_offsets->push_back(_);\n            i++;\n        } while (!(((_->iscript_id() == 65535) ? (_->offset() == 0) : (false))));\n    }\n    m__io->seek(_pos);\n    f_entree_offsets = true;\n    return m_entree_offsets;\n}\n\nstd::vector<iscript_bin_t::scpe_type_t*>* iscript_bin_t::scpe() {\n    if (f_scpe)\n        return m_scpe;\n    m_scpe = new std::vector<scpe_type_t*>();\n    const int l_scpe = _root()->entree_offsets()->size();\n    for (int i = 0; i < l_scpe; i++) {\n        m_scpe->push_back(new scpe_type_t(i, m__io, this, m__root));\n    }\n    f_scpe = true;\n    return m_scpe;\n}\n"
  },
  {
    "path": "src/kaitai/iscript_bin.h",
    "content": "#ifndef ISCRIPT_BIN_H_\n#define ISCRIPT_BIN_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include \"opcode_list_type.h\"\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\nclass opcode_list_type_t;\n\nclass iscript_bin_t : public kaitai::kstruct {\n\npublic:\n    class scpe_content_type_t;\n    class trgtrangecondjmp_type_t;\n    class u1_type_t;\n    class playsounds_type_t;\n    class randcondjmp_type_t;\n    class empty_type_t;\n    class pos_type_t;\n    class sprl_type_t;\n    class opcode_type_t;\n    class trgcondjmp_type_t;\n    class entree_offset_type_t;\n    class scpe_type_t;\n    class playsndbtwn_type_t;\n    class imgl_type_t;\n    class waitrand_type_t;\n    class sprov_type_t;\n    class scpe_header_type_t;\n    class u2_type_t;\n\n    enum opcode_t {\n        OPCODE_PLAYFRAM = 0,\n        OPCODE_PLAYFRAMTILE = 1,\n        OPCODE_SETHORPOS = 2,\n        OPCODE_SETVERTPOS = 3,\n        OPCODE_SETPOS = 4,\n        OPCODE_WAIT = 5,\n        OPCODE_WAITRAND = 6,\n        OPCODE_GOTO = 7,\n        OPCODE_IMGOL = 8,\n        OPCODE_IMGUL = 9,\n        OPCODE_IMGOLORIG = 10,\n        OPCODE_SWITCHUL = 11,\n        OPCODE_UNKNOWN_0C = 12,\n        OPCODE_IMGOLUSELO = 13,\n        OPCODE_IMGULUSELO = 14,\n        OPCODE_SPROL = 15,\n        OPCODE_HIGHSPROL = 16,\n        OPCODE_LOWSPRUL = 17,\n        OPCODE_UFLUNSTABLE = 18,\n        OPCODE_SPRULUSELO = 19,\n        OPCODE_SPRUL = 20,\n        OPCODE_SPROLUSELO = 21,\n        OPCODE_END = 22,\n        OPCODE_SETFLIPSTATE = 23,\n        OPCODE_PLAYSND = 24,\n        OPCODE_PLAYSNDRAND = 25,\n        OPCODE_PLAYSNDBTWN = 26,\n        OPCODE_DOMISSILEDMG = 27,\n        OPCODE_ATTACKMELEE = 28,\n        OPCODE_FOLLOWMAINGRAPHIC = 29,\n        OPCODE_RANDCONDJMP = 30,\n        OPCODE_TURNCCWISE = 31,\n        OPCODE_TURNCWISE = 32,\n        OPCODE_TURN1CWISE = 33,\n        OPCODE_TURNRAND = 34,\n        OPCODE_SETSPAWNFRAME = 35,\n        OPCODE_SIGORDER = 36,\n        OPCODE_ATTACKWITH = 37,\n        OPCODE_ATTACK = 38,\n        OPCODE_CASTSPELL = 39,\n        OPCODE_USEWEAPON = 40,\n        OPCODE_MOVE = 41,\n        OPCODE_GOTOREPEATATTK = 42,\n        OPCODE_ENGFRAME = 43,\n        OPCODE_ENGSET = 44,\n        OPCODE_UNKNOWN_2D = 45,\n        OPCODE_NOBRKCODESTART = 46,\n        OPCODE_NOBRKCODEEND = 47,\n        OPCODE_IGNOREREST = 48,\n        OPCODE_ATTKSHIFTPROJ = 49,\n        OPCODE_TMPRMGRAPHICSTART = 50,\n        OPCODE_TMPRMGRAPHICEND = 51,\n        OPCODE_SETFLDIRECT = 52,\n        OPCODE_CALL = 53,\n        OPCODE_RETURN = 54,\n        OPCODE_SETFLSPEED = 55,\n        OPCODE_CREATEGASOVERLAYS = 56,\n        OPCODE_PWRUPCONDJMP = 57,\n        OPCODE_TRGTRANGECONDJMP = 58,\n        OPCODE_TRGTARCCONDJMP = 59,\n        OPCODE_CURDIRECTCONDJMP = 60,\n        OPCODE_IMGULNEXTID = 61,\n        OPCODE_UNKNOWN_3E = 62,\n        OPCODE_LIFTOFFCONDJMP = 63,\n        OPCODE_WARPOVERLAY = 64,\n        OPCODE_ORDERDONE = 65,\n        OPCODE_GRDSPROL = 66,\n        OPCODE_UNKNOWN_43 = 67,\n        OPCODE_DOGRDDAMAGE = 68\n    };\n\n    iscript_bin_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~iscript_bin_t();\n\n    class scpe_content_type_t : public kaitai::kstruct {\n\n    public:\n\n        scpe_content_type_t(kaitai::kstream* p__io, iscript_bin_t::scpe_type_t* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~scpe_content_type_t();\n\n    private:\n        bool f_scpe_opcode_list;\n        opcode_list_type_t* m_scpe_opcode_list;\n        bool n_scpe_opcode_list;\n\n    public:\n        bool _is_null_scpe_opcode_list() { scpe_opcode_list(); return n_scpe_opcode_list; };\n\n    private:\n\n    public:\n        opcode_list_type_t* scpe_opcode_list();\n\n    private:\n        uint16_t m_scpe_opcode_offset;\n        iscript_bin_t* m__root;\n        iscript_bin_t::scpe_type_t* m__parent;\n\n    public:\n        uint16_t scpe_opcode_offset() const { return m_scpe_opcode_offset; }\n        iscript_bin_t* _root() const { return m__root; }\n        iscript_bin_t::scpe_type_t* _parent() const { return m__parent; }\n    };\n\n    class trgtrangecondjmp_type_t : public kaitai::kstruct {\n\n    public:\n\n        trgtrangecondjmp_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~trgtrangecondjmp_type_t();\n\n    private:\n        uint16_t m_distance;\n        uint16_t m_labelname;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint16_t distance() const { return m_distance; }\n        uint16_t labelname() const { return m_labelname; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class u1_type_t : public kaitai::kstruct {\n\n    public:\n\n        u1_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~u1_type_t();\n\n    private:\n        uint8_t m_value;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint8_t value() const { return m_value; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class playsounds_type_t : public kaitai::kstruct {\n\n    public:\n\n        playsounds_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~playsounds_type_t();\n\n    private:\n        uint8_t m_number_sounds;\n        std::vector<uint16_t>* m_sound;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint8_t number_sounds() const { return m_number_sounds; }\n        std::vector<uint16_t>* sound() const { return m_sound; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class randcondjmp_type_t : public kaitai::kstruct {\n\n    public:\n\n        randcondjmp_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~randcondjmp_type_t();\n\n    private:\n        uint8_t m_randchance;\n        uint16_t m_labelname;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint8_t randchance() const { return m_randchance; }\n        uint16_t labelname() const { return m_labelname; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class empty_type_t : public kaitai::kstruct {\n\n    public:\n\n        empty_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~empty_type_t();\n\n    private:\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class pos_type_t : public kaitai::kstruct {\n\n    public:\n\n        pos_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~pos_type_t();\n\n    private:\n        uint8_t m_x;\n        uint8_t m_y;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint8_t x() const { return m_x; }\n        uint8_t y() const { return m_y; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class sprl_type_t : public kaitai::kstruct {\n\n    public:\n\n        sprl_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~sprl_type_t();\n\n    private:\n        uint16_t m_sprite;\n        pos_type_t* m_pos;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint16_t sprite() const { return m_sprite; }\n        pos_type_t* pos() const { return m_pos; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class opcode_type_t : public kaitai::kstruct {\n\n    public:\n\n        opcode_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~opcode_type_t();\n\n    private:\n        opcode_t m_code;\n        kaitai::kstruct* m_args;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        opcode_t code() const { return m_code; }\n        kaitai::kstruct* args() const { return m_args; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class trgcondjmp_type_t : public kaitai::kstruct {\n\n    public:\n\n        trgcondjmp_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~trgcondjmp_type_t();\n\n    private:\n        uint16_t m_angle1;\n        uint16_t m_angle2;\n        uint16_t m_labelname;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint16_t angle1() const { return m_angle1; }\n        uint16_t angle2() const { return m_angle2; }\n        uint16_t labelname() const { return m_labelname; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class entree_offset_type_t : public kaitai::kstruct {\n\n    public:\n\n        entree_offset_type_t(kaitai::kstream* p__io, iscript_bin_t* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~entree_offset_type_t();\n\n    private:\n        uint16_t m_iscript_id;\n        uint16_t m_offset;\n        iscript_bin_t* m__root;\n        iscript_bin_t* m__parent;\n\n    public:\n        uint16_t iscript_id() const { return m_iscript_id; }\n        uint16_t offset() const { return m_offset; }\n        iscript_bin_t* _root() const { return m__root; }\n        iscript_bin_t* _parent() const { return m__parent; }\n    };\n\n    class scpe_type_t : public kaitai::kstruct {\n\n    public:\n\n        scpe_type_t(uint16_t p_i, kaitai::kstream* p__io, iscript_bin_t* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~scpe_type_t();\n\n    private:\n        bool f_scpe_header;\n        scpe_header_type_t* m_scpe_header;\n\n    public:\n        scpe_header_type_t* scpe_header();\n\n    private:\n        bool f_num_scpe_content;\n        int8_t m_num_scpe_content;\n\n    public:\n        int8_t num_scpe_content();\n\n    private:\n        bool f_scpe_content;\n        std::vector<scpe_content_type_t*>* m_scpe_content;\n\n    public:\n        std::vector<scpe_content_type_t*>* scpe_content();\n\n    private:\n        uint16_t m_i;\n        iscript_bin_t* m__root;\n        iscript_bin_t* m__parent;\n\n    public:\n        uint16_t i() const { return m_i; }\n        iscript_bin_t* _root() const { return m__root; }\n        iscript_bin_t* _parent() const { return m__parent; }\n    };\n\n    class playsndbtwn_type_t : public kaitai::kstruct {\n\n    public:\n\n        playsndbtwn_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~playsndbtwn_type_t();\n\n    private:\n        uint16_t m_firstsound;\n        uint16_t m_lastsound;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint16_t firstsound() const { return m_firstsound; }\n        uint16_t lastsound() const { return m_lastsound; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class imgl_type_t : public kaitai::kstruct {\n\n    public:\n\n        imgl_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~imgl_type_t();\n\n    private:\n        uint16_t m_image;\n        pos_type_t* m_pos;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint16_t image() const { return m_image; }\n        pos_type_t* pos() const { return m_pos; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class waitrand_type_t : public kaitai::kstruct {\n\n    public:\n\n        waitrand_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~waitrand_type_t();\n\n    private:\n        uint8_t m_ticks1;\n        uint8_t m_ticks2;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint8_t ticks1() const { return m_ticks1; }\n        uint8_t ticks2() const { return m_ticks2; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class sprov_type_t : public kaitai::kstruct {\n\n    public:\n\n        sprov_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~sprov_type_t();\n\n    private:\n        uint16_t m_sprite;\n        uint8_t m_overlay;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint16_t sprite() const { return m_sprite; }\n        uint8_t overlay() const { return m_overlay; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\n    class scpe_header_type_t : public kaitai::kstruct {\n\n    public:\n\n        scpe_header_type_t(kaitai::kstream* p__io, iscript_bin_t::scpe_type_t* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~scpe_header_type_t();\n\n    private:\n        uint32_t m_scpe_magic;\n        uint8_t m_scpe_content_type;\n        std::string m_padding;\n        iscript_bin_t* m__root;\n        iscript_bin_t::scpe_type_t* m__parent;\n\n    public:\n        uint32_t scpe_magic() const { return m_scpe_magic; }\n        uint8_t scpe_content_type() const { return m_scpe_content_type; }\n        std::string padding() const { return m_padding; }\n        iscript_bin_t* _root() const { return m__root; }\n        iscript_bin_t::scpe_type_t* _parent() const { return m__parent; }\n    };\n\n    class u2_type_t : public kaitai::kstruct {\n\n    public:\n\n        u2_type_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, iscript_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~u2_type_t();\n\n    private:\n        uint16_t m_value;\n        iscript_bin_t* m__root;\n        kaitai::kstruct* m__parent;\n\n    public:\n        uint16_t value() const { return m_value; }\n        iscript_bin_t* _root() const { return m__root; }\n        kaitai::kstruct* _parent() const { return m__parent; }\n    };\n\nprivate:\n    bool f_version_tag;\n    uint32_t m_version_tag;\n\npublic:\n\n    /**\n     * value is 0x0 in case of broodwar and any other value for plain old starcraft\n     */\n    uint32_t version_tag();\n\nprivate:\n    bool f_entree_table_pos;\n    uint16_t m_entree_table_pos;\n\npublic:\n    uint16_t entree_table_pos();\n\nprivate:\n    bool f_entree_offsets;\n    std::vector<entree_offset_type_t*>* m_entree_offsets;\n\npublic:\n\n    /**\n     * read entree offsets until the magic stop sign '0xFFFF 0x0000' is found\n     */\n    std::vector<entree_offset_type_t*>* entree_offsets();\n\nprivate:\n    bool f_scpe;\n    std::vector<scpe_type_t*>* m_scpe;\n\npublic:\n\n    /**\n     * tbd\n     */\n    std::vector<scpe_type_t*>* scpe();\n\nprivate:\n    uint16_t m_first_word;\n    iscript_bin_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n    uint16_t first_word() const { return m_first_word; }\n    iscript_bin_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // ISCRIPT_BIN_H_\n"
  },
  {
    "path": "src/kaitai/iscript_bin.ksy",
    "content": "meta:\n  id: iscript_bin\n  endian: le\n  ks-opaque-types: true\n  \nseq:\n  - id: first_word\n    type: u2\n  \ninstances:\n  version_tag:\n    pos: 0x2\n    type: u4\n    doc: |\n      value is 0x0 in case of broodwar and any other value for plain old starcraft\n    \n  entree_table_pos:\n    value: 'version_tag == 0x0 ? first_word : 0x0'\n\n  entree_offsets:\n    type: entree_offset_type\n    pos: entree_table_pos\n    repeat: until\n    repeat-until: '(_.iscript_id == 0xFFFF) ? ( _.offset == 0x0) : false'\n    doc: |\n      read entree offsets until the magic stop sign '0xFFFF 0x0000' is found\n      \n  scpe:\n    type: scpe_type(_index)\n    repeat: expr\n    repeat-expr: _root.entree_offsets.size\n    doc: |\n      tbd\n\ntypes:\n  entree_offset_type:\n    seq:\n      - id: iscript_id\n        type: u2\n      - id: offset\n        type: u2\n\n  scpe_type:\n    params:\n      - id: i\n        type: u2\n    instances:\n      scpe_header:\n        pos: _parent.entree_offsets[i].offset\n        type: scpe_header_type\n      num_scpe_content:\n        value:  |\n          (scpe_header.scpe_content_type == 0) ? 2 : \n          (scpe_header.scpe_content_type == 1) ? 2 :\n          (scpe_header.scpe_content_type == 2) ? 4 : \n          (scpe_header.scpe_content_type == 12) ? 14 : \n          (scpe_header.scpe_content_type == 13) ? 14 : \n          (scpe_header.scpe_content_type == 14) ? 15 : \n          (scpe_header.scpe_content_type == 15) ? 15 : \n          (scpe_header.scpe_content_type == 20) ? 21 : \n          (scpe_header.scpe_content_type == 21) ? 21 : \n          (scpe_header.scpe_content_type == 23) ? 23 : \n          (scpe_header.scpe_content_type == 24) ? 25 : \n          (scpe_header.scpe_content_type == 26) ? 27 : \n          (scpe_header.scpe_content_type == 27) ? 27 : \n          (scpe_header.scpe_content_type == 28) ? 27 : \n          (scpe_header.scpe_content_type == 29) ? 27 : \n          0\n      scpe_content:\n        pos: _parent.entree_offsets[i].offset + 8\n        type: scpe_content_type\n        repeat: expr\n        repeat-expr: num_scpe_content\n        \n  scpe_header_type:\n    seq:\n      - id: scpe_magic\n        type: u4\n      - id: scpe_content_type\n        type: u1\n      - id: padding\n        size: 3\n        \n  scpe_content_type:\n    seq:\n      - id: scpe_opcode_offset\n        type: u2\n    instances:\n      scpe_opcode_list:\n        pos: scpe_opcode_offset\n        if: scpe_opcode_offset != 0\n        type: opcode_list_type(_parent, _root) # custom ks-opaque-types for C++ generation\n        #type: opcode_type # for kaitai IDE development parse only one element\n\n  opcode_type:\n    seq:\n      - id: code\n        type: u1\n        enum: opcode\n      - id: args\n        type:\n          switch-on: code\n          cases:\n            'opcode::playfram'         : u2_type\n            'opcode::playframtile'     : u2_type\n            'opcode::sethorpos'        : u1_type\n            'opcode::setvertpos'       : u1_type\n            'opcode::setpos'           : pos_type\n            'opcode::wait'             : u1_type\n            'opcode::waitrand'         : waitrand_type\n            'opcode::goto'             : u2_type #INSTR_JMP\n            'opcode::imgol'            : imgl_type\n            'opcode::imgul'            : imgl_type\n            'opcode::imgolorig'        : u2_type\n            'opcode::switchul'         : u2_type\n            'opcode::unknown_0c'       : empty_type\n            'opcode::imgoluselo'       : imgl_type\n            'opcode::imguluselo'       : imgl_type\n            'opcode::sprol'            : sprl_type\n            'opcode::highsprol'        : sprl_type\n            'opcode::lowsprul'         : sprl_type\n            'opcode::uflunstable'      : u2_type\n            'opcode::spruluselo'       : sprl_type\n            'opcode::sprul'            : sprl_type\n            'opcode::sproluselo'       : sprov_type\n            'opcode::end'              : empty_type #INSTR_TERM\n            'opcode::setflipstate'     : u1_type\n            'opcode::playsnd'          : u2_type\n            'opcode::playsndrand'      : playsounds_type\n            'opcode::playsndbtwn'      : playsndbtwn_type\n            'opcode::domissiledmg'     : empty_type\n            'opcode::attackmelee'      : playsounds_type\n            'opcode::followmaingraphic': empty_type\n            'opcode::randcondjmp'      : randcondjmp_type #INSTR_COND_JMP\n            'opcode::turnccwise'       : u1_type\n            'opcode::turncwise'        : u1_type\n            'opcode::turn1cwise'       : empty_type\n            'opcode::turnrand'         : u1_type\n            'opcode::setspawnframe'    : u1_type\n            'opcode::sigorder'         : u1_type\n            'opcode::attackwith'       : u1_type\n            'opcode::attack'           : empty_type\n            'opcode::castspell'        : empty_type\n            'opcode::useweapon'        : u1_type\n            'opcode::move'             : u1_type\n            'opcode::gotorepeatattk'   : empty_type\n            'opcode::engframe'         : u1_type\n            'opcode::engset'           : u1_type\n            'opcode::unknown_2d'       : empty_type\n            'opcode::nobrkcodestart'   : empty_type\n            'opcode::nobrkcodeend'     : empty_type\n            'opcode::ignorerest'       : empty_type\n            'opcode::attkshiftproj'    : u1_type\n            'opcode::tmprmgraphicstart': empty_type\n            'opcode::tmprmgraphicend'  : empty_type\n            'opcode::setfldirect'      : u1_type\n            'opcode::call'             : u2_type #INSTR_COND_JMP\n            'opcode::return'           : empty_type #INSTR_TERM\n            'opcode::setflspeed'       : u2_type\n            'opcode::creategasoverlays': u1_type\n            'opcode::pwrupcondjmp'     : u2_type #INSTR_COND_JMP\n            'opcode::trgtrangecondjmp' : trgtrangecondjmp_type #INSTR_COND_JMP\n            'opcode::trgtarccondjmp'   : trgcondjmp_type #INSTR_COND_JMP\n            'opcode::curdirectcondjmp' : trgcondjmp_type #INSTR_COND_JMP\n            'opcode::imgulnextid'      : pos_type\n            'opcode::unknown_3e'       : empty_type\n            'opcode::liftoffcondjmp'   : u2_type #INSTR_COND_JMP\n            'opcode::warpoverlay'      : u2_type\n            'opcode::orderdone'        : u1_type\n            'opcode::grdsprol'         : sprl_type\n            'opcode::unknown_43'       : empty_type\n            'opcode::dogrddamage'      : empty_type\n            _: empty_type\n        \n  empty_type:\n    seq: []\n        \n  u1_type:\n    seq:\n      - id: value\n        type: u1\n       \n  u2_type:\n    seq:\n      - id: value\n        type: u2\n        \n  pos_type:\n    seq:\n      - id: x\n        type: u1\n      - id: y\n        type: u1\n        \n  waitrand_type:\n    seq:\n      - id: ticks1\n        type: u1\n      - id: ticks2\n        type: u1\n        \n  imgl_type:\n    seq:\n      - id: image\n        type: u2\n      - id: pos\n        type: pos_type\n        \n  sprl_type:\n    seq:\n      - id: sprite\n        type: u2\n      - id: pos\n        type: pos_type\n      \n  sprov_type:\n    seq:\n      - id: sprite\n        type: u2\n      - id: overlay\n        type: u1\n      \n  playsndbtwn_type:\n    seq:\n      - id: firstsound\n        type: u2\n      - id: lastsound\n        type: u2\n        \n  playsounds_type:\n    seq:\n      - id: number_sounds\n        type: u1\n      - id: sound\n        type: u2\n        repeat: expr\n        repeat-expr: number_sounds\n  \n  randcondjmp_type:\n    seq:\n      - id: randchance\n        type: u1\n      - id: labelname\n        type: u2\n\n  trgtrangecondjmp_type:\n    seq:\n      - id: distance\n        type: u2\n      - id: labelname\n        type: u2\n  \n  trgcondjmp_type:\n    seq:\n      - id: angle1\n        type: u2\n      - id: angle2\n        type: u2\n      - id: labelname\n        type: u2\n  \nenums:\n  opcode:\n    0x00: playfram           # <frame#>: # displays a particular frame, adjusted for direction.\n    0x01: playframtile       # <frame#>: # displays a particular frame dependent on tileset.\n    0x02: sethorpos          # <x>: # sets the current horizontal offset of the current image overlay.\n    0x03: setvertpos         # <y>: # sets the vertical position of an image overlay.\n    0x04: setpos             # <x> <y>: # sets the current horizontal and vertical position of the current image overlay.\n    0x05: wait               # <#ticks>: # pauses script execution for a specific number of ticks.\n    0x06: waitrand           # <#ticks1> <#ticks2>: # pauses script execution for a random number of ticks given two possible wait times. \n    0x07: goto               # <labelname>: # unconditionally jumps to a specific code block.\n    0x08: imgol              # <image#> <x> <y>: # displays an active image overlay at an animation level higher than the current image overlay at a specified offset position.\n    0x09: imgul              # <image#> <x> <y>: # displays an active image overlay at an animation level lower than the current image overlay at a specified offset position.\n    0x0a: imgolorig          # <image#>: # displays an active image overlay at an animation level higher than the current image overlay at the relative origin offset position.\n    0x0b: switchul           # <image#>: # only for powerups. Hypothesised to replace the image overlay that was first created by the current image overlay.\n    0x0c: unknown_0c         # no parameters: # unknown.\n    0x0d: imgoluselo         # <image#> <x> <y>: # displays an active image overlay at an animation level higher than the current image overlay, using a LO* file to determine the offset position.\n    0x0e: imguluselo         # <image#> <x> <y>: # displays an active image overlay at an animation level lower than the current image overlay, using a LO* file to determine the offset position.\n    0x0f: sprol              # <sprite#> <x> <y>: # spawns a sprite one animation level above the current image overlay at a specific offset position.\n    0x10: highsprol          # <sprite#> <x> <y>: # spawns a sprite at the highest animation level at a specific offset position.\n    0x11: lowsprul           # <sprite#> <x> <y>: # spawns a sprite at the lowest animation level at a specific offset position.\n    0x12: uflunstable        # <flingy#: # creates an flingy with restrictions; supposedly crashes in most cases.\n    0x13: spruluselo         # <sprite#> <x> <y>: # spawns a sprite one animation level below the current image overlay at a specific offset position. The new sprite inherits the direction of the current sprite. Requires LO* file for unknown reason.\n    0x14: sprul              # <sprite#> <x> <y>: # spawns a sprite one animation level below the current image overlay at a specific offset position. The new sprite inherits the direction of the current sprite.\n    0x15: sproluselo         # <sprite#> <overlay#>: # spawns a sprite one animation level above the current image overlay, using a specified LO* file for the offset position information. The new sprite inherits the direction of the current sprite.\n    0x16: end                # no parameters: # destroys the current active image overlay, also removing the current sprite if the image overlay is the last in one in the current sprite.\n    0x17: setflipstate       # <flipstate>: # sets flip state of the current image overlay.\n    0x18: playsnd            # <sound#>: # plays a sound.\n    0x19: playsndrand        # <#sounds> <sound#> <...>: # plays a random sound from a list.\n    0x1a: playsndbtwn        # <firstsound#> <lastsound#>: # plays a random sound between two inclusive sfxdata.dat entry IDs.\n    0x1b: domissiledmg       # no parameters: # causes the damage of a weapon flingy to be applied according to its weapons.dat entry.\n    0x1c: attackmelee        # <#sounds> <sound#> <...>: # applies damage to target without creating a flingy and plays a sound.\n    0x1d: followmaingraphic  # no parameters: # causes the current image overlay to display the same frame as the parent image overlay.\n    0x1e: randcondjmp        # <randchance#> <labelname>: # random jump, chance of performing jump depends on the parameter.\n    0x1f: turnccwise         # <turnamount>: # turns the flingy counterclockwise by a particular amount.\n    0x20: turncwise          # <turnamount>: # turns the flingy clockwise by a particular amount.\n    0x21: turn1cwise         # no parameters: # turns the flingy clockwise by one direction unit.\n    0x22: turnrand           # <turnamount>: # turns the flingy a specified amount in a random direction, with a heavy bias towards turning clockwise.\n    0x23: setspawnframe      # <direction>: # in specific situations, performs a natural rotation to the given direction.\n    0x24: sigorder           # <signal#>: # allows the current unit's order to proceed if it has paused for an animation to be completed.\n    0x25: attackwith         # <ground = 1, air = 2>: # attack with either the ground or air weapon depending on a parameter.\n    0x26: attack             # no parameters: # attack with either the ground or air weapon depending on target.\n    0x27: castspell          # no parameters: # identifies when a spell should be cast in a spellcasting animation. The spell is determined by the unit's current order.\n    0x28: useweapon          # <weapon#>: # makes the unit use a specific weapons.dat ID on its target.\n    0x29: move               # <movedistance>: # sets the unit to move forward a certain number of pixels at the end of the current tick.\n    0x2a: gotorepeatattk     # no parameters: # signals to StarCraft that after this point, when the unit's cooldown time is over, the repeat attack animation can be called.\n    0x2b: engframe           # <frame#>: # plays a particular frame, often used in engine glow animations.\n    0x2c: engset             # <frameset#>: # plays a particular frame set, often used in engine glow animations.\n    0x2d: unknown_2d         # no parameters: # hypothesised to hide the current image overlay until the next animation.\n    0x2e: nobrkcodestart     # no parameters: # holds the processing of player orders until a nobrkcodeend is encountered.\n    0x2f: nobrkcodeend       # no parameters: # allows the processing of player orders after a nobrkcodestart instruction.\n    0x30: ignorerest         # no parameters: # conceptually, this causes the script to stop until the next animation is called.\n    0x31: attkshiftproj      # <distance>: # creates the weapon flingy at a particular distance in front of the unit.\n    0x32: tmprmgraphicstart  # no parameters: # sets the current image overlay state to hidden.\n    0x33: tmprmgraphicend    # no parameters: # sets the current image overlay state to visible.\n    0x34: setfldirect        # <direction>: # sets the current direction of the flingy.\n    0x35: call               # <labelname>: # calls a code block.\n    0x36: return             # no parameters: # returns from call.\n    0x37: setflspeed         # <speed>: # sets the flingy.dat speed of the current flingy.\n    0x38: creategasoverlays  # <gasoverlay#>: # creates gas image overlays at offsets specified by LO* files.\n    0x39: pwrupcondjmp       # <labelname>: # jumps to a code block if the current unit is a powerup and it is currently picked up.\n    0x3a: trgtrangecondjmp   # <distance> <labelname>: # jumps to a block depending on the distance to the target.\n    0x3b: trgtarccondjmp     # <angle1> <angle2> <labelname>: # jumps to a block depending on the current angle of the target.\n    0x3c: curdirectcondjmp   # <angle1> <angle2> <labelname>: # only for units. Jump to a code block if the current sprite is facing a particular direction.\n    0x3d: imgulnextid        # <x> <y>: # displays an active image overlay at the shadow animation level at a specified offset position. The image overlay that will be displayed is the one that is after the current image overlay in images.dat.\n    0x3e: unknown_3e         # no parameters: # unknown.\n    0x3f: liftoffcondjmp     # <labelname>: # jumps to a code block when the current unit that is a building that is lifted off.\n    0x40: warpoverlay        # <frame#>: # hypothesised to display the current image overlay's frame clipped to the outline of the parent image overlay.\n    0x41: orderdone          # <signal#>: # most likely used with orders that continually repeat, like the Medic's healing and the Valkyrie's afterburners (which no longer exist), to clear the sigorder flag to stop the order.\n    0x42: grdsprol           # <sprite#> <x> <y>: # spawns a sprite one animation level above the current image overlay at a specific offset position, but only if the current sprite is over ground-passable terrain.\n    0x43: unknown_43         # no parameters: # unknown.\n    0x44: dogrddamage        # no parameters: # applies damage like domissiledmg when on ground-unit-passable terrain.\n    \n"
  },
  {
    "path": "src/kaitai/kaitai_generate.sh",
    "content": "#!/bin/bash\n\nDAT_FILES=\"units_dat weapons_dat file_tbl flingy_dat sprites_dat images_dat sfxdata_dat portdata_dat upgrades_dat orders_dat techdata_dat mapdata_dat iscript_bin\"\nTILESET_FILES=\"tileset_cv5  tileset_dddata_bin  tileset_vf4  tileset_vr4  tileset_vx4\"\nKSY_FILES=\"$DAT_FILES $TILESET_FILES\"\n\n## where to store the docs\nmkdir -p ../../doc/kaitai\n\necho \"Clean old generated source files...\"\nfor item in $KSY_FILES\ndo\n  rm -f $item.cpp $item.h\n  KSY=$item.ksy\n  DOT=$item.dot\n  SVG=$item.svg\n  echo \"Generating source and documentation from: $KSY\"\n  kaitai-struct-compiler $KSY -t cpp_stl\n  kaitai-struct-compiler $KSY -t graphviz\n  dot $DOT -Tsvg > ../../doc/kaitai/$SVG\ndone\n\n"
  },
  {
    "path": "src/kaitai/kaitaistream.cpp",
    "content": "#include <kaitai/kaitaistream.h>\n\n#if defined(__APPLE__)\n#include <machine/endian.h>\n#include <libkern/OSByteOrder.h>\n#define bswap_16(x) OSSwapInt16(x)\n#define bswap_32(x) OSSwapInt32(x)\n#define bswap_64(x) OSSwapInt64(x)\n#define __BYTE_ORDER    BYTE_ORDER\n#define __BIG_ENDIAN    BIG_ENDIAN\n#define __LITTLE_ENDIAN LITTLE_ENDIAN\n#elif defined(_MSC_VER) // !__APPLE__\n#include <stdlib.h>\n#define __LITTLE_ENDIAN     1234\n#define __BIG_ENDIAN        4321\n#define __BYTE_ORDER        __LITTLE_ENDIAN\n#define bswap_16(x) _byteswap_ushort(x)\n#define bswap_32(x) _byteswap_ulong(x)\n#define bswap_64(x) _byteswap_uint64(x)\n#else // !__APPLE__ or !_MSC_VER\n#include <endian.h>\n#include <byteswap.h>\n#endif\n\n#include <iostream>\n#include <vector>\n#include <stdexcept>\n\nkaitai::kstream::kstream(std::istream *io) {\n    m_io = io;\n    init();\n}\n\nkaitai::kstream::kstream(const std::string &data) : m_io_str(data) {\n    m_io = &m_io_str;\n    init();\n}\n\nvoid kaitai::kstream::init() {\n    exceptions_enable();\n    align_to_byte();\n}\n\nvoid kaitai::kstream::close() {\n    //  m_io->close();\n}\n\nvoid kaitai::kstream::exceptions_enable() const {\n    m_io->exceptions(\n        std::istream::eofbit |\n        std::istream::failbit |\n        std::istream::badbit\n    );\n}\n\n// ========================================================================\n// Stream positioning\n// ========================================================================\n\nbool kaitai::kstream::is_eof() const {\n    if (m_bits_left > 0) {\n        return false;\n    }\n    char t;\n    m_io->exceptions(std::istream::badbit);\n    m_io->get(t);\n    if (m_io->eof()) {\n        m_io->clear();\n        exceptions_enable();\n        return true;\n    } else {\n        m_io->unget();\n        exceptions_enable();\n        return false;\n    }\n}\n\nvoid kaitai::kstream::seek(uint64_t pos) {\n    m_io->seekg(pos);\n}\n\nuint64_t kaitai::kstream::pos() {\n    return m_io->tellg();\n}\n\nuint64_t kaitai::kstream::size() {\n    std::iostream::pos_type cur_pos = m_io->tellg();\n    m_io->seekg(0, std::ios::end);\n    std::iostream::pos_type len = m_io->tellg();\n    m_io->seekg(cur_pos);\n    return len;\n}\n\n// ========================================================================\n// Integer numbers\n// ========================================================================\n\n// ------------------------------------------------------------------------\n// Signed\n// ------------------------------------------------------------------------\n\nint8_t kaitai::kstream::read_s1() {\n    char t;\n    m_io->get(t);\n    return t;\n}\n\n// ........................................................................\n// Big-endian\n// ........................................................................\n\nint16_t kaitai::kstream::read_s2be() {\n    int16_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 2);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_16(t);\n#endif\n    return t;\n}\n\nint32_t kaitai::kstream::read_s4be() {\n    int32_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 4);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_32(t);\n#endif\n    return t;\n}\n\nint64_t kaitai::kstream::read_s8be() {\n    int64_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 8);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_64(t);\n#endif\n    return t;\n}\n\n// ........................................................................\n// Little-endian\n// ........................................................................\n\nint16_t kaitai::kstream::read_s2le() {\n    int16_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 2);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_16(t);\n#endif\n    return t;\n}\n\nint32_t kaitai::kstream::read_s4le() {\n    int32_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 4);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_32(t);\n#endif\n    return t;\n}\n\nint64_t kaitai::kstream::read_s8le() {\n    int64_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 8);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_64(t);\n#endif\n    return t;\n}\n\n// ------------------------------------------------------------------------\n// Unsigned\n// ------------------------------------------------------------------------\n\nuint8_t kaitai::kstream::read_u1() {\n    char t;\n    m_io->get(t);\n    return t;\n}\n\n// ........................................................................\n// Big-endian\n// ........................................................................\n\nuint16_t kaitai::kstream::read_u2be() {\n    uint16_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 2);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_16(t);\n#endif\n    return t;\n}\n\nuint32_t kaitai::kstream::read_u4be() {\n    uint32_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 4);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_32(t);\n#endif\n    return t;\n}\n\nuint64_t kaitai::kstream::read_u8be() {\n    uint64_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 8);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_64(t);\n#endif\n    return t;\n}\n\n// ........................................................................\n// Little-endian\n// ........................................................................\n\nuint16_t kaitai::kstream::read_u2le() {\n    uint16_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 2);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_16(t);\n#endif\n    return t;\n}\n\nuint32_t kaitai::kstream::read_u4le() {\n    uint32_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 4);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_32(t);\n#endif\n    return t;\n}\n\nuint64_t kaitai::kstream::read_u8le() {\n    uint64_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 8);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_64(t);\n#endif\n    return t;\n}\n\n// ========================================================================\n// Floating point numbers\n// ========================================================================\n\n// ........................................................................\n// Big-endian\n// ........................................................................\n\nfloat kaitai::kstream::read_f4be() {\n    uint32_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 4);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_32(t);\n#endif\n    return reinterpret_cast<float &>(t);\n}\n\ndouble kaitai::kstream::read_f8be() {\n    uint64_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 8);\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n    t = bswap_64(t);\n#endif\n    return reinterpret_cast<double &>(t);\n}\n\n// ........................................................................\n// Little-endian\n// ........................................................................\n\nfloat kaitai::kstream::read_f4le() {\n    uint32_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 4);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_32(t);\n#endif\n    return reinterpret_cast<float &>(t);\n}\n\ndouble kaitai::kstream::read_f8le() {\n    uint64_t t;\n    m_io->read(reinterpret_cast<char *>(&t), 8);\n#if __BYTE_ORDER == __BIG_ENDIAN\n    t = bswap_64(t);\n#endif\n    return reinterpret_cast<double &>(t);\n}\n\n// ========================================================================\n// Unaligned bit values\n// ========================================================================\n\nvoid kaitai::kstream::align_to_byte() {\n    m_bits_left = 0;\n    m_bits = 0;\n}\n\nuint64_t kaitai::kstream::read_bits_int_be(int n) {\n    uint64_t res = 0;\n\n    int bits_needed = n - m_bits_left;\n    m_bits_left = -bits_needed & 7; // `-bits_needed mod 8`\n\n    if (bits_needed > 0) {\n        // 1 bit  => 1 byte\n        // 8 bits => 1 byte\n        // 9 bits => 2 bytes\n        int bytes_needed = ((bits_needed - 1) / 8) + 1; // `ceil(bits_needed / 8)`\n        if (bytes_needed > 8)\n            throw std::runtime_error(\"read_bits_int_be: more than 8 bytes requested\");\n        uint8_t buf[8];\n        m_io->read(reinterpret_cast<char *>(buf), bytes_needed);\n        for (int i = 0; i < bytes_needed; i++) {\n            res = res << 8 | buf[i];\n        }\n\n        uint64_t new_bits = res;\n        res = res >> m_bits_left | (bits_needed < 64 ? m_bits << bits_needed : 0); // avoid undefined behavior of `x << 64`\n        m_bits = new_bits; // will be masked at the end of the function\n    } else {\n        res = m_bits >> -bits_needed; // shift unneeded bits out\n    }\n\n    uint64_t mask = (UINT64_C(1) << m_bits_left) - 1; // `m_bits_left` is in range 0..7, so `(1 << 64)` does not have to be considered\n    m_bits &= mask;\n\n    return res;\n}\n\n// Deprecated, use read_bits_int_be() instead.\nuint64_t kaitai::kstream::read_bits_int(int n) {\n    return read_bits_int_be(n);\n}\n\nuint64_t kaitai::kstream::read_bits_int_le(int n) {\n    uint64_t res = 0;\n    int bits_needed = n - m_bits_left;\n\n    if (bits_needed > 0) {\n        // 1 bit  => 1 byte\n        // 8 bits => 1 byte\n        // 9 bits => 2 bytes\n        int bytes_needed = ((bits_needed - 1) / 8) + 1; // `ceil(bits_needed / 8)`\n        if (bytes_needed > 8)\n            throw std::runtime_error(\"read_bits_int_le: more than 8 bytes requested\");\n        uint8_t buf[8];\n        m_io->read(reinterpret_cast<char *>(buf), bytes_needed);\n        for (int i = 0; i < bytes_needed; i++) {\n            res |= static_cast<uint64_t>(buf[i]) << (i * 8);\n        }\n\n        // NB: for bit shift operators in C++, \"if the value of the right operand is\n        // negative or is greater or equal to the number of bits in the promoted left\n        // operand, the behavior is undefined.\" (see\n        // https://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators)\n        // So we define our desired behavior here.\n        uint64_t new_bits = bits_needed < 64 ? res >> bits_needed : 0;\n        res = res << m_bits_left | m_bits;\n        m_bits = new_bits;\n    } else {\n        res = m_bits;\n        m_bits >>= n;\n    }\n\n    m_bits_left = -bits_needed & 7; // `-bits_needed mod 8`\n\n    if (n < 64) {\n        uint64_t mask = (UINT64_C(1) << n) - 1;\n        res &= mask;\n    }\n    // if `n == 64`, do nothing\n    return res;\n}\n\n// ========================================================================\n// Byte arrays\n// ========================================================================\n\nstd::string kaitai::kstream::read_bytes(std::streamsize len) {\n    std::vector<char> result(len);\n\n    // NOTE: streamsize type is signed, negative values are only *supposed* to not be used.\n    // http://en.cppreference.com/w/cpp/io/streamsize\n    if (len < 0) {\n        throw std::runtime_error(\"read_bytes: requested a negative amount\");\n    }\n\n    if (len > 0) {\n        m_io->read(&result[0], len);\n    }\n\n    return std::string(result.begin(), result.end());\n}\n\nstd::string kaitai::kstream::read_bytes_full() {\n    std::iostream::pos_type p1 = m_io->tellg();\n    m_io->seekg(0, std::ios::end);\n    std::iostream::pos_type p2 = m_io->tellg();\n    size_t len = p2 - p1;\n\n    // Note: this requires a std::string to be backed with a\n    // contiguous buffer. Officially, it's a only requirement since\n    // C++11 (C++98 and C++03 didn't have this requirement), but all\n    // major implementations had contiguous buffers anyway.\n    std::string result(len, ' ');\n    m_io->seekg(p1);\n    m_io->read(&result[0], len);\n\n    return result;\n}\n\nstd::string kaitai::kstream::read_bytes_term(char term, bool include, bool consume, bool eos_error) {\n    std::string result;\n    std::getline(*m_io, result, term);\n    if (m_io->eof()) {\n        // encountered EOF\n        if (eos_error) {\n            throw std::runtime_error(\"read_bytes_term: encountered EOF\");\n        }\n    } else {\n        // encountered terminator\n        if (include)\n            result.push_back(term);\n        if (!consume)\n            m_io->unget();\n    }\n    return result;\n}\n\nstd::string kaitai::kstream::ensure_fixed_contents(std::string expected) {\n    std::string actual = read_bytes(expected.length());\n\n    if (actual != expected) {\n        // NOTE: I think printing it outright is not best idea, it could contain non-ASCII characters\n        // like backspace and beeps and whatnot. It would be better to print hexlified version, and\n        // also to redirect it to stderr.\n        throw std::runtime_error(\"ensure_fixed_contents: actual data does not match expected data\");\n    }\n\n    return actual;\n}\n\nstd::string kaitai::kstream::bytes_strip_right(std::string src, char pad_byte) {\n    std::size_t new_len = src.length();\n\n    while (new_len > 0 && src[new_len - 1] == pad_byte)\n        new_len--;\n\n    return src.substr(0, new_len);\n}\n\nstd::string kaitai::kstream::bytes_terminate(std::string src, char term, bool include) {\n    std::size_t new_len = 0;\n    std::size_t max_len = src.length();\n\n    while (new_len < max_len && src[new_len] != term)\n        new_len++;\n\n    if (include && new_len < max_len)\n        new_len++;\n\n    return src.substr(0, new_len);\n}\n\n// ========================================================================\n// Byte array processing\n// ========================================================================\n\nstd::string kaitai::kstream::process_xor_one(std::string data, uint8_t key) {\n    size_t len = data.length();\n    std::string result(len, ' ');\n\n    for (size_t i = 0; i < len; i++)\n        result[i] = data[i] ^ key;\n\n    return result;\n}\n\nstd::string kaitai::kstream::process_xor_many(std::string data, std::string key) {\n    size_t len = data.length();\n    size_t kl = key.length();\n    std::string result(len, ' ');\n\n    size_t ki = 0;\n    for (size_t i = 0; i < len; i++) {\n        result[i] = data[i] ^ key[ki];\n        ki++;\n        if (ki >= kl)\n            ki = 0;\n    }\n\n    return result;\n}\n\nstd::string kaitai::kstream::process_rotate_left(std::string data, int amount) {\n    size_t len = data.length();\n    std::string result(len, ' ');\n\n    for (size_t i = 0; i < len; i++) {\n        uint8_t bits = data[i];\n        result[i] = (bits << amount) | (bits >> (8 - amount));\n    }\n\n    return result;\n}\n\n#ifdef KS_ZLIB\n#include <zlib.h>\n\nstd::string kaitai::kstream::process_zlib(std::string data) {\n    int ret;\n\n    unsigned char *src_ptr = reinterpret_cast<unsigned char *>(&data[0]);\n    std::stringstream dst_strm;\n\n    z_stream strm;\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n\n    ret = inflateInit(&strm);\n    if (ret != Z_OK)\n        throw std::runtime_error(\"process_zlib: inflateInit error\");\n\n    strm.next_in = src_ptr;\n    strm.avail_in = data.length();\n\n    unsigned char outbuffer[ZLIB_BUF_SIZE];\n    std::string outstring;\n\n    // get the decompressed bytes blockwise using repeated calls to inflate\n    do {\n        strm.next_out = reinterpret_cast<Bytef *>(outbuffer);\n        strm.avail_out = sizeof(outbuffer);\n\n        ret = inflate(&strm, 0);\n\n        if (outstring.size() < strm.total_out)\n            outstring.append(reinterpret_cast<char *>(outbuffer), strm.total_out - outstring.size());\n    } while (ret == Z_OK);\n\n    if (ret != Z_STREAM_END) { // an error occurred that was not EOF\n        std::ostringstream exc_msg;\n        exc_msg << \"process_zlib: error #\" << ret << \"): \" << strm.msg;\n        throw std::runtime_error(exc_msg.str());\n    }\n\n    if (inflateEnd(&strm) != Z_OK)\n        throw std::runtime_error(\"process_zlib: inflateEnd error\");\n\n    return outstring;\n}\n#endif\n\n// ========================================================================\n// Misc utility methods\n// ========================================================================\n\nint kaitai::kstream::mod(int a, int b) {\n    if (b <= 0)\n        throw std::invalid_argument(\"mod: divisor b <= 0\");\n    int r = a % b;\n    if (r < 0)\n        r += b;\n    return r;\n}\n\n#include <algorithm>\nvoid kaitai::kstream::unsigned_to_decimal(uint64_t number, char *buffer) {\n    // Implementation from https://ideone.com/nrQfA8 by Alf P. Steinbach\n    // (see https://www.zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html#comment-1033931478)\n    if (number == 0) {\n        *buffer++ = '0';\n    } else {\n        char *p_first = buffer;\n        while (number != 0) {\n            *buffer++ = static_cast<char>('0' + number % 10);\n            number /= 10;\n        }\n        std::reverse(p_first, buffer);\n    }\n    *buffer = '\\0';\n}\n\nstd::string kaitai::kstream::reverse(std::string val) {\n    std::reverse(val.begin(), val.end());\n\n    return val;\n}\n\nuint8_t kaitai::kstream::byte_array_min(const std::string val) {\n    uint8_t min = 0xff; // UINT8_MAX\n    std::string::const_iterator end = val.end();\n    for (std::string::const_iterator it = val.begin(); it != end; ++it) {\n        uint8_t cur = static_cast<uint8_t>(*it);\n        if (cur < min) {\n            min = cur;\n        }\n    }\n    return min;\n}\n\nuint8_t kaitai::kstream::byte_array_max(const std::string val) {\n    uint8_t max = 0; // UINT8_MIN\n    std::string::const_iterator end = val.end();\n    for (std::string::const_iterator it = val.begin(); it != end; ++it) {\n        uint8_t cur = static_cast<uint8_t>(*it);\n        if (cur > max) {\n            max = cur;\n        }\n    }\n    return max;\n}\n\n// ========================================================================\n// Other internal methods\n// ========================================================================\n\n#ifndef KS_STR_DEFAULT_ENCODING\n#define KS_STR_DEFAULT_ENCODING \"UTF-8\"\n#endif\n\n#ifdef KS_STR_ENCODING_ICONV\n\n#include <iconv.h>\n#include <cerrno>\n#include <stdexcept>\n\nstd::string kaitai::kstream::bytes_to_str(std::string src, std::string src_enc) {\n    iconv_t cd = iconv_open(KS_STR_DEFAULT_ENCODING, src_enc.c_str());\n\n    if (cd == (iconv_t)-1) {\n        if (errno == EINVAL) {\n            throw std::runtime_error(\"bytes_to_str: invalid encoding pair conversion requested\");\n        } else {\n            throw std::runtime_error(\"bytes_to_str: error opening iconv\");\n        }\n    }\n\n    size_t src_len = src.length();\n    size_t src_left = src_len;\n\n    // Start with a buffer length of double the source length.\n    size_t dst_len = src_len * 2;\n    std::string dst(dst_len, ' ');\n    size_t dst_left = dst_len;\n\n    char *src_ptr = &src[0];\n    char *dst_ptr = &dst[0];\n\n    while (true) {\n        size_t res = iconv(cd, &src_ptr, &src_left, &dst_ptr, &dst_left);\n\n        if (res == (size_t)-1) {\n            if (errno == E2BIG) {\n                // dst buffer is not enough to accomodate whole string\n                // enlarge the buffer and try again\n                size_t dst_used = dst_len - dst_left;\n                dst_left += dst_len;\n                dst_len += dst_len;\n                dst.resize(dst_len);\n\n                // dst.resize might have allocated destination buffer in another area\n                // of memory, thus our previous pointer \"dst\" will be invalid; re-point\n                // it using \"dst_used\".\n                dst_ptr = &dst[dst_used];\n            } else {\n                throw std::runtime_error(\"bytes_to_str: iconv error\");\n            }\n        } else {\n            // conversion successful\n            dst.resize(dst_len - dst_left);\n            break;\n        }\n    }\n\n    if (iconv_close(cd) != 0) {\n        throw std::runtime_error(\"bytes_to_str: iconv close error\");\n    }\n\n    return dst;\n}\n#elif defined(KS_STR_ENCODING_NONE)\nstd::string kaitai::kstream::bytes_to_str(std::string src, std::string src_enc) {\n    return src;\n}\n#else\n#error Need to decide how to handle strings: please define one of: KS_STR_ENCODING_ICONV, KS_STR_ENCODING_NONE\n#endif\n"
  },
  {
    "path": "src/kaitai/kaitaistream.h",
    "content": "#ifndef KAITAI_STREAM_H\n#define KAITAI_STREAM_H\n\n// Kaitai Struct runtime API version: x.y.z = 'xxxyyyzzz' decimal\n#define KAITAI_STRUCT_VERSION 10000L\n\n#include <istream>\n#include <sstream>\n#include <stdint.h>\n#include <sys/types.h>\n#include <limits>\n\nnamespace kaitai {\n\n/**\n * Kaitai Stream class (kaitai::kstream) is an implementation of\n * <a href=\"https://doc.kaitai.io/stream_api.html\">Kaitai Struct stream API</a>\n * for C++/STL. It's implemented as a wrapper over generic STL std::istream.\n *\n * It provides a wide variety of simple methods to read (parse) binary\n * representations of primitive types, such as integer and floating\n * point numbers, byte arrays and strings, and also provides stream\n * positioning / navigation methods with unified cross-language and\n * cross-toolkit semantics.\n *\n * Typically, end users won't access Kaitai Stream class manually, but would\n * describe a binary structure format using .ksy language and then would use\n * Kaitai Struct compiler to generate source code in desired target language.\n * That code, in turn, would use this class and API to do the actual parsing\n * job.\n */\nclass kstream {\npublic:\n    /**\n     * Constructs new Kaitai Stream object, wrapping a given std::istream.\n     * \\param io istream object to use for this Kaitai Stream\n     */\n    kstream(std::istream* io);\n\n    /**\n     * Constructs new Kaitai Stream object, wrapping a given in-memory data\n     * buffer.\n     * \\param data data buffer to use for this Kaitai Stream\n     */\n    kstream(const std::string& data);\n\n    void close();\n\n    /** @name Stream positioning */\n    //@{\n    /**\n     * Check if stream pointer is at the end of stream. Note that the semantics\n     * are different from traditional STL semantics: one does *not* need to do a\n     * read (which will fail) after the actual end of the stream to trigger EOF\n     * flag, which can be accessed after that read. It is sufficient to just be\n     * at the end of the stream for this method to return true.\n     * \\return \"true\" if we are located at the end of the stream.\n     */\n    bool is_eof() const;\n\n    /**\n     * Set stream pointer to designated position.\n     * \\param pos new position (offset in bytes from the beginning of the stream)\n     */\n    void seek(uint64_t pos);\n\n    /**\n     * Get current position of a stream pointer.\n     * \\return pointer position, number of bytes from the beginning of the stream\n     */\n    uint64_t pos();\n\n    /**\n     * Get total size of the stream in bytes.\n     * \\return size of the stream in bytes\n     */\n    uint64_t size();\n    //@}\n\n    /** @name Integer numbers */\n    //@{\n\n    // ------------------------------------------------------------------------\n    // Signed\n    // ------------------------------------------------------------------------\n\n    int8_t read_s1();\n\n    // ........................................................................\n    // Big-endian\n    // ........................................................................\n\n    int16_t read_s2be();\n    int32_t read_s4be();\n    int64_t read_s8be();\n\n    // ........................................................................\n    // Little-endian\n    // ........................................................................\n\n    int16_t read_s2le();\n    int32_t read_s4le();\n    int64_t read_s8le();\n\n    // ------------------------------------------------------------------------\n    // Unsigned\n    // ------------------------------------------------------------------------\n\n    uint8_t read_u1();\n\n    // ........................................................................\n    // Big-endian\n    // ........................................................................\n\n    uint16_t read_u2be();\n    uint32_t read_u4be();\n    uint64_t read_u8be();\n\n    // ........................................................................\n    // Little-endian\n    // ........................................................................\n\n    uint16_t read_u2le();\n    uint32_t read_u4le();\n    uint64_t read_u8le();\n\n    //@}\n\n    /** @name Floating point numbers */\n    //@{\n\n    // ........................................................................\n    // Big-endian\n    // ........................................................................\n\n    float read_f4be();\n    double read_f8be();\n\n    // ........................................................................\n    // Little-endian\n    // ........................................................................\n\n    float read_f4le();\n    double read_f8le();\n\n    //@}\n\n    /** @name Unaligned bit values */\n    //@{\n\n    void align_to_byte();\n    uint64_t read_bits_int_be(int n);\n    uint64_t read_bits_int(int n);\n    uint64_t read_bits_int_le(int n);\n\n    //@}\n\n    /** @name Byte arrays */\n    //@{\n\n    std::string read_bytes(std::streamsize len);\n    std::string read_bytes_full();\n    std::string read_bytes_term(char term, bool include, bool consume, bool eos_error);\n    std::string ensure_fixed_contents(std::string expected);\n\n    static std::string bytes_strip_right(std::string src, char pad_byte);\n    static std::string bytes_terminate(std::string src, char term, bool include);\n    static std::string bytes_to_str(std::string src, std::string src_enc);\n\n    //@}\n\n    /** @name Byte array processing */\n    //@{\n\n    /**\n     * Performs a XOR processing with given data, XORing every byte of input with a single\n     * given value.\n     * @param data data to process\n     * @param key value to XOR with\n     * @return processed data\n     */\n    static std::string process_xor_one(std::string data, uint8_t key);\n\n    /**\n     * Performs a XOR processing with given data, XORing every byte of input with a key\n     * array, repeating key array many times, if necessary (i.e. if data array is longer\n     * than key array).\n     * @param data data to process\n     * @param key array of bytes to XOR with\n     * @return processed data\n     */\n    static std::string process_xor_many(std::string data, std::string key);\n\n    /**\n     * Performs a circular left rotation shift for a given buffer by a given amount of bits,\n     * using groups of 1 bytes each time. Right circular rotation should be performed\n     * using this procedure with corrected amount.\n     * @param data source data to process\n     * @param amount number of bits to shift by\n     * @return copy of source array with requested shift applied\n     */\n    static std::string process_rotate_left(std::string data, int amount);\n\n#ifdef KS_ZLIB\n    /**\n     * Performs an unpacking (\"inflation\") of zlib-compressed data with usual zlib headers.\n     * @param data data to unpack\n     * @return unpacked data\n     * @throws IOException\n     */\n    static std::string process_zlib(std::string data);\n#endif\n\n    //@}\n\n    /**\n     * Performs modulo operation between two integers: dividend `a`\n     * and divisor `b`. Divisor `b` is expected to be positive. The\n     * result is always 0 <= x <= b - 1.\n     */\n    static int mod(int a, int b);\n\n    /**\n     * Converts given integer `val` to a decimal string representation.\n     * Should be used in place of std::to_string() (which is available only\n     * since C++11) in older C++ implementations.\n     */\n    template<typename I>\n// check for C++11 support - https://stackoverflow.com/a/40512515\n#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)\n    // https://stackoverflow.com/a/27913885\n    typename std::enable_if<\n            std::is_integral<I>::value &&\n            // check if we don't have something too large like GCC's `__int128_t`\n            std::numeric_limits<I>::max() >= 0 &&\n            std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max(),\n            std::string\n    >::type\n#else\n    std::string\n#endif\n    static to_string(I val) {\n        // in theory, `digits10 + 3` would be enough (minus sign + leading digit\n        // + null terminator), but let's add a little more to be safe\n        char buf[std::numeric_limits<I>::digits10 + 5];\n        if (val < 0) {\n            buf[0] = '-';\n            // get absolute value without undefined behavior (https://stackoverflow.com/a/12231604)\n            unsigned_to_decimal(-static_cast<uint64_t>(val), &buf[1]);\n        } else {\n            unsigned_to_decimal(val, buf);\n        }\n        return std::string(buf);\n    }\n\n    /**\n     * Reverses given string `val`, so that the first character becomes the\n     * last and the last one becomes the first. This should be used to avoid\n     * the need of local variables at the caller.\n     */\n    static std::string reverse(std::string val);\n\n    /**\n     * Finds the minimal byte in a byte array, treating bytes as\n     * unsigned values.\n     * @param val byte array to scan\n     * @return minimal byte in byte array as integer\n     */\n    static uint8_t byte_array_min(const std::string val);\n\n    /**\n     * Finds the maximal byte in a byte array, treating bytes as\n     * unsigned values.\n     * @param val byte array to scan\n     * @return maximal byte in byte array as integer\n     */\n    static uint8_t byte_array_max(const std::string val);\n\nprivate:\n    std::istream* m_io;\n    std::istringstream m_io_str;\n    int m_bits_left;\n    uint64_t m_bits;\n\n    void init();\n    void exceptions_enable() const;\n\n    static void unsigned_to_decimal(uint64_t number, char *buffer);\n\n    static const int ZLIB_BUF_SIZE = 128 * 1024;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "src/kaitai/kaitaistruct.h",
    "content": "#ifndef KAITAI_STRUCT_H\n#define KAITAI_STRUCT_H\n\n#include <kaitai/kaitaistream.h>\n\nnamespace kaitai {\n\nclass kstruct {\npublic:\n    kstruct(kstream *_io) { m__io = _io; }\n    virtual ~kstruct() {}\nprotected:\n    kstream *m__io;\npublic:\n    kstream *_io() { return m__io; }\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "src/kaitai/mapdata_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"mapdata_dat.h\"\n\nmapdata_dat_t::mapdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, mapdata_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_mission_dir = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid mapdata_dat_t::_read() {\n    m_mission_dir = new std::vector<uint32_t>();\n    {\n        int i = 0;\n        while (!m__io->is_eof()) {\n            m_mission_dir->push_back(m__io->read_u4le());\n            i++;\n        }\n    }\n}\n\nmapdata_dat_t::~mapdata_dat_t() {\n    _clean_up();\n}\n\nvoid mapdata_dat_t::_clean_up() {\n    if (m_mission_dir) {\n        delete m_mission_dir; m_mission_dir = 0;\n    }\n}\n"
  },
  {
    "path": "src/kaitai/mapdata_dat.h",
    "content": "#ifndef MAPDATA_DAT_H_\n#define MAPDATA_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass mapdata_dat_t : public kaitai::kstruct {\n\npublic:\n\n    mapdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, mapdata_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~mapdata_dat_t();\n\nprivate:\n    std::vector<uint32_t>* m_mission_dir;\n    mapdata_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * Path where the game will look for the original campaigns map file (\"staredit/scenario.chk\") and the WAV files (\"staredit/wav/\").\n     */\n    std::vector<uint32_t>* mission_dir() const { return m_mission_dir; }\n    mapdata_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // MAPDATA_DAT_H_\n"
  },
  {
    "path": "src/kaitai/mapdata_dat.ksy",
    "content": "meta:\n  id: mapdata_dat\n  endian: le\n  bit-endian: le\n  \nseq:\n  - id: mission_dir\n    type: u4\n    repeat: eos\n    doc: |\n      Path where the game will look for the original campaigns map file (\"staredit/scenario.chk\") and the WAV files (\"staredit/wav/\").\n"
  },
  {
    "path": "src/kaitai/meson.build",
    "content": "startool_kaitai_dat_sources = files(\n\t'kaitaistream.cpp',\n\t'units_dat.cpp',\n\t'weapons_dat.cpp',\n\t'file_tbl.cpp',\n\t'flingy_dat.cpp',\n\t'sprites_dat.cpp',\n\t'images_dat.cpp',\n\t'sfxdata_dat.cpp',\n\t'portdata_dat.cpp',\n\t'upgrades_dat.cpp',\n\t'orders_dat.cpp',\n\t'techdata_dat.cpp',\n\t'mapdata_dat.cpp',\n\t'iscript_bin.cpp',\n\t'opcode_list_type.cpp'\n)\n\nstartool_kaitai_tileset_sources = files(\n\t'tileset_cv5.cpp',\n\t'tileset_vf4.cpp',\n\t'tileset_vr4.cpp',\n\t'tileset_vx4.cpp',\n\t'tileset_dddata_bin.cpp'\n)\n\nstartool_kaitai_sources = startool_kaitai_dat_sources + startool_kaitai_tileset_sources\n"
  },
  {
    "path": "src/kaitai/opcode_list_type.cpp",
    "content": "/*\n * opcode_list_type.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"opcode_list_type.h\"\n#include \"iscript_bin.h\"\n\n#include <iostream>\n\nusing namespace std;\n\nopcode_list_type_t::opcode_list_type_t(kaitai::kstruct* p__parent, iscript_bin_t* p__root, kaitai::kstream* p__io) :\n  kaitai::kstruct(p__io),\n  m__root(p__root),\n  m__parent(p__parent),\n  m_pos(m__io->pos()),\n  m_opcode_list(nullptr)\n{\n\n}\n\nopcode_list_type_t::~opcode_list_type_t()\n{\n  _clean_up();\n}\n\nstd::vector<kaitai::kstruct*>* opcode_list_type_t::read_list(std::unordered_set<uint16_t> scpe_offset_table)\n{\n  if (m_opcode_list)\n  {\n    return m_opcode_list;\n  }\n  else\n  {\n    m_opcode_list = new std::vector<kaitai::kstruct*>();\n  }\n\n  m_scpe_offset_table = scpe_offset_table;\n\n  std::streampos _pos = m__io->pos();\n  m__io->seek(m_pos);\n  try\n  {\n    _read();\n  }\n  catch(...)\n  {\n    _clean_up();\n    throw;\n  }\n  m__io->seek(_pos);\n\n  return m_opcode_list;\n}\n\nvoid opcode_list_type_t::_read()\n{\n  int scpe_opcode_offset = 0;\n  bool end_criteria = false;\n  do\n  {\n    iscript_bin_t::opcode_type_t *opcode = new iscript_bin_t::opcode_type_t(m__io, m__parent, m__root);\n    //cout << \"_read::code: \" << hex << opcode->code() << endl;\n    m_opcode_list->push_back(opcode);\n\n    // set next offset position\n    scpe_opcode_offset = m__io->pos();\n\n    if(m_scpe_offset_table.find(scpe_opcode_offset) != m_scpe_offset_table.end())\n    {\n      end_criteria = true;\n    }\n\n    // for now stop when GOTO opcode is found\n    if(opcode->code() == iscript_bin_t::opcode_t::OPCODE_GOTO)\n    {\n      end_criteria = true;\n    }\n  }\n  while(!end_criteria);\n}\n\nvoid opcode_list_type_t::_clean_up()\n{\n  delete m_opcode_list;\n}\n"
  },
  {
    "path": "src/kaitai/opcode_list_type.h",
    "content": "/*\n * opcode_list_type.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef OPCODE_LIST_TYPE_H\n#define OPCODE_LIST_TYPE_H\n\n#include \"kaitaistruct.h\"\n\n// system\n#include <unordered_set>\n#include <vector>\n\n  // forward declarations\nclass iscript_bin_t;\n\nclass  opcode_list_type_t : public kaitai::kstruct\n{\npublic:\n  opcode_list_type_t(kaitai::kstruct* p__parent, iscript_bin_t* p__root, kaitai::kstream* p__io);\n  ~opcode_list_type_t();\n\n  std::vector<kaitai::kstruct*>* read_list(std::unordered_set<uint16_t> scpe_offset_table);\n\nprivate:\n  void _read();\n  void _clean_up();\n\n  std::unordered_set<uint16_t> m_scpe_offset_table;\n  iscript_bin_t* m__root;\n  kaitai::kstruct* m__parent;\n  std::streampos m_pos;\n\n  std::vector<kaitai::kstruct*>* m_opcode_list;\n};\n\n#endif /* OPCODE_LIST_TYPE_H */\n"
  },
  {
    "path": "src/kaitai/orders_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"orders_dat.h\"\n\norders_dat_t::orders_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, orders_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_label = 0;\n    m_use_weapon_targeting = 0;\n    m_unknown2 = 0;\n    m_unknown3 = 0;\n    m_unknown4 = 0;\n    m_unknown5 = 0;\n    m_interruptible = 0;\n    m_unknown7 = 0;\n    m_queueable = 0;\n    m_unknown9 = 0;\n    m_unknown10 = 0;\n    m_unknown11 = 0;\n    m_unknown12 = 0;\n    m_targeting = 0;\n    m_energy = 0;\n    m_animation = 0;\n    m_highlight = 0;\n    m_unknown17 = 0;\n    m_obscured_order = 0;\n    f_num_lines = false;\n    f_record_size = false;\n    f_file_size = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid orders_dat_t::_read() {\n    m_label = new std::vector<uint16_t>();\n    const int l_label = num_lines();\n    for (int i = 0; i < l_label; i++) {\n        m_label->push_back(m__io->read_u2le());\n    }\n    m_use_weapon_targeting = new std::vector<uint8_t>();\n    const int l_use_weapon_targeting = num_lines();\n    for (int i = 0; i < l_use_weapon_targeting; i++) {\n        m_use_weapon_targeting->push_back(m__io->read_u1());\n    }\n    m_unknown2 = new std::vector<uint8_t>();\n    const int l_unknown2 = num_lines();\n    for (int i = 0; i < l_unknown2; i++) {\n        m_unknown2->push_back(m__io->read_u1());\n    }\n    m_unknown3 = new std::vector<uint8_t>();\n    const int l_unknown3 = num_lines();\n    for (int i = 0; i < l_unknown3; i++) {\n        m_unknown3->push_back(m__io->read_u1());\n    }\n    m_unknown4 = new std::vector<uint8_t>();\n    const int l_unknown4 = num_lines();\n    for (int i = 0; i < l_unknown4; i++) {\n        m_unknown4->push_back(m__io->read_u1());\n    }\n    m_unknown5 = new std::vector<uint8_t>();\n    const int l_unknown5 = num_lines();\n    for (int i = 0; i < l_unknown5; i++) {\n        m_unknown5->push_back(m__io->read_u1());\n    }\n    m_interruptible = new std::vector<uint8_t>();\n    const int l_interruptible = num_lines();\n    for (int i = 0; i < l_interruptible; i++) {\n        m_interruptible->push_back(m__io->read_u1());\n    }\n    m_unknown7 = new std::vector<uint8_t>();\n    const int l_unknown7 = num_lines();\n    for (int i = 0; i < l_unknown7; i++) {\n        m_unknown7->push_back(m__io->read_u1());\n    }\n    m_queueable = new std::vector<uint8_t>();\n    const int l_queueable = num_lines();\n    for (int i = 0; i < l_queueable; i++) {\n        m_queueable->push_back(m__io->read_u1());\n    }\n    m_unknown9 = new std::vector<uint8_t>();\n    const int l_unknown9 = num_lines();\n    for (int i = 0; i < l_unknown9; i++) {\n        m_unknown9->push_back(m__io->read_u1());\n    }\n    m_unknown10 = new std::vector<uint8_t>();\n    const int l_unknown10 = num_lines();\n    for (int i = 0; i < l_unknown10; i++) {\n        m_unknown10->push_back(m__io->read_u1());\n    }\n    m_unknown11 = new std::vector<uint8_t>();\n    const int l_unknown11 = num_lines();\n    for (int i = 0; i < l_unknown11; i++) {\n        m_unknown11->push_back(m__io->read_u1());\n    }\n    m_unknown12 = new std::vector<uint8_t>();\n    const int l_unknown12 = num_lines();\n    for (int i = 0; i < l_unknown12; i++) {\n        m_unknown12->push_back(m__io->read_u1());\n    }\n    m_targeting = new std::vector<uint8_t>();\n    const int l_targeting = num_lines();\n    for (int i = 0; i < l_targeting; i++) {\n        m_targeting->push_back(m__io->read_u1());\n    }\n    m_energy = new std::vector<uint8_t>();\n    const int l_energy = num_lines();\n    for (int i = 0; i < l_energy; i++) {\n        m_energy->push_back(m__io->read_u1());\n    }\n    m_animation = new std::vector<uint8_t>();\n    const int l_animation = num_lines();\n    for (int i = 0; i < l_animation; i++) {\n        m_animation->push_back(m__io->read_u1());\n    }\n    m_highlight = new std::vector<uint16_t>();\n    const int l_highlight = num_lines();\n    for (int i = 0; i < l_highlight; i++) {\n        m_highlight->push_back(m__io->read_u2le());\n    }\n    m_unknown17 = new std::vector<uint16_t>();\n    const int l_unknown17 = num_lines();\n    for (int i = 0; i < l_unknown17; i++) {\n        m_unknown17->push_back(m__io->read_u2le());\n    }\n    m_obscured_order = new std::vector<uint8_t>();\n    const int l_obscured_order = num_lines();\n    for (int i = 0; i < l_obscured_order; i++) {\n        m_obscured_order->push_back(m__io->read_u1());\n    }\n}\n\norders_dat_t::~orders_dat_t() {\n    _clean_up();\n}\n\nvoid orders_dat_t::_clean_up() {\n    if (m_label) {\n        delete m_label; m_label = 0;\n    }\n    if (m_use_weapon_targeting) {\n        delete m_use_weapon_targeting; m_use_weapon_targeting = 0;\n    }\n    if (m_unknown2) {\n        delete m_unknown2; m_unknown2 = 0;\n    }\n    if (m_unknown3) {\n        delete m_unknown3; m_unknown3 = 0;\n    }\n    if (m_unknown4) {\n        delete m_unknown4; m_unknown4 = 0;\n    }\n    if (m_unknown5) {\n        delete m_unknown5; m_unknown5 = 0;\n    }\n    if (m_interruptible) {\n        delete m_interruptible; m_interruptible = 0;\n    }\n    if (m_unknown7) {\n        delete m_unknown7; m_unknown7 = 0;\n    }\n    if (m_queueable) {\n        delete m_queueable; m_queueable = 0;\n    }\n    if (m_unknown9) {\n        delete m_unknown9; m_unknown9 = 0;\n    }\n    if (m_unknown10) {\n        delete m_unknown10; m_unknown10 = 0;\n    }\n    if (m_unknown11) {\n        delete m_unknown11; m_unknown11 = 0;\n    }\n    if (m_unknown12) {\n        delete m_unknown12; m_unknown12 = 0;\n    }\n    if (m_targeting) {\n        delete m_targeting; m_targeting = 0;\n    }\n    if (m_energy) {\n        delete m_energy; m_energy = 0;\n    }\n    if (m_animation) {\n        delete m_animation; m_animation = 0;\n    }\n    if (m_highlight) {\n        delete m_highlight; m_highlight = 0;\n    }\n    if (m_unknown17) {\n        delete m_unknown17; m_unknown17 = 0;\n    }\n    if (m_obscured_order) {\n        delete m_obscured_order; m_obscured_order = 0;\n    }\n}\n\nint32_t orders_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = (file_size() / record_size());\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nint8_t orders_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 22;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint32_t orders_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n"
  },
  {
    "path": "src/kaitai/orders_dat.h",
    "content": "#ifndef ORDERS_DAT_H_\n#define ORDERS_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass orders_dat_t : public kaitai::kstruct {\n\npublic:\n\n    orders_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, orders_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~orders_dat_t();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    std::vector<uint16_t>* m_label;\n    std::vector<uint8_t>* m_use_weapon_targeting;\n    std::vector<uint8_t>* m_unknown2;\n    std::vector<uint8_t>* m_unknown3;\n    std::vector<uint8_t>* m_unknown4;\n    std::vector<uint8_t>* m_unknown5;\n    std::vector<uint8_t>* m_interruptible;\n    std::vector<uint8_t>* m_unknown7;\n    std::vector<uint8_t>* m_queueable;\n    std::vector<uint8_t>* m_unknown9;\n    std::vector<uint8_t>* m_unknown10;\n    std::vector<uint8_t>* m_unknown11;\n    std::vector<uint8_t>* m_unknown12;\n    std::vector<uint8_t>* m_targeting;\n    std::vector<uint8_t>* m_energy;\n    std::vector<uint8_t>* m_animation;\n    std::vector<uint16_t>* m_highlight;\n    std::vector<uint16_t>* m_unknown17;\n    std::vector<uint8_t>* m_obscured_order;\n    orders_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * Probably the label of the order. Doesn't do anything - used only for convenience. [pointer to stat_txt.tbl]\n     */\n    std::vector<uint16_t>* label() const { return m_label; }\n\n    /**\n     * Order will use the weapons.dat targeting settings.\n     */\n    std::vector<uint8_t>* use_weapon_targeting() const { return m_use_weapon_targeting; }\n    std::vector<uint8_t>* unknown2() const { return m_unknown2; }\n    std::vector<uint8_t>* unknown3() const { return m_unknown3; }\n    std::vector<uint8_t>* unknown4() const { return m_unknown4; }\n    std::vector<uint8_t>* unknown5() const { return m_unknown5; }\n\n    /**\n     * Order's execution can be interrupted by calling another order (e.g. movement or something). Does not work for the \"Die\" order.\n     */\n    std::vector<uint8_t>* interruptible() const { return m_interruptible; }\n    std::vector<uint8_t>* unknown7() const { return m_unknown7; }\n    std::vector<uint8_t>* queueable() const { return m_queueable; }\n\n    /**\n     * Order execution can be queued using the SHIFT+click combination, up to 16 times.\n     */\n    std::vector<uint8_t>* unknown9() const { return m_unknown9; }\n    std::vector<uint8_t>* unknown10() const { return m_unknown10; }\n    std::vector<uint8_t>* unknown11() const { return m_unknown11; }\n    std::vector<uint8_t>* unknown12() const { return m_unknown12; }\n\n    /**\n     * Weapon used by the order to determine the targeting rules, if \"Use Weapon Targeting\" is checked. [pointer to weapons.dat]\n     */\n    std::vector<uint8_t>* targeting() const { return m_targeting; }\n\n    /**\n     * Technology used to determine the energy cost of calling the order. [pointer to techdata.dat]\n     */\n    std::vector<uint8_t>* energy() const { return m_energy; }\n\n    /**\n     * Unit Iscript animation to use while calling the order.\n     */\n    std::vector<uint8_t>* animation() const { return m_animation; }\n\n    /**\n     * Determines which icon on the button panel is highlightened when the order is being called. If the selected icon is not present, no icon is highlightened. 65535 = no highlight at all [pointer to cmdicons.grp]\n     */\n    std::vector<uint16_t>* highlight() const { return m_highlight; }\n    std::vector<uint16_t>* unknown17() const { return m_unknown17; }\n\n    /**\n     * Order to be run if the target is obscured by the Fog-of-War. [pointer to orders.dat]\n     */\n    std::vector<uint8_t>* obscured_order() const { return m_obscured_order; }\n    orders_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // ORDERS_DAT_H_\n"
  },
  {
    "path": "src/kaitai/orders_dat.ksy",
    "content": "meta:\n  id: orders_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: label\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Probably the label of the order. Doesn't do anything - used only for convenience. [pointer to stat_txt.tbl]\n\n  - id: use_weapon_targeting\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Order will use the weapons.dat targeting settings.\n\n  - id: unknown2\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown3\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown4\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown5\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: interruptible\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Order's execution can be interrupted by calling another order (e.g. movement or something). Does not work for the \"Die\" order.\n\n  - id: unknown7\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: queueable\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown9\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Order execution can be queued using the SHIFT+click combination, up to 16 times.\n\n  - id: unknown10\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown11\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown12\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: targeting\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Weapon used by the order to determine the targeting rules, if \"Use Weapon Targeting\" is checked. [pointer to weapons.dat]\n\n  - id: energy\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Technology used to determine the energy cost of calling the order. [pointer to techdata.dat]\n\n  - id: animation\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Unit Iscript animation to use while calling the order.\n\n  - id: highlight\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Determines which icon on the button panel is highlightened when the order is being called. If the selected icon is not present, no icon is highlightened. 65535 = no highlight at all [pointer to cmdicons.grp]\n\n  - id: unknown17\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: obscured_order\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Order to be run if the target is obscured by the Fog-of-War. [pointer to orders.dat]\n\ninstances:\n  num_lines:\n    value: file_size / record_size\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 22\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  file_size:\n    value: '_io.size'\n"
  },
  {
    "path": "src/kaitai/portdata_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"portdata_dat.h\"\n\nportdata_dat_t::portdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, portdata_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_video_idle = 0;\n    m_video_talking = 0;\n    m_change_idle = 0;\n    m_change_talking = 0;\n    m_unknown1_idle = 0;\n    m_unknown1_talking = 0;\n    f_num_lines = false;\n    f_record_size = false;\n    f_file_size = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid portdata_dat_t::_read() {\n    m_video_idle = new std::vector<uint32_t>();\n    const int l_video_idle = (num_lines() / 2);\n    for (int i = 0; i < l_video_idle; i++) {\n        m_video_idle->push_back(m__io->read_u4le());\n    }\n    m_video_talking = new std::vector<uint32_t>();\n    const int l_video_talking = (num_lines() / 2);\n    for (int i = 0; i < l_video_talking; i++) {\n        m_video_talking->push_back(m__io->read_u4le());\n    }\n    m_change_idle = new std::vector<uint8_t>();\n    const int l_change_idle = (num_lines() / 2);\n    for (int i = 0; i < l_change_idle; i++) {\n        m_change_idle->push_back(m__io->read_u1());\n    }\n    m_change_talking = new std::vector<uint8_t>();\n    const int l_change_talking = (num_lines() / 2);\n    for (int i = 0; i < l_change_talking; i++) {\n        m_change_talking->push_back(m__io->read_u1());\n    }\n    m_unknown1_idle = new std::vector<uint8_t>();\n    const int l_unknown1_idle = (num_lines() / 2);\n    for (int i = 0; i < l_unknown1_idle; i++) {\n        m_unknown1_idle->push_back(m__io->read_u1());\n    }\n    m_unknown1_talking = new std::vector<uint8_t>();\n    const int l_unknown1_talking = (num_lines() / 2);\n    for (int i = 0; i < l_unknown1_talking; i++) {\n        m_unknown1_talking->push_back(m__io->read_u1());\n    }\n}\n\nportdata_dat_t::~portdata_dat_t() {\n    _clean_up();\n}\n\nvoid portdata_dat_t::_clean_up() {\n    if (m_video_idle) {\n        delete m_video_idle; m_video_idle = 0;\n    }\n    if (m_video_talking) {\n        delete m_video_talking; m_video_talking = 0;\n    }\n    if (m_change_idle) {\n        delete m_change_idle; m_change_idle = 0;\n    }\n    if (m_change_talking) {\n        delete m_change_talking; m_change_talking = 0;\n    }\n    if (m_unknown1_idle) {\n        delete m_unknown1_idle; m_unknown1_idle = 0;\n    }\n    if (m_unknown1_talking) {\n        delete m_unknown1_talking; m_unknown1_talking = 0;\n    }\n}\n\nint32_t portdata_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = (file_size() / record_size());\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nint8_t portdata_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 6;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint32_t portdata_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n"
  },
  {
    "path": "src/kaitai/portdata_dat.h",
    "content": "#ifndef PORTDATA_DAT_H_\n#define PORTDATA_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass portdata_dat_t : public kaitai::kstruct {\n\npublic:\n\n    portdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, portdata_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~portdata_dat_t();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    std::vector<uint32_t>* m_video_idle;\n    std::vector<uint32_t>* m_video_talking;\n    std::vector<uint8_t>* m_change_idle;\n    std::vector<uint8_t>* m_change_talking;\n    std::vector<uint8_t>* m_unknown1_idle;\n    std::vector<uint8_t>* m_unknown1_talking;\n    portdata_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * Smacker portrait video for idle animations. [1-based pointer to portdata.tbl]\n     */\n    std::vector<uint32_t>* video_idle() const { return m_video_idle; }\n\n    /**\n     * Smacker portrait video for talking animations. [1-based pointer to portdata.tbl]\n     */\n    std::vector<uint32_t>* video_talking() const { return m_video_talking; }\n\n    /**\n     * Controls how often the first idle animation, with the index of 0, will be overlooked and a portrait with different index will be played. The higher the value and the more it gets near 100, the more often will the first animation be skipped. Values over 100 make the game use only the first portrait.\n     */\n    std::vector<uint8_t>* change_idle() const { return m_change_idle; }\n\n    /**\n     * Controls how often the first talking animation, with the index of 0, will be overlooked and a portrait with different index will be played. The higher the value and the more it gets near 100, the more often will the first animation be skipped. Values over 100 make the game use only the first portrait.\n     */\n    std::vector<uint8_t>* change_talking() const { return m_change_talking; }\n    std::vector<uint8_t>* unknown1_idle() const { return m_unknown1_idle; }\n    std::vector<uint8_t>* unknown1_talking() const { return m_unknown1_talking; }\n    portdata_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // PORTDATA_DAT_H_\n"
  },
  {
    "path": "src/kaitai/portdata_dat.ksy",
    "content": "meta:\n  id: portdata_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: video_idle\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines / 2\n    doc: |\n      Smacker portrait video for idle animations. [1-based pointer to portdata.tbl]\n\n  - id: video_talking\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines / 2\n    doc: |\n      Smacker portrait video for talking animations. [1-based pointer to portdata.tbl]\n\n\n  - id: change_idle\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines / 2\n    doc: |\n      Controls how often the first idle animation, with the index of 0, will be overlooked and a portrait with different index will be played. The higher the value and the more it gets near 100, the more often will the first animation be skipped. Values over 100 make the game use only the first portrait.\n\n  - id: change_talking\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines / 2\n    doc: |\n      Controls how often the first talking animation, with the index of 0, will be overlooked and a portrait with different index will be played. The higher the value and the more it gets near 100, the more often will the first animation be skipped. Values over 100 make the game use only the first portrait.\n\n\n  - id: unknown1_idle\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines / 2\n\n  - id: unknown1_talking\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines / 2\n\n\ninstances:\n  num_lines:\n    value: file_size / record_size\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 6\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  file_size:\n    value: '_io.size'\n"
  },
  {
    "path": "src/kaitai/sfxdata_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"sfxdata_dat.h\"\n\nsfxdata_dat_t::sfxdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, sfxdata_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_sound_file = 0;\n    m_unknown1 = 0;\n    m_unknown2 = 0;\n    m_unknown3 = 0;\n    m_unknown4 = 0;\n    f_num_lines = false;\n    f_record_size = false;\n    f_file_size = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid sfxdata_dat_t::_read() {\n    m_sound_file = new std::vector<uint32_t>();\n    const int l_sound_file = num_lines();\n    for (int i = 0; i < l_sound_file; i++) {\n        m_sound_file->push_back(m__io->read_u4le());\n    }\n    m_unknown1 = new std::vector<uint8_t>();\n    const int l_unknown1 = num_lines();\n    for (int i = 0; i < l_unknown1; i++) {\n        m_unknown1->push_back(m__io->read_u1());\n    }\n    m_unknown2 = new std::vector<uint8_t>();\n    const int l_unknown2 = num_lines();\n    for (int i = 0; i < l_unknown2; i++) {\n        m_unknown2->push_back(m__io->read_u1());\n    }\n    m_unknown3 = new std::vector<uint16_t>();\n    const int l_unknown3 = num_lines();\n    for (int i = 0; i < l_unknown3; i++) {\n        m_unknown3->push_back(m__io->read_u2le());\n    }\n    m_unknown4 = new std::vector<uint8_t>();\n    const int l_unknown4 = num_lines();\n    for (int i = 0; i < l_unknown4; i++) {\n        m_unknown4->push_back(m__io->read_u1());\n    }\n}\n\nsfxdata_dat_t::~sfxdata_dat_t() {\n    _clean_up();\n}\n\nvoid sfxdata_dat_t::_clean_up() {\n    if (m_sound_file) {\n        delete m_sound_file; m_sound_file = 0;\n    }\n    if (m_unknown1) {\n        delete m_unknown1; m_unknown1 = 0;\n    }\n    if (m_unknown2) {\n        delete m_unknown2; m_unknown2 = 0;\n    }\n    if (m_unknown3) {\n        delete m_unknown3; m_unknown3 = 0;\n    }\n    if (m_unknown4) {\n        delete m_unknown4; m_unknown4 = 0;\n    }\n}\n\nint32_t sfxdata_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = (file_size() / record_size());\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nint8_t sfxdata_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 9;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint32_t sfxdata_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n"
  },
  {
    "path": "src/kaitai/sfxdata_dat.h",
    "content": "#ifndef SFXDATA_DAT_H_\n#define SFXDATA_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass sfxdata_dat_t : public kaitai::kstruct {\n\npublic:\n\n    sfxdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, sfxdata_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~sfxdata_dat_t();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    std::vector<uint32_t>* m_sound_file;\n    std::vector<uint8_t>* m_unknown1;\n    std::vector<uint8_t>* m_unknown2;\n    std::vector<uint16_t>* m_unknown3;\n    std::vector<uint8_t>* m_unknown4;\n    sfxdata_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * The actual wave file associated with the sfxdata entry. [pointer to sfxdata.tbl]\n     */\n    std::vector<uint32_t>* sound_file() const { return m_sound_file; }\n    std::vector<uint8_t>* unknown1() const { return m_unknown1; }\n    std::vector<uint8_t>* unknown2() const { return m_unknown2; }\n    std::vector<uint16_t>* unknown3() const { return m_unknown3; }\n    std::vector<uint8_t>* unknown4() const { return m_unknown4; }\n    sfxdata_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // SFXDATA_DAT_H_\n"
  },
  {
    "path": "src/kaitai/sfxdata_dat.ksy",
    "content": "meta:\n  id: sfxdata_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: sound_file\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The actual wave file associated with the sfxdata entry. [pointer to sfxdata.tbl]\n\n#Unknown 1: priority\n#Unknown 2: Various flags:\n#- 1 preload\n#- 2 unitSpeech\n#- 16 oneAtTime\n#- 32 neverPreempt\n#Unknown 3: lengthAdjust\n#Unknown 4: minVolume\n\n  - id: unknown1\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown2\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown3\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: unknown4\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n\ninstances:\n  num_lines:\n    value: file_size / record_size\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 9\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  file_size:\n    value: '_io.size'"
  },
  {
    "path": "src/kaitai/sprites_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"sprites_dat.h\"\n\nsprites_dat_t::sprites_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, sprites_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_image = 0;\n    m_health_bar = 0;\n    m_unknown2 = 0;\n    m_is_visible = 0;\n    m_select_circle_image_size = 0;\n    m_select_circle_vertical_pos = 0;\n    f_file_size_rest = false;\n    f_file_size_first_130 = false;\n    f_num_lines = false;\n    f_file_size = false;\n    f_record_size = false;\n    f_record_size_first_130 = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid sprites_dat_t::_read() {\n    m_image = new std::vector<uint16_t>();\n    const int l_image = num_lines();\n    for (int i = 0; i < l_image; i++) {\n        m_image->push_back(m__io->read_u2le());\n    }\n    m_health_bar = new std::vector<uint8_t>();\n    const int l_health_bar = (num_lines() - 130);\n    for (int i = 0; i < l_health_bar; i++) {\n        m_health_bar->push_back(m__io->read_u1());\n    }\n    m_unknown2 = new std::vector<uint8_t>();\n    const int l_unknown2 = num_lines();\n    for (int i = 0; i < l_unknown2; i++) {\n        m_unknown2->push_back(m__io->read_u1());\n    }\n    m_is_visible = new std::vector<uint8_t>();\n    const int l_is_visible = num_lines();\n    for (int i = 0; i < l_is_visible; i++) {\n        m_is_visible->push_back(m__io->read_u1());\n    }\n    m_select_circle_image_size = new std::vector<uint8_t>();\n    const int l_select_circle_image_size = (num_lines() - 130);\n    for (int i = 0; i < l_select_circle_image_size; i++) {\n        m_select_circle_image_size->push_back(m__io->read_u1());\n    }\n    m_select_circle_vertical_pos = new std::vector<uint8_t>();\n    const int l_select_circle_vertical_pos = (num_lines() - 130);\n    for (int i = 0; i < l_select_circle_vertical_pos; i++) {\n        m_select_circle_vertical_pos->push_back(m__io->read_u1());\n    }\n}\n\nsprites_dat_t::~sprites_dat_t() {\n    _clean_up();\n}\n\nvoid sprites_dat_t::_clean_up() {\n    if (m_image) {\n        delete m_image; m_image = 0;\n    }\n    if (m_health_bar) {\n        delete m_health_bar; m_health_bar = 0;\n    }\n    if (m_unknown2) {\n        delete m_unknown2; m_unknown2 = 0;\n    }\n    if (m_is_visible) {\n        delete m_is_visible; m_is_visible = 0;\n    }\n    if (m_select_circle_image_size) {\n        delete m_select_circle_image_size; m_select_circle_image_size = 0;\n    }\n    if (m_select_circle_vertical_pos) {\n        delete m_select_circle_vertical_pos; m_select_circle_vertical_pos = 0;\n    }\n}\n\nint32_t sprites_dat_t::file_size_rest() {\n    if (f_file_size_rest)\n        return m_file_size_rest;\n    m_file_size_rest = (file_size() - file_size_first_130());\n    f_file_size_rest = true;\n    return m_file_size_rest;\n}\n\nint32_t sprites_dat_t::file_size_first_130() {\n    if (f_file_size_first_130)\n        return m_file_size_first_130;\n    m_file_size_first_130 = (record_size_first_130() * 130);\n    f_file_size_first_130 = true;\n    return m_file_size_first_130;\n}\n\nint32_t sprites_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = ((file_size_rest() / record_size()) + 130);\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nint32_t sprites_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n\nint8_t sprites_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 7;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint8_t sprites_dat_t::record_size_first_130() {\n    if (f_record_size_first_130)\n        return m_record_size_first_130;\n    m_record_size_first_130 = 4;\n    f_record_size_first_130 = true;\n    return m_record_size_first_130;\n}\n"
  },
  {
    "path": "src/kaitai/sprites_dat.h",
    "content": "#ifndef SPRITES_DAT_H_\n#define SPRITES_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass sprites_dat_t : public kaitai::kstruct {\n\npublic:\n\n    sprites_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, sprites_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~sprites_dat_t();\n\nprivate:\n    bool f_file_size_rest;\n    int32_t m_file_size_rest;\n\npublic:\n\n    /**\n     * File size for the records after 130. This number might change from file to file.\n     */\n    int32_t file_size_rest();\n\nprivate:\n    bool f_file_size_first_130;\n    int32_t m_file_size_first_130;\n\npublic:\n\n    /**\n     * File size for the first 130 records that is always static size.\n     */\n    int32_t file_size_first_130();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of the dynamic rest file size though the record size gives the number of records in the file to parse.\n     * The static first 130 are then added to this number.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized (starting from record 130).\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_record_size_first_130;\n    int8_t m_record_size_first_130;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized (the first 130 records).\n     */\n    int8_t record_size_first_130();\n\nprivate:\n    std::vector<uint16_t>* m_image;\n    std::vector<uint8_t>* m_health_bar;\n    std::vector<uint8_t>* m_unknown2;\n    std::vector<uint8_t>* m_is_visible;\n    std::vector<uint8_t>* m_select_circle_image_size;\n    std::vector<uint8_t>* m_select_circle_vertical_pos;\n    sprites_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * The images.dat entry corresponding to the sprites.dat entry [pointer to images.dat]\n     */\n    std::vector<uint16_t>* image() const { return m_image; }\n\n    /**\n     * The length of the Hit Points/Shields/Energy bar below the sprite, in pixels. The way the actual number of \"boxes\" is calculated is the following: substract 1 from the value, divide the result by 3 and round it down. Even though a sprite may actually USE less than 6 boxes, 6 boxes is the minimal amount that will be SHOWN in-game (just that some will not be functional). Values below 6 will all result in 1 box being USED.\n     * This property is only available from unit index 130 to num_lines\n     */\n    std::vector<uint8_t>* health_bar() const { return m_health_bar; }\n\n    /**\n     * tbd\n     */\n    std::vector<uint8_t>* unknown2() const { return m_unknown2; }\n\n    /**\n     * Sprite will start as visible. Unchecked, used to hide the \"White Circle\", the Zerg Beacon used by Subterranean Spines, and few other things.\n     */\n    std::vector<uint8_t>* is_visible() const { return m_is_visible; }\n\n    /**\n     * The size of the in-game selection circle. The different sizes are actually different images.dat entries, so in order to use custom ones you need to replace them. The \"Dashed\" selection circles are used to mark allied units in multiplayer games, but if used on the players own units they will not disappear after deselecting the unit, and also they will NOT be removed on its death, still providing limited vision to the player.[pointer to images.dat, starting at ID#561 as 0]\n     * This property is only available from unit index 130 to num_lines\n     */\n    std::vector<uint8_t>* select_circle_image_size() const { return m_select_circle_image_size; }\n\n    /**\n     * The vertical position of the in-game selection circle and the Health/Shield/Energy bar. The higher the number, the more downwards from the main sprite will they be positioned. Around 127 the display \"loops back\" and appears actually ABOVE the main sprite. 255 will put it back in its original position.\n     * This property is only available from unit index 130 to num_lines\n     */\n    std::vector<uint8_t>* select_circle_vertical_pos() const { return m_select_circle_vertical_pos; }\n    sprites_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // SPRITES_DAT_H_\n"
  },
  {
    "path": "src/kaitai/sprites_dat.ksy",
    "content": "meta:\n  id: sprites_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: image\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The images.dat entry corresponding to the sprites.dat entry [pointer to images.dat]\n\n  - id: health_bar\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines-130\n    doc: |\n      The length of the Hit Points/Shields/Energy bar below the sprite, in pixels. The way the actual number of \"boxes\" is calculated is the following: substract 1 from the value, divide the result by 3 and round it down. Even though a sprite may actually USE less than 6 boxes, 6 boxes is the minimal amount that will be SHOWN in-game (just that some will not be functional). Values below 6 will all result in 1 box being USED.\n      This property is only available from unit index 130 to num_lines\n\n  - id: unknown2\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      tbd\n\n  - id: is_visible\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Sprite will start as visible. Unchecked, used to hide the \"White Circle\", the Zerg Beacon used by Subterranean Spines, and few other things.\n\n  - id: select_circle_image_size\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines-130\n    doc: |\n      The size of the in-game selection circle. The different sizes are actually different images.dat entries, so in order to use custom ones you need to replace them. The \"Dashed\" selection circles are used to mark allied units in multiplayer games, but if used on the players own units they will not disappear after deselecting the unit, and also they will NOT be removed on its death, still providing limited vision to the player.[pointer to images.dat, starting at ID#561 as 0]\n      This property is only available from unit index 130 to num_lines\n\n  - id: select_circle_vertical_pos\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines-130\n    doc: |\n      The vertical position of the in-game selection circle and the Health/Shield/Energy bar. The higher the number, the more downwards from the main sprite will they be positioned. Around 127 the display \"loops back\" and appears actually ABOVE the main sprite. 255 will put it back in its original position.\n      This property is only available from unit index 130 to num_lines\n\ninstances:\n  num_lines:\n    value: 'file_size_rest / record_size + 130'\n    doc: |\n      A division of the dynamic rest file size though the record size gives the number of records in the file to parse.\n      The static first 130 are then added to this number.\n\n  record_size:\n    value: 7\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized (starting from record 130).\n\n  record_size_first_130:\n    value: 4\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized (the first 130 records).\n\n  file_size_first_130:\n    value: 'record_size_first_130 * 130'\n    doc: |\n      File size for the first 130 records that is always static size.\n\n  file_size_rest:\n    value: 'file_size - file_size_first_130'\n    doc:   |\n      File size for the records after 130. This number might change from file to file.\n\n  file_size:\n    value: '_io.size'\n"
  },
  {
    "path": "src/kaitai/techdata_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"techdata_dat.h\"\n\ntechdata_dat_t::techdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, techdata_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_mineral_cost = 0;\n    m_vespene_cost = 0;\n    m_research_time = 0;\n    m_energy_required = 0;\n    m_unknown4 = 0;\n    m_icon = 0;\n    m_label = 0;\n    m_race = 0;\n    m_unused = 0;\n    m_broodwar_flag = 0;\n    f_record_count_broodwar = false;\n    f_record_count = false;\n    f_num_lines = false;\n    f_has_broodwar_flag = false;\n    f_file_size = false;\n    f_record_size = false;\n    f_record_size_broodwar = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid techdata_dat_t::_read() {\n    m_mineral_cost = new std::vector<uint16_t>();\n    const int l_mineral_cost = num_lines();\n    for (int i = 0; i < l_mineral_cost; i++) {\n        m_mineral_cost->push_back(m__io->read_u2le());\n    }\n    m_vespene_cost = new std::vector<uint16_t>();\n    const int l_vespene_cost = num_lines();\n    for (int i = 0; i < l_vespene_cost; i++) {\n        m_vespene_cost->push_back(m__io->read_u2le());\n    }\n    m_research_time = new std::vector<uint16_t>();\n    const int l_research_time = num_lines();\n    for (int i = 0; i < l_research_time; i++) {\n        m_research_time->push_back(m__io->read_u2le());\n    }\n    m_energy_required = new std::vector<uint16_t>();\n    const int l_energy_required = num_lines();\n    for (int i = 0; i < l_energy_required; i++) {\n        m_energy_required->push_back(m__io->read_u2le());\n    }\n    m_unknown4 = new std::vector<uint32_t>();\n    const int l_unknown4 = num_lines();\n    for (int i = 0; i < l_unknown4; i++) {\n        m_unknown4->push_back(m__io->read_u4le());\n    }\n    m_icon = new std::vector<uint16_t>();\n    const int l_icon = num_lines();\n    for (int i = 0; i < l_icon; i++) {\n        m_icon->push_back(m__io->read_u2le());\n    }\n    m_label = new std::vector<uint16_t>();\n    const int l_label = num_lines();\n    for (int i = 0; i < l_label; i++) {\n        m_label->push_back(m__io->read_u2le());\n    }\n    m_race = new std::vector<uint8_t>();\n    const int l_race = num_lines();\n    for (int i = 0; i < l_race; i++) {\n        m_race->push_back(m__io->read_u1());\n    }\n    m_unused = new std::vector<uint8_t>();\n    const int l_unused = num_lines();\n    for (int i = 0; i < l_unused; i++) {\n        m_unused->push_back(m__io->read_u1());\n    }\n    n_broodwar_flag = true;\n    if (has_broodwar_flag() == true) {\n        n_broodwar_flag = false;\n        m_broodwar_flag = new std::vector<uint8_t>();\n        const int l_broodwar_flag = num_lines();\n        for (int i = 0; i < l_broodwar_flag; i++) {\n            m_broodwar_flag->push_back(m__io->read_u1());\n        }\n    }\n}\n\ntechdata_dat_t::~techdata_dat_t() {\n    _clean_up();\n}\n\nvoid techdata_dat_t::_clean_up() {\n    if (m_mineral_cost) {\n        delete m_mineral_cost; m_mineral_cost = 0;\n    }\n    if (m_vespene_cost) {\n        delete m_vespene_cost; m_vespene_cost = 0;\n    }\n    if (m_research_time) {\n        delete m_research_time; m_research_time = 0;\n    }\n    if (m_energy_required) {\n        delete m_energy_required; m_energy_required = 0;\n    }\n    if (m_unknown4) {\n        delete m_unknown4; m_unknown4 = 0;\n    }\n    if (m_icon) {\n        delete m_icon; m_icon = 0;\n    }\n    if (m_label) {\n        delete m_label; m_label = 0;\n    }\n    if (m_race) {\n        delete m_race; m_race = 0;\n    }\n    if (m_unused) {\n        delete m_unused; m_unused = 0;\n    }\n    if (!n_broodwar_flag) {\n        if (m_broodwar_flag) {\n            delete m_broodwar_flag; m_broodwar_flag = 0;\n        }\n    }\n}\n\nint32_t techdata_dat_t::record_count_broodwar() {\n    if (f_record_count_broodwar)\n        return m_record_count_broodwar;\n    m_record_count_broodwar = (file_size() / record_size_broodwar());\n    f_record_count_broodwar = true;\n    return m_record_count_broodwar;\n}\n\nint32_t techdata_dat_t::record_count() {\n    if (f_record_count)\n        return m_record_count;\n    m_record_count = (file_size() / record_size());\n    f_record_count = true;\n    return m_record_count;\n}\n\nint32_t techdata_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = ((kaitai::kstream::mod(file_size(), record_size()) == 0) ? (record_count()) : (record_count_broodwar()));\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nbool techdata_dat_t::has_broodwar_flag() {\n    if (f_has_broodwar_flag)\n        return m_has_broodwar_flag;\n    m_has_broodwar_flag = ((kaitai::kstream::mod(file_size(), record_size()) == 0) ? (false) : (true));\n    f_has_broodwar_flag = true;\n    return m_has_broodwar_flag;\n}\n\nint32_t techdata_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n\nint8_t techdata_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 18;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint8_t techdata_dat_t::record_size_broodwar() {\n    if (f_record_size_broodwar)\n        return m_record_size_broodwar;\n    m_record_size_broodwar = 19;\n    f_record_size_broodwar = true;\n    return m_record_size_broodwar;\n}\n"
  },
  {
    "path": "src/kaitai/techdata_dat.h",
    "content": "#ifndef TECHDATA_DAT_H_\n#define TECHDATA_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass techdata_dat_t : public kaitai::kstruct {\n\npublic:\n\n    techdata_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, techdata_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~techdata_dat_t();\n\nprivate:\n    bool f_record_count_broodwar;\n    int32_t m_record_count_broodwar;\n\npublic:\n\n    /**\n     * Count of records in the data file. (Need to check with modulo operator if this is the case) [broodwar data]\n     */\n    int32_t record_count_broodwar();\n\nprivate:\n    bool f_record_count;\n    int32_t m_record_count;\n\npublic:\n\n    /**\n     * Count of records in the data file. (Need to check with modulo operator if this is the case)\n     */\n    int32_t record_count();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_has_broodwar_flag;\n    bool m_has_broodwar_flag;\n\npublic:\n\n    /**\n     * true in case the brodowar data is parsed\n     */\n    bool has_broodwar_flag();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_record_size_broodwar;\n    int8_t m_record_size_broodwar;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized. [broodwar data]\n     */\n    int8_t record_size_broodwar();\n\nprivate:\n    std::vector<uint16_t>* m_mineral_cost;\n    std::vector<uint16_t>* m_vespene_cost;\n    std::vector<uint16_t>* m_research_time;\n    std::vector<uint16_t>* m_energy_required;\n    std::vector<uint32_t>* m_unknown4;\n    std::vector<uint16_t>* m_icon;\n    std::vector<uint16_t>* m_label;\n    std::vector<uint8_t>* m_race;\n    std::vector<uint8_t>* m_unused;\n    std::vector<uint8_t>* m_broodwar_flag;\n    bool n_broodwar_flag;\n\npublic:\n    bool _is_null_broodwar_flag() { broodwar_flag(); return n_broodwar_flag; };\n\nprivate:\n    techdata_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * Minerals cost for the research of the technology.\n     */\n    std::vector<uint16_t>* mineral_cost() const { return m_mineral_cost; }\n\n    /**\n     * Vespene gas cost for the research of the technology.\n     */\n    std::vector<uint16_t>* vespene_cost() const { return m_vespene_cost; }\n\n    /**\n     * Research time of the technology in 1/24ths of a second (at Fastest speed). Value of 0 will crash the game.\n     */\n    std::vector<uint16_t>* research_time() const { return m_research_time; }\n\n    /**\n     * Energy cost for using the technology.\n     */\n    std::vector<uint16_t>* energy_required() const { return m_energy_required; }\n\n    /**\n     * unknown\n     */\n    std::vector<uint32_t>* unknown4() const { return m_unknown4; }\n\n    /**\n     * Icon displayed for the technology. [pointer to a frame in unit\\cmdbtns\\cmdicons.grp]\n     */\n    std::vector<uint16_t>* icon() const { return m_icon; }\n\n    /**\n     * The name of the technology. Displayed in StarEdit and when you highlight the tech's icon during research. [pointer to stat_txt.tbl]\n     */\n    std::vector<uint16_t>* label() const { return m_label; }\n\n    /**\n     * Determines which race can use/research the technology. \"All\" will disable the tech in StarEdit (but not in-game).\n     */\n    std::vector<uint8_t>* race() const { return m_race; }\n\n    /**\n     * unused\n     */\n    std::vector<uint8_t>* unused() const { return m_unused; }\n\n    /**\n     * Makes the technology available only while playing the BroodWar expansion set.\n     */\n    std::vector<uint8_t>* broodwar_flag() const { return m_broodwar_flag; }\n    techdata_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // TECHDATA_DAT_H_\n"
  },
  {
    "path": "src/kaitai/techdata_dat.ksy",
    "content": "meta:\n  id: techdata_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: mineral_cost\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Minerals cost for the research of the technology.\n\n  - id: vespene_cost\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Vespene gas cost for the research of the technology.\n\n  - id: research_time\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Research time of the technology in 1/24ths of a second (at Fastest speed). Value of 0 will crash the game.\n\n  - id: energy_required\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Energy cost for using the technology.\n\n  - id: unknown4\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      unknown\n\n  - id: icon\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Icon displayed for the technology. [pointer to a frame in unit\\cmdbtns\\cmdicons.grp]\n\n  - id: label\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The name of the technology. Displayed in StarEdit and when you highlight the tech's icon during research. [pointer to stat_txt.tbl]\n\n  - id: race\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Determines which race can use/research the technology. \"All\" will disable the tech in StarEdit (but not in-game).\n\n  - id: unused\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      unused\n\n  - id: broodwar_flag\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    if: has_broodwar_flag == true\n    doc: |\n      Makes the technology available only while playing the BroodWar expansion set.\n\ninstances:\n  has_broodwar_flag:\n    value: 'file_size % record_size == 0 ? false : true'\n    doc: |\n      true in case the brodowar data is parsed\n\n  num_lines:\n    value: 'file_size % record_size == 0 ? record_count : record_count_broodwar'\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 18\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  record_count:\n    value: 'file_size / record_size'\n    doc: |\n      Count of records in the data file. (Need to check with modulo operator if this is the case)\n\n  record_size_broodwar:\n    value: 19\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized. [broodwar data]\n\n  record_count_broodwar:\n    value: 'file_size / record_size_broodwar'\n    doc: |\n      Count of records in the data file. (Need to check with modulo operator if this is the case) [broodwar data]\n\n  file_size:\n    value: '_io.size'\n"
  },
  {
    "path": "src/kaitai/tileset_cv5.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"tileset_cv5.h\"\n\ntileset_cv5_t::tileset_cv5_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, tileset_cv5_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_elements = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_cv5_t::_read() {\n    m_elements = new std::vector<group_t*>();\n    {\n        int i = 0;\n        while (!m__io->is_eof()) {\n            m_elements->push_back(new group_t(m__io, this, m__root));\n            i++;\n        }\n    }\n}\n\ntileset_cv5_t::~tileset_cv5_t() {\n    _clean_up();\n}\n\nvoid tileset_cv5_t::_clean_up() {\n    if (m_elements) {\n        for (std::vector<group_t*>::iterator it = m_elements->begin(); it != m_elements->end(); ++it) {\n            delete *it;\n        }\n        delete m_elements; m_elements = 0;\n    }\n}\n\ntileset_cv5_t::group_t::group_t(kaitai::kstream* p__io, tileset_cv5_t* p__parent, tileset_cv5_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_ground = 0;\n    m_megatile_references = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_cv5_t::group_t::_read() {\n    m_doodad = m__io->read_u2le();\n    m_ground = new ground_nibbles_t(m__io, this, m__root);\n    m_unknown1 = m__io->read_u2le();\n    m_unknown2 = m__io->read_u2le();\n    m_unknown3 = m__io->read_u2le();\n    m_unknown4 = m__io->read_u2le();\n    m_unknown5 = m__io->read_u2le();\n    m_unknown6 = m__io->read_u2le();\n    m_unknown7 = m__io->read_u2le();\n    m_unknown8 = m__io->read_u2le();\n    m_megatile_references = new std::vector<uint16_t>();\n    const int l_megatile_references = 16;\n    for (int i = 0; i < l_megatile_references; i++) {\n        m_megatile_references->push_back(m__io->read_u2le());\n    }\n}\n\ntileset_cv5_t::group_t::~group_t() {\n    _clean_up();\n}\n\nvoid tileset_cv5_t::group_t::_clean_up() {\n    if (m_ground) {\n        delete m_ground; m_ground = 0;\n    }\n    if (m_megatile_references) {\n        delete m_megatile_references; m_megatile_references = 0;\n    }\n}\n\ntileset_cv5_t::ground_nibbles_t::ground_nibbles_t(kaitai::kstream* p__io, tileset_cv5_t::group_t* p__parent, tileset_cv5_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_cv5_t::ground_nibbles_t::_read() {\n    m_buildable = m__io->read_bits_int_le(4);\n    m_ground_type = m__io->read_bits_int_le(4);\n    m_unknown1 = m__io->read_bits_int_le(4);\n    m_ground_height = m__io->read_bits_int_le(4);\n}\n\ntileset_cv5_t::ground_nibbles_t::~ground_nibbles_t() {\n    _clean_up();\n}\n\nvoid tileset_cv5_t::ground_nibbles_t::_clean_up() {\n}\n"
  },
  {
    "path": "src/kaitai/tileset_cv5.h",
    "content": "#ifndef TILESET_CV5_H_\n#define TILESET_CV5_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass tileset_cv5_t : public kaitai::kstruct {\n\npublic:\n    class group_t;\n    class ground_nibbles_t;\n\n    tileset_cv5_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, tileset_cv5_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~tileset_cv5_t();\n\n    class group_t : public kaitai::kstruct {\n\n    public:\n\n        group_t(kaitai::kstream* p__io, tileset_cv5_t* p__parent = 0, tileset_cv5_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~group_t();\n\n    private:\n        uint16_t m_doodad;\n        ground_nibbles_t* m_ground;\n        uint16_t m_unknown1;\n        uint16_t m_unknown2;\n        uint16_t m_unknown3;\n        uint16_t m_unknown4;\n        uint16_t m_unknown5;\n        uint16_t m_unknown6;\n        uint16_t m_unknown7;\n        uint16_t m_unknown8;\n        std::vector<uint16_t>* m_megatile_references;\n        tileset_cv5_t* m__root;\n        tileset_cv5_t* m__parent;\n\n    public:\n        uint16_t doodad() const { return m_doodad; }\n        ground_nibbles_t* ground() const { return m_ground; }\n        uint16_t unknown1() const { return m_unknown1; }\n        uint16_t unknown2() const { return m_unknown2; }\n        uint16_t unknown3() const { return m_unknown3; }\n        uint16_t unknown4() const { return m_unknown4; }\n        uint16_t unknown5() const { return m_unknown5; }\n        uint16_t unknown6() const { return m_unknown6; }\n        uint16_t unknown7() const { return m_unknown7; }\n        uint16_t unknown8() const { return m_unknown8; }\n        std::vector<uint16_t>* megatile_references() const { return m_megatile_references; }\n        tileset_cv5_t* _root() const { return m__root; }\n        tileset_cv5_t* _parent() const { return m__parent; }\n    };\n\n    class ground_nibbles_t : public kaitai::kstruct {\n\n    public:\n\n        ground_nibbles_t(kaitai::kstream* p__io, tileset_cv5_t::group_t* p__parent = 0, tileset_cv5_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~ground_nibbles_t();\n\n    private:\n        uint64_t m_buildable;\n        uint64_t m_ground_type;\n        uint64_t m_unknown1;\n        uint64_t m_ground_height;\n        tileset_cv5_t* m__root;\n        tileset_cv5_t::group_t* m__parent;\n\n    public:\n        uint64_t buildable() const { return m_buildable; }\n        uint64_t ground_type() const { return m_ground_type; }\n        uint64_t unknown1() const { return m_unknown1; }\n        uint64_t ground_height() const { return m_ground_height; }\n        tileset_cv5_t* _root() const { return m__root; }\n        tileset_cv5_t::group_t* _parent() const { return m__parent; }\n    };\n\nprivate:\n    std::vector<group_t*>* m_elements;\n    tileset_cv5_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n    std::vector<group_t*>* elements() const { return m_elements; }\n    tileset_cv5_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // TILESET_CV5_H_\n"
  },
  {
    "path": "src/kaitai/tileset_cv5.ksy",
    "content": "meta:\n  id: tileset_cv5\n  endian: le\n  bit-endian: le\n  \nseq:\n  - id: elements\n    type: group\n    repeat: eos\n\ntypes:\n  group:\n    seq:\n      - id: doodad\n        type: u2\n\n      - id: ground\n        type: ground_nibbles\n        \n      - id: unknown1\n        type: u2\n        \n      - id: unknown2\n        type: u2\n        \n      - id: unknown3\n        type: u2\n        \n      - id: unknown4\n        type: u2\n        \n      - id: unknown5\n        type: u2\n        \n      - id: unknown6\n        type: u2\n        \n      - id: unknown7\n        type: u2\n        \n      - id: unknown8\n        type: u2\n        \n      - id: megatile_references\n        type: u2\n        repeat: expr\n        repeat-expr: 16\n        \n  ground_nibbles:\n    seq:\n      - id: buildable\n        type: b4\n        \n      - id: ground_type\n        type: b4\n        \n      - id: unknown1\n        type: b4\n        \n      - id: ground_height\n        type: b4\n        "
  },
  {
    "path": "src/kaitai/tileset_dddata_bin.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"tileset_dddata_bin.h\"\n\ntileset_dddata_bin_t::tileset_dddata_bin_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, tileset_dddata_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_doodad = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_dddata_bin_t::_read() {\n    m_doodad = new std::vector<doodad_type_t*>();\n    {\n        int i = 0;\n        while (!m__io->is_eof()) {\n            m_doodad->push_back(new doodad_type_t(m__io, this, m__root));\n            i++;\n        }\n    }\n}\n\ntileset_dddata_bin_t::~tileset_dddata_bin_t() {\n    _clean_up();\n}\n\nvoid tileset_dddata_bin_t::_clean_up() {\n    if (m_doodad) {\n        for (std::vector<doodad_type_t*>::iterator it = m_doodad->begin(); it != m_doodad->end(); ++it) {\n            delete *it;\n        }\n        delete m_doodad; m_doodad = 0;\n    }\n}\n\ntileset_dddata_bin_t::doodad_type_t::doodad_type_t(kaitai::kstream* p__io, tileset_dddata_bin_t* p__parent, tileset_dddata_bin_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_placing = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_dddata_bin_t::doodad_type_t::_read() {\n    m_placing = new std::vector<uint16_t>();\n    const int l_placing = 512;\n    for (int i = 0; i < l_placing; i++) {\n        m_placing->push_back(m__io->read_u2le());\n    }\n}\n\ntileset_dddata_bin_t::doodad_type_t::~doodad_type_t() {\n    _clean_up();\n}\n\nvoid tileset_dddata_bin_t::doodad_type_t::_clean_up() {\n    if (m_placing) {\n        delete m_placing; m_placing = 0;\n    }\n}\n"
  },
  {
    "path": "src/kaitai/tileset_dddata_bin.h",
    "content": "#ifndef TILESET_DDDATA_BIN_H_\n#define TILESET_DDDATA_BIN_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass tileset_dddata_bin_t : public kaitai::kstruct {\n\npublic:\n    class doodad_type_t;\n\n    tileset_dddata_bin_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, tileset_dddata_bin_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~tileset_dddata_bin_t();\n\n    class doodad_type_t : public kaitai::kstruct {\n\n    public:\n\n        doodad_type_t(kaitai::kstream* p__io, tileset_dddata_bin_t* p__parent = 0, tileset_dddata_bin_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~doodad_type_t();\n\n    private:\n        std::vector<uint16_t>* m_placing;\n        tileset_dddata_bin_t* m__root;\n        tileset_dddata_bin_t* m__parent;\n\n    public:\n        std::vector<uint16_t>* placing() const { return m_placing; }\n        tileset_dddata_bin_t* _root() const { return m__root; }\n        tileset_dddata_bin_t* _parent() const { return m__parent; }\n    };\n\nprivate:\n    std::vector<doodad_type_t*>* m_doodad;\n    tileset_dddata_bin_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n    std::vector<doodad_type_t*>* doodad() const { return m_doodad; }\n    tileset_dddata_bin_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // TILESET_DDDATA_BIN_H_\n"
  },
  {
    "path": "src/kaitai/tileset_dddata_bin.ksy",
    "content": "meta:\n  id: tileset_dddata_bin\n  endian: le\n  bit-endian: le\n  \nseq:\n  - id: doodad\n    type: doodad_type\n    repeat: eos\n\ntypes:\n  doodad_type:\n    seq:\n      - id: placing\n        type: u2\n        repeat: expr\n        repeat-expr: 512"
  },
  {
    "path": "src/kaitai/tileset_vf4.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"tileset_vf4.h\"\n\ntileset_vf4_t::tileset_vf4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, tileset_vf4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_elements = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vf4_t::_read() {\n    m_elements = new std::vector<minitile_t*>();\n    {\n        int i = 0;\n        while (!m__io->is_eof()) {\n            m_elements->push_back(new minitile_t(m__io, this, m__root));\n            i++;\n        }\n    }\n}\n\ntileset_vf4_t::~tileset_vf4_t() {\n    _clean_up();\n}\n\nvoid tileset_vf4_t::_clean_up() {\n    if (m_elements) {\n        for (std::vector<minitile_t*>::iterator it = m_elements->begin(); it != m_elements->end(); ++it) {\n            delete *it;\n        }\n        delete m_elements; m_elements = 0;\n    }\n}\n\ntileset_vf4_t::minitile_t::minitile_t(kaitai::kstream* p__io, tileset_vf4_t* p__parent, tileset_vf4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_flags = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vf4_t::minitile_t::_read() {\n    m_flags = new std::vector<minitile_flags_types_t*>();\n    const int l_flags = 16;\n    for (int i = 0; i < l_flags; i++) {\n        m_flags->push_back(new minitile_flags_types_t(m__io, this, m__root));\n    }\n}\n\ntileset_vf4_t::minitile_t::~minitile_t() {\n    _clean_up();\n}\n\nvoid tileset_vf4_t::minitile_t::_clean_up() {\n    if (m_flags) {\n        for (std::vector<minitile_flags_types_t*>::iterator it = m_flags->begin(); it != m_flags->end(); ++it) {\n            delete *it;\n        }\n        delete m_flags; m_flags = 0;\n    }\n}\n\ntileset_vf4_t::minitile_flags_types_t::minitile_flags_types_t(kaitai::kstream* p__io, tileset_vf4_t::minitile_t* p__parent, tileset_vf4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    f_walkable = false;\n    f_blocks_view = false;\n    f_mid_elevation = false;\n    f_ramp = false;\n    f_high_elevation = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vf4_t::minitile_flags_types_t::_read() {\n    m_flags_raw = m__io->read_u2le();\n}\n\ntileset_vf4_t::minitile_flags_types_t::~minitile_flags_types_t() {\n    _clean_up();\n}\n\nvoid tileset_vf4_t::minitile_flags_types_t::_clean_up() {\n}\n\nint32_t tileset_vf4_t::minitile_flags_types_t::walkable() {\n    if (f_walkable)\n        return m_walkable;\n    m_walkable = (flags_raw() & 1);\n    f_walkable = true;\n    return m_walkable;\n}\n\nint32_t tileset_vf4_t::minitile_flags_types_t::blocks_view() {\n    if (f_blocks_view)\n        return m_blocks_view;\n    m_blocks_view = (flags_raw() & 8);\n    f_blocks_view = true;\n    return m_blocks_view;\n}\n\nint32_t tileset_vf4_t::minitile_flags_types_t::mid_elevation() {\n    if (f_mid_elevation)\n        return m_mid_elevation;\n    m_mid_elevation = (flags_raw() & 2);\n    f_mid_elevation = true;\n    return m_mid_elevation;\n}\n\nint32_t tileset_vf4_t::minitile_flags_types_t::ramp() {\n    if (f_ramp)\n        return m_ramp;\n    m_ramp = (flags_raw() & 16);\n    f_ramp = true;\n    return m_ramp;\n}\n\nint32_t tileset_vf4_t::minitile_flags_types_t::high_elevation() {\n    if (f_high_elevation)\n        return m_high_elevation;\n    m_high_elevation = (flags_raw() & 4);\n    f_high_elevation = true;\n    return m_high_elevation;\n}\n"
  },
  {
    "path": "src/kaitai/tileset_vf4.h",
    "content": "#ifndef TILESET_VF4_H_\n#define TILESET_VF4_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass tileset_vf4_t : public kaitai::kstruct {\n\npublic:\n    class minitile_t;\n    class minitile_flags_types_t;\n\n    tileset_vf4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, tileset_vf4_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~tileset_vf4_t();\n\n    class minitile_t : public kaitai::kstruct {\n\n    public:\n\n        minitile_t(kaitai::kstream* p__io, tileset_vf4_t* p__parent = 0, tileset_vf4_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~minitile_t();\n\n    private:\n        std::vector<minitile_flags_types_t*>* m_flags;\n        tileset_vf4_t* m__root;\n        tileset_vf4_t* m__parent;\n\n    public:\n        std::vector<minitile_flags_types_t*>* flags() const { return m_flags; }\n        tileset_vf4_t* _root() const { return m__root; }\n        tileset_vf4_t* _parent() const { return m__parent; }\n    };\n\n    class minitile_flags_types_t : public kaitai::kstruct {\n\n    public:\n\n        minitile_flags_types_t(kaitai::kstream* p__io, tileset_vf4_t::minitile_t* p__parent = 0, tileset_vf4_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~minitile_flags_types_t();\n\n    private:\n        bool f_walkable;\n        int32_t m_walkable;\n\n    public:\n        int32_t walkable();\n\n    private:\n        bool f_blocks_view;\n        int32_t m_blocks_view;\n\n    public:\n        int32_t blocks_view();\n\n    private:\n        bool f_mid_elevation;\n        int32_t m_mid_elevation;\n\n    public:\n        int32_t mid_elevation();\n\n    private:\n        bool f_ramp;\n        int32_t m_ramp;\n\n    public:\n        int32_t ramp();\n\n    private:\n        bool f_high_elevation;\n        int32_t m_high_elevation;\n\n    public:\n        int32_t high_elevation();\n\n    private:\n        uint16_t m_flags_raw;\n        tileset_vf4_t* m__root;\n        tileset_vf4_t::minitile_t* m__parent;\n\n    public:\n        uint16_t flags_raw() const { return m_flags_raw; }\n        tileset_vf4_t* _root() const { return m__root; }\n        tileset_vf4_t::minitile_t* _parent() const { return m__parent; }\n    };\n\nprivate:\n    std::vector<minitile_t*>* m_elements;\n    tileset_vf4_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n    std::vector<minitile_t*>* elements() const { return m_elements; }\n    tileset_vf4_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // TILESET_VF4_H_\n"
  },
  {
    "path": "src/kaitai/tileset_vf4.ksy",
    "content": "meta:\n  id: tileset_vf4\n  endian: le\n  bit-endian: le\n  \nseq:\n  - id: elements\n    type: minitile\n    repeat: eos\n\ntypes:\n  minitile:\n    seq:\n      - id: flags\n        type: minitile_flags_types\n        repeat: expr\n        repeat-expr: 16\n        \n  minitile_flags_types:\n    seq:\n      - id: flags_raw\n        type: u2\n        \n    instances:\n      walkable:\n        value: flags_raw & 0x01\n        \n      mid_elevation:\n        value: flags_raw & 0x02\n        \n      high_elevation:\n        value: flags_raw & 0x04\n        \n      blocks_view:\n        value: flags_raw & 0x08\n        \n      ramp:\n        value: flags_raw & 0x10\n        "
  },
  {
    "path": "src/kaitai/tileset_vr4.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"tileset_vr4.h\"\n\ntileset_vr4_t::tileset_vr4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, tileset_vr4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_elements = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vr4_t::_read() {\n    m_elements = new std::vector<pixel_type_t*>();\n    {\n        int i = 0;\n        while (!m__io->is_eof()) {\n            m_elements->push_back(new pixel_type_t(m__io, this, m__root));\n            i++;\n        }\n    }\n}\n\ntileset_vr4_t::~tileset_vr4_t() {\n    _clean_up();\n}\n\nvoid tileset_vr4_t::_clean_up() {\n    if (m_elements) {\n        for (std::vector<pixel_type_t*>::iterator it = m_elements->begin(); it != m_elements->end(); ++it) {\n            delete *it;\n        }\n        delete m_elements; m_elements = 0;\n    }\n}\n\ntileset_vr4_t::pixel_type_t::pixel_type_t(kaitai::kstream* p__io, tileset_vr4_t* p__parent, tileset_vr4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vr4_t::pixel_type_t::_read() {\n    m_minitile = m__io->read_bytes(64);\n}\n\ntileset_vr4_t::pixel_type_t::~pixel_type_t() {\n    _clean_up();\n}\n\nvoid tileset_vr4_t::pixel_type_t::_clean_up() {\n}\n"
  },
  {
    "path": "src/kaitai/tileset_vr4.h",
    "content": "#ifndef TILESET_VR4_H_\n#define TILESET_VR4_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass tileset_vr4_t : public kaitai::kstruct {\n\npublic:\n    class pixel_type_t;\n\n    tileset_vr4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, tileset_vr4_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~tileset_vr4_t();\n\n    class pixel_type_t : public kaitai::kstruct {\n\n    public:\n\n        pixel_type_t(kaitai::kstream* p__io, tileset_vr4_t* p__parent = 0, tileset_vr4_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~pixel_type_t();\n\n    private:\n        std::string m_minitile;\n        tileset_vr4_t* m__root;\n        tileset_vr4_t* m__parent;\n\n    public:\n        std::string minitile() const { return m_minitile; }\n        tileset_vr4_t* _root() const { return m__root; }\n        tileset_vr4_t* _parent() const { return m__parent; }\n    };\n\nprivate:\n    std::vector<pixel_type_t*>* m_elements;\n    tileset_vr4_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n    std::vector<pixel_type_t*>* elements() const { return m_elements; }\n    tileset_vr4_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // TILESET_VR4_H_\n"
  },
  {
    "path": "src/kaitai/tileset_vr4.ksy",
    "content": "meta:\n  id: tileset_vr4\n  endian: le\n  bit-endian: le\n  \nseq:\n  - id: elements\n    type: pixel_type\n    repeat: eos\n\n    \ntypes:\n  pixel_type:\n    seq:\n      - id: minitile\n        size: 64"
  },
  {
    "path": "src/kaitai/tileset_vx4.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"tileset_vx4.h\"\n\ntileset_vx4_t::tileset_vx4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, tileset_vx4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_elements = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vx4_t::_read() {\n    m_elements = new std::vector<megatile_type_t*>();\n    {\n        int i = 0;\n        while (!m__io->is_eof()) {\n            m_elements->push_back(new megatile_type_t(m__io, this, m__root));\n            i++;\n        }\n    }\n}\n\ntileset_vx4_t::~tileset_vx4_t() {\n    _clean_up();\n}\n\nvoid tileset_vx4_t::_clean_up() {\n    if (m_elements) {\n        for (std::vector<megatile_type_t*>::iterator it = m_elements->begin(); it != m_elements->end(); ++it) {\n            delete *it;\n        }\n        delete m_elements; m_elements = 0;\n    }\n}\n\ntileset_vx4_t::megatile_type_t::megatile_type_t(kaitai::kstream* p__io, tileset_vx4_t* p__parent, tileset_vx4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    m_graphic_ref = 0;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vx4_t::megatile_type_t::_read() {\n    m_graphic_ref = new std::vector<graphic_ref_type_t*>();\n    const int l_graphic_ref = 16;\n    for (int i = 0; i < l_graphic_ref; i++) {\n        m_graphic_ref->push_back(new graphic_ref_type_t(m__io, this, m__root));\n    }\n}\n\ntileset_vx4_t::megatile_type_t::~megatile_type_t() {\n    _clean_up();\n}\n\nvoid tileset_vx4_t::megatile_type_t::_clean_up() {\n    if (m_graphic_ref) {\n        for (std::vector<graphic_ref_type_t*>::iterator it = m_graphic_ref->begin(); it != m_graphic_ref->end(); ++it) {\n            delete *it;\n        }\n        delete m_graphic_ref; m_graphic_ref = 0;\n    }\n}\n\ntileset_vx4_t::graphic_ref_type_t::graphic_ref_type_t(kaitai::kstream* p__io, tileset_vx4_t::megatile_type_t* p__parent, tileset_vx4_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    f_vr4_ref = false;\n    f_horizontal_flip = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid tileset_vx4_t::graphic_ref_type_t::_read() {\n    m_vr4_ref_flip_raw = m__io->read_u2le();\n}\n\ntileset_vx4_t::graphic_ref_type_t::~graphic_ref_type_t() {\n    _clean_up();\n}\n\nvoid tileset_vx4_t::graphic_ref_type_t::_clean_up() {\n}\n\nint32_t tileset_vx4_t::graphic_ref_type_t::vr4_ref() {\n    if (f_vr4_ref)\n        return m_vr4_ref;\n    m_vr4_ref = (vr4_ref_flip_raw() >> 1);\n    f_vr4_ref = true;\n    return m_vr4_ref;\n}\n\nint32_t tileset_vx4_t::graphic_ref_type_t::horizontal_flip() {\n    if (f_horizontal_flip)\n        return m_horizontal_flip;\n    m_horizontal_flip = (vr4_ref_flip_raw() & 1);\n    f_horizontal_flip = true;\n    return m_horizontal_flip;\n}\n"
  },
  {
    "path": "src/kaitai/tileset_vx4.h",
    "content": "#ifndef TILESET_VX4_H_\n#define TILESET_VX4_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass tileset_vx4_t : public kaitai::kstruct {\n\npublic:\n    class megatile_type_t;\n    class graphic_ref_type_t;\n\n    tileset_vx4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, tileset_vx4_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~tileset_vx4_t();\n\n    class megatile_type_t : public kaitai::kstruct {\n\n    public:\n\n        megatile_type_t(kaitai::kstream* p__io, tileset_vx4_t* p__parent = 0, tileset_vx4_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~megatile_type_t();\n\n    private:\n        std::vector<graphic_ref_type_t*>* m_graphic_ref;\n        tileset_vx4_t* m__root;\n        tileset_vx4_t* m__parent;\n\n    public:\n        std::vector<graphic_ref_type_t*>* graphic_ref() const { return m_graphic_ref; }\n        tileset_vx4_t* _root() const { return m__root; }\n        tileset_vx4_t* _parent() const { return m__parent; }\n    };\n\n    class graphic_ref_type_t : public kaitai::kstruct {\n\n    public:\n\n        graphic_ref_type_t(kaitai::kstream* p__io, tileset_vx4_t::megatile_type_t* p__parent = 0, tileset_vx4_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~graphic_ref_type_t();\n\n    private:\n        bool f_vr4_ref;\n        int32_t m_vr4_ref;\n\n    public:\n\n        /**\n         * The index reference in the vx4 data file\n         */\n        int32_t vr4_ref();\n\n    private:\n        bool f_horizontal_flip;\n        int32_t m_horizontal_flip;\n\n    public:\n\n        /**\n         * Flag if the minitile is flipped horizontal\n         */\n        int32_t horizontal_flip();\n\n    private:\n        uint16_t m_vr4_ref_flip_raw;\n        tileset_vx4_t* m__root;\n        tileset_vx4_t::megatile_type_t* m__parent;\n\n    public:\n\n        /**\n         * This is the raw parsed value. Use vr4_ref and horizontal_flip.\n         */\n        uint16_t vr4_ref_flip_raw() const { return m_vr4_ref_flip_raw; }\n        tileset_vx4_t* _root() const { return m__root; }\n        tileset_vx4_t::megatile_type_t* _parent() const { return m__parent; }\n    };\n\nprivate:\n    std::vector<megatile_type_t*>* m_elements;\n    tileset_vx4_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n    std::vector<megatile_type_t*>* elements() const { return m_elements; }\n    tileset_vx4_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // TILESET_VX4_H_\n"
  },
  {
    "path": "src/kaitai/tileset_vx4.ksy",
    "content": "meta:\n  id: tileset_vx4\n  endian: le\n  bit-endian: le\n  \nseq:\n  - id: elements\n    type: megatile_type\n    repeat: eos\n\ntypes:\n  megatile_type:\n    seq:\n      - id: graphic_ref\n        type: graphic_ref_type\n        repeat: expr\n        repeat-expr: 16\n        \n  graphic_ref_type:\n    seq:\n      - id: vr4_ref_flip_raw\n        type: u2\n        doc: |\n          This is the raw parsed value. Use vr4_ref and horizontal_flip.\n        \n    instances:\n      vr4_ref:\n        value: vr4_ref_flip_raw >> 1\n        doc: |\n          The index reference in the vx4 data file\n        \n      horizontal_flip:\n        value: vr4_ref_flip_raw & 1\n        doc: |\n          Flag if the minitile is flipped horizontal"
  },
  {
    "path": "src/kaitai/units_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"units_dat.h\"\n\nunits_dat_t::units_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_flingy = 0;\n    m_subunit1 = 0;\n    m_subunit2 = 0;\n    m_infestation = 0;\n    m_construction_animation = 0;\n    m_unit_direction = 0;\n    m_shield_enable = 0;\n    m_shield_amount = 0;\n    m_hit_points = 0;\n    m_elevation_level = 0;\n    m_unknown = 0;\n    m_rank = 0;\n    m_ai_computer_idle = 0;\n    m_ai_human_idle = 0;\n    m_ai_return_to_idle = 0;\n    m_ai_attack_unit = 0;\n    m_ai_attack_move = 0;\n    m_ground_weapon = 0;\n    m_max_ground_hits = 0;\n    m_air_weapon = 0;\n    m_max_air_hits = 0;\n    m_ai_internal = 0;\n    m_special_ability_flags = 0;\n    m__raw_special_ability_flags = 0;\n    m__io__raw_special_ability_flags = 0;\n    m_target_acquisition_range = 0;\n    m_sight_range = 0;\n    m_armor_upgrade = 0;\n    m_unit_size = 0;\n    m_armor = 0;\n    m_right_click_action = 0;\n    m_ready_sound = 0;\n    m_what_sound_start = 0;\n    m_what_sound_end = 0;\n    m_piss_sound_start = 0;\n    m_piss_sound_end = 0;\n    m_yes_sound_start = 0;\n    m_yes_sound_end = 0;\n    m_staredit_placement_box = 0;\n    m_addon_position = 0;\n    m_unit_dimension = 0;\n    m_portrait = 0;\n    m_mineral_cost = 0;\n    m_vespene_cost = 0;\n    m_build_time = 0;\n    m_requirements = 0;\n    m_staredit_group_flags = 0;\n    m__raw_staredit_group_flags = 0;\n    m__io__raw_staredit_group_flags = 0;\n    m_supply_provided = 0;\n    m_supply_required = 0;\n    m_space_required = 0;\n    m_space_provided = 0;\n    m_build_score = 0;\n    m_destroy_score = 0;\n    m_unit_map_string = 0;\n    m_broodwar_flag = 0;\n    m_staredit_availability_flags = 0;\n    m__raw_staredit_availability_flags = 0;\n    m__io__raw_staredit_availability_flags = 0;\n    f_sc_file_size = false;\n    f_bw_file_size = false;\n    f_file_size = false;\n    f_is_format_sc = false;\n    f_is_format_bw = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::_read() {\n    m_flingy = new std::vector<uint8_t>();\n    const int l_flingy = 228;\n    for (int i = 0; i < l_flingy; i++) {\n        m_flingy->push_back(m__io->read_u1());\n    }\n    m_subunit1 = new std::vector<uint16_t>();\n    const int l_subunit1 = 228;\n    for (int i = 0; i < l_subunit1; i++) {\n        m_subunit1->push_back(m__io->read_u2le());\n    }\n    m_subunit2 = new std::vector<uint16_t>();\n    const int l_subunit2 = 228;\n    for (int i = 0; i < l_subunit2; i++) {\n        m_subunit2->push_back(m__io->read_u2le());\n    }\n    m_infestation = new std::vector<uint16_t>();\n    const int l_infestation = 96;\n    for (int i = 0; i < l_infestation; i++) {\n        m_infestation->push_back(m__io->read_u2le());\n    }\n    m_construction_animation = new std::vector<uint32_t>();\n    const int l_construction_animation = 228;\n    for (int i = 0; i < l_construction_animation; i++) {\n        m_construction_animation->push_back(m__io->read_u4le());\n    }\n    m_unit_direction = new std::vector<uint8_t>();\n    const int l_unit_direction = 228;\n    for (int i = 0; i < l_unit_direction; i++) {\n        m_unit_direction->push_back(m__io->read_u1());\n    }\n    m_shield_enable = new std::vector<uint8_t>();\n    const int l_shield_enable = 228;\n    for (int i = 0; i < l_shield_enable; i++) {\n        m_shield_enable->push_back(m__io->read_u1());\n    }\n    m_shield_amount = new std::vector<uint16_t>();\n    const int l_shield_amount = 228;\n    for (int i = 0; i < l_shield_amount; i++) {\n        m_shield_amount->push_back(m__io->read_u2le());\n    }\n    m_hit_points = new std::vector<hit_points_type_t*>();\n    const int l_hit_points = 228;\n    for (int i = 0; i < l_hit_points; i++) {\n        m_hit_points->push_back(new hit_points_type_t(m__io, this, m__root));\n    }\n    m_elevation_level = new std::vector<uint8_t>();\n    const int l_elevation_level = 228;\n    for (int i = 0; i < l_elevation_level; i++) {\n        m_elevation_level->push_back(m__io->read_u1());\n    }\n    m_unknown = new std::vector<uint8_t>();\n    const int l_unknown = 228;\n    for (int i = 0; i < l_unknown; i++) {\n        m_unknown->push_back(m__io->read_u1());\n    }\n    m_rank = new std::vector<uint8_t>();\n    const int l_rank = 228;\n    for (int i = 0; i < l_rank; i++) {\n        m_rank->push_back(m__io->read_u1());\n    }\n    m_ai_computer_idle = new std::vector<uint8_t>();\n    const int l_ai_computer_idle = 228;\n    for (int i = 0; i < l_ai_computer_idle; i++) {\n        m_ai_computer_idle->push_back(m__io->read_u1());\n    }\n    m_ai_human_idle = new std::vector<uint8_t>();\n    const int l_ai_human_idle = 228;\n    for (int i = 0; i < l_ai_human_idle; i++) {\n        m_ai_human_idle->push_back(m__io->read_u1());\n    }\n    m_ai_return_to_idle = new std::vector<uint8_t>();\n    const int l_ai_return_to_idle = 228;\n    for (int i = 0; i < l_ai_return_to_idle; i++) {\n        m_ai_return_to_idle->push_back(m__io->read_u1());\n    }\n    m_ai_attack_unit = new std::vector<uint8_t>();\n    const int l_ai_attack_unit = 228;\n    for (int i = 0; i < l_ai_attack_unit; i++) {\n        m_ai_attack_unit->push_back(m__io->read_u1());\n    }\n    m_ai_attack_move = new std::vector<uint8_t>();\n    const int l_ai_attack_move = 228;\n    for (int i = 0; i < l_ai_attack_move; i++) {\n        m_ai_attack_move->push_back(m__io->read_u1());\n    }\n    m_ground_weapon = new std::vector<uint8_t>();\n    const int l_ground_weapon = 228;\n    for (int i = 0; i < l_ground_weapon; i++) {\n        m_ground_weapon->push_back(m__io->read_u1());\n    }\n    n_max_ground_hits = true;\n    if (is_format_bw() == true) {\n        n_max_ground_hits = false;\n        m_max_ground_hits = new std::vector<uint8_t>();\n        const int l_max_ground_hits = 228;\n        for (int i = 0; i < l_max_ground_hits; i++) {\n            m_max_ground_hits->push_back(m__io->read_u1());\n        }\n    }\n    m_air_weapon = new std::vector<uint8_t>();\n    const int l_air_weapon = 228;\n    for (int i = 0; i < l_air_weapon; i++) {\n        m_air_weapon->push_back(m__io->read_u1());\n    }\n    n_max_air_hits = true;\n    if (is_format_bw() == true) {\n        n_max_air_hits = false;\n        m_max_air_hits = new std::vector<uint8_t>();\n        const int l_max_air_hits = 228;\n        for (int i = 0; i < l_max_air_hits; i++) {\n            m_max_air_hits->push_back(m__io->read_u1());\n        }\n    }\n    m_ai_internal = new std::vector<uint8_t>();\n    const int l_ai_internal = 228;\n    for (int i = 0; i < l_ai_internal; i++) {\n        m_ai_internal->push_back(m__io->read_u1());\n    }\n    m__raw_special_ability_flags = new std::vector<std::string>();\n    m__io__raw_special_ability_flags = new std::vector<kaitai::kstream*>();\n    m_special_ability_flags = new std::vector<special_ability_flags_type_t*>();\n    const int l_special_ability_flags = 228;\n    for (int i = 0; i < l_special_ability_flags; i++) {\n        m__raw_special_ability_flags->push_back(m__io->read_bytes(4));\n        kaitai::kstream* io__raw_special_ability_flags = new kaitai::kstream(m__raw_special_ability_flags->at(m__raw_special_ability_flags->size() - 1));\n        m__io__raw_special_ability_flags->push_back(io__raw_special_ability_flags);\n        m_special_ability_flags->push_back(new special_ability_flags_type_t(io__raw_special_ability_flags, this, m__root));\n    }\n    m_target_acquisition_range = new std::vector<uint8_t>();\n    const int l_target_acquisition_range = 228;\n    for (int i = 0; i < l_target_acquisition_range; i++) {\n        m_target_acquisition_range->push_back(m__io->read_u1());\n    }\n    m_sight_range = new std::vector<uint8_t>();\n    const int l_sight_range = 228;\n    for (int i = 0; i < l_sight_range; i++) {\n        m_sight_range->push_back(m__io->read_u1());\n    }\n    m_armor_upgrade = new std::vector<uint8_t>();\n    const int l_armor_upgrade = 228;\n    for (int i = 0; i < l_armor_upgrade; i++) {\n        m_armor_upgrade->push_back(m__io->read_u1());\n    }\n    m_unit_size = new std::vector<unit_size_enum_t>();\n    const int l_unit_size = 228;\n    for (int i = 0; i < l_unit_size; i++) {\n        m_unit_size->push_back(static_cast<units_dat_t::unit_size_enum_t>(m__io->read_u1()));\n    }\n    m_armor = new std::vector<uint8_t>();\n    const int l_armor = 228;\n    for (int i = 0; i < l_armor; i++) {\n        m_armor->push_back(m__io->read_u1());\n    }\n    m_right_click_action = new std::vector<right_click_action_enum_t>();\n    const int l_right_click_action = 228;\n    for (int i = 0; i < l_right_click_action; i++) {\n        m_right_click_action->push_back(static_cast<units_dat_t::right_click_action_enum_t>(m__io->read_u1()));\n    }\n    m_ready_sound = new std::vector<uint16_t>();\n    const int l_ready_sound = 106;\n    for (int i = 0; i < l_ready_sound; i++) {\n        m_ready_sound->push_back(m__io->read_u2le());\n    }\n    m_what_sound_start = new std::vector<uint16_t>();\n    const int l_what_sound_start = 228;\n    for (int i = 0; i < l_what_sound_start; i++) {\n        m_what_sound_start->push_back(m__io->read_u2le());\n    }\n    m_what_sound_end = new std::vector<uint16_t>();\n    const int l_what_sound_end = 228;\n    for (int i = 0; i < l_what_sound_end; i++) {\n        m_what_sound_end->push_back(m__io->read_u2le());\n    }\n    m_piss_sound_start = new std::vector<uint16_t>();\n    const int l_piss_sound_start = 106;\n    for (int i = 0; i < l_piss_sound_start; i++) {\n        m_piss_sound_start->push_back(m__io->read_u2le());\n    }\n    m_piss_sound_end = new std::vector<uint16_t>();\n    const int l_piss_sound_end = 106;\n    for (int i = 0; i < l_piss_sound_end; i++) {\n        m_piss_sound_end->push_back(m__io->read_u2le());\n    }\n    m_yes_sound_start = new std::vector<uint16_t>();\n    const int l_yes_sound_start = 106;\n    for (int i = 0; i < l_yes_sound_start; i++) {\n        m_yes_sound_start->push_back(m__io->read_u2le());\n    }\n    m_yes_sound_end = new std::vector<uint16_t>();\n    const int l_yes_sound_end = 106;\n    for (int i = 0; i < l_yes_sound_end; i++) {\n        m_yes_sound_end->push_back(m__io->read_u2le());\n    }\n    m_staredit_placement_box = new std::vector<staredit_placement_box_type_t*>();\n    const int l_staredit_placement_box = 228;\n    for (int i = 0; i < l_staredit_placement_box; i++) {\n        m_staredit_placement_box->push_back(new staredit_placement_box_type_t(m__io, this, m__root));\n    }\n    m_addon_position = new std::vector<addon_position_type_t*>();\n    const int l_addon_position = 96;\n    for (int i = 0; i < l_addon_position; i++) {\n        m_addon_position->push_back(new addon_position_type_t(m__io, this, m__root));\n    }\n    m_unit_dimension = new std::vector<unit_dimension_type_t*>();\n    const int l_unit_dimension = 228;\n    for (int i = 0; i < l_unit_dimension; i++) {\n        m_unit_dimension->push_back(new unit_dimension_type_t(m__io, this, m__root));\n    }\n    m_portrait = new std::vector<uint16_t>();\n    const int l_portrait = 228;\n    for (int i = 0; i < l_portrait; i++) {\n        m_portrait->push_back(m__io->read_u2le());\n    }\n    m_mineral_cost = new std::vector<uint16_t>();\n    const int l_mineral_cost = 228;\n    for (int i = 0; i < l_mineral_cost; i++) {\n        m_mineral_cost->push_back(m__io->read_u2le());\n    }\n    m_vespene_cost = new std::vector<uint16_t>();\n    const int l_vespene_cost = 228;\n    for (int i = 0; i < l_vespene_cost; i++) {\n        m_vespene_cost->push_back(m__io->read_u2le());\n    }\n    m_build_time = new std::vector<uint16_t>();\n    const int l_build_time = 228;\n    for (int i = 0; i < l_build_time; i++) {\n        m_build_time->push_back(m__io->read_u2le());\n    }\n    m_requirements = new std::vector<uint16_t>();\n    const int l_requirements = 228;\n    for (int i = 0; i < l_requirements; i++) {\n        m_requirements->push_back(m__io->read_u2le());\n    }\n    m__raw_staredit_group_flags = new std::vector<std::string>();\n    m__io__raw_staredit_group_flags = new std::vector<kaitai::kstream*>();\n    m_staredit_group_flags = new std::vector<staredit_group_flags_type_t*>();\n    const int l_staredit_group_flags = 228;\n    for (int i = 0; i < l_staredit_group_flags; i++) {\n        m__raw_staredit_group_flags->push_back(m__io->read_bytes(1));\n        kaitai::kstream* io__raw_staredit_group_flags = new kaitai::kstream(m__raw_staredit_group_flags->at(m__raw_staredit_group_flags->size() - 1));\n        m__io__raw_staredit_group_flags->push_back(io__raw_staredit_group_flags);\n        m_staredit_group_flags->push_back(new staredit_group_flags_type_t(io__raw_staredit_group_flags, this, m__root));\n    }\n    m_supply_provided = new std::vector<uint8_t>();\n    const int l_supply_provided = 228;\n    for (int i = 0; i < l_supply_provided; i++) {\n        m_supply_provided->push_back(m__io->read_u1());\n    }\n    m_supply_required = new std::vector<uint8_t>();\n    const int l_supply_required = 228;\n    for (int i = 0; i < l_supply_required; i++) {\n        m_supply_required->push_back(m__io->read_u1());\n    }\n    m_space_required = new std::vector<uint8_t>();\n    const int l_space_required = 228;\n    for (int i = 0; i < l_space_required; i++) {\n        m_space_required->push_back(m__io->read_u1());\n    }\n    m_space_provided = new std::vector<uint8_t>();\n    const int l_space_provided = 228;\n    for (int i = 0; i < l_space_provided; i++) {\n        m_space_provided->push_back(m__io->read_u1());\n    }\n    m_build_score = new std::vector<uint16_t>();\n    const int l_build_score = 228;\n    for (int i = 0; i < l_build_score; i++) {\n        m_build_score->push_back(m__io->read_u2le());\n    }\n    m_destroy_score = new std::vector<uint16_t>();\n    const int l_destroy_score = 228;\n    for (int i = 0; i < l_destroy_score; i++) {\n        m_destroy_score->push_back(m__io->read_u2le());\n    }\n    m_unit_map_string = new std::vector<uint16_t>();\n    const int l_unit_map_string = 228;\n    for (int i = 0; i < l_unit_map_string; i++) {\n        m_unit_map_string->push_back(m__io->read_u2le());\n    }\n    n_broodwar_flag = true;\n    if (is_format_bw() == true) {\n        n_broodwar_flag = false;\n        m_broodwar_flag = new std::vector<uint8_t>();\n        const int l_broodwar_flag = 228;\n        for (int i = 0; i < l_broodwar_flag; i++) {\n            m_broodwar_flag->push_back(m__io->read_u1());\n        }\n    }\n    m__raw_staredit_availability_flags = new std::vector<std::string>();\n    m__io__raw_staredit_availability_flags = new std::vector<kaitai::kstream*>();\n    m_staredit_availability_flags = new std::vector<staredit_availability_flags_type_t*>();\n    const int l_staredit_availability_flags = 228;\n    for (int i = 0; i < l_staredit_availability_flags; i++) {\n        m__raw_staredit_availability_flags->push_back(m__io->read_bytes(2));\n        kaitai::kstream* io__raw_staredit_availability_flags = new kaitai::kstream(m__raw_staredit_availability_flags->at(m__raw_staredit_availability_flags->size() - 1));\n        m__io__raw_staredit_availability_flags->push_back(io__raw_staredit_availability_flags);\n        m_staredit_availability_flags->push_back(new staredit_availability_flags_type_t(io__raw_staredit_availability_flags, this, m__root));\n    }\n}\n\nunits_dat_t::~units_dat_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::_clean_up() {\n    if (m_flingy) {\n        delete m_flingy; m_flingy = 0;\n    }\n    if (m_subunit1) {\n        delete m_subunit1; m_subunit1 = 0;\n    }\n    if (m_subunit2) {\n        delete m_subunit2; m_subunit2 = 0;\n    }\n    if (m_infestation) {\n        delete m_infestation; m_infestation = 0;\n    }\n    if (m_construction_animation) {\n        delete m_construction_animation; m_construction_animation = 0;\n    }\n    if (m_unit_direction) {\n        delete m_unit_direction; m_unit_direction = 0;\n    }\n    if (m_shield_enable) {\n        delete m_shield_enable; m_shield_enable = 0;\n    }\n    if (m_shield_amount) {\n        delete m_shield_amount; m_shield_amount = 0;\n    }\n    if (m_hit_points) {\n        for (std::vector<hit_points_type_t*>::iterator it = m_hit_points->begin(); it != m_hit_points->end(); ++it) {\n            delete *it;\n        }\n        delete m_hit_points; m_hit_points = 0;\n    }\n    if (m_elevation_level) {\n        delete m_elevation_level; m_elevation_level = 0;\n    }\n    if (m_unknown) {\n        delete m_unknown; m_unknown = 0;\n    }\n    if (m_rank) {\n        delete m_rank; m_rank = 0;\n    }\n    if (m_ai_computer_idle) {\n        delete m_ai_computer_idle; m_ai_computer_idle = 0;\n    }\n    if (m_ai_human_idle) {\n        delete m_ai_human_idle; m_ai_human_idle = 0;\n    }\n    if (m_ai_return_to_idle) {\n        delete m_ai_return_to_idle; m_ai_return_to_idle = 0;\n    }\n    if (m_ai_attack_unit) {\n        delete m_ai_attack_unit; m_ai_attack_unit = 0;\n    }\n    if (m_ai_attack_move) {\n        delete m_ai_attack_move; m_ai_attack_move = 0;\n    }\n    if (m_ground_weapon) {\n        delete m_ground_weapon; m_ground_weapon = 0;\n    }\n    if (!n_max_ground_hits) {\n        if (m_max_ground_hits) {\n            delete m_max_ground_hits; m_max_ground_hits = 0;\n        }\n    }\n    if (m_air_weapon) {\n        delete m_air_weapon; m_air_weapon = 0;\n    }\n    if (!n_max_air_hits) {\n        if (m_max_air_hits) {\n            delete m_max_air_hits; m_max_air_hits = 0;\n        }\n    }\n    if (m_ai_internal) {\n        delete m_ai_internal; m_ai_internal = 0;\n    }\n    if (m__raw_special_ability_flags) {\n        delete m__raw_special_ability_flags; m__raw_special_ability_flags = 0;\n    }\n    if (m__io__raw_special_ability_flags) {\n        for (std::vector<kaitai::kstream*>::iterator it = m__io__raw_special_ability_flags->begin(); it != m__io__raw_special_ability_flags->end(); ++it) {\n            delete *it;\n        }\n        delete m__io__raw_special_ability_flags; m__io__raw_special_ability_flags = 0;\n    }\n    if (m_special_ability_flags) {\n        for (std::vector<special_ability_flags_type_t*>::iterator it = m_special_ability_flags->begin(); it != m_special_ability_flags->end(); ++it) {\n            delete *it;\n        }\n        delete m_special_ability_flags; m_special_ability_flags = 0;\n    }\n    if (m_target_acquisition_range) {\n        delete m_target_acquisition_range; m_target_acquisition_range = 0;\n    }\n    if (m_sight_range) {\n        delete m_sight_range; m_sight_range = 0;\n    }\n    if (m_armor_upgrade) {\n        delete m_armor_upgrade; m_armor_upgrade = 0;\n    }\n    if (m_unit_size) {\n        delete m_unit_size; m_unit_size = 0;\n    }\n    if (m_armor) {\n        delete m_armor; m_armor = 0;\n    }\n    if (m_right_click_action) {\n        delete m_right_click_action; m_right_click_action = 0;\n    }\n    if (m_ready_sound) {\n        delete m_ready_sound; m_ready_sound = 0;\n    }\n    if (m_what_sound_start) {\n        delete m_what_sound_start; m_what_sound_start = 0;\n    }\n    if (m_what_sound_end) {\n        delete m_what_sound_end; m_what_sound_end = 0;\n    }\n    if (m_piss_sound_start) {\n        delete m_piss_sound_start; m_piss_sound_start = 0;\n    }\n    if (m_piss_sound_end) {\n        delete m_piss_sound_end; m_piss_sound_end = 0;\n    }\n    if (m_yes_sound_start) {\n        delete m_yes_sound_start; m_yes_sound_start = 0;\n    }\n    if (m_yes_sound_end) {\n        delete m_yes_sound_end; m_yes_sound_end = 0;\n    }\n    if (m_staredit_placement_box) {\n        for (std::vector<staredit_placement_box_type_t*>::iterator it = m_staredit_placement_box->begin(); it != m_staredit_placement_box->end(); ++it) {\n            delete *it;\n        }\n        delete m_staredit_placement_box; m_staredit_placement_box = 0;\n    }\n    if (m_addon_position) {\n        for (std::vector<addon_position_type_t*>::iterator it = m_addon_position->begin(); it != m_addon_position->end(); ++it) {\n            delete *it;\n        }\n        delete m_addon_position; m_addon_position = 0;\n    }\n    if (m_unit_dimension) {\n        for (std::vector<unit_dimension_type_t*>::iterator it = m_unit_dimension->begin(); it != m_unit_dimension->end(); ++it) {\n            delete *it;\n        }\n        delete m_unit_dimension; m_unit_dimension = 0;\n    }\n    if (m_portrait) {\n        delete m_portrait; m_portrait = 0;\n    }\n    if (m_mineral_cost) {\n        delete m_mineral_cost; m_mineral_cost = 0;\n    }\n    if (m_vespene_cost) {\n        delete m_vespene_cost; m_vespene_cost = 0;\n    }\n    if (m_build_time) {\n        delete m_build_time; m_build_time = 0;\n    }\n    if (m_requirements) {\n        delete m_requirements; m_requirements = 0;\n    }\n    if (m__raw_staredit_group_flags) {\n        delete m__raw_staredit_group_flags; m__raw_staredit_group_flags = 0;\n    }\n    if (m__io__raw_staredit_group_flags) {\n        for (std::vector<kaitai::kstream*>::iterator it = m__io__raw_staredit_group_flags->begin(); it != m__io__raw_staredit_group_flags->end(); ++it) {\n            delete *it;\n        }\n        delete m__io__raw_staredit_group_flags; m__io__raw_staredit_group_flags = 0;\n    }\n    if (m_staredit_group_flags) {\n        for (std::vector<staredit_group_flags_type_t*>::iterator it = m_staredit_group_flags->begin(); it != m_staredit_group_flags->end(); ++it) {\n            delete *it;\n        }\n        delete m_staredit_group_flags; m_staredit_group_flags = 0;\n    }\n    if (m_supply_provided) {\n        delete m_supply_provided; m_supply_provided = 0;\n    }\n    if (m_supply_required) {\n        delete m_supply_required; m_supply_required = 0;\n    }\n    if (m_space_required) {\n        delete m_space_required; m_space_required = 0;\n    }\n    if (m_space_provided) {\n        delete m_space_provided; m_space_provided = 0;\n    }\n    if (m_build_score) {\n        delete m_build_score; m_build_score = 0;\n    }\n    if (m_destroy_score) {\n        delete m_destroy_score; m_destroy_score = 0;\n    }\n    if (m_unit_map_string) {\n        delete m_unit_map_string; m_unit_map_string = 0;\n    }\n    if (!n_broodwar_flag) {\n        if (m_broodwar_flag) {\n            delete m_broodwar_flag; m_broodwar_flag = 0;\n        }\n    }\n    if (m__raw_staredit_availability_flags) {\n        delete m__raw_staredit_availability_flags; m__raw_staredit_availability_flags = 0;\n    }\n    if (m__io__raw_staredit_availability_flags) {\n        for (std::vector<kaitai::kstream*>::iterator it = m__io__raw_staredit_availability_flags->begin(); it != m__io__raw_staredit_availability_flags->end(); ++it) {\n            delete *it;\n        }\n        delete m__io__raw_staredit_availability_flags; m__io__raw_staredit_availability_flags = 0;\n    }\n    if (m_staredit_availability_flags) {\n        for (std::vector<staredit_availability_flags_type_t*>::iterator it = m_staredit_availability_flags->begin(); it != m_staredit_availability_flags->end(); ++it) {\n            delete *it;\n        }\n        delete m_staredit_availability_flags; m_staredit_availability_flags = 0;\n    }\n}\n\nunits_dat_t::staredit_group_flags_type_t::staredit_group_flags_type_t(kaitai::kstream* p__io, units_dat_t* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::staredit_group_flags_type_t::_read() {\n    m_zerg = m__io->read_bits_int_le(1);\n    m_terran = m__io->read_bits_int_le(1);\n    m_protoss = m__io->read_bits_int_le(1);\n    m_men = m__io->read_bits_int_le(1);\n    m_building = m__io->read_bits_int_le(1);\n    m_factory = m__io->read_bits_int_le(1);\n    m_independent = m__io->read_bits_int_le(1);\n    m_neutral = m__io->read_bits_int_le(1);\n}\n\nunits_dat_t::staredit_group_flags_type_t::~staredit_group_flags_type_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::staredit_group_flags_type_t::_clean_up() {\n}\n\nunits_dat_t::hit_points_type_t::hit_points_type_t(kaitai::kstream* p__io, units_dat_t* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n    f_hitpoints = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::hit_points_type_t::_read() {\n    m_hitpoints0 = m__io->read_u2be();\n    m_hitpoints1 = m__io->read_u2be();\n}\n\nunits_dat_t::hit_points_type_t::~hit_points_type_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::hit_points_type_t::_clean_up() {\n}\n\nint32_t units_dat_t::hit_points_type_t::hitpoints() {\n    if (f_hitpoints)\n        return m_hitpoints;\n    m_hitpoints = (hitpoints0() + hitpoints1());\n    f_hitpoints = true;\n    return m_hitpoints;\n}\n\nunits_dat_t::addon_position_type_t::addon_position_type_t(kaitai::kstream* p__io, units_dat_t* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::addon_position_type_t::_read() {\n    m_horizontal = m__io->read_u2le();\n    m_vertical = m__io->read_u2le();\n}\n\nunits_dat_t::addon_position_type_t::~addon_position_type_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::addon_position_type_t::_clean_up() {\n}\n\nunits_dat_t::special_ability_flags_type_t::special_ability_flags_type_t(kaitai::kstream* p__io, units_dat_t* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::special_ability_flags_type_t::_read() {\n    m_building = m__io->read_bits_int_le(1);\n    m_addon = m__io->read_bits_int_le(1);\n    m_flyer = m__io->read_bits_int_le(1);\n    m_resourceminer = m__io->read_bits_int_le(1);\n    m_subunit = m__io->read_bits_int_le(1);\n    m_flyingbuilding = m__io->read_bits_int_le(1);\n    m_hero = m__io->read_bits_int_le(1);\n    m_regenerate = m__io->read_bits_int_le(1);\n    m_animatedidle = m__io->read_bits_int_le(1);\n    m_cloakable = m__io->read_bits_int_le(1);\n    m_twounitsinoneegg = m__io->read_bits_int_le(1);\n    m_singleentity = m__io->read_bits_int_le(1);\n    m_resourcedepot = m__io->read_bits_int_le(1);\n    m_resourcecontainter = m__io->read_bits_int_le(1);\n    m_robotic = m__io->read_bits_int_le(1);\n    m_detector = m__io->read_bits_int_le(1);\n    m_organic = m__io->read_bits_int_le(1);\n    m_requirescreep = m__io->read_bits_int_le(1);\n    m_unused = m__io->read_bits_int_le(1);\n    m_requirespsi = m__io->read_bits_int_le(1);\n    m_burrowable = m__io->read_bits_int_le(1);\n    m_spellcaster = m__io->read_bits_int_le(1);\n    m_permanentcloak = m__io->read_bits_int_le(1);\n    m_pickupitem = m__io->read_bits_int_le(1);\n    m_ignoresupplycheck = m__io->read_bits_int_le(1);\n    m_usemediumoverlays = m__io->read_bits_int_le(1);\n    m_uselargeoverlays = m__io->read_bits_int_le(1);\n    m_battlereactions = m__io->read_bits_int_le(1);\n    m_fullautoattack = m__io->read_bits_int_le(1);\n    m_invincible = m__io->read_bits_int_le(1);\n    m_mechanical = m__io->read_bits_int_le(1);\n    m_producesunits = m__io->read_bits_int_le(1);\n}\n\nunits_dat_t::special_ability_flags_type_t::~special_ability_flags_type_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::special_ability_flags_type_t::_clean_up() {\n}\n\nunits_dat_t::staredit_placement_box_type_t::staredit_placement_box_type_t(kaitai::kstream* p__io, units_dat_t* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::staredit_placement_box_type_t::_read() {\n    m_width = m__io->read_u2le();\n    m_height = m__io->read_u2le();\n}\n\nunits_dat_t::staredit_placement_box_type_t::~staredit_placement_box_type_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::staredit_placement_box_type_t::_clean_up() {\n}\n\nunits_dat_t::unit_dimension_type_t::unit_dimension_type_t(kaitai::kstream* p__io, units_dat_t* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::unit_dimension_type_t::_read() {\n    m_left = m__io->read_u2le();\n    m_up = m__io->read_u2le();\n    m_right = m__io->read_u2le();\n    m_down = m__io->read_u2le();\n}\n\nunits_dat_t::unit_dimension_type_t::~unit_dimension_type_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::unit_dimension_type_t::_clean_up() {\n}\n\nunits_dat_t::staredit_availability_flags_type_t::staredit_availability_flags_type_t(kaitai::kstream* p__io, units_dat_t* p__parent, units_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = p__root;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid units_dat_t::staredit_availability_flags_type_t::_read() {\n    m_non_neutral = m__io->read_bits_int_le(1);\n    m_unit_listing = m__io->read_bits_int_le(1);\n    m_mission_briefing = m__io->read_bits_int_le(1);\n    m_player_settings = m__io->read_bits_int_le(1);\n    m_all_races = m__io->read_bits_int_le(1);\n    m_set_doodad_state = m__io->read_bits_int_le(1);\n    m_non_location_triggers = m__io->read_bits_int_le(1);\n    m_unit_hero_settings = m__io->read_bits_int_le(1);\n    m_location_triggers = m__io->read_bits_int_le(1);\n    m_brood_war_only = m__io->read_bits_int_le(1);\n    m__unnamed10 = m__io->read_bits_int_le(6);\n}\n\nunits_dat_t::staredit_availability_flags_type_t::~staredit_availability_flags_type_t() {\n    _clean_up();\n}\n\nvoid units_dat_t::staredit_availability_flags_type_t::_clean_up() {\n}\n\nint32_t units_dat_t::sc_file_size() {\n    if (f_sc_file_size)\n        return m_sc_file_size;\n    m_sc_file_size = 19192;\n    f_sc_file_size = true;\n    return m_sc_file_size;\n}\n\nint32_t units_dat_t::bw_file_size() {\n    if (f_bw_file_size)\n        return m_bw_file_size;\n    m_bw_file_size = 19876;\n    f_bw_file_size = true;\n    return m_bw_file_size;\n}\n\nint32_t units_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n\nbool units_dat_t::is_format_sc() {\n    if (f_is_format_sc)\n        return m_is_format_sc;\n    m_is_format_sc = ((file_size() == sc_file_size()) ? (true) : (false));\n    f_is_format_sc = true;\n    return m_is_format_sc;\n}\n\nbool units_dat_t::is_format_bw() {\n    if (f_is_format_bw)\n        return m_is_format_bw;\n    m_is_format_bw = ((file_size() == bw_file_size()) ? (true) : (false));\n    f_is_format_bw = true;\n    return m_is_format_bw;\n}\n"
  },
  {
    "path": "src/kaitai/units_dat.h",
    "content": "#ifndef UNITS_DAT_H_\n#define UNITS_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass units_dat_t : public kaitai::kstruct {\n\npublic:\n    class staredit_group_flags_type_t;\n    class hit_points_type_t;\n    class addon_position_type_t;\n    class special_ability_flags_type_t;\n    class staredit_placement_box_type_t;\n    class unit_dimension_type_t;\n    class staredit_availability_flags_type_t;\n\n    enum unit_size_enum_t {\n        UNIT_SIZE_ENUM_INDENDENT = 0,\n        UNIT_SIZE_ENUM_SMALL = 1,\n        UNIT_SIZE_ENUM_MEDIUM = 2,\n        UNIT_SIZE_ENUM_LARGE = 3\n    };\n\n    enum right_click_action_enum_t {\n        RIGHT_CLICK_ACTION_ENUM_NO_COMMANDS_AUO_ATTACK = 0,\n        RIGHT_CLICK_ACTION_ENUM_NORMAL_MOVEMENT_NORMAL_ATTACK = 1,\n        RIGHT_CLICK_ACTION_ENUM_NORMAL_MOVEMENT_NO_ATTACK = 2,\n        RIGHT_CLICK_ACTION_ENUM_NO_MOVEMENT_NORMAL_ATTACK = 3,\n        RIGHT_CLICK_ACTION_ENUM_HARVEST = 4,\n        RIGHT_CLICK_ACTION_ENUM_HARVEST_REPAIR = 5,\n        RIGHT_CLICK_ACTION_ENUM_NOTHING_WITH_INDICATOR = 6\n    };\n\n    units_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, units_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~units_dat_t();\n\n    /**\n     * zerg: Unit is from race \"Zerg\"\n     * terran: Unit is from race \"Terran\"\n     * protoss: Unit is from race \"Protoss\"\n     * men: Unit is a \"Men\"-type unit for triggers.\n     * building: Unit is a \"Building\"-type unit for triggers.\n     * factory: Unit is a \"Factory\"-type unit for triggers.\n     * independent: Unit is treated as an Independent unit (abandoned unit type).\n     * neutral: Unit is treated as a Neutral unit.\n     */\n\n    class staredit_group_flags_type_t : public kaitai::kstruct {\n\n    public:\n\n        staredit_group_flags_type_t(kaitai::kstream* p__io, units_dat_t* p__parent = 0, units_dat_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~staredit_group_flags_type_t();\n\n    private:\n        bool m_zerg;\n        bool m_terran;\n        bool m_protoss;\n        bool m_men;\n        bool m_building;\n        bool m_factory;\n        bool m_independent;\n        bool m_neutral;\n        units_dat_t* m__root;\n        units_dat_t* m__parent;\n\n    public:\n        bool zerg() const { return m_zerg; }\n        bool terran() const { return m_terran; }\n        bool protoss() const { return m_protoss; }\n        bool men() const { return m_men; }\n        bool building() const { return m_building; }\n        bool factory() const { return m_factory; }\n        bool independent() const { return m_independent; }\n        bool neutral() const { return m_neutral; }\n        units_dat_t* _root() const { return m__root; }\n        units_dat_t* _parent() const { return m__parent; }\n    };\n\n    class hit_points_type_t : public kaitai::kstruct {\n\n    public:\n\n        hit_points_type_t(kaitai::kstream* p__io, units_dat_t* p__parent = 0, units_dat_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~hit_points_type_t();\n\n    private:\n        bool f_hitpoints;\n        int32_t m_hitpoints;\n\n    public:\n        int32_t hitpoints();\n\n    private:\n        uint16_t m_hitpoints0;\n        uint16_t m_hitpoints1;\n        units_dat_t* m__root;\n        units_dat_t* m__parent;\n\n    public:\n        uint16_t hitpoints0() const { return m_hitpoints0; }\n        uint16_t hitpoints1() const { return m_hitpoints1; }\n        units_dat_t* _root() const { return m__root; }\n        units_dat_t* _parent() const { return m__parent; }\n    };\n\n    class addon_position_type_t : public kaitai::kstruct {\n\n    public:\n\n        addon_position_type_t(kaitai::kstream* p__io, units_dat_t* p__parent = 0, units_dat_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~addon_position_type_t();\n\n    private:\n        uint16_t m_horizontal;\n        uint16_t m_vertical;\n        units_dat_t* m__root;\n        units_dat_t* m__parent;\n\n    public:\n        uint16_t horizontal() const { return m_horizontal; }\n        uint16_t vertical() const { return m_vertical; }\n        units_dat_t* _root() const { return m__root; }\n        units_dat_t* _parent() const { return m__parent; }\n    };\n\n    /**\n     * building: Unit is considered as a building for targeting purposes, and affects Addons-related properties. Also allows for other units to be built/trained 'inside' the unit and makes the unit placement dependent on the \"Placement Box\" property instead of the \"Unit Dimensions\".\n     * addon: Makes the building placeable in a special way, dependent on the main building. If unchecked, the building will still use the standard way of placing the addon, but after lift-off, it will be inaccessible.\n     * flyer: If unchecked, the unit is targeted by Ground weapons. If checked, unit can be targeted by Air weapons. It also makes the unit \"fly\" in the way that it chooses the shortest path to its destination, moving over terrain and other units.\n     * resourceminer: Unit can gather/return resources. Does NOT affect building construction abilities (except a tiny Drone glitch if you cancel a building morph). Requires a .LOO file pointed from the \"Overlay 3\" property in Images.dat to work. Vespene Gas harvesting seems good for all units, but Minerals may cause crashes, depending on the unit you use (e.g. Marine is OK, but the Firebat will crash)\n     * subunit: Makes the unit a \"sub-unit\", i.e. allows it to be a part of another unit (like the tank turret to the tank body) through the Subunit property (see Graphics tab). A non-subunit-type unit used as a subunit will crash the game. To have a sub-unit properly placed on a unit, you also require altering the images.dat properties of the base sprite as well as certain other settings. Expect crashes more than often while working with this property.\n     * flyingbuilding: Allows/Disallows the unit to be in the \"In Transit\" (or \"Flying\") state both in the game and in StarEdit, but it will crash if the unit does not have a Lift-off and Landing animations (in Iscript.bin). Does not affect buttons available for the unit.\n     * hero: Unit has all its upgrades researched from the start and receives a white wireframe box (instead of the standard blue one). If a unit is also a spellcaster, it will have 250 energy points, regardless if there is an energy upgrade for it or not.\n     * regenerate: Unit will slowly regain Hit Points, until its full HP capacity.\n     * animatedidle:\n     * cloakable: Allows/Disallows the unit to use the Cloak technology. It does NOT give/remove the \"Cloak\" button but allows the unit to display the \"Group (Cloakers)\" button set when selected in a group.\n     * twounitsinoneegg: 2 units will come out of one Zerg Egg instead of just one. The cost for morphing will NOT be doubled, but the amount of the used supplies will equal 2 times the normal amount. To accomplish the full effect you will also have to add a \"Construction\" graphics and set a \"Landing Dust\" overlay to it.\n     * singleentity: Unit cannot be selected in a group, but only as a single unit. Unit cannot be selected by dragging a selection box, by a SHIFT-Click nor a double-click.\n     * resourcedepot: Makes a building (and ONLY a building) a place workers can return resources to. Also makes it impossible to place/land the building next to a unit with the \"Resource Container\" property.\n     * resourcecontainter: Unit does not generate an error message if targeted for Gathering by a worker. Allows/Disallows to set unit's resources capacity in StarEdit, but does not make a unit other than original resource actually store resources in-game. Unchecked, makes the original resources capacity equal to 0, although workers will still try to harvest it. Prevents \"Resource Depots\" from being located next to it.\n     * robotic: Unit is treated as a robotic-type target for weapons and spells (e.g. it cannot be targeted with Spawn Broodlings)\n     * detector: Unit can detect cloaked enemy units and receives the \"Detector\" title under its name.\n     * organic: Unit is treated as an organic-type target for weapons and spells (e.g. Maelstrom).\n     * requirescreep: Building MUST be built on creep. It will also get a creep outline around it.\n     * unused:\n     * requirespsi: Unit must be built within a PSI field, like that produced by pylons. If it is not within a PSI field, it will become \"Disabled\" and not function. Can be given to any unit. You can also disable it on Protoss buildings so they can be built anywhere.\n     * burrowable: Allows/Disallows the unit to use the Burrow technology. It does NOT give/remove the \"Burrow\" button.\n     * spellcaster: Unit receives a mana bar and will slowly regain mana points through time. Combined with the Permanent Cloak property, will prevent unit from regaining mana.\n     * permanentcloak: Unit is constantly cloaked. If the unit is also a Spellcaster, giving this property will make it lose mana until 0.\n     * pickupitem: Related to powerups. Not completely understood.\n     * ignoresupplycheck: Even if you don't have the supply available to build the unit, the engine will still build it and add that to your supply.\n     * usemediumoverlays: Unit will use medium spell overlay graphics.\n     * uselargeoverlays: Unit will use large spell overlay graphics.\n     * battlereactions: Unit will show battle reactions,i.e. if it sees an enemy it will move to it and attack, if it is attacked by an unreachable enemy (e.g. an Air unit and it doesn't have an Air weapon) it will run away. Works ONLY if the unit's Idle AI Orders are set to Guard.\n     * fullautoattack: Unit will attack any enemy that enters its firing range. If unchecked, unit will attack the enemy ONLY if it is facing its direction, e.g. because it has an animated idle state.\n     * invincible: Unit cannot be a target of any sort of weapons or spells. It also hides the unit's Hit Points value.\n     * mechanical: Unit is treated as a mechanical-type target for weapons and spells (e.g. Lockdown). It can also be repaired by SCVs.\n     * producesunits:\n     */\n\n    class special_ability_flags_type_t : public kaitai::kstruct {\n\n    public:\n\n        special_ability_flags_type_t(kaitai::kstream* p__io, units_dat_t* p__parent = 0, units_dat_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~special_ability_flags_type_t();\n\n    private:\n        bool m_building;\n        bool m_addon;\n        bool m_flyer;\n        bool m_resourceminer;\n        bool m_subunit;\n        bool m_flyingbuilding;\n        bool m_hero;\n        bool m_regenerate;\n        bool m_animatedidle;\n        bool m_cloakable;\n        bool m_twounitsinoneegg;\n        bool m_singleentity;\n        bool m_resourcedepot;\n        bool m_resourcecontainter;\n        bool m_robotic;\n        bool m_detector;\n        bool m_organic;\n        bool m_requirescreep;\n        bool m_unused;\n        bool m_requirespsi;\n        bool m_burrowable;\n        bool m_spellcaster;\n        bool m_permanentcloak;\n        bool m_pickupitem;\n        bool m_ignoresupplycheck;\n        bool m_usemediumoverlays;\n        bool m_uselargeoverlays;\n        bool m_battlereactions;\n        bool m_fullautoattack;\n        bool m_invincible;\n        bool m_mechanical;\n        bool m_producesunits;\n        units_dat_t* m__root;\n        units_dat_t* m__parent;\n\n    public:\n        bool building() const { return m_building; }\n        bool addon() const { return m_addon; }\n        bool flyer() const { return m_flyer; }\n        bool resourceminer() const { return m_resourceminer; }\n        bool subunit() const { return m_subunit; }\n        bool flyingbuilding() const { return m_flyingbuilding; }\n        bool hero() const { return m_hero; }\n        bool regenerate() const { return m_regenerate; }\n        bool animatedidle() const { return m_animatedidle; }\n        bool cloakable() const { return m_cloakable; }\n        bool twounitsinoneegg() const { return m_twounitsinoneegg; }\n        bool singleentity() const { return m_singleentity; }\n        bool resourcedepot() const { return m_resourcedepot; }\n        bool resourcecontainter() const { return m_resourcecontainter; }\n        bool robotic() const { return m_robotic; }\n        bool detector() const { return m_detector; }\n        bool organic() const { return m_organic; }\n        bool requirescreep() const { return m_requirescreep; }\n        bool unused() const { return m_unused; }\n        bool requirespsi() const { return m_requirespsi; }\n        bool burrowable() const { return m_burrowable; }\n        bool spellcaster() const { return m_spellcaster; }\n        bool permanentcloak() const { return m_permanentcloak; }\n        bool pickupitem() const { return m_pickupitem; }\n        bool ignoresupplycheck() const { return m_ignoresupplycheck; }\n        bool usemediumoverlays() const { return m_usemediumoverlays; }\n        bool uselargeoverlays() const { return m_uselargeoverlays; }\n        bool battlereactions() const { return m_battlereactions; }\n        bool fullautoattack() const { return m_fullautoattack; }\n        bool invincible() const { return m_invincible; }\n        bool mechanical() const { return m_mechanical; }\n        bool producesunits() const { return m_producesunits; }\n        units_dat_t* _root() const { return m__root; }\n        units_dat_t* _parent() const { return m__parent; }\n    };\n\n    class staredit_placement_box_type_t : public kaitai::kstruct {\n\n    public:\n\n        staredit_placement_box_type_t(kaitai::kstream* p__io, units_dat_t* p__parent = 0, units_dat_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~staredit_placement_box_type_t();\n\n    private:\n        uint16_t m_width;\n        uint16_t m_height;\n        units_dat_t* m__root;\n        units_dat_t* m__parent;\n\n    public:\n        uint16_t width() const { return m_width; }\n        uint16_t height() const { return m_height; }\n        units_dat_t* _root() const { return m__root; }\n        units_dat_t* _parent() const { return m__parent; }\n    };\n\n    class unit_dimension_type_t : public kaitai::kstruct {\n\n    public:\n\n        unit_dimension_type_t(kaitai::kstream* p__io, units_dat_t* p__parent = 0, units_dat_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~unit_dimension_type_t();\n\n    private:\n        uint16_t m_left;\n        uint16_t m_up;\n        uint16_t m_right;\n        uint16_t m_down;\n        units_dat_t* m__root;\n        units_dat_t* m__parent;\n\n    public:\n        uint16_t left() const { return m_left; }\n        uint16_t up() const { return m_up; }\n        uint16_t right() const { return m_right; }\n        uint16_t down() const { return m_down; }\n        units_dat_t* _root() const { return m__root; }\n        units_dat_t* _parent() const { return m__parent; }\n    };\n\n    /**\n     * non_neutral: Unit belongs to a 1-8 Player, takes its corresponding color and appears in the player's corresponding menu in the unit listing on the left. If unchecked, the unit belongs to the 12th Player (neutral), takes the dark aqua color and appears under the \"Neutral\" menu in the unit listing.\n     * unit_listing: Unit is availabe in the unit listing on the left and in the Brush Palette.\n     * mission_briefing: Unit's portrait is available in Mission Briefing.\n     * player_settings: Unit is available in the Player Settings.\n     * all_races: Unit is available for all races in the unit list in StarEdit.\n     * set_doodad_state: Unit is available for the \"Set Doodad State\" trigger.\n     * non_location_triggers: Unit appears in the unit selection box when using Non-locational triggers (Remove, Kill etc.)\n     * unit_hero_settings: Unit is available in Unit&Hero Settings.\n     * location_triggers: Unit appears in the unit selection box when using locational triggers (Remove at, Kill at etc.). Even if unchecked, the unit WILL appear for selection when using the \"Create at\" trigger action.\n     * brood_war_only: Unit is available only if BroodWar Expansion is installed.\n     */\n\n    class staredit_availability_flags_type_t : public kaitai::kstruct {\n\n    public:\n\n        staredit_availability_flags_type_t(kaitai::kstream* p__io, units_dat_t* p__parent = 0, units_dat_t* p__root = 0);\n\n    private:\n        void _read();\n        void _clean_up();\n\n    public:\n        ~staredit_availability_flags_type_t();\n\n    private:\n        bool m_non_neutral;\n        bool m_unit_listing;\n        bool m_mission_briefing;\n        bool m_player_settings;\n        bool m_all_races;\n        bool m_set_doodad_state;\n        bool m_non_location_triggers;\n        bool m_unit_hero_settings;\n        bool m_location_triggers;\n        bool m_brood_war_only;\n        uint64_t m__unnamed10;\n        units_dat_t* m__root;\n        units_dat_t* m__parent;\n\n    public:\n        bool non_neutral() const { return m_non_neutral; }\n        bool unit_listing() const { return m_unit_listing; }\n        bool mission_briefing() const { return m_mission_briefing; }\n        bool player_settings() const { return m_player_settings; }\n        bool all_races() const { return m_all_races; }\n        bool set_doodad_state() const { return m_set_doodad_state; }\n        bool non_location_triggers() const { return m_non_location_triggers; }\n        bool unit_hero_settings() const { return m_unit_hero_settings; }\n        bool location_triggers() const { return m_location_triggers; }\n        bool brood_war_only() const { return m_brood_war_only; }\n        uint64_t _unnamed10() const { return m__unnamed10; }\n        units_dat_t* _root() const { return m__root; }\n        units_dat_t* _parent() const { return m__parent; }\n    };\n\nprivate:\n    bool f_sc_file_size;\n    int32_t m_sc_file_size;\n\npublic:\n    int32_t sc_file_size();\n\nprivate:\n    bool f_bw_file_size;\n    int32_t m_bw_file_size;\n\npublic:\n    int32_t bw_file_size();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    bool f_is_format_sc;\n    bool m_is_format_sc;\n\npublic:\n\n    /**\n     * This is true if plain starcraft units.dat is found\n     */\n    bool is_format_sc();\n\nprivate:\n    bool f_is_format_bw;\n    bool m_is_format_bw;\n\npublic:\n\n    /**\n     * This is true if broodwar or remastered units.dat is found\n     */\n    bool is_format_bw();\n\nprivate:\n    std::vector<uint8_t>* m_flingy;\n    std::vector<uint16_t>* m_subunit1;\n    std::vector<uint16_t>* m_subunit2;\n    std::vector<uint16_t>* m_infestation;\n    std::vector<uint32_t>* m_construction_animation;\n    std::vector<uint8_t>* m_unit_direction;\n    std::vector<uint8_t>* m_shield_enable;\n    std::vector<uint16_t>* m_shield_amount;\n    std::vector<hit_points_type_t*>* m_hit_points;\n    std::vector<uint8_t>* m_elevation_level;\n    std::vector<uint8_t>* m_unknown;\n    std::vector<uint8_t>* m_rank;\n    std::vector<uint8_t>* m_ai_computer_idle;\n    std::vector<uint8_t>* m_ai_human_idle;\n    std::vector<uint8_t>* m_ai_return_to_idle;\n    std::vector<uint8_t>* m_ai_attack_unit;\n    std::vector<uint8_t>* m_ai_attack_move;\n    std::vector<uint8_t>* m_ground_weapon;\n    std::vector<uint8_t>* m_max_ground_hits;\n    bool n_max_ground_hits;\n\npublic:\n    bool _is_null_max_ground_hits() { max_ground_hits(); return n_max_ground_hits; };\n\nprivate:\n    std::vector<uint8_t>* m_air_weapon;\n    std::vector<uint8_t>* m_max_air_hits;\n    bool n_max_air_hits;\n\npublic:\n    bool _is_null_max_air_hits() { max_air_hits(); return n_max_air_hits; };\n\nprivate:\n    std::vector<uint8_t>* m_ai_internal;\n    std::vector<special_ability_flags_type_t*>* m_special_ability_flags;\n    std::vector<uint8_t>* m_target_acquisition_range;\n    std::vector<uint8_t>* m_sight_range;\n    std::vector<uint8_t>* m_armor_upgrade;\n    std::vector<unit_size_enum_t>* m_unit_size;\n    std::vector<uint8_t>* m_armor;\n    std::vector<right_click_action_enum_t>* m_right_click_action;\n    std::vector<uint16_t>* m_ready_sound;\n    std::vector<uint16_t>* m_what_sound_start;\n    std::vector<uint16_t>* m_what_sound_end;\n    std::vector<uint16_t>* m_piss_sound_start;\n    std::vector<uint16_t>* m_piss_sound_end;\n    std::vector<uint16_t>* m_yes_sound_start;\n    std::vector<uint16_t>* m_yes_sound_end;\n    std::vector<staredit_placement_box_type_t*>* m_staredit_placement_box;\n    std::vector<addon_position_type_t*>* m_addon_position;\n    std::vector<unit_dimension_type_t*>* m_unit_dimension;\n    std::vector<uint16_t>* m_portrait;\n    std::vector<uint16_t>* m_mineral_cost;\n    std::vector<uint16_t>* m_vespene_cost;\n    std::vector<uint16_t>* m_build_time;\n    std::vector<uint16_t>* m_requirements;\n    std::vector<staredit_group_flags_type_t*>* m_staredit_group_flags;\n    std::vector<uint8_t>* m_supply_provided;\n    std::vector<uint8_t>* m_supply_required;\n    std::vector<uint8_t>* m_space_required;\n    std::vector<uint8_t>* m_space_provided;\n    std::vector<uint16_t>* m_build_score;\n    std::vector<uint16_t>* m_destroy_score;\n    std::vector<uint16_t>* m_unit_map_string;\n    std::vector<uint8_t>* m_broodwar_flag;\n    bool n_broodwar_flag;\n\npublic:\n    bool _is_null_broodwar_flag() { broodwar_flag(); return n_broodwar_flag; };\n\nprivate:\n    std::vector<staredit_availability_flags_type_t*>* m_staredit_availability_flags;\n    units_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n    std::vector<std::string>* m__raw_special_ability_flags;\n    std::vector<kaitai::kstream*>* m__io__raw_special_ability_flags;\n    std::vector<std::string>* m__raw_staredit_group_flags;\n    std::vector<kaitai::kstream*>* m__io__raw_staredit_group_flags;\n    std::vector<std::string>* m__raw_staredit_availability_flags;\n    std::vector<kaitai::kstream*>* m__io__raw_staredit_availability_flags;\n\npublic:\n\n    /**\n     * Unit's main graphics object. [pointer to flingy.dat]\n     */\n    std::vector<uint8_t>* flingy() const { return m_flingy; }\n\n    /**\n     * Main subunit to the unit. Various turrets mostly. [pointer to units.dat]\n     */\n    std::vector<uint16_t>* subunit1() const { return m_subunit1; }\n\n    /**\n     * Secondary subunit. Unused. [pointer to units.dat]\n     */\n    std::vector<uint16_t>* subunit2() const { return m_subunit2; }\n\n    /**\n     * Unit to transform into after Infestation. Exists only for units of ID 106-201 (buildings). [pointer to units.dat]\n     */\n    std::vector<uint16_t>* infestation() const { return m_infestation; }\n\n    /**\n     * Construction graphics of the unit (used mostly with buildings). 0-Scourge = No graphics. [pointer to images.dat]\n     */\n    std::vector<uint32_t>* construction_animation() const { return m_construction_animation; }\n\n    /**\n     * Direction unit will face after it is created. Values start at 0 (the unit will face the top of the screen) and go on clockwise through subsequent turning stages until 31 (unit will face a little left from the complete turn). Value of 32 means unit will face a random direction.\n     */\n    std::vector<uint8_t>* unit_direction() const { return m_unit_direction; }\n\n    /**\n     * Enables Shields for the unit. Works for any unit, not only Protoss. Terran and zerg buildings with shields do NOT acquire full shield capacity during construction.\n     */\n    std::vector<uint8_t>* shield_enable() const { return m_shield_enable; }\n\n    /**\n     * Amount of Shield Points the unit has. Shields are reduced before the unit's Hit Points are affected.\n     */\n    std::vector<uint16_t>* shield_amount() const { return m_shield_amount; }\n\n    /**\n     * Unit Hit Points (HP) or \"life\" amount.\n     */\n    std::vector<hit_points_type_t*>* hit_points() const { return m_hit_points; }\n\n    /**\n     * The elevation level at which the unit moves. It can be used to make units moves like flyers, but still be attacked by ground weapons and act as ground units to specific special abilities (like Recall). Higher values puts the unit higher over terrain and other units.\n     */\n    std::vector<uint8_t>* elevation_level() const { return m_elevation_level; }\n\n    /**\n     * TODO: this might be \"movement_type\" but meaning is unclear\n     */\n    std::vector<uint8_t>* unknown() const { return m_unknown; }\n\n    /**\n     * Controls ground units movement: units with lower Rank will stop and wait to allow units with higher Rank to continue movement. Has no effects on air units. Also the order this unit is displayed in its folder in StarEdit. Max of 255.\n     * also known as 'sublabel'\n     */\n    std::vector<uint8_t>* rank() const { return m_rank; }\n\n    /**\n     * Order given to the unit if it is under computer control and does nothing. [pointer to orders.dat]      name 'Computer AI Idle'\n     */\n    std::vector<uint8_t>* ai_computer_idle() const { return m_ai_computer_idle; }\n\n    /**\n     * Order given to the unit if it is under a human player's control and does nothing. [pointer to orders.dat]\n     */\n    std::vector<uint8_t>* ai_human_idle() const { return m_ai_human_idle; }\n\n    /**\n     * Order executed after the unit has finished executing another order and returns to Idle state. [pointer to orders.dat]\n     */\n    std::vector<uint8_t>* ai_return_to_idle() const { return m_ai_return_to_idle; }\n\n    /**\n     * Order executed if the units is ordered to attack an enemy unit, also through the Right-Click action. [pointer to orders.dat]\n     */\n    std::vector<uint8_t>* ai_attack_unit() const { return m_ai_attack_unit; }\n\n    /**\n     * Order executed if the unit is ordered to Attack Ground. [pointer to orders.dat]\n     */\n    std::vector<uint8_t>* ai_attack_move() const { return m_ai_attack_move; }\n\n    /**\n     * Weapon used for attacking \"ground\" units - those with the \"Flying Target\" advanced flag unchecked. [pointer to weapons.dat]\n     */\n    std::vector<uint8_t>* ground_weapon() const { return m_ground_weapon; }\n\n    /**\n     * Max number of times unit hits its target per Ground attack. This value is for statistics purposes only. Changing it only affects the value displayed in StarEdit.\n     * Only broodwar/remastered variants of units.dat have this data block.\n     */\n    std::vector<uint8_t>* max_ground_hits() const { return m_max_ground_hits; }\n\n    /**\n     * Weapon used for attacking \"air\" or \"flying\" units - those with the \"Flying Target\" advanced flag checked. [pointer to weapons.dat]\n     */\n    std::vector<uint8_t>* air_weapon() const { return m_air_weapon; }\n\n    /**\n     * Max number of times unit hits its target per Air attack. This value is for statistics purposes only. Changing it only affects the value displayed in StarEdit.\n     * Only broodwar/remastered variants of units.dat have this data block.\n     */\n    std::vector<uint8_t>* max_air_hits() const { return m_max_air_hits; }\n\n    /**\n     * Some AI-related property. Not completely understood.\n     */\n    std::vector<uint8_t>* ai_internal() const { return m_ai_internal; }\n\n    /**\n     * Advanced flags. Check the type for detail specification.\n     */\n    std::vector<special_ability_flags_type_t*>* special_ability_flags() const { return m_special_ability_flags; }\n\n    /**\n     * Range at which the Carrier will launch Interceptors and Reaver Scarabs. Also determines the range at which melee units and Medics will pickup targets. Value of 0 makes the game use the Weapons.dat for range data. 1 range unit here equals 2 range units in weapons.dat.\n     */\n    std::vector<uint8_t>* target_acquisition_range() const { return m_target_acquisition_range; }\n\n    /**\n     * Range (in matrices) indicating how much Fog-Of-War will the unit clear up.\n     */\n    std::vector<uint8_t>* sight_range() const { return m_sight_range; }\n\n    /**\n     * Researching this upgrade will improve the unit's Armor by 1. [pointer to upgrades.dat]\n     */\n    std::vector<uint8_t>* armor_upgrade() const { return m_armor_upgrade; }\n\n    /**\n     * Used to calculate the \"Explosive\" and \"Concussive\" weapons damage: Explosive (50% to Small, 75% to Medium), Concussive (50% to Medium, 25% to Large). \"Independent\" - the unit will lose 1 HP every second attack it takes (by no matter what unit or which weapon and regardless of its Armor. Spell effects may vary, e.g. Plague works normally, but Irradiate doesn't).\n     */\n    std::vector<unit_size_enum_t>* unit_size() const { return m_unit_size; }\n\n    /**\n     * Unit basic Armor level. Armor is subtracted from damage caused by every attack from another unit. If Armor is higher than the attack damage, the unit will act as if was of \"Independent\" Unit Size.\n     */\n    std::vector<uint8_t>* armor() const { return m_armor; }\n\n    /**\n     * Determines what actions may, or may not be taken by the unit if it is given an order through the Right-Click action.\n     */\n    std::vector<right_click_action_enum_t>* right_click_action() const { return m_right_click_action; }\n\n    /**\n     * Sound played after the unit is trained/built. 0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n     * Only unit id 0 to 106 have this sound.\n     */\n    std::vector<uint16_t>* ready_sound() const { return m_ready_sound; }\n\n    /**\n     * First of the \"What\" sounds - played when you select the unit.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n     */\n    std::vector<uint16_t>* what_sound_start() const { return m_what_sound_start; }\n\n    /**\n     * Last of the \"What\" sounds - played when you select the unit.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n     */\n    std::vector<uint16_t>* what_sound_end() const { return m_what_sound_end; }\n\n    /**\n     * First of the \"Annoyed\" sounds - played when you click multiple times on the same unit.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n     */\n    std::vector<uint16_t>* piss_sound_start() const { return m_piss_sound_start; }\n\n    /**\n     * Last of the \"Annoyed\" sounds - played when you click multiple times on the same unit.  0=No sound, substract 1 to get the target sfxdata entry. [pointer to sfxdata.dat]\n     */\n    std::vector<uint16_t>* piss_sound_end() const { return m_piss_sound_end; }\n\n    /**\n     * First of the \"Yes\" sounds - played when you give the unit an order.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n     */\n    std::vector<uint16_t>* yes_sound_start() const { return m_yes_sound_start; }\n\n    /**\n     * Last of the \"Yes\" sounds - played when you give the unit an order.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n     */\n    std::vector<uint16_t>* yes_sound_end() const { return m_yes_sound_end; }\n\n    /**\n     * Width/Height of the green placement rectangle in StarEdit, in pixels.\n     */\n    std::vector<staredit_placement_box_type_t*>* staredit_placement_box() const { return m_staredit_placement_box; }\n\n    /**\n     * Horizontal/vertical distance in pixels at which an addon will be placed. Exists only for units of ID 106-201 (buildings).\n     */\n    std::vector<addon_position_type_t*>* addon_position() const { return m_addon_position; }\n\n    /**\n     * Space the unit takes from its position. Measured in pixels.\n     */\n    std::vector<unit_dimension_type_t*>* unit_dimension() const { return m_unit_dimension; }\n\n    /**\n     * Unit's Idle portrait. Talking Portraits are determined by adding 110 to this value [pointer to portdata.dat]\n     */\n    std::vector<uint16_t>* portrait() const { return m_portrait; }\n\n    /**\n     * Amount of minerals needed to train/build the unit.\n     */\n    std::vector<uint16_t>* mineral_cost() const { return m_mineral_cost; }\n\n    /**\n     * Amount of Vespene Gas needed to train/build the unit.\n     */\n    std::vector<uint16_t>* vespene_cost() const { return m_vespene_cost; }\n\n    /**\n     * Amount of time it takes to train/build the unit, in 1/24ths of a second (at Fastest speed).\n     */\n    std::vector<uint16_t>* build_time() const { return m_build_time; }\n\n    /**\n     * TBD\n     */\n    std::vector<uint16_t>* requirements() const { return m_requirements; }\n\n    /**\n     * Flags used in StarEdit. Check the type for detail specification.\n     */\n    std::vector<staredit_group_flags_type_t*>* staredit_group_flags() const { return m_staredit_group_flags; }\n\n    /**\n     * Amount of Supply/Psi/Control required to train/build the unit. Halves are rounded down for the display, but calculated normally.\n     * TODO: check why StarDat shows always the half of what is in units.dat\n     */\n    std::vector<uint8_t>* supply_provided() const { return m_supply_provided; }\n\n    /**\n     * Amount of Supply/Psi/Control required to train/build the unit. Halves are rounded down for the display, but calculated normally.\n     * TODO: check why StarDat shows always the half of what is in units.dat\n     */\n    std::vector<uint8_t>* supply_required() const { return m_supply_required; }\n\n    /**\n     * Amount of loading space the unit takes up in a transport. If it is higher than the transport's loading space, the unit cannot be loaded. It DOES NOT resize the unit's wireframe when inside the transport.\n     */\n    std::vector<uint8_t>* space_required() const { return m_space_required; }\n\n    /**\n     * Amout of loading space the unit has. Used with dropships. This IS NOT the number of units the transporting unit may carry as different unit may take up different amount of loading space.\n     */\n    std::vector<uint8_t>* space_provided() const { return m_space_provided; }\n\n    /**\n     * Amount of points given for training/building the unit, counted to the total score after the end of a game.\n     */\n    std::vector<uint16_t>* build_score() const { return m_build_score; }\n\n    /**\n     * Amount of points given for destroying the unit, counted to the total score after the end of a game. It is also used by the AI for targetting purposes. Units with a higher destroy score will be targeted first.\n     */\n    std::vector<uint16_t>* destroy_score() const { return m_destroy_score; }\n\n    /**\n     * If this property is different from 0, the unit's name will be read from the strings stored within the map (CHK) that is currently loaded, instead of the stat_txt.tbl file.\n     */\n    std::vector<uint16_t>* unit_map_string() const { return m_unit_map_string; }\n\n    /**\n     * Makes the unit available only while playing BroodWar expansion set.\n     * Only broodwar/remastered variants of units.dat have this data block.\n     */\n    std::vector<uint8_t>* broodwar_flag() const { return m_broodwar_flag; }\n\n    /**\n     * Flags used in StarEdit. Check the type for detail specification.\n     */\n    std::vector<staredit_availability_flags_type_t*>* staredit_availability_flags() const { return m_staredit_availability_flags; }\n    units_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n    std::vector<std::string>* _raw_special_ability_flags() const { return m__raw_special_ability_flags; }\n    std::vector<kaitai::kstream*>* _io__raw_special_ability_flags() const { return m__io__raw_special_ability_flags; }\n    std::vector<std::string>* _raw_staredit_group_flags() const { return m__raw_staredit_group_flags; }\n    std::vector<kaitai::kstream*>* _io__raw_staredit_group_flags() const { return m__io__raw_staredit_group_flags; }\n    std::vector<std::string>* _raw_staredit_availability_flags() const { return m__raw_staredit_availability_flags; }\n    std::vector<kaitai::kstream*>* _io__raw_staredit_availability_flags() const { return m__io__raw_staredit_availability_flags; }\n};\n\n#endif  // UNITS_DAT_H_\n"
  },
  {
    "path": "src/kaitai/units_dat.ksy",
    "content": "meta:\n  id: units_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: flingy\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Unit's main graphics object. [pointer to flingy.dat]\n\n  - id: subunit1\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Main subunit to the unit. Various turrets mostly. [pointer to units.dat]\n\n  - id: subunit2\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Secondary subunit. Unused. [pointer to units.dat]\n\n  - id: infestation\n    type: u2\n    repeat: expr\n    repeat-expr: 96\n    doc: |\n      Unit to transform into after Infestation. Exists only for units of ID 106-201 (buildings). [pointer to units.dat]\n\n  - id: construction_animation\n    type: u4\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Construction graphics of the unit (used mostly with buildings). 0-Scourge = No graphics. [pointer to images.dat]\n\n  - id: unit_direction\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Direction unit will face after it is created. Values start at 0 (the unit will face the top of the screen) and go on clockwise through subsequent turning stages until 31 (unit will face a little left from the complete turn). Value of 32 means unit will face a random direction.\n\n  - id: shield_enable\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Enables Shields for the unit. Works for any unit, not only Protoss. Terran and zerg buildings with shields do NOT acquire full shield capacity during construction.\n\n  - id: shield_amount\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of Shield Points the unit has. Shields are reduced before the unit's Hit Points are affected.\n\n  - id: hit_points\n    type: hit_points_type\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Unit Hit Points (HP) or \"life\" amount.\n\n  - id: elevation_level\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      The elevation level at which the unit moves. It can be used to make units moves like flyers, but still be attacked by ground weapons and act as ground units to specific special abilities (like Recall). Higher values puts the unit higher over terrain and other units.\n\n  - id: unknown\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      TODO: this might be \"movement_type\" but meaning is unclear\n\n  - id: rank\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Controls ground units movement: units with lower Rank will stop and wait to allow units with higher Rank to continue movement. Has no effects on air units. Also the order this unit is displayed in its folder in StarEdit. Max of 255.\n      also known as 'sublabel'\n\n  - id: ai_computer_idle\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Order given to the unit if it is under computer control and does nothing. [pointer to orders.dat]      name 'Computer AI Idle'\n\n  - id: ai_human_idle\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Order given to the unit if it is under a human player's control and does nothing. [pointer to orders.dat]\n\n  - id: ai_return_to_idle\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Order executed after the unit has finished executing another order and returns to Idle state. [pointer to orders.dat]\n\n  - id: ai_attack_unit\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Order executed if the units is ordered to attack an enemy unit, also through the Right-Click action. [pointer to orders.dat]\n\n  - id: ai_attack_move\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Order executed if the unit is ordered to Attack Ground. [pointer to orders.dat]\n\n  - id: ground_weapon\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Weapon used for attacking \"ground\" units - those with the \"Flying Target\" advanced flag unchecked. [pointer to weapons.dat]\n\n  - id: max_ground_hits\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    if: is_format_bw == true\n    doc: |\n      Max number of times unit hits its target per Ground attack. This value is for statistics purposes only. Changing it only affects the value displayed in StarEdit.\n      Only broodwar/remastered variants of units.dat have this data block.\n\n  - id: air_weapon\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Weapon used for attacking \"air\" or \"flying\" units - those with the \"Flying Target\" advanced flag checked. [pointer to weapons.dat]\n\n  - id: max_air_hits\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    if: is_format_bw == true\n    doc: |\n      Max number of times unit hits its target per Air attack. This value is for statistics purposes only. Changing it only affects the value displayed in StarEdit.\n      Only broodwar/remastered variants of units.dat have this data block.\n\n  - id: ai_internal\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Some AI-related property. Not completely understood.\n\n  - id: special_ability_flags\n    type: special_ability_flags_type\n    size: 4\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Advanced flags. Check the type for detail specification.\n\n  - id: target_acquisition_range\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Range at which the Carrier will launch Interceptors and Reaver Scarabs. Also determines the range at which melee units and Medics will pickup targets. Value of 0 makes the game use the Weapons.dat for range data. 1 range unit here equals 2 range units in weapons.dat.\n\n  - id: sight_range\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Range (in matrices) indicating how much Fog-Of-War will the unit clear up.\n\n  - id: armor_upgrade\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Researching this upgrade will improve the unit's Armor by 1. [pointer to upgrades.dat]\n\n  - id: unit_size\n    type: u1\n    enum: unit_size_enum\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Used to calculate the \"Explosive\" and \"Concussive\" weapons damage: Explosive (50% to Small, 75% to Medium), Concussive (50% to Medium, 25% to Large). \"Independent\" - the unit will lose 1 HP every second attack it takes (by no matter what unit or which weapon and regardless of its Armor. Spell effects may vary, e.g. Plague works normally, but Irradiate doesn't).\n\n  - id: armor\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Unit basic Armor level. Armor is subtracted from damage caused by every attack from another unit. If Armor is higher than the attack damage, the unit will act as if was of \"Independent\" Unit Size.\n\n  - id: right_click_action\n    type: u1\n    enum: right_click_action_enum\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Determines what actions may, or may not be taken by the unit if it is given an order through the Right-Click action.\n\n  - id: ready_sound\n    type: u2\n    repeat: expr\n    repeat-expr: 106\n    doc: |\n      Sound played after the unit is trained/built. 0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n      Only unit id 0 to 106 have this sound.\n\n  - id: what_sound_start\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      First of the \"What\" sounds - played when you select the unit.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n\n  - id: what_sound_end\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Last of the \"What\" sounds - played when you select the unit.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n\n  - id: piss_sound_start\n    type: u2\n    repeat: expr\n    repeat-expr: 106\n    doc: |\n      First of the \"Annoyed\" sounds - played when you click multiple times on the same unit.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n\n  - id: piss_sound_end\n    type: u2\n    repeat: expr\n    repeat-expr: 106\n    doc: |\n      Last of the \"Annoyed\" sounds - played when you click multiple times on the same unit.  0=No sound, substract 1 to get the target sfxdata entry. [pointer to sfxdata.dat]\n\n  - id: yes_sound_start\n    type: u2\n    repeat: expr\n    repeat-expr: 106\n    doc: |\n      First of the \"Yes\" sounds - played when you give the unit an order.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n\n  - id: yes_sound_end\n    type: u2\n    repeat: expr\n    repeat-expr: 106\n    doc: |\n      Last of the \"Yes\" sounds - played when you give the unit an order.  0=No sound, substract 1 to get the target sfxdata.dat entry. [pointer to sfxdata.dat]\n\n  - id: staredit_placement_box\n    type: staredit_placement_box_type\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Width/Height of the green placement rectangle in StarEdit, in pixels.\n\n  - id: addon_position\n    type: addon_position_type\n    repeat: expr\n    repeat-expr: 96\n    doc: |\n      Horizontal/vertical distance in pixels at which an addon will be placed. Exists only for units of ID 106-201 (buildings).\n\n  - id: unit_dimension\n    type: unit_dimension_type\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Space the unit takes from its position. Measured in pixels.\n\n  - id: portrait\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Unit's Idle portrait. Talking Portraits are determined by adding 110 to this value [pointer to portdata.dat]\n\n  - id: mineral_cost\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of minerals needed to train/build the unit.\n\n  - id: vespene_cost\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of Vespene Gas needed to train/build the unit.\n\n  - id: build_time\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of time it takes to train/build the unit, in 1/24ths of a second (at Fastest speed).\n\n  - id: requirements\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      TBD\n\n  - id: staredit_group_flags\n    type: staredit_group_flags_type\n    repeat: expr\n    repeat-expr: 228\n    size: 1\n    doc: |\n      Flags used in StarEdit. Check the type for detail specification.\n\n  - id: supply_provided\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of Supply/Psi/Control required to train/build the unit. Halves are rounded down for the display, but calculated normally.\n      TODO: check why StarDat shows always the half of what is in units.dat\n\n  - id: supply_required\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of Supply/Psi/Control required to train/build the unit. Halves are rounded down for the display, but calculated normally.\n      TODO: check why StarDat shows always the half of what is in units.dat\n\n  - id: space_required\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of loading space the unit takes up in a transport. If it is higher than the transport's loading space, the unit cannot be loaded. It DOES NOT resize the unit's wireframe when inside the transport.\n\n  - id: space_provided\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amout of loading space the unit has. Used with dropships. This IS NOT the number of units the transporting unit may carry as different unit may take up different amount of loading space.\n\n  - id: build_score\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of points given for training/building the unit, counted to the total score after the end of a game.\n\n  - id: destroy_score\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Amount of points given for destroying the unit, counted to the total score after the end of a game. It is also used by the AI for targetting purposes. Units with a higher destroy score will be targeted first.\n\n  - id: unit_map_string\n    type: u2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      If this property is different from 0, the unit's name will be read from the strings stored within the map (CHK) that is currently loaded, instead of the stat_txt.tbl file.\n\n  - id: broodwar_flag\n    type: u1\n    repeat: expr\n    repeat-expr: 228\n    if: is_format_bw == true\n    doc: |\n      Makes the unit available only while playing BroodWar expansion set.\n      Only broodwar/remastered variants of units.dat have this data block.\n\n  - id: staredit_availability_flags\n    type: staredit_availability_flags_type\n    size: 2\n    repeat: expr\n    repeat-expr: 228\n    doc: |\n      Flags used in StarEdit. Check the type for detail specification.\n\ninstances:\n  is_format_sc:\n    value: 'file_size == sc_file_size ? true : false'\n    doc: |\n      This is true if plain starcraft units.dat is found\n\n  is_format_bw:\n    value: 'file_size == bw_file_size ? true : false'\n    doc: |\n      This is true if broodwar or remastered units.dat is found\n\n  sc_file_size:\n    value: 19192\n\n  bw_file_size:\n    value: 19876\n\n  file_size:\n    value: '_io.size'\n\ntypes:\n  staredit_placement_box_type:\n    seq:\n      - id: width\n        type: u2\n      - id: height\n        type: u2\n\n  addon_position_type:\n    seq:\n      - id: horizontal\n        type: u2\n      - id: vertical\n        type: u2\n\n  hit_points_type:\n    seq:\n      - id: hitpoints0\n        type: u2be\n      - id: hitpoints1\n        type: u2be\n\n    instances:\n      hitpoints:\n        value: hitpoints0 + hitpoints1\n\n  unit_dimension_type:\n    seq:\n      - id: left\n        type: u2\n      - id: up\n        type: u2\n      - id: right\n        type: u2\n      - id: down\n        type: u2\n\n  special_ability_flags_type:\n    seq:\n      - id: building\n        type: b1  # 0b0000_0001 = 0x01\n      - id: addon\n        type: b1  # 0b0000_0010 = 0x02\n      - id: flyer\n        type: b1  # 0b0000_0100 = 0x04\n      - id: resourceminer\n        type: b1  # 0b0000_1000 = 0x08\n      - id: subunit\n        type: b1  # 0b0001_0000 = 0x10\n      - id: flyingbuilding\n        type: b1  # 0b0010_0000 = 0x20\n      - id: hero\n        type: b1  # 0b0100_0000 = 0x40\n      - id: regenerate\n        type: b1  # 0b1000_0000 = 0x80\n      - id: animatedidle\n        type: b1  # 0b0000_0001_0000_0000 = 0x100\n      - id: cloakable\n        type: b1  # 0b0000_0010_0000_0000 = 0x200\n      - id: twounitsinoneegg\n        type: b1  # 0b0000_0100_0000_0000 = 0x400\n      - id: singleentity\n        type: b1  # 0b0000_1000_0000_0000 = 0x800\n      - id: resourcedepot\n        type: b1  # 0b0001_0000_0000_0000 = 0x1000\n      - id: resourcecontainter\n        type: b1  # 0b0010_0000_0000_0000 = 0x2000\n      - id: robotic\n        type: b1  # 0b0100_0000_0000_0000 = 0x4000\n      - id: detector\n        type: b1  # 0b1000_0000_0000_0000 = 0x8000\n      - id: organic\n        type: b1  # 0b0000_0000_0000_0001_0000_0000_0000_0000 = 0x10000\n      - id: requirescreep\n        type: b1  # 0b0000_0000_0000_0010_0000_0000_0000_0000 = 0x20000\n      - id: unused\n        type: b1  # 0b0000_0000_0000_0100_0000_0000_0000_0000 = 0x40000\n      - id: requirespsi\n        type: b1  # 0b0000_0000_0000_1000_0000_0000_0000_0000 = 0x80000\n      - id: burrowable\n        type: b1  # 0b0000_0000_0001_0000_0000_0000_0000_0000 = 0x100000\n      - id: spellcaster\n        type: b1  # 0b0000_0000_0010_0000_0000_0000_0000_0000 = 0x200000\n      - id: permanentcloak\n        type: b1  # 0b0000_0000_0100_0000_0000_0000_0000_0000 = 0x400000\n      - id: pickupitem\n        type: b1  # 0b0000_0000_1000_0000_0000_0000_0000_0000 = 0x800000\n      - id: ignoresupplycheck\n        type: b1  # 0b0000_0001_0000_0000_0000_0000_0000_0000 = 0x1000000\n      - id: usemediumoverlays\n        type: b1  # 0b0000_0010_0000_0000_0000_0000_0000_0000 = 0x2000000\n      - id: uselargeoverlays\n        type: b1  # 0b0000_0100_0000_0000_0000_0000_0000_0000 = 0x4000000\n      - id: battlereactions\n        type: b1  # 0b0000_1000_0000_0000_0000_0000_0000_0000 = 0x8000000\n      - id: fullautoattack\n        type: b1  # 0b0001_0000_0000_0000_0000_0000_0000_0000 = 0x1000000\n      - id: invincible\n        type: b1  # 0b0010_0000_0000_0000_0000_0000_0000_0000 = 0x2000000\n      - id: mechanical\n        type: b1  # 0b0100_0000_0000_0000_0000_0000_0000_0000 = 0x4000000\n      - id: producesunits\n        type: b1  # 0b1000_0000_0000_0000_0000_0000_0000_0000 = 0x8000000\n    doc: |\n      building: Unit is considered as a building for targeting purposes, and affects Addons-related properties. Also allows for other units to be built/trained 'inside' the unit and makes the unit placement dependent on the \"Placement Box\" property instead of the \"Unit Dimensions\".\n      addon: Makes the building placeable in a special way, dependent on the main building. If unchecked, the building will still use the standard way of placing the addon, but after lift-off, it will be inaccessible.\n      flyer: If unchecked, the unit is targeted by Ground weapons. If checked, unit can be targeted by Air weapons. It also makes the unit \"fly\" in the way that it chooses the shortest path to its destination, moving over terrain and other units.\n      resourceminer: Unit can gather/return resources. Does NOT affect building construction abilities (except a tiny Drone glitch if you cancel a building morph). Requires a .LOO file pointed from the \"Overlay 3\" property in Images.dat to work. Vespene Gas harvesting seems good for all units, but Minerals may cause crashes, depending on the unit you use (e.g. Marine is OK, but the Firebat will crash)\n      subunit: Makes the unit a \"sub-unit\", i.e. allows it to be a part of another unit (like the tank turret to the tank body) through the Subunit property (see Graphics tab). A non-subunit-type unit used as a subunit will crash the game. To have a sub-unit properly placed on a unit, you also require altering the images.dat properties of the base sprite as well as certain other settings. Expect crashes more than often while working with this property.\n      flyingbuilding: Allows/Disallows the unit to be in the \"In Transit\" (or \"Flying\") state both in the game and in StarEdit, but it will crash if the unit does not have a Lift-off and Landing animations (in Iscript.bin). Does not affect buttons available for the unit.\n      hero: Unit has all its upgrades researched from the start and receives a white wireframe box (instead of the standard blue one). If a unit is also a spellcaster, it will have 250 energy points, regardless if there is an energy upgrade for it or not.\n      regenerate: Unit will slowly regain Hit Points, until its full HP capacity.\n      animatedidle:\n      cloakable: Allows/Disallows the unit to use the Cloak technology. It does NOT give/remove the \"Cloak\" button but allows the unit to display the \"Group (Cloakers)\" button set when selected in a group.\n      twounitsinoneegg: 2 units will come out of one Zerg Egg instead of just one. The cost for morphing will NOT be doubled, but the amount of the used supplies will equal 2 times the normal amount. To accomplish the full effect you will also have to add a \"Construction\" graphics and set a \"Landing Dust\" overlay to it.\n      singleentity: Unit cannot be selected in a group, but only as a single unit. Unit cannot be selected by dragging a selection box, by a SHIFT-Click nor a double-click.\n      resourcedepot: Makes a building (and ONLY a building) a place workers can return resources to. Also makes it impossible to place/land the building next to a unit with the \"Resource Container\" property.\n      resourcecontainter: Unit does not generate an error message if targeted for Gathering by a worker. Allows/Disallows to set unit's resources capacity in StarEdit, but does not make a unit other than original resource actually store resources in-game. Unchecked, makes the original resources capacity equal to 0, although workers will still try to harvest it. Prevents \"Resource Depots\" from being located next to it.\n      robotic: Unit is treated as a robotic-type target for weapons and spells (e.g. it cannot be targeted with Spawn Broodlings)\n      detector: Unit can detect cloaked enemy units and receives the \"Detector\" title under its name.\n      organic: Unit is treated as an organic-type target for weapons and spells (e.g. Maelstrom).\n      requirescreep: Building MUST be built on creep. It will also get a creep outline around it.\n      unused:\n      requirespsi: Unit must be built within a PSI field, like that produced by pylons. If it is not within a PSI field, it will become \"Disabled\" and not function. Can be given to any unit. You can also disable it on Protoss buildings so they can be built anywhere.\n      burrowable: Allows/Disallows the unit to use the Burrow technology. It does NOT give/remove the \"Burrow\" button.\n      spellcaster: Unit receives a mana bar and will slowly regain mana points through time. Combined with the Permanent Cloak property, will prevent unit from regaining mana.\n      permanentcloak: Unit is constantly cloaked. If the unit is also a Spellcaster, giving this property will make it lose mana until 0.\n      pickupitem: Related to powerups. Not completely understood.\n      ignoresupplycheck: Even if you don't have the supply available to build the unit, the engine will still build it and add that to your supply.\n      usemediumoverlays: Unit will use medium spell overlay graphics.\n      uselargeoverlays: Unit will use large spell overlay graphics.\n      battlereactions: Unit will show battle reactions,i.e. if it sees an enemy it will move to it and attack, if it is attacked by an unreachable enemy (e.g. an Air unit and it doesn't have an Air weapon) it will run away. Works ONLY if the unit's Idle AI Orders are set to Guard.\n      fullautoattack: Unit will attack any enemy that enters its firing range. If unchecked, unit will attack the enemy ONLY if it is facing its direction, e.g. because it has an animated idle state.\n      invincible: Unit cannot be a target of any sort of weapons or spells. It also hides the unit's Hit Points value.\n      mechanical: Unit is treated as a mechanical-type target for weapons and spells (e.g. Lockdown). It can also be repaired by SCVs.\n      producesunits:\n\n  staredit_group_flags_type:\n    seq:\n      - id: zerg\n        type: b1  # 0b0000_0001 = 0x01\n      - id: terran\n        type: b1  # 0b0000_0010 = 0x02\n      - id: protoss\n        type: b1  # 0b0000_0100 = 0x04\n      - id: men\n        type: b1  # 0b0000_1000 = 0x08\n      - id: building\n        type: b1  # 0b0001_0000 = 0x10\n      - id: factory\n        type: b1  # 0b0010_0000 = 0x20\n      - id: independent\n        type: b1  # 0b0100_0000 = 0x40\n      - id: neutral\n        type: b1  # 0b1000_0000 = 0x80\n    doc: |\n      zerg: Unit is from race \"Zerg\"\n      terran: Unit is from race \"Terran\"\n      protoss: Unit is from race \"Protoss\"\n      men: Unit is a \"Men\"-type unit for triggers.\n      building: Unit is a \"Building\"-type unit for triggers.\n      factory: Unit is a \"Factory\"-type unit for triggers.\n      independent: Unit is treated as an Independent unit (abandoned unit type).\n      neutral: Unit is treated as a Neutral unit.\n\n  staredit_availability_flags_type:\n    seq:\n      - id: non_neutral\n        type: b1  # 0b0000_0001 = 0x01\n      - id: unit_listing\n        type: b1  # 0b0000_0010 = 0x02\n      - id: mission_briefing\n        type: b1  # 0b0000_0100 = 0x04\n      - id: player_settings\n        type: b1  # 0b0000_1000 = 0x08\n      - id: all_races\n        type: b1  # 0b0001_0000 = 0x10\n      - id: set_doodad_state\n        type: b1  # 0b0010_0000 = 0x20\n      - id: non_location_triggers\n        type: b1  # 0b0100_0000 = 0x40\n      - id: unit_hero_settings\n        type: b1  # 0b1000_0000 = 0x80\n      - id: location_triggers\n        type: b1  # 0b0000_0001_0000_0000 = 0x100\n      - id: brood_war_only\n        type: b1  # 0b0000_0010_0000_0000 = 0x200\n      - type: b6  # 0b1111_1100_0000_0000\n    doc: |\n      non_neutral: Unit belongs to a 1-8 Player, takes its corresponding color and appears in the player's corresponding menu in the unit listing on the left. If unchecked, the unit belongs to the 12th Player (neutral), takes the dark aqua color and appears under the \"Neutral\" menu in the unit listing.\n      unit_listing: Unit is availabe in the unit listing on the left and in the Brush Palette.\n      mission_briefing: Unit's portrait is available in Mission Briefing.\n      player_settings: Unit is available in the Player Settings.\n      all_races: Unit is available for all races in the unit list in StarEdit.\n      set_doodad_state: Unit is available for the \"Set Doodad State\" trigger.\n      non_location_triggers: Unit appears in the unit selection box when using Non-locational triggers (Remove, Kill etc.)\n      unit_hero_settings: Unit is available in Unit&Hero Settings.\n      location_triggers: Unit appears in the unit selection box when using locational triggers (Remove at, Kill at etc.). Even if unchecked, the unit WILL appear for selection when using the \"Create at\" trigger action.\n      brood_war_only: Unit is available only if BroodWar Expansion is installed.\n\nenums:\n  unit_size_enum:\n    0: indendent\n    1: small\n    2: medium\n    3: large\n\n  right_click_action_enum:\n    0: no_commands_auo_attack\n    1: normal_movement_normal_attack\n    2: normal_movement_no_attack\n    3: no_movement_normal_attack\n    4: harvest\n    5: harvest_repair\n    6: nothing_with_indicator\n"
  },
  {
    "path": "src/kaitai/upgrades_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"upgrades_dat.h\"\n\nupgrades_dat_t::upgrades_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, upgrades_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_mineral_cost_base = 0;\n    m_mineral_cost_factor = 0;\n    m_vespene_cost_base = 0;\n    m_vespene_cost_factor = 0;\n    m_research_time_base = 0;\n    m_research_time_factor = 0;\n    m_unknown6 = 0;\n    m_icon = 0;\n    m_label = 0;\n    m_race = 0;\n    m_max_repeats = 0;\n    m_broodwar_flags = 0;\n    f_record_count_broodwar = false;\n    f_record_count = false;\n    f_num_lines = false;\n    f_has_broodwar_flag = false;\n    f_file_size = false;\n    f_record_size = false;\n    f_record_size_broodwar = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid upgrades_dat_t::_read() {\n    m_mineral_cost_base = new std::vector<uint16_t>();\n    const int l_mineral_cost_base = num_lines();\n    for (int i = 0; i < l_mineral_cost_base; i++) {\n        m_mineral_cost_base->push_back(m__io->read_u2le());\n    }\n    m_mineral_cost_factor = new std::vector<uint16_t>();\n    const int l_mineral_cost_factor = num_lines();\n    for (int i = 0; i < l_mineral_cost_factor; i++) {\n        m_mineral_cost_factor->push_back(m__io->read_u2le());\n    }\n    m_vespene_cost_base = new std::vector<uint16_t>();\n    const int l_vespene_cost_base = num_lines();\n    for (int i = 0; i < l_vespene_cost_base; i++) {\n        m_vespene_cost_base->push_back(m__io->read_u2le());\n    }\n    m_vespene_cost_factor = new std::vector<uint16_t>();\n    const int l_vespene_cost_factor = num_lines();\n    for (int i = 0; i < l_vespene_cost_factor; i++) {\n        m_vespene_cost_factor->push_back(m__io->read_u2le());\n    }\n    m_research_time_base = new std::vector<uint16_t>();\n    const int l_research_time_base = num_lines();\n    for (int i = 0; i < l_research_time_base; i++) {\n        m_research_time_base->push_back(m__io->read_u2le());\n    }\n    m_research_time_factor = new std::vector<uint16_t>();\n    const int l_research_time_factor = num_lines();\n    for (int i = 0; i < l_research_time_factor; i++) {\n        m_research_time_factor->push_back(m__io->read_u2le());\n    }\n    m_unknown6 = new std::vector<uint16_t>();\n    const int l_unknown6 = num_lines();\n    for (int i = 0; i < l_unknown6; i++) {\n        m_unknown6->push_back(m__io->read_u2le());\n    }\n    m_icon = new std::vector<uint16_t>();\n    const int l_icon = num_lines();\n    for (int i = 0; i < l_icon; i++) {\n        m_icon->push_back(m__io->read_u2le());\n    }\n    m_label = new std::vector<uint16_t>();\n    const int l_label = num_lines();\n    for (int i = 0; i < l_label; i++) {\n        m_label->push_back(m__io->read_u2le());\n    }\n    m_race = new std::vector<uint8_t>();\n    const int l_race = num_lines();\n    for (int i = 0; i < l_race; i++) {\n        m_race->push_back(m__io->read_u1());\n    }\n    m_max_repeats = new std::vector<uint8_t>();\n    const int l_max_repeats = num_lines();\n    for (int i = 0; i < l_max_repeats; i++) {\n        m_max_repeats->push_back(m__io->read_u1());\n    }\n    n_broodwar_flags = true;\n    if (has_broodwar_flag() == true) {\n        n_broodwar_flags = false;\n        m_broodwar_flags = new std::vector<uint8_t>();\n        const int l_broodwar_flags = num_lines();\n        for (int i = 0; i < l_broodwar_flags; i++) {\n            m_broodwar_flags->push_back(m__io->read_u1());\n        }\n    }\n}\n\nupgrades_dat_t::~upgrades_dat_t() {\n    _clean_up();\n}\n\nvoid upgrades_dat_t::_clean_up() {\n    if (m_mineral_cost_base) {\n        delete m_mineral_cost_base; m_mineral_cost_base = 0;\n    }\n    if (m_mineral_cost_factor) {\n        delete m_mineral_cost_factor; m_mineral_cost_factor = 0;\n    }\n    if (m_vespene_cost_base) {\n        delete m_vespene_cost_base; m_vespene_cost_base = 0;\n    }\n    if (m_vespene_cost_factor) {\n        delete m_vespene_cost_factor; m_vespene_cost_factor = 0;\n    }\n    if (m_research_time_base) {\n        delete m_research_time_base; m_research_time_base = 0;\n    }\n    if (m_research_time_factor) {\n        delete m_research_time_factor; m_research_time_factor = 0;\n    }\n    if (m_unknown6) {\n        delete m_unknown6; m_unknown6 = 0;\n    }\n    if (m_icon) {\n        delete m_icon; m_icon = 0;\n    }\n    if (m_label) {\n        delete m_label; m_label = 0;\n    }\n    if (m_race) {\n        delete m_race; m_race = 0;\n    }\n    if (m_max_repeats) {\n        delete m_max_repeats; m_max_repeats = 0;\n    }\n    if (!n_broodwar_flags) {\n        if (m_broodwar_flags) {\n            delete m_broodwar_flags; m_broodwar_flags = 0;\n        }\n    }\n}\n\nint32_t upgrades_dat_t::record_count_broodwar() {\n    if (f_record_count_broodwar)\n        return m_record_count_broodwar;\n    m_record_count_broodwar = (file_size() / record_size_broodwar());\n    f_record_count_broodwar = true;\n    return m_record_count_broodwar;\n}\n\nint32_t upgrades_dat_t::record_count() {\n    if (f_record_count)\n        return m_record_count;\n    m_record_count = (file_size() / record_size());\n    f_record_count = true;\n    return m_record_count;\n}\n\nint32_t upgrades_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = ((kaitai::kstream::mod(file_size(), record_size()) == 0) ? (record_count()) : (record_count_broodwar()));\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nbool upgrades_dat_t::has_broodwar_flag() {\n    if (f_has_broodwar_flag)\n        return m_has_broodwar_flag;\n    m_has_broodwar_flag = ((kaitai::kstream::mod(file_size(), record_size()) == 0) ? (false) : (true));\n    f_has_broodwar_flag = true;\n    return m_has_broodwar_flag;\n}\n\nint32_t upgrades_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n\nint8_t upgrades_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 20;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint8_t upgrades_dat_t::record_size_broodwar() {\n    if (f_record_size_broodwar)\n        return m_record_size_broodwar;\n    m_record_size_broodwar = 21;\n    f_record_size_broodwar = true;\n    return m_record_size_broodwar;\n}\n"
  },
  {
    "path": "src/kaitai/upgrades_dat.h",
    "content": "#ifndef UPGRADES_DAT_H_\n#define UPGRADES_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass upgrades_dat_t : public kaitai::kstruct {\n\npublic:\n\n    upgrades_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, upgrades_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~upgrades_dat_t();\n\nprivate:\n    bool f_record_count_broodwar;\n    int32_t m_record_count_broodwar;\n\npublic:\n\n    /**\n     * Count of records in the data file. (Need to check with modulo operator if this is the case) [broodwar data]\n     */\n    int32_t record_count_broodwar();\n\nprivate:\n    bool f_record_count;\n    int32_t m_record_count;\n\npublic:\n\n    /**\n     * Count of records in the data file. (Need to check with modulo operator if this is the case)\n     */\n    int32_t record_count();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_has_broodwar_flag;\n    bool m_has_broodwar_flag;\n\npublic:\n\n    /**\n     * true in case the brodowar data is parsed\n     */\n    bool has_broodwar_flag();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_record_size_broodwar;\n    int8_t m_record_size_broodwar;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized. [broodwar data]\n     */\n    int8_t record_size_broodwar();\n\nprivate:\n    std::vector<uint16_t>* m_mineral_cost_base;\n    std::vector<uint16_t>* m_mineral_cost_factor;\n    std::vector<uint16_t>* m_vespene_cost_base;\n    std::vector<uint16_t>* m_vespene_cost_factor;\n    std::vector<uint16_t>* m_research_time_base;\n    std::vector<uint16_t>* m_research_time_factor;\n    std::vector<uint16_t>* m_unknown6;\n    std::vector<uint16_t>* m_icon;\n    std::vector<uint16_t>* m_label;\n    std::vector<uint8_t>* m_race;\n    std::vector<uint8_t>* m_max_repeats;\n    std::vector<uint8_t>* m_broodwar_flags;\n    bool n_broodwar_flags;\n\npublic:\n    bool _is_null_broodwar_flags() { broodwar_flags(); return n_broodwar_flags; };\n\nprivate:\n    upgrades_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * Basic minerals cost for the upgrade.\n     */\n    std::vector<uint16_t>* mineral_cost_base() const { return m_mineral_cost_base; }\n\n    /**\n     * Additional cost in minerals, per level of the upgrade.\n     */\n    std::vector<uint16_t>* mineral_cost_factor() const { return m_mineral_cost_factor; }\n\n    /**\n     * Basic Vespene gas cost for the upgrade.\n     */\n    std::vector<uint16_t>* vespene_cost_base() const { return m_vespene_cost_base; }\n\n    /**\n     * Additional cost in Vespene gas, per level of the upgrade.\n     */\n    std::vector<uint16_t>* vespene_cost_factor() const { return m_vespene_cost_factor; }\n\n    /**\n     * Basic research time for the upgrade, in 1/24ths of a second (at Fastest speed). A value of 0 will crash the original game.\n     */\n    std::vector<uint16_t>* research_time_base() const { return m_research_time_base; }\n\n    /**\n     * Additional time the research takes, per level of the upgrade, in 1/24ths of a second (at Fastest speed).\n     */\n    std::vector<uint16_t>* research_time_factor() const { return m_research_time_factor; }\n    std::vector<uint16_t>* unknown6() const { return m_unknown6; }\n\n    /**\n     * Icon displayed for the upgrade. [pointer to a frame in unit\\cmdbtns\\cmdicons.grp]\n     */\n    std::vector<uint16_t>* icon() const { return m_icon; }\n\n    /**\n     * The name of the upgrade. Displayed in StarEdit and when you highlight the upgrade's icon during research. [pointer to stat_txt.tbl]\n     */\n    std::vector<uint16_t>* label() const { return m_label; }\n\n    /**\n     * Determines which race can use/research the upgrade. \"All\" will disable the tech in StarEdit (but not in-game).\n     */\n    std::vector<uint8_t>* race() const { return m_race; }\n\n    /**\n     * Total number of times the upgrade can be researched.\n     */\n    std::vector<uint8_t>* max_repeats() const { return m_max_repeats; }\n\n    /**\n     * Makes the upgrade available only while playing the BroodWar expansion set.\n     */\n    std::vector<uint8_t>* broodwar_flags() const { return m_broodwar_flags; }\n    upgrades_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // UPGRADES_DAT_H_\n"
  },
  {
    "path": "src/kaitai/upgrades_dat.ksy",
    "content": "meta:\n  id: upgrades_dat\n  endian: le\n  bit-endian: le\n\nseq:\n  - id: mineral_cost_base\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Basic minerals cost for the upgrade.\n\n  - id: mineral_cost_factor\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Additional cost in minerals, per level of the upgrade.\n\n  - id: vespene_cost_base\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Basic Vespene gas cost for the upgrade.\n\n  - id: vespene_cost_factor\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Additional cost in Vespene gas, per level of the upgrade.\n\n  - id: research_time_base\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Basic research time for the upgrade, in 1/24ths of a second (at Fastest speed). A value of 0 will crash the original game.\n\n  - id: research_time_factor\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Additional time the research takes, per level of the upgrade, in 1/24ths of a second (at Fastest speed).\n\n  - id: unknown6\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n\n  - id: icon\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Icon displayed for the upgrade. [pointer to a frame in unit\\cmdbtns\\cmdicons.grp]\n\n  - id: label\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The name of the upgrade. Displayed in StarEdit and when you highlight the upgrade's icon during research. [pointer to stat_txt.tbl]\n\n  - id: race\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Determines which race can use/research the upgrade. \"All\" will disable the tech in StarEdit (but not in-game).\n\n  - id: max_repeats\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Total number of times the upgrade can be researched.\n\n  - id: broodwar_flags\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    if: has_broodwar_flag == true\n    doc: |\n      Makes the upgrade available only while playing the BroodWar expansion set.\n\ninstances:\n  has_broodwar_flag:\n    value: 'file_size % record_size == 0 ? false : true'\n    doc: |\n      true in case the brodowar data is parsed\n\n  num_lines:\n    value: 'file_size % record_size == 0 ? record_count : record_count_broodwar'\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 20\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  record_count:\n    value: 'file_size / record_size'\n    doc: |\n      Count of records in the data file. (Need to check with modulo operator if this is the case)\n\n  record_size_broodwar:\n    value: 21\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized. [broodwar data]\n\n  record_count_broodwar:\n    value: 'file_size / record_size_broodwar'\n    doc: |\n      Count of records in the data file. (Need to check with modulo operator if this is the case) [broodwar data]\n\n  file_size:\n    value: '_io.size'\n"
  },
  {
    "path": "src/kaitai/weapons_dat.cpp",
    "content": "// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"weapons_dat.h\"\n\nweapons_dat_t::weapons_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, weapons_dat_t* p__root) : kaitai::kstruct(p__io) {\n    m__parent = p__parent;\n    m__root = this;\n    m_label = 0;\n    m_graphics = 0;\n    m_explosion = 0;\n    m_target_flags = 0;\n    m_minimum_range = 0;\n    m_maximum_range = 0;\n    m_damage_upgrade = 0;\n    m_weapon_type = 0;\n    m_weapon_behaviour = 0;\n    m_remove_after = 0;\n    m_explosive_type = 0;\n    m_inner_splash_range = 0;\n    m_medium_splash_range = 0;\n    m_outer_splash_range = 0;\n    m_damage_amount = 0;\n    m_damage_bonus = 0;\n    m_weapon_cooldown = 0;\n    m_damage_factor = 0;\n    m_attack_angle = 0;\n    m_launch_spin = 0;\n    m_x_offset = 0;\n    m_y_offset = 0;\n    m_error_message = 0;\n    m_icon = 0;\n    f_num_lines = false;\n    f_record_size = false;\n    f_file_size = false;\n\n    try {\n        _read();\n    } catch(...) {\n        _clean_up();\n        throw;\n    }\n}\n\nvoid weapons_dat_t::_read() {\n    m_label = new std::vector<uint16_t>();\n    const int l_label = num_lines();\n    for (int i = 0; i < l_label; i++) {\n        m_label->push_back(m__io->read_u2le());\n    }\n    m_graphics = new std::vector<uint32_t>();\n    const int l_graphics = num_lines();\n    for (int i = 0; i < l_graphics; i++) {\n        m_graphics->push_back(m__io->read_u4le());\n    }\n    m_explosion = new std::vector<uint8_t>();\n    const int l_explosion = num_lines();\n    for (int i = 0; i < l_explosion; i++) {\n        m_explosion->push_back(m__io->read_u1());\n    }\n    m_target_flags = new std::vector<attack_type_enum_t>();\n    const int l_target_flags = num_lines();\n    for (int i = 0; i < l_target_flags; i++) {\n        m_target_flags->push_back(static_cast<weapons_dat_t::attack_type_enum_t>(m__io->read_u2le()));\n    }\n    m_minimum_range = new std::vector<uint32_t>();\n    const int l_minimum_range = num_lines();\n    for (int i = 0; i < l_minimum_range; i++) {\n        m_minimum_range->push_back(m__io->read_u4le());\n    }\n    m_maximum_range = new std::vector<uint32_t>();\n    const int l_maximum_range = num_lines();\n    for (int i = 0; i < l_maximum_range; i++) {\n        m_maximum_range->push_back(m__io->read_u4le());\n    }\n    m_damage_upgrade = new std::vector<uint8_t>();\n    const int l_damage_upgrade = num_lines();\n    for (int i = 0; i < l_damage_upgrade; i++) {\n        m_damage_upgrade->push_back(m__io->read_u1());\n    }\n    m_weapon_type = new std::vector<weapon_type_enum_t>();\n    const int l_weapon_type = num_lines();\n    for (int i = 0; i < l_weapon_type; i++) {\n        m_weapon_type->push_back(static_cast<weapons_dat_t::weapon_type_enum_t>(m__io->read_u1()));\n    }\n    m_weapon_behaviour = new std::vector<uint8_t>();\n    const int l_weapon_behaviour = num_lines();\n    for (int i = 0; i < l_weapon_behaviour; i++) {\n        m_weapon_behaviour->push_back(m__io->read_u1());\n    }\n    m_remove_after = new std::vector<uint8_t>();\n    const int l_remove_after = num_lines();\n    for (int i = 0; i < l_remove_after; i++) {\n        m_remove_after->push_back(m__io->read_u1());\n    }\n    m_explosive_type = new std::vector<uint8_t>();\n    const int l_explosive_type = num_lines();\n    for (int i = 0; i < l_explosive_type; i++) {\n        m_explosive_type->push_back(m__io->read_u1());\n    }\n    m_inner_splash_range = new std::vector<uint16_t>();\n    const int l_inner_splash_range = num_lines();\n    for (int i = 0; i < l_inner_splash_range; i++) {\n        m_inner_splash_range->push_back(m__io->read_u2le());\n    }\n    m_medium_splash_range = new std::vector<uint16_t>();\n    const int l_medium_splash_range = num_lines();\n    for (int i = 0; i < l_medium_splash_range; i++) {\n        m_medium_splash_range->push_back(m__io->read_u2le());\n    }\n    m_outer_splash_range = new std::vector<uint16_t>();\n    const int l_outer_splash_range = num_lines();\n    for (int i = 0; i < l_outer_splash_range; i++) {\n        m_outer_splash_range->push_back(m__io->read_u2le());\n    }\n    m_damage_amount = new std::vector<uint16_t>();\n    const int l_damage_amount = num_lines();\n    for (int i = 0; i < l_damage_amount; i++) {\n        m_damage_amount->push_back(m__io->read_u2le());\n    }\n    m_damage_bonus = new std::vector<uint16_t>();\n    const int l_damage_bonus = num_lines();\n    for (int i = 0; i < l_damage_bonus; i++) {\n        m_damage_bonus->push_back(m__io->read_u2le());\n    }\n    m_weapon_cooldown = new std::vector<uint8_t>();\n    const int l_weapon_cooldown = num_lines();\n    for (int i = 0; i < l_weapon_cooldown; i++) {\n        m_weapon_cooldown->push_back(m__io->read_u1());\n    }\n    m_damage_factor = new std::vector<uint8_t>();\n    const int l_damage_factor = num_lines();\n    for (int i = 0; i < l_damage_factor; i++) {\n        m_damage_factor->push_back(m__io->read_u1());\n    }\n    m_attack_angle = new std::vector<uint8_t>();\n    const int l_attack_angle = num_lines();\n    for (int i = 0; i < l_attack_angle; i++) {\n        m_attack_angle->push_back(m__io->read_u1());\n    }\n    m_launch_spin = new std::vector<uint8_t>();\n    const int l_launch_spin = num_lines();\n    for (int i = 0; i < l_launch_spin; i++) {\n        m_launch_spin->push_back(m__io->read_u1());\n    }\n    m_x_offset = new std::vector<uint8_t>();\n    const int l_x_offset = num_lines();\n    for (int i = 0; i < l_x_offset; i++) {\n        m_x_offset->push_back(m__io->read_u1());\n    }\n    m_y_offset = new std::vector<uint8_t>();\n    const int l_y_offset = num_lines();\n    for (int i = 0; i < l_y_offset; i++) {\n        m_y_offset->push_back(m__io->read_u1());\n    }\n    m_error_message = new std::vector<uint16_t>();\n    const int l_error_message = num_lines();\n    for (int i = 0; i < l_error_message; i++) {\n        m_error_message->push_back(m__io->read_u2le());\n    }\n    m_icon = new std::vector<uint16_t>();\n    const int l_icon = num_lines();\n    for (int i = 0; i < l_icon; i++) {\n        m_icon->push_back(m__io->read_u2le());\n    }\n}\n\nweapons_dat_t::~weapons_dat_t() {\n    _clean_up();\n}\n\nvoid weapons_dat_t::_clean_up() {\n    if (m_label) {\n        delete m_label; m_label = 0;\n    }\n    if (m_graphics) {\n        delete m_graphics; m_graphics = 0;\n    }\n    if (m_explosion) {\n        delete m_explosion; m_explosion = 0;\n    }\n    if (m_target_flags) {\n        delete m_target_flags; m_target_flags = 0;\n    }\n    if (m_minimum_range) {\n        delete m_minimum_range; m_minimum_range = 0;\n    }\n    if (m_maximum_range) {\n        delete m_maximum_range; m_maximum_range = 0;\n    }\n    if (m_damage_upgrade) {\n        delete m_damage_upgrade; m_damage_upgrade = 0;\n    }\n    if (m_weapon_type) {\n        delete m_weapon_type; m_weapon_type = 0;\n    }\n    if (m_weapon_behaviour) {\n        delete m_weapon_behaviour; m_weapon_behaviour = 0;\n    }\n    if (m_remove_after) {\n        delete m_remove_after; m_remove_after = 0;\n    }\n    if (m_explosive_type) {\n        delete m_explosive_type; m_explosive_type = 0;\n    }\n    if (m_inner_splash_range) {\n        delete m_inner_splash_range; m_inner_splash_range = 0;\n    }\n    if (m_medium_splash_range) {\n        delete m_medium_splash_range; m_medium_splash_range = 0;\n    }\n    if (m_outer_splash_range) {\n        delete m_outer_splash_range; m_outer_splash_range = 0;\n    }\n    if (m_damage_amount) {\n        delete m_damage_amount; m_damage_amount = 0;\n    }\n    if (m_damage_bonus) {\n        delete m_damage_bonus; m_damage_bonus = 0;\n    }\n    if (m_weapon_cooldown) {\n        delete m_weapon_cooldown; m_weapon_cooldown = 0;\n    }\n    if (m_damage_factor) {\n        delete m_damage_factor; m_damage_factor = 0;\n    }\n    if (m_attack_angle) {\n        delete m_attack_angle; m_attack_angle = 0;\n    }\n    if (m_launch_spin) {\n        delete m_launch_spin; m_launch_spin = 0;\n    }\n    if (m_x_offset) {\n        delete m_x_offset; m_x_offset = 0;\n    }\n    if (m_y_offset) {\n        delete m_y_offset; m_y_offset = 0;\n    }\n    if (m_error_message) {\n        delete m_error_message; m_error_message = 0;\n    }\n    if (m_icon) {\n        delete m_icon; m_icon = 0;\n    }\n}\n\nint32_t weapons_dat_t::num_lines() {\n    if (f_num_lines)\n        return m_num_lines;\n    m_num_lines = (file_size() / record_size());\n    f_num_lines = true;\n    return m_num_lines;\n}\n\nint8_t weapons_dat_t::record_size() {\n    if (f_record_size)\n        return m_record_size;\n    m_record_size = 42;\n    f_record_size = true;\n    return m_record_size;\n}\n\nint32_t weapons_dat_t::file_size() {\n    if (f_file_size)\n        return m_file_size;\n    m_file_size = _io()->size();\n    f_file_size = true;\n    return m_file_size;\n}\n"
  },
  {
    "path": "src/kaitai/weapons_dat.h",
    "content": "#ifndef WEAPONS_DAT_H_\n#define WEAPONS_DAT_H_\n\n// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\n#include \"kaitai/kaitaistruct.h\"\n#include <stdint.h>\n#include <vector>\n\n#if KAITAI_STRUCT_VERSION < 9000L\n#error \"Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required\"\n#endif\n\nclass weapons_dat_t : public kaitai::kstruct {\n\npublic:\n\n    enum attack_type_enum_t {\n        ATTACK_TYPE_ENUM_AIR_ONLY = 1,\n        ATTACK_TYPE_ENUM_GROUND_ONLY = 2,\n        ATTACK_TYPE_ENUM_GROUND_AND_AIR = 3,\n        ATTACK_TYPE_ENUM_UNITS_ONLY = 4,\n        ATTACK_TYPE_ENUM_GROUND_UNITS_ONLY = 18\n    };\n\n    enum weapon_type_enum_t {\n        WEAPON_TYPE_ENUM_NDEPENDENT = 0,\n        WEAPON_TYPE_ENUM_EXPLOSIVE = 1,\n        WEAPON_TYPE_ENUM_CONCUSSIVE = 2,\n        WEAPON_TYPE_ENUM_NORMAL = 3,\n        WEAPON_TYPE_ENUM_IGNORE_AMOR = 4\n    };\n\n    weapons_dat_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, weapons_dat_t* p__root = 0);\n\nprivate:\n    void _read();\n    void _clean_up();\n\npublic:\n    ~weapons_dat_t();\n\nprivate:\n    bool f_num_lines;\n    int32_t m_num_lines;\n\npublic:\n\n    /**\n     * A division of file size though the record size gives the number of records in the file to parse.\n     */\n    int32_t num_lines();\n\nprivate:\n    bool f_record_size;\n    int8_t m_record_size;\n\npublic:\n\n    /**\n     * The size of one data record. This is all type sizes in the format summarized.\n     */\n    int8_t record_size();\n\nprivate:\n    bool f_file_size;\n    int32_t m_file_size;\n\npublic:\n    int32_t file_size();\n\nprivate:\n    std::vector<uint16_t>* m_label;\n    std::vector<uint32_t>* m_graphics;\n    std::vector<uint8_t>* m_explosion;\n    std::vector<attack_type_enum_t>* m_target_flags;\n    std::vector<uint32_t>* m_minimum_range;\n    std::vector<uint32_t>* m_maximum_range;\n    std::vector<uint8_t>* m_damage_upgrade;\n    std::vector<weapon_type_enum_t>* m_weapon_type;\n    std::vector<uint8_t>* m_weapon_behaviour;\n    std::vector<uint8_t>* m_remove_after;\n    std::vector<uint8_t>* m_explosive_type;\n    std::vector<uint16_t>* m_inner_splash_range;\n    std::vector<uint16_t>* m_medium_splash_range;\n    std::vector<uint16_t>* m_outer_splash_range;\n    std::vector<uint16_t>* m_damage_amount;\n    std::vector<uint16_t>* m_damage_bonus;\n    std::vector<uint8_t>* m_weapon_cooldown;\n    std::vector<uint8_t>* m_damage_factor;\n    std::vector<uint8_t>* m_attack_angle;\n    std::vector<uint8_t>* m_launch_spin;\n    std::vector<uint8_t>* m_x_offset;\n    std::vector<uint8_t>* m_y_offset;\n    std::vector<uint16_t>* m_error_message;\n    std::vector<uint16_t>* m_icon;\n    weapons_dat_t* m__root;\n    kaitai::kstruct* m__parent;\n\npublic:\n\n    /**\n     * The name of the weapon, displayed when you highlight its icon in the control bar. [pointer to stat_txt.tbl]\n     */\n    std::vector<uint16_t>* label() const { return m_label; }\n\n    /**\n     * The main graphics that the weapon uses. 0-Scourge = No graphics.[pointer to flingy.dat]\n     */\n    std::vector<uint32_t>* graphics() const { return m_graphics; }\n\n    /**\n     * Effect the weapon has on the area around the target after hitting its target. Used to determine different type of spell effects and splash damage.\n     * TODO: create enum\n     * 0 = Nothing\n     * 1 = Lockdown\n     * 2 = Irradiate\n     * 3 = Spider Mines (Chase Unit)\n     * 4 = Normal\n     * 5 = No Damage\n     * 6 = No Damage\n     * 7 = EMP Shockwave\n     * 8 = Yamato Gun\n     * 9 = No Damage\n     * 10 = No Damage\n     * 11 = No Damage\n     * 12 = No Damage\n     * 13 = Broodling\n     * 14 = Dark Swarm\n     * 15 = Plague\n     * 16 = Consume\n     * 17 = Ensnare\n     * 18 = Parasite\n     * 19 = Psi Storm\n     * 20 = Normal\n     * 21 = Normal\n     * 22 = Stasis\n     * 23 = 1/4 Damage?\n     * 24 = Normal\n     * 25 = 1/3 Damage?\n     */\n    std::vector<uint8_t>* explosion() const { return m_explosion; }\n    std::vector<attack_type_enum_t>* target_flags() const { return m_target_flags; }\n\n    /**\n     * Minimal range from which the weapon can be used.\n     * TODO: StaDat shows here value/16 but no sure why.\n     */\n    std::vector<uint32_t>* minimum_range() const { return m_minimum_range; }\n\n    /**\n     * Maximal range from which the weapon can be used.\n     * TODO: StaDat shows here value/16 but no sure why.\n     */\n    std::vector<uint32_t>* maximum_range() const { return m_maximum_range; }\n\n    /**\n     * The upgrade that will increase the damage dealt by the weapon by the \"Bonus\" value.\n     * Pointer to [upgrades.dat]\n     */\n    std::vector<uint8_t>* damage_upgrade() const { return m_damage_upgrade; }\n\n    /**\n     * The type of damage the weapon does. Normal, Explosive and Concussive do different amount of damage to units of different Size (Small, Medium or Large): Normal does equal damage to Small, Medium and Large. Explosive does 50% to Small and 75% to Medium. Concussive does 50% to Medium and 25% to Large.  Independent deals 1 point of damage every second attack, regardless of target's armor.\n     */\n    std::vector<weapon_type_enum_t>* weapon_type() const { return m_weapon_type; }\n\n    /**\n     * Determines how the weapon sprite will \"behave\" when it attacks the target. Weapon behaviours that \"Follow\" will track the target as it moves, those that \"Don't Follow\" will strike the place where the target was at the moment of attack.\n     * TODO: take enum values from StarDat\n     */\n    std::vector<uint8_t>* weapon_behaviour() const { return m_weapon_behaviour; }\n\n    /**\n     * Time until the weapon is removed if it does not hit a target. 1 game second equals: on Fastest-24, on Faster-21, on Fast-18, on Normal-15, on Slow-12, on Slower-9 and on Slowest-6.\n     */\n    std::vector<uint8_t>* remove_after() const { return m_remove_after; }\n\n    /**\n     * Effect the weapon has on the area around the target after hitting its target. Used to determine different type of spell effects and splash damage.\n     */\n    std::vector<uint8_t>* explosive_type() const { return m_explosive_type; }\n\n    /**\n     * Distance from the target at which the weapon will deal 100% of its base damage. Works ONLY if the \"Explosion\" is set to \"Nuclear Missile\", \"Splash (Radial)\", \"Splash (Enemy)\" or \"Splash (Air)\".\n     */\n    std::vector<uint16_t>* inner_splash_range() const { return m_inner_splash_range; }\n\n    /**\n     * Distance from the target at which the weapon will deal 50% of its base damage. Works ONLY if the \"Explosion\" is set to \"Nuclear Missile\", \"Splash (Radial)\", \"Splash (Enemy)\" or \"Splash (Air)\".\n     */\n    std::vector<uint16_t>* medium_splash_range() const { return m_medium_splash_range; }\n\n    /**\n     * Distance from the target at which the weapon will deal 25% of its base damage. Works ONLY if the \"Explosion\" is set to \"Nuclear Missile\", \"Splash (Radial)\", \"Splash (Enemy)\" or \"Splash (Air)\".\n     */\n    std::vector<uint16_t>* outer_splash_range() const { return m_outer_splash_range; }\n\n    /**\n     * The basic amount of damage the weapon will inflict when it hits.\n     */\n    std::vector<uint16_t>* damage_amount() const { return m_damage_amount; }\n\n    /**\n     * The amount of damage added to the basic value for each level of the upgrade.\n     */\n    std::vector<uint16_t>* damage_bonus() const { return m_damage_bonus; }\n\n    /**\n     * \"Reload time\" - time delay between two attacks. Depends on the game speed used. 1 game second equals: on Fastest-24, on Faster-21, on Fast-18, on Normal-15, on Slow-12, on Slower-9 and on Slowest-6. Value of 0 will crash the game.\n     */\n    std::vector<uint8_t>* weapon_cooldown() const { return m_weapon_cooldown; }\n\n    /**\n     * Usually, multiple this value by the Damage Amount to get the total damage that is DISPLAYED for the weapon. To a degree also the number of weapons used per attack, but anything other than 2 will result in 1 weapon being used. (e.g. Goliath, Scout and Valkyrie use 2 missiles per attack).\n     */\n    std::vector<uint8_t>* damage_factor() const { return m_damage_factor; }\n\n    /**\n     * Angle within which the weapon can be fired without waiting for the unit's graphics to turn. 128 = 180 degrees.\n     */\n    std::vector<uint8_t>* attack_angle() const { return m_attack_angle; }\n\n    /**\n     * Angle by which the weapon's sprite will spin after it is spawned. 128 = 180 degrees.\n     */\n    std::vector<uint8_t>* launch_spin() const { return m_launch_spin; }\n\n    /**\n     * Distance (in pixels) from the front of the attacking unit (depending on which direction it is facing), at which the weapon's sprite will be spawned.\n     */\n    std::vector<uint8_t>* x_offset() const { return m_x_offset; }\n\n    /**\n     * Distance (in pixels) from the top of the attacking unit, at which the weapon's sprite will be spawned.\n     */\n    std::vector<uint8_t>* y_offset() const { return m_y_offset; }\n\n    /**\n     * The line displayed when the weapon is to acquire an invalid target (e.g. attacking a Mutalisk with a ground-only weapon, like Flamethrower) [pointer to stat_txt.tbl]\n     */\n    std::vector<uint16_t>* error_message() const { return m_error_message; }\n\n    /**\n     * The icon used for the weapon. [pointer to a frame in unit\\cmdbtns\\cmdicons.grp]\n     */\n    std::vector<uint16_t>* icon() const { return m_icon; }\n    weapons_dat_t* _root() const { return m__root; }\n    kaitai::kstruct* _parent() const { return m__parent; }\n};\n\n#endif  // WEAPONS_DAT_H_\n"
  },
  {
    "path": "src/kaitai/weapons_dat.ksy",
    "content": "meta:\n  id: weapons_dat\n  endian: le\n\nseq:\n  - id: label\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The name of the weapon, displayed when you highlight its icon in the control bar. [pointer to stat_txt.tbl]\n\n  - id: graphics\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The main graphics that the weapon uses. 0-Scourge = No graphics.[pointer to flingy.dat]\n\n  - id: explosion\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Effect the weapon has on the area around the target after hitting its target. Used to determine different type of spell effects and splash damage.\n      TODO: create enum\n      0 = Nothing\n      1 = Lockdown\n      2 = Irradiate\n      3 = Spider Mines (Chase Unit)\n      4 = Normal\n      5 = No Damage\n      6 = No Damage\n      7 = EMP Shockwave\n      8 = Yamato Gun\n      9 = No Damage\n      10 = No Damage\n      11 = No Damage\n      12 = No Damage\n      13 = Broodling\n      14 = Dark Swarm\n      15 = Plague\n      16 = Consume\n      17 = Ensnare\n      18 = Parasite\n      19 = Psi Storm\n      20 = Normal\n      21 = Normal\n      22 = Stasis\n      23 = 1/4 Damage?\n      24 = Normal\n      25 = 1/3 Damage?\n\n  - id: target_flags\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    enum: attack_type_enum\n    # TODO: work on this bitfield (DatEdit has better definition)\n    # 200 Bytes | 1 Integer / Weapon\n    #  1 = Attacks Air only\n    #  2 = Attacks Ground only\n    #  3 = Attacks Ground and Air\n    #  4 = Units Only (No Buildings)\n    # 18 = Ground Units (No Hover) Only\n\n  - id: minimum_range\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Minimal range from which the weapon can be used.\n      TODO: StaDat shows here value/16 but no sure why.\n\n  - id: maximum_range\n    type: u4\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Maximal range from which the weapon can be used.\n      TODO: StaDat shows here value/16 but no sure why.\n\n  - id: damage_upgrade\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The upgrade that will increase the damage dealt by the weapon by the \"Bonus\" value.\n      Pointer to [upgrades.dat]\n\n  - id: weapon_type\n    type: u1\n    enum: weapon_type_enum\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The type of damage the weapon does. Normal, Explosive and Concussive do different amount of damage to units of different Size (Small, Medium or Large): Normal does equal damage to Small, Medium and Large. Explosive does 50% to Small and 75% to Medium. Concussive does 50% to Medium and 25% to Large.  Independent deals 1 point of damage every second attack, regardless of target's armor.\n\n  - id: weapon_behaviour\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Determines how the weapon sprite will \"behave\" when it attacks the target. Weapon behaviours that \"Follow\" will track the target as it moves, those that \"Don't Follow\" will strike the place where the target was at the moment of attack.\n      TODO: take enum values from StarDat\n    # 0 = Flies to target\n    # 1 = Seeks Target\n    # 2 = Appears on Target\n    # 4 = Persistant Explosion\n    # 5 = Wraps around Target?\n    # 6 = Suicide\n    # 7 = Bounce\n\n  - id: remove_after\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Time until the weapon is removed if it does not hit a target. 1 game second equals: on Fastest-24, on Faster-21, on Fast-18, on Normal-15, on Slow-12, on Slower-9 and on Slowest-6.\n\n  - id: explosive_type\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Effect the weapon has on the area around the target after hitting its target. Used to determine different type of spell effects and splash damage.\n    # TODO: copy values from StarDat\n    #  1 = Normal\n    #  2 = Normal\n    #  3 = Normal\n    #  4 = Lockdown\n    #  5 = Unknown\n    #  6 = Parasite\n    #  7 = Spawn Broodlings\n    #  8 = EMP Shockwave (No gfx, just energy drain)\n    #  9 = Irradiate\n    # 10 = Ensnare\n    # 11 = Plague\n    # 12 = Stasis\n    # 13 = Dark Swarm\n    # 14 = Normal\n    # 15 = Normal\n\n  - id: inner_splash_range\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Distance from the target at which the weapon will deal 100% of its base damage. Works ONLY if the \"Explosion\" is set to \"Nuclear Missile\", \"Splash (Radial)\", \"Splash (Enemy)\" or \"Splash (Air)\".\n\n  - id: medium_splash_range\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Distance from the target at which the weapon will deal 50% of its base damage. Works ONLY if the \"Explosion\" is set to \"Nuclear Missile\", \"Splash (Radial)\", \"Splash (Enemy)\" or \"Splash (Air)\".\n\n  - id: outer_splash_range\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Distance from the target at which the weapon will deal 25% of its base damage. Works ONLY if the \"Explosion\" is set to \"Nuclear Missile\", \"Splash (Radial)\", \"Splash (Enemy)\" or \"Splash (Air)\".\n\n  - id: damage_amount\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The basic amount of damage the weapon will inflict when it hits.\n\n  - id: damage_bonus\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The amount of damage added to the basic value for each level of the upgrade.\n\n  - id: weapon_cooldown\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      \"Reload time\" - time delay between two attacks. Depends on the game speed used. 1 game second equals: on Fastest-24, on Faster-21, on Fast-18, on Normal-15, on Slow-12, on Slower-9 and on Slowest-6. Value of 0 will crash the game.\n\n  - id: damage_factor\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Usually, multiple this value by the Damage Amount to get the total damage that is DISPLAYED for the weapon. To a degree also the number of weapons used per attack, but anything other than 2 will result in 1 weapon being used. (e.g. Goliath, Scout and Valkyrie use 2 missiles per attack).\n\n  - id: attack_angle\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Angle within which the weapon can be fired without waiting for the unit's graphics to turn. 128 = 180 degrees.\n\n  - id: launch_spin\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Angle by which the weapon's sprite will spin after it is spawned. 128 = 180 degrees.\n\n  - id: x_offset\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Distance (in pixels) from the front of the attacking unit (depending on which direction it is facing), at which the weapon's sprite will be spawned.\n\n  - id: y_offset\n    type: u1\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      Distance (in pixels) from the top of the attacking unit, at which the weapon's sprite will be spawned.\n\n  - id: error_message\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The line displayed when the weapon is to acquire an invalid target (e.g. attacking a Mutalisk with a ground-only weapon, like Flamethrower) [pointer to stat_txt.tbl]\n\n  - id: icon\n    type: u2\n    repeat: expr\n    repeat-expr: num_lines\n    doc: |\n      The icon used for the weapon. [pointer to a frame in unit\\cmdbtns\\cmdicons.grp]\n\ninstances:\n  num_lines:\n    value: file_size / record_size\n    doc: |\n      A division of file size though the record size gives the number of records in the file to parse.\n\n  record_size:\n    value: 42\n    doc: |\n      The size of one data record. This is all type sizes in the format summarized.\n\n  file_size:\n    value: '_io.size'\n\nenums:\n  attack_type_enum:\n    1: air_only\n    2: ground_only\n    3: ground_and_air\n    4: units_only # no buildings\n    18: ground_units_only # no hover units\n\n  weapon_type_enum:\n    0: ndependent\n    1: explosive\n    2: concussive\n    3: normal\n    4: ignore_amor\n\n"
  },
  {
    "path": "src/libgrp/Exceptions/GRPException.cpp",
    "content": "#include \"GRPException.hpp\"\n\nvoid GRPException::SetErrorMessage(const std::string &errorMessage)\n{\n    humanReadableError = \"GRPException: \";\n    humanReadableError.append(errorMessage);\n}\n\nstd::string GRPException::GetErrorMessage()\n{\n    return humanReadableError;\n}"
  },
  {
    "path": "src/libgrp/Exceptions/GRPException.hpp",
    "content": "#ifndef GRPException_H\n#define GRPException_H\n\n#include <exception>\n#include <string>\n\n//!The base exception class\n/*!A base exception class for which all other GRPImage/Frame and\n *Colorpalettes are based on\n * \\pre NA\n * \\post NA\n * \\note */\n\nclass GRPException : public virtual std::exception\n{\n    \npublic:\n    \n    //!Set the human readable message\n    /*!Set a string with a message for the user/developer\n     *  to see.\n     * \\pre NA\n     * \\post Sets message to string\n     * \\note NA*/\n    void SetErrorMessage(const std::string &errorMessage);\n    \n    ~GRPException() throw() {}\n    virtual std::string GetErrorMessage();\nprotected:\n        //Stored message for error throw\n       std::string humanReadableError;\nprivate:\n    \n};\n#endif"
  },
  {
    "path": "src/libgrp/Exceptions/GRPFrame/GRPFrameException.cpp",
    "content": ""
  },
  {
    "path": "src/libgrp/Exceptions/GRPFrame/GRPFrameException.hpp",
    "content": "#ifndef GRPFrameException_Header\n#define GRPFrameException_Header\n\n#include \"../GRPException.hpp\"\n\nclass GRPFrameException : public GRPException {};\nclass GRPFrameInvalidFrameDemensions : public GRPFrameException {};\nclass GRPFrameInvalidImageDemensions : public GRPFrameException {};\n\n#endif"
  },
  {
    "path": "src/libgrp/Exceptions/GRPImage/GRPImageException.cpp",
    "content": ""
  },
  {
    "path": "src/libgrp/Exceptions/GRPImage/GRPImageException.hpp",
    "content": "#ifndef GRPImageException_Header\n#define GRPImageException_Header\n\n#include \"../GRPException.hpp\"\nclass GRPImageException : public GRPException {};\n\nclass GRPImageInvalidFrameNumber : public GRPImageException {};\nclass GRPImageNoLoadedPaletteSet : public GRPImageException {};\nclass GRPImageNoFrameLoaded : public GRPImageException {};\nclass GRPImageImageMagickNotCompiledIn : public GRPImageException {};\n\n#endif"
  },
  {
    "path": "src/libgrp/GRPFrame/GRPFrame.cpp",
    "content": "#include \"GRPFrame.hpp\"\n\nGRPFrame::GRPFrame()\n{\n  xOffset = 0;\n  yOffset = 0;\n  width = 0;\n  height = 0;\n  dataOffset = 0;\n}\n\nvoid GRPFrame::SetImageSize(const uint8_t &inputFrameWidth, const uint8_t &inputFrameHeight)\n{\n  if(inputFrameWidth <= 0 || inputFrameHeight <= 0)\n  {\n    GRPFrameInvalidFrameDemensions badDemensions;\n    badDemensions.SetErrorMessage(\"Invalid Frame width\");\n    throw badDemensions;\n  }\n  width = inputFrameWidth;\n  height = inputFrameHeight;\n}\n\nuint8_t GRPFrame::GetImageWidth()\n{\n  return width;\n}\nuint8_t GRPFrame::GetImageHeight()\n{\n  return height;\n}\n\nvoid GRPFrame::SetImageOffsets(const uint8_t &inputXOffset, const uint8_t &inputYOffset)\n{\n  xOffset = inputXOffset;\n  yOffset = inputYOffset;\n}\nuint8_t GRPFrame::GetXOffset()\n{\n  return xOffset;\n}\nuint8_t GRPFrame::GetYOffset()\n{\n  return yOffset;\n}\nvoid GRPFrame::SetDataOffset(const uint32_t &inputDataOffset)\n{\n  dataOffset = inputDataOffset;\n}\nuint32_t GRPFrame::GetDataOffset()\n{\n  return dataOffset;\n}\n"
  },
  {
    "path": "src/libgrp/GRPFrame/GRPFrame.hpp",
    "content": "#ifndef GRPFrame_Header\n#define GRPFrame_Header\n\n/*!GRPFrame Datastructure\n *  \\brief     A datastructure for holding a the specific image data\n *  \\details   Contains one image from the a GRPImage, this data structure\n *              is normally in a list or vector of images.\n *  \\author    Bradley Clemetson\n *  \\version   1.0.0\n *  \\date      July 8, 2013\n *  \\copyright LGPLv2\n */\n\n#include <list>\n#include \"../Exceptions/GRPFrame/GRPFrameException.hpp\"\n\n//Allow Windows to use 8/16/32 byte values\n#if defined(_WIN32)\n#include <stdint.h>\ntypedef uint8_t u_int8_t;\ntypedef uint16_t u_int16_t;\ntypedef uint32_t u_int32_t;\n#else\n#include <inttypes.h>\n#endif\n\n//Used to map what pixels are in a image\n//are set to Palette values and location\n//Position 0,0 is the upper left corner\nstruct UniquePixel\n{\n  int xPosition;\n  int yPosition;\n  uint8_t colorPaletteReference;\n};\n\nclass GRPFrame\n{\npublic:\n  GRPFrame();\n\n\n  //!Sets the Image Size\n  /*!Sets the size of the frame width and height\n   * \\pre NA\n   * \\param[in] inputFrameWidth The image frame width (Normally GrpFrame's maxWidth)\n   * \\param[in] inputFrameHeight The image frame height (Normally GrpFrame's maxHeight)\n   * \\note Would like to use this is query the owner GRPImage if bigger then maxWidth or maxheight*/\n  void SetImageSize(const uint8_t &inputFrameWidth, const uint8_t &inputFrameHeight);\n\n  //!Gets the image width\n  /*!Gets the Image width\n   * \\pre NA\n   * \\returns The image width\n   * \\note NA*/\n  uint8_t GetImageWidth();\n\n  //!Gets the image height\n  /*!Gets the Image height\n   * \\pre NA\n   * \\returns The image height\n   * \\note NA*/\n  uint8_t GetImageHeight();\n\n  //!Sets the Image Size\n  /*!Sets the size of the frame width and height\n   * \\pre NA\n   * \\param[in] inputXOffset The initial image X offset where the start of the image is to be drawn\n   * \\param[in] inputYOffset The initial image Y offset where the start of the image is to be drawn\n   * \\note Would like to use this is query the owner GRPImage if bigger then maxWidth or maxheight*/\n  void SetImageOffsets(const uint8_t &inputXOffset, const uint8_t &inputYOffset);\n\n  //!Gets the image X offset\n  /*!Gets the Image X offset\n   * \\pre NA\n   * \\returns The image X offset\n   * \\note NA*/\n  uint8_t GetXOffset();\n\n  //!Gets the image Y offset\n  /*!Gets the Image Y offset\n   * \\pre NA\n   * \\returns The image Y offset\n   * \\note NA*/\n  uint8_t GetYOffset();\n\n  //!Sets the Image Size\n  /*!Sets the size of the frame width and height\n   * \\pre NA\n   * \\param[in] inputDataOffset The initial image X offset where the start of the image is to be drawn\n   * \\note Would like to use this is query the owner GRPImage if bigger inputDataOffset is bigger then whole file*/\n  void SetDataOffset(const uint32_t &inputDataOffset);\n\n  //!Gets the image data offset\n  /*!Gets the Image data offset\n   * \\pre NA\n   * \\returns The image data offset\n   * \\note NA*/\n  uint32_t GetDataOffset();\n\n\n\n  //The unique pixel data, to be placed on to the final converted canvas\n  //or screen surface\n  std::list<UniquePixel> frameData;\n\nprotected:\n\n  //The drawing image width/height of the image in the frame\n  uint8_t width;\n  uint8_t height;\n\n  //Tells us where to begin drawing\n  uint8_t xOffset;\n  uint8_t yOffset;\n\n  //Offset of the Framedata (starting at the beginning of the GRPfile)\n  uint32_t dataOffset;\nprivate:\n};\n\n#endif"
  },
  {
    "path": "src/libgrp/GRPImage/GRPImage.cpp",
    "content": "#include \"GRPImage.hpp\"\n#include \"PngExporter.h\"\n#include \"StringUtil.h\"\n\n#include <string.h>\n#include <iostream>\n#include <cmath>\n#include <sstream>\n#include <unordered_map>\n\nusing namespace std;\n\n//#define VERBOSE 10 // debug\n\nGRPImage::GRPImage() :\n  mCurrentPalette(nullptr),\n  mNumberOfFrames(0),\n  mMaxImageWidth(0),\n  mMaxImageHeight(0),\n  mUncompressed(false)\n{\n\n}\n\nGRPImage::GRPImage(std::vector<char> *inputImage, bool removeDuplicates) :\n  mCurrentPalette(nullptr),\n  mNumberOfFrames(0),\n  mMaxImageWidth(0),\n  mMaxImageHeight(0),\n  mUncompressed(false)\n{\n  LoadImage(inputImage, removeDuplicates);\n}\n\nGRPImage::GRPImage(std::string filePath, bool removeDuplicates) :\n  mCurrentPalette(nullptr),\n  mNumberOfFrames(0),\n  mMaxImageWidth(0),\n  mMaxImageHeight(0),\n  mUncompressed(false)\n{\n  LoadImage(filePath, removeDuplicates);\n}\n\nGRPImage::~GRPImage()\n{\n  CleanGRPImage();\n}\n\nbool GRPImage::DetectUncompressed(std::vector<char> *inputImage)\n{\n  bool uncompressed = false;\n\n  std::vector<char>::iterator currentDataPosition = inputImage->begin();\n\n  // jump over the basic GRP header info\n  currentDataPosition += 2;\n\n  // jump over the maximum image width & height\n  currentDataPosition += 2;\n  currentDataPosition += 2;\n\n  //Temporary image demension placeholders\n  uint8_t tempWidth = 0;\n  uint8_t tempHeight = 0;\n  uint32_t tempDataOffset = 0;\n\n  uint32_t firstOffset = 0;\n  int imagePayload = 0;\n\n  //Create a hash table to stop the creation of duplicates\n  std::unordered_map<uint32_t, bool> uniqueGRPImages;\n  std::unordered_map<uint32_t, bool>::const_iterator uniqueGRPCheck;\n\n  //Load each GRP Header into a GRPFrame & Allocate\n  for(int currentGRPFrame = 0; currentGRPFrame < mNumberOfFrames; currentGRPFrame++)\n  {\n    //Jump over the image xOffset\n    currentDataPosition += 1;\n\n    //Jump over the image yOffset\n    currentDataPosition += 1;\n\n    //Read in the image width\n    std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &tempWidth);\n    currentDataPosition += 1;\n\n    //Read in the image height\n    std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &tempHeight);\n    currentDataPosition += 1;\n\n    //Read in the image dataOffset\n    std::copy(currentDataPosition, (currentDataPosition + 4),(char *) &tempDataOffset);\n    currentDataPosition += 4;\n\n    uniqueGRPCheck = uniqueGRPImages.find(tempDataOffset);\n    if(uniqueGRPCheck == uniqueGRPImages.end())\n    {\n      imagePayload += tempWidth * tempHeight;\n    }\n\n    uniqueGRPImages.insert(std::make_pair(tempDataOffset, true));\n\n    if(firstOffset == 0)\n    {\n      firstOffset = tempDataOffset;\n    }\n  }\n\n  //cout << \"completeImageSize: \"  << to_string(imagePayload + firstOffset) << endl;\n\n  if(firstOffset + imagePayload == inputImage->size())\n  {\n    uncompressed = true;\n  }\n  else\n  {\n    uncompressed = false;\n  }\n\n  return uncompressed;\n}\n\nvoid GRPImage::DecodeHeader(std::vector<char> *inputImage)\n{\n  std::vector<char>::iterator currentDataPosition = inputImage->begin();\n\n  //Get basic GRP header info\n  std::copy(currentDataPosition,(currentDataPosition + 2),(char *) &mNumberOfFrames);\n  currentDataPosition += 2;\n\n  //Get the maximum image width & height\n  std::copy(currentDataPosition, (currentDataPosition + 2),(char *) &mMaxImageWidth);\n  currentDataPosition += 2;\n\n  std::copy(currentDataPosition, (currentDataPosition + 2),(char *) &mMaxImageHeight);\n  currentDataPosition += 2;\n}\n\nvoid GRPImage::LoadImage(std::vector<char> *inputImage, bool removeDuplicates)\n{\n  CleanGRPImage();\n  std::vector<char>::iterator currentDataPosition = inputImage->begin();\n\n  DecodeHeader(inputImage);\n\n  mUncompressed = DetectUncompressed(inputImage);\n\n  // jump over the basic GRP header info\n  currentDataPosition += 2;\n\n  // jump over the maximum image width & height\n  currentDataPosition += 2;\n  currentDataPosition += 2;\n\n#if VERBOSE >= 2\n  std::cout << \"GRP Image Number of Frames: \" << mNumberOfFrames << \" maxWidth: \" << mMaxImageWidth << \" maxHeight: \" << mMaxImageHeight << '\\n';\n#endif\n\n  //Temporary image demension placeholders\n  uint8_t tempValue1 = 0;\n  uint8_t tempValue2 = 0;\n  uint32_t tempDataOffset = 0;\n\n  //Create a hash table to stop the creation of duplicates\n  std::unordered_map<uint32_t, bool> uniqueGRPImages;\n  std::unordered_map<uint32_t, bool>::const_iterator uniqueGRPCheck;\n\n  //int bestWidth = 0;\n  //int bestHeight = 0;\n\n  //Load each GRP Header into a GRPFrame & Allocate\n  for(int currentGRPFrame = 0; currentGRPFrame < mNumberOfFrames; currentGRPFrame++)\n  {\n    GRPFrame *currentImageFrame = new GRPFrame;\n\n    //Read in the image xOffset\n    std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &tempValue1);\n    currentDataPosition += 1;\n\n    //Read in the image yOffset\n    std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &tempValue2);\n    currentDataPosition += 1;\n    currentImageFrame->SetImageOffsets(tempValue1, tempValue2);\n\n    //Read in the image width\n    std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &tempValue1);\n    currentDataPosition += 1;\n\n    //Read in the image height\n    std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &tempValue2);\n    currentDataPosition += 1;\n    currentImageFrame->SetImageSize(tempValue1, tempValue2);\n\n    //Read in the image dataOffset\n    std::copy(currentDataPosition, (currentDataPosition + 4),(char *) &tempDataOffset);\n    currentDataPosition += 4;\n    currentImageFrame->SetDataOffset(tempDataOffset);\n\n#if VERBOSE >= 2\n    std::cout << \"Current Frame: \" << currentGRPFrame << \" Width: \" << (int) currentImageFrame->GetImageWidth() << \" Height: \"\n              << (int) currentImageFrame->GetImageHeight() << \"\\nxPosition: \" << (int) currentImageFrame->GetXOffset()\n              << \" yPosition: \" << (int) currentImageFrame->GetYOffset() << \" with offset \" << (int)currentImageFrame->GetDataOffset() << '\\n';\n#endif\n    uniqueGRPCheck = uniqueGRPImages.find(currentImageFrame->GetDataOffset());\n    if(removeDuplicates && (uniqueGRPCheck != uniqueGRPImages.end()))\n    {\n      // in case of not included duplicates delete the frame\n      delete currentImageFrame;\n    }\n    else\n    {\n      //The GRPImage is unique save in the unordered set\n      uniqueGRPImages.insert(std::make_pair<uint32_t,bool>(currentImageFrame->GetDataOffset(),true));\n\n      //Decode Frame here\n      if(mUncompressed)\n      {\n        DecodeGRPFrameDataUncompressed(inputImage, currentImageFrame);\n      }\n      else\n      {\n        DecodeGRPFrameData(inputImage, currentImageFrame);\n      }\n\n      mImageFrames.push_back(currentImageFrame);\n    }\n  }\n\n  if (removeDuplicates)\n  {\n    mNumberOfFrames = mImageFrames.size();\n  }\n}\n\nvoid GRPImage::LoadImage(std::string filePath, bool removeDuplicates)\n{\n  DataChunk dcImage;\n  dcImage.read(filePath);\n  vector<char> vecImage = dcImage.getCharVector();\n\n  LoadImage(&vecImage, removeDuplicates);\n}\n\nvoid GRPImage::DecodeGRPFrameDataUncompressed(std::vector<char> *inputData, GRPFrame *targetFrame)\n{\n  if(targetFrame == NULL || (targetFrame->frameData.size() == 0))\n  {\n    GRPImageNoFrameLoaded noFrameLoaded;\n    noFrameLoaded.SetErrorMessage(\"No GRP Frame is loaded\");\n  }\n  if(mCurrentPalette == NULL)\n  {\n    GRPImageNoLoadedPaletteSet noPaletteLoaded;\n    noPaletteLoaded.SetErrorMessage(\"No palette has been set or loaded\");\n  }\n\n  //Seek to the Row offset data\n  std::vector<char>::iterator currentDataPosition = inputData->begin();\n  currentDataPosition += targetFrame->GetDataOffset();\n\n  //The currentRow (x coordinate) that the decoder is at, it is used to\n  //set the image position.\n  int currentProcessingRow = 0;\n\n  //The initial byte of data from the GRPFile\n  //It is often the operation that will be done\n  //of the proceding data\n  uint8_t rawPacket;\n\n  //The struct keeps a (X,Y) coordinates to the position\n  //of the referenced color to allow for drawing on the screen\n  //or Imagemagick to convert.\n  UniquePixel currentUniquePixel;\n\n  //Goto each row and process the row data\n  for(int currentProcessingHeight = 0; currentProcessingHeight < targetFrame->GetImageHeight(); currentProcessingHeight++)\n  {\n\n#if VERBOSE >= 2\n    //std::cout << \"Current row offset is: \" << (targetFrame->GetDataOffset() + (imageRowOffsets.at(currentProcessingHeight))) << '\\n';\n#endif\n    //Seek to the point of the first byte in the rowData from the\n    //1.Skip over to the Frame data\n    //2.Skip over the size of the targetFrame->size() last time read bytes\n    currentDataPosition = inputData->begin() + targetFrame->frameData.size();\n    currentDataPosition += (targetFrame->GetDataOffset());\n\n    currentProcessingRow = 0;\n\n    while(currentProcessingRow < targetFrame->GetImageWidth())\n    {\n\n        std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &rawPacket);\n        currentDataPosition += 1;\n\n        currentUniquePixel.xPosition = currentProcessingRow;\n        currentUniquePixel.yPosition = currentProcessingHeight;\n        currentUniquePixel.colorPaletteReference = rawPacket;\n        targetFrame->frameData.push_back(currentUniquePixel);\n\n        currentProcessingRow++;\n    }\n  }\n\n#if VERBOSE >= 5\n  std::cout << \"Frame data is size: \" << targetFrame->frameData.size() << '\\n';\n  for(std::list<UniquePixel>::iterator it = targetFrame->frameData.begin(); it != targetFrame->frameData.end(); it++)\n  {\n    std::cout << '(' << it->xPosition << ',' << it->yPosition << \") = \" << (int) it->colorPaletteReference << '\\n';\n  }\n#endif\n}\n\nvoid GRPImage::DecodeGRPFrameData(std::vector<char> *inputData, GRPFrame *targetFrame)\n{\n  if(targetFrame == NULL || (targetFrame->frameData.size() == 0))\n  {\n    GRPImageNoFrameLoaded noFrameLoaded;\n    noFrameLoaded.SetErrorMessage(\"No GRP Frame is loaded\");\n  }\n  if(mCurrentPalette == NULL)\n  {\n    GRPImageNoLoadedPaletteSet noPaletteLoaded;\n    noPaletteLoaded.SetErrorMessage(\"No palette has been set or loaded\");\n  }\n\n\n  //Seek to the Row offset data\n  std::vector<char>::iterator currentDataPosition = inputData->begin();\n  currentDataPosition += targetFrame->GetDataOffset();\n\n  //Create a vector of all the Image row offsets\n  std::vector<uint16_t> imageRowOffsets;\n  imageRowOffsets.resize(targetFrame->GetImageHeight());\n\n  //Read in the ImageRow offsets\n  for (int currentReadingRowOffset = 0; currentReadingRowOffset < targetFrame->GetImageHeight(); currentReadingRowOffset++)\n  {\n    std::copy(currentDataPosition, (currentDataPosition + 2),(char *) &imageRowOffsets.at(currentReadingRowOffset));\n    currentDataPosition += 2;\n  }\n\n  //The currentRow (x coordinate) that the decoder is at, it is used to\n  //set the image position.\n  int currentProcessingRow = 0;\n\n  //The initial byte of data from the GRPFile\n  //It is often the operation that will be done\n  //of the proceding data\n  uint8_t rawPacket;\n\n  //The references to a particular color\n  uint8_t convertedPacket;\n\n  //The struct keeps a (X,Y) coordinates to the position\n  //of the referenced color to allow for drawing on the screen\n  //or Imagemagick to convert.\n  UniquePixel currentUniquePixel;\n\n\n  //Goto each row and process the row data\n  for(int currentProcessingHeight = 0; currentProcessingHeight < targetFrame->GetImageHeight(); currentProcessingHeight++)\n  {\n\n#if VERBOSE >= 2\n    std::cout << \"Current row offset is: \" << (targetFrame->GetDataOffset() + (imageRowOffsets.at(currentProcessingHeight))) << '\\n';\n#endif\n    //Seek to the point of the first byte in the rowData from the\n    //1.Skip over to the Frame data\n    //2.Skip over by the Row offset mentioned in the list\n    currentDataPosition = inputData->begin();\n    currentDataPosition += (targetFrame->GetDataOffset() + imageRowOffsets.at(currentProcessingHeight));\n\n    currentProcessingRow = 0;\n\n    while(currentProcessingRow < targetFrame->GetImageWidth())\n    {\n      std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &rawPacket);\n      currentDataPosition += 1;\n      if(!(rawPacket & 0x80))\n      {\n        //Repeat Operation (The first byte indicates a repeat pixel operation)\n        //The next byte indicates how far down the row to repeat.\n        if(rawPacket & 0x40)\n        {\n          rawPacket &= 0x3f;\n          std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &convertedPacket);\n          currentDataPosition += 1;\n\n          //Set the Player color (Not implemented yet :|\n          //covertedPacket = tableof unitColor[ colorbyte+gr_gamenr];\n          int operationCounter = rawPacket;\n          currentUniquePixel.xPosition = currentProcessingRow;\n          do\n          {\n\n            currentUniquePixel.yPosition = currentProcessingHeight;\n            currentUniquePixel.colorPaletteReference = convertedPacket;\n            targetFrame->frameData.push_back(currentUniquePixel);\n            currentUniquePixel.xPosition++;\n          }\n          while (--operationCounter);\n\n          currentProcessingRow += rawPacket;\n        }\n        else\n        {\n          //Copy Pixel Operation, and how many pixels to copy directly\n          int operationCounter = rawPacket;\n          if(operationCounter > 0)\n          {\n            do\n            {\n              std::copy(currentDataPosition, (currentDataPosition + 1),(char *) &convertedPacket);\n              currentDataPosition += 1;\n\n              currentUniquePixel.xPosition = currentProcessingRow;\n              currentUniquePixel.yPosition = currentProcessingHeight;\n              currentUniquePixel.colorPaletteReference = convertedPacket;\n              targetFrame->frameData.push_back(currentUniquePixel);\n              currentProcessingRow++;\n            }\n            while (--operationCounter);\n          }\n        }\n      }\n      else\n      {\n        //Skip the next \"rawPacket\" # of pixels\n        rawPacket &= 0x7f;\n        currentProcessingRow += rawPacket;\n      }\n    }\n  }\n\n#if VERBOSE >= 5\n  std::cout << \"Frame data is size: \" << targetFrame->frameData.size() << '\\n';\n  for(std::list<UniquePixel>::iterator it = targetFrame->frameData.begin(); it != targetFrame->frameData.end(); it++)\n  {\n    std::cout << '(' << it->xPosition << ',' << it->yPosition << \") = \" << (int) it->colorPaletteReference << '\\n';\n  }\n#endif\n\n}\n\nuint16_t GRPImage::getNumberOfFrames() const\n{\n  return mNumberOfFrames;\n}\nuint16_t GRPImage::getMaxImageWidth() const\n{\n  return mMaxImageWidth;\n}\nuint16_t GRPImage::getMaxImageHeight() const\n{\n  return mMaxImageHeight;\n}\n\nvoid GRPImage::SetColorPalette(std::shared_ptr<AbstractPalette> selectedColorPalette)\n{\n  if(selectedColorPalette)\n    mCurrentPalette = selectedColorPalette;\n}\n\nvoid GRPImage::SaveStitchedPNG(const std::string &outFilePath, int startingFrame, int endingFrame, unsigned int imagesPerRow, bool rgba)\n{\n  vector<int> frameEnumarator;\n\n  for(int i = startingFrame; i < endingFrame; i++)\n  {\n    frameEnumarator.push_back(i);\n  }\n\n  SaveStitchedPNG(outFilePath, frameEnumarator, imagesPerRow, rgba);\n}\n\nvoid GRPImage::SaveStitchedPNG(const std::string &outFilePath, std::vector<int> frameEnumerator, unsigned int imagesPerRow, bool rgba)\n{\n  if(!mCurrentPalette)\n  {\n    GRPImageNoLoadedPaletteSet noPalette;\n    noPalette.SetErrorMessage(\"No loaded set\");\n  }\n\n  shared_ptr<PaletteImage> paletteImage;\n\n  // limit the 'imagePerRow' input parameter in both directions to something useful\n  if((imagesPerRow >= frameEnumerator.size()) || (imagesPerRow == 0))\n  {\n    imagesPerRow = frameEnumerator.size();\n  }\n\n  Color currentPalettePixel;\n  std::stringstream fileOutPath;\n  int currentImageDestinationColumn = 0;\n  unsigned int currentImageDestinationRow = 0;\n\n  int bestWidth = 0;\n  int bestHeight = 0;\n  for(int currentProcessingFrame : frameEnumerator)\n  {\n    GRPFrame *currentImageFrame = mImageFrames.at(currentProcessingFrame);\n\n    // calculate the best width/height for that image (only for uncompressed or only partly exported)\n    if((mUncompressed) || (frameEnumerator.size() != mNumberOfFrames))\n    {\n      if (currentImageFrame->GetXOffset() + currentImageFrame->GetImageWidth() > bestWidth)\n      {\n        bestWidth = currentImageFrame->GetXOffset() + currentImageFrame->GetImageWidth();\n      }\n\n      if (currentImageFrame->GetYOffset() + currentImageFrame->GetImageHeight() > bestHeight)\n      {\n        bestHeight = currentImageFrame->GetYOffset() + currentImageFrame->GetImageHeight();\n      }\n      mMaxImageWidth = bestWidth;\n      mMaxImageHeight = bestHeight;\n    }\n  }\n\n  int image_width = (mMaxImageWidth * imagesPerRow);\n  int image_height = (mMaxImageHeight * (ceil( (float)frameEnumerator.size()/imagesPerRow)));\n\n  // create the complete image with all stitched small images\n  paletteImage = make_shared<PaletteImage>(Size(image_width, image_height));\n\n  for(int currentProcessingFrame : frameEnumerator)\n  {\n    GRPFrame *currentFrame = mImageFrames.at(currentProcessingFrame);\n\n    //If a row in a stitched image is complete, move onto the next row\n    if(currentImageDestinationRow >= imagesPerRow)\n    {\n      currentImageDestinationColumn++;\n      currentImageDestinationRow = 0;\n    }\n\n    //Start appling the pixels with the refence colorpalettes\n    for (std::list<UniquePixel>::iterator currentProcessPixel = currentFrame->frameData.begin(); currentProcessPixel != currentFrame->frameData.end(); currentProcessPixel++)\n    {\n        Pos pixel_pos((currentFrame->GetXOffset() + currentProcessPixel->xPosition) + (mMaxImageWidth * currentImageDestinationRow),\n                      (currentFrame->GetYOffset() + currentProcessPixel->yPosition) + (mMaxImageHeight * currentImageDestinationColumn) );\n\n        paletteImage->at(pixel_pos) = currentProcessPixel->colorPaletteReference;\n    }\n\n    currentImageDestinationRow++;\n  }\n  //Now that all the pixels are in place, lets write the result to disk\n  PngExporter::save(outFilePath, *paletteImage, mCurrentPalette, 0, rgba);\n}\n\nvoid GRPImage::SaveSinglePNG(const std::string &outFilePath, int startingFrame, int endingFrame, bool rgba)\n{\n  SaveSinglePNG(outFilePath, std::vector<std::string>(), startingFrame, endingFrame, rgba);\n}\n\nvoid GRPImage::SaveSinglePNG(const std::string &outFilePath, const std::vector<std::string> &fileNames, int startingFrame, int endingFrame, bool rgba)\n{\n  if(!mCurrentPalette)\n  {\n    GRPImageNoLoadedPaletteSet noPalette;\n    noPalette.SetErrorMessage(\"No loaded set\");\n  }\n\n  shared_ptr<PaletteImage> paletteImage;\n\n  Color currentPalettePixel;\n  std::stringstream fileOutPath;\n\n  unsigned int i = 0;\n  for(int currentProcessingFrame = startingFrame; currentProcessingFrame < endingFrame; ++currentProcessingFrame)\n  {\n    GRPFrame *currentFrame = mImageFrames.at(currentProcessingFrame);\n\n    // create a image for each frame\n    //cout << \"image size: \" << to_string(currentFrame->GetImageWidth()) << \"/\" <<  to_string(currentFrame->GetImageHeight()) << endl;\n    paletteImage = make_shared<PaletteImage>(Size(currentFrame->GetImageWidth(), currentFrame->GetImageHeight()));\n\n    //Start appling the pixels with the refence colorpalettes\n    for (std::list<UniquePixel>::iterator currentProcessPixel = currentFrame->frameData.begin(); currentProcessPixel != currentFrame->frameData.end(); currentProcessPixel++)\n    {\n      Pos pixel_pos((currentProcessPixel->xPosition),\n                    (currentProcessPixel->yPosition));\n      //cout << \"put color to: \" << to_string(pixel_pos.getX()) << \"/\" << to_string(pixel_pos.getY()) << endl;\n\n      paletteImage->at(pixel_pos) = currentProcessPixel->colorPaletteReference;\n    }\n\n    //It's time to write the current frame to a file\n    string frameOutput = outFilePath;\n\n    // if the name vector is empty use the string %d replacer\n    if(fileNames.empty())\n    {\n      replaceString(\"%d\", to_string(currentProcessingFrame), frameOutput);\n    }\n    else\n    {\n      if(i < fileNames.size())\n      {\n        frameOutput += \"/\" + fileNames.at(i);\n      }\n      else\n      {\n        // name fallback in case the input doesn't contain a name\n        frameOutput += \"/\" + to_string(i) + \".png\";\n      }\n    }\n\n    PngExporter::save(frameOutput, *paletteImage, mCurrentPalette, 0, rgba);\n\n    i++;\n  }\n\n}\n\nvoid GRPImage::CleanGRPImage()\n{\n  for(unsigned int i = 0; i < mImageFrames.size(); i++)\n  {\n    GRPFrame *frame = mImageFrames.at(i);\n    delete frame;\n  }\n  mImageFrames.resize(0);\n}\n\n"
  },
  {
    "path": "src/libgrp/GRPImage/GRPImage.hpp",
    "content": "/*!\n *  \\brief     The main\n *  \\details   This class runs all the underlying generic functions required\n * \t\t\t\tfor nearly all objects in the framework\n *  \\author    Bradley Clemetson, from GRPLib Authors\n *  \\version   1.0.0\n *  \\date      Jan 13, 2013\n *  \\copyright LGPLv2\n *  \\section basicsGRPFormat Basic Format Aspects\n *  \\section conventions Naming Conventions\n *  \\section av\n *  \\image html GRPFileLayout.png\n */\n#ifndef GRPImage_Header\n#define GRPImage_Header\n\n#include \"AbstractPalette.h\"\n\n#include \"libgrp/GRPFrame/GRPFrame.hpp\"\n\n#include \"libgrp/Exceptions/GRPImage/GRPImageException.hpp\"\n#include <list>\n#include <fstream>\n\n//Allow Windows to use 8/16/32 byte values\n#if defined(_WIN32)\n#include <stdint.h>\ntypedef uint8_t u_int8_t;\ntypedef uint16_t u_int16_t;\ntypedef uint32_t u_int32_t;\n#else\n#include <unordered_map>\n#include <inttypes.h>\n#endif\n\nenum GRPImageType {STANDARD, SHADOW};\n\nclass GRPImage\n{\n\npublic:\n  GRPImage();\n\n  //!Set image data from memory\n  /*! Use the image data that is loaded in a the specified\n   * vector.\n   * \\pre The inputInput vector must be defined and contain\n   *      valid grp image data. Otherwise there will be decoding\n   *      errors. (garbled up junk images)\n   * \\param[in] inputPalette The memory location of the image\n   *      to be decoded/encoded.\n   * \\param[in] removeDuplicates Remove GRPFrames that are the same\n   * \\warning This will not make a copy of the std::vector<char> data\n   *      so if you delete the vector before/during processing it will likly crash.\n   * \\note Same thing as LoadImage, but on object construction*/\n  GRPImage(std::vector<char> *inputImage, bool removeDuplicates = true);\n\n  //!Load image data from a file (.grp)\n  /*! Load a GRP file to use when decoding/encoding\n   * a GRPImage.\n   * \\pre Filepath must be to a valid .grp image file\n   * \\post The file is loaded into memory for the GRPImage\n   * \\param[in] filePath The file path to the grp image file\n   * \\param[in] removeDuplicates Remove GRPFrames that are the same\n   * \\note NA*/\n  GRPImage(std::string filePath, bool removeDuplicates = true);\n\n  //!Deallocates the GRPImage and it's data\n  /*! Deallocated all data related to the GRP Image\n   * \\pre NA\n   * \\post Data is deleted\n   * \\note NA*/\n  ~GRPImage();\n\n  //!Set image data from memory\n  /*! Use the image data that is loaded in a the specified\n   * vector.\n   * \\pre The inputInput vector must be defined and contain\n   *      valid grp image data. Otherwise there will be decoding\n   *      errors. (garbled up junk images)\n   * \\param[in] inputPalette The memory location of the image\n   *      to be decoded/encoded.\n   * \\param[in] removeDuplicates Remove GRPFrames that are the same\n   * \\warning This will not make a copy of the std::vector<char> data\n   *      so if you delete the vector before/during processing it will likly crash.\n   * \\note NA*/\n  void LoadImage(std::vector<char> *inputImage, bool removeDuplicates = true);\n\n  //!Load image data from a file (.grp)\n  /*! Load a GRP file to use when decoding/encoding\n   * a GRPImage.\n   * \\pre Filepath must be to a valid .grp image file\n   * \\post The file is loaded into memory for the GRPImage\n   * \\param[in] filePath The file path to the grp image file\n   * \\note NA*/\n  void LoadImage(std::string filePath, bool removeDuplicates = true);\n\n  //!Return the number of frames in a GRPImage\n  /*! Return the number of frames in a GRP image animation.\n   * \\pre GRP image data must be defined and loaded into\n   *      imageData.\n   * \\returns The number of image frames in a GRP Image.\n   * \\note NA*/\n  uint16_t getNumberOfFrames() const;\n\n  //!Return the maximum width of any GRP image Frame\n  /*! Returns the maximum width of any GRP image Frame\n   *  allowing for easier decoding and encoding to a\n   *  single image.\n   * \\pre GRPImage must be defined and have imageData loaded\n   * \\returns The maximum width of any individual GRP Frame.\n   * \\note NA*/\n  uint16_t getMaxImageWidth() const;\n  //!Return the maximum height of any GRP image Frame\n  /*! Returns the maximum height of any GRP image Frame\n   *  allowing for easier decoding and encoding to a\n   *  single image.\n   * \\pre GRPImage must be defined and have imageData loaded\n   * \\returns The maximum height of any individual GRP Frame.\n   * \\note NA*/\n  uint16_t getMaxImageHeight() const;\n\n  //!Set the desired colorPalette to use\n  /*!Sets the colorPalette that will be used as reference for image\n   *conversion.\n   * \\param[in] selectedColorPalette The Palette to apply to images\n   * \\warning GRPImage will not delete the color palette upon deallocation,\n   * \\warning If the palette is not the correct palette for the image\n   *      during the conversion process you may get a invalidColors or\n   *      throw exception\n   * \\note NA*/\n  void SetColorPalette(std::shared_ptr<AbstractPalette> selectedColorPalette);\n\n  /*!Save the GRPImage frames to a PNG file via libpng\n   * \\pre GRPImage is loaded.\n   * \\post Outputs a image to the ourFilePath.\n   * \\param[in] outFilePath The output image file path. (use %d for single image frame replace in the exported image path)\n   * \\param[in] startingFrame The first image that you would like saved.\n   * \\param[in] endingFrame The frame you would like to stop saving on.\n   * \\param[in] singleStitchedImage Stitch the GRP frames together into one image.\n   * \\param[in] imagesPerRow If stitching is enabled, how many images should be save per row.\n   * \\note NA*/\n  void SaveStitchedPNG(const std::string &outFilePath, int startingFrame, int endingFrame, unsigned int imagesPerRow, bool rgba);\n\n  void SaveStitchedPNG(const std::string &outFilePath, std::vector<int> frameEnumerator, unsigned int imagesPerRow, bool rgba);\n\n  void SaveSinglePNG(const std::string &outFilePath, int startingFrame, int endingFrame, bool rgba);\n\n  void SaveSinglePNG(const std::string &outFilePath, const std::vector<std::string> &fileNames, int startingFrame, int endingFrame, bool rgba);\n\nprotected:\n\n  //!Deleted any GRPImage data for reuse\n  /*! Deallocated all data related to the GRP Image\n   * \\pre NA\n   * \\post Data is deleted\n   * \\note NA*/\n  void CleanGRPImage();\n\n  //!Decode the GRPFrameData\n  /*!Decode the GRP compression and save the unique pixels to the GRPFrame datastruct\n   * \\pre GRPImage Loaded\n   * \\post GRPImage Frame is decoded into the frame\n   * \\param[in] inputData A vector of the GRPImage file data\n   * \\param[in] targetFrame The frame to store the resulting image data\n   * \\note NA*/\n  void DecodeGRPFrameData(std::vector<char> *inputData, GRPFrame *targetFrame);\n\n  /*!Decode the GRP uncompressed data and save the unique pixels to the GRPFrame datastruct\n   *\n   */\n  void DecodeGRPFrameDataUncompressed(std::vector<char> *inputData, GRPFrame *targetFrame);\n\nprivate:\n  bool DetectUncompressed(std::vector<char> *inputImage);\n\n  void DecodeHeader(std::vector<char> *inputImage);\n\n  //The decoded GRPFrames\n  std::vector<GRPFrame *> mImageFrames;\n\n  //The palette that will be used during conversion\n  std::shared_ptr<AbstractPalette> mCurrentPalette;\n\n\n  //GRPimage Header\n  uint16_t mNumberOfFrames;\n  uint16_t mMaxImageWidth;\n  uint16_t mMaxImageHeight;\n  bool mUncompressed;\n};\n#endif\n"
  },
  {
    "path": "src/libgrp/libgrp.cpp",
    "content": "#include \"libgrp.hpp\"\n\n"
  },
  {
    "path": "src/libgrp/libgrp.hpp",
    "content": "#ifndef libgrp_H\n#define libgrp_H\n/*! \\mainpage General Information\n *  GRP Format Motivation\n *  =====================\n *  It was necessary to minimize memory use because we endeavored to make Blizzard games\\n\n *  playable on low-spec systems. Consequently the GRP format needed to be highly compressed\\n\n *  to maximize the number of frames we could fit in memory. - Patrick Wyatt\n *\n *  libgrp Motivation\n *  ================\n *  1. Extensive Documentation\n *  2. Cross Platform (Windows, Mac OSX, Linux)\n *  3. C++ (Use of OOP Techniques)\\n\n *  While some libraries may offer 1 or 2 of these\n *  aspects, none were are to fulfill all of the requirments. This is\n *  not to imply that the implementation of any of these libraries were\n *  incorrect (in fact many techniques are pulled from them); the goal\n *  was to make the expirence easier to maintain and utilize in other applications.\n *\n *  CMake Build Options\n *  ===================\n *  There are three parameters that can be modified.\\n\n *  1. VERBOSE - The amount of information outputted to the console\n *      while processing GRP files and ColorPalettes.\\n\n *      DEFAULT = 0 Range = [1 - 5]\\n\n *      To set add the cmake flag \"-DVERBOSE=[DesiredValue]\"\\n\\n\n *  2. UNITTESTS - Compile the Boost Unit tests inluded with libgrp.\n *      This will require that the Boost Library with the Unit Test Framework Module\n *      be compiled and installed.\\n To enable unit tests\n *      Add the cmake flag \"-DUNITTESTS=on\"\\n\\n\n *  3. SAMPLECODE - To compile the sample code.\\n\n *      Add the cmake flag \"-DSAMPLECODE=on\"\\n\n *\n *  Sample Code\n *  ===========\n *  Sample code can be found from the root directory folder\\n\n *  \"SampleSource/\"\n *\n *  Credits\n *  =======\n *  1. Bradley Clemetson\\n\n *      @ http://codeprogrammers.net\n *  2. grplib Developers (botik32, infbonzay)\\n\n *      @ http://sourceforge.net/projects/grplib/\n *  3. grpapi Developer (ShadowFlare)\\n\n *      @ http://sfsrealm.hopto.org/\n *\n *  Special Thanks\n *  ==============\n *  1. Author of the GRP Format (Patrick Wyatt)\\n\n *      @ http://www.codeofhonor.com/blog/\n */\n\n#include \"GRPImage/GRPImage.hpp\"\n#include \"Exceptions/GRPImage/GRPImageException.hpp\"\n\n#include \"GRPFrame/GRPFrame.hpp\"\n#include \"Exceptions/GRPException.hpp\"\n\n#endif\n"
  },
  {
    "path": "src/libgrp/meson.build",
    "content": "libgrp_sources = files(\n\t'./Exceptions/GRPException.cpp',\n\t'./Exceptions/GRPFrame/GRPFrameException.cpp',\n\t'./Exceptions/GRPImage/GRPImageException.cpp',\n\t'./libgrp.cpp',\n\t'./GRPFrame/GRPFrame.cpp',\n\t'./GRPImage/GRPImage.cpp'\n)\n\n"
  },
  {
    "path": "src/luagen.cpp",
    "content": "/*\n * luagen.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include <luagen.h>\n\nusing namespace std;\n\nnamespace lg {\n\nstd::string boolean(bool b)\n{\n  return b ? \"true\" : \"false\";\n}\n\nstd::string integer(int i)\n{\n  return to_string(i);\n}\n\nstd::string function(const std::string &name, const std::initializer_list<std::string> &functionParams)\n{\n  return function(name, params(functionParams));\n}\n\nstd::string function(const std::string &name, const std::string &functionParams)\n{\n  string func_str(name + \"(\");\n  func_str += functionParams;\n  func_str += \")\";\n\n  return func_str;\n}\n\nstd::string table(const std::initializer_list<std::string> &tableElements)\n{\n  return table(params(tableElements));\n}\n\nstd::string table(const std::string &content)\n{\n  string table_str(\"{\");\n  table_str += content;\n  table_str += \"}\";\n\n  return table_str;\n}\n\nstd::string assign(const std::string &left, const std::string &right)\n{\n  string assign_str(left + \" = \" + right);\n\n  return assign_str;\n}\n\nstd::string compare(const std::string &left, const std::string &right)\n{\n  string compare_str(left + \" == \" + right);\n\n  return compare_str;\n}\n\nstd::string quote(const std::string &text)\n{\n  string quote_str(\"\\\"\");\n  quote_str += text;\n  quote_str += \"\\\"\";\n\n  return quote_str;\n}\n\nstd::string singleQuote(const std::string &text)\n{\n  string quote_str(\"'\");\n  quote_str += text;\n  quote_str += \"'\";\n\n  return quote_str;\n}\n\nstd::string params(const std::initializer_list<std::string> &params_init_list)\n{\n  return params(params_init_list.begin(), params_init_list.end());\n}\n\nstd::string params(const std::vector<std::string> &params_vector)\n{\n  return params(params_vector.begin(), params_vector.end());\n}\n\nstd::string paramsQuote(const std::initializer_list<std::string> &params_init_list)\n{\n  return paramsQuote(params_init_list.begin(), params_init_list.end());\n}\n\nstd::string paramsQuote(const std::vector<std::string> &params_vector)\n{\n  return paramsQuote(params_vector.begin(), params_vector.end());\n}\n\nstd::string line(const std::string &str)\n{\n  return string(str + '\\n');\n}\n\nstd::string sizeTable(const Size &s)\n{\n  return table({to_string(s.getWidth()), to_string(s.getHeight())});\n}\n\nstd::string posTable(const Pos &p)\n{\n  return table({to_string(p.getX()), to_string(p.getY())});\n}\n\nstd::string DefineUnitType(const std::string &id, const std::string &unitTable)\n{\n  return function(\"DefineUnitType\", {quote(id), unitTable});\n}\n\nstd::string DefineUnitType(const std::string &id, const std::initializer_list<std::string> &tableElements)\n{\n  return DefineUnitType(id, table(tableElements));\n}\n\nstd::string CreateUnit(const std::string &id, int playerID, const Pos &pos)\n{\n  return function(\"CreateUnit\", {quote(id), to_string(playerID), posTable(pos)});\n}\n\nstd::string DefineTileset(const std::string &name, const std::string &image, const std::initializer_list<std::string> &slotsTable)\n{\n  return function(\"DefineTileset\", {quote(\"name\"), quote(name), quote(\"size\"), table({\"32\", \"32\"}), quote(\"image\"), quote(image), quote(\"slots\"), table(slotsTable)});\n}\n\nstd::string tilesetSlotEntry(const std::string &type, const std::initializer_list<std::string> &propertiesQuotedParams, const std::initializer_list<std::string> &tilesTable)\n{\n  return params({quote(type), table({paramsQuote(propertiesQuotedParams), table(tilesTable)})});\n}\n\nstd::string tilesetSlotEntryNonMix(const std::string &type, const std::initializer_list<std::string> &propertiesQuotedParams, const std::initializer_list<std::string> &tilesTable)\n{\n  return params({quote(type), table({paramsQuote(propertiesQuotedParams), table(tilesTable)})});\n}\n\n} /* namespace lg */\n"
  },
  {
    "path": "src/luagen.h",
    "content": "/*\n * luagen.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef LUAGEN_H\n#define LUAGEN_H\n\n// project\n#include \"Size.h\"\n#include \"Pos.h\"\n\n// system\n#include <iostream>\n#include <string>\n#include <list>\n#include <initializer_list>\n#include <vector>\n\n/**\n * Design of this LUA code generator is to be most simple and use strings.\n * But saves typing and less errors adding strings while generating code.\n */\nnamespace lg\n{\n  // type generators\n  std::string boolean(bool b);\n\n  std::string integer(int i);\n\n  // generic LUA language generators\n  std::string function(const std::string &name, const std::initializer_list<std::string> &functionParams);\n  std::string function(const std::string &name, const std::string &functionParams = \"\");\n\n  /**\n   * Create a LUA table from the std::initializer_list. The function calls implicit params().\n   *\n   * @return example: {one, two, three}\n   */\n  std::string table(const std::initializer_list<std::string> &tableElements);\n\n  /**\n   * Create a LUA table from the input string. So it assumes the input string is yet in a parameterized form.\n   *\n   * @return example: {example}\n   */\n  std::string table(const std::string &content);\n\n  /**\n   * Create a LUA assignment from left and right side\n   *\n   * @return example: left = right\n   */\n  std::string assign(const std::string &left, const std::string &right);\n\n  /**\n   * Create a LUA assignment from left and right side\n   *\n   * @return example: left == right\n   */\n  std::string compare(const std::string &left, const std::string &right);\n\n  /**\n   * Put surrounding quotes around:\n   *\n   * @return example: \"example\"\n   */\n  std::string quote(const std::string &text);\n\n  /**\n   * Put surrounding quotes around:\n   *\n   * @return example: 'example'\n   */\n  std::string singleQuote(const std::string &text);\n\n  /**\n   * internal template function for implementation of params() outer interfaces\n   */\n  template<typename T>\n  std::string params(T first, T last)\n  {\n    std::string param_str;\n\n    for(auto func_it = first; func_it != last; func_it++)\n    {\n      const std::string &param = *func_it;\n\n      if(func_it != first)\n      {\n        param_str += \", \";\n      }\n\n      param_str += param;\n    }\n\n    return param_str;\n  }\n\n  /**\n   * Loop over the parameters and generate a comma separated function parameter list\n   *\n   * @param params_init_list give input list in form of {...} initializer list\n   *\n   * @return example: one, two, three\n   */\n  std::string params(const std::initializer_list<std::string> &params_init_list);\n\n  /**\n   * Loop over the parameters and generate a comma separated function parameter list\n   *\n   * @param param_vector give input list in form of vector initializer list\n   *\n   * @return example: one, two, three\n   */\n  std::string params(const std::vector<std::string> &params_vector);\n\n  /**\n   * internal template function for implementation of paramsQuote() outer interfaces\n   */\n  template<typename T>\n  std::string paramsQuote(T first, T last)\n  {\n    std::string param_str;\n\n    for(auto func_it = first; func_it != last; func_it++)\n    {\n      const std::string &param = *func_it;\n\n      if(func_it != first)\n      {\n        param_str += \", \";\n      }\n\n      param_str += \"\\\"\" + param + \"\\\"\";\n    }\n\n    return param_str;\n  }\n\n  /**\n   * Convenience function to quote all parameters\n   *\n   * @return example: \"one\", \"two\", \"three\"\n   */\n  std::string paramsQuote(const std::initializer_list<std::string> &params_init_list);\n\n  /**\n   * Convenience function to quote all parameters\n   *\n   * @return example: \"one\", \"two\", \"three\"\n   */\n  std::string paramsQuote(const std::vector<std::string> &params_vector);\n\n  /**\n   * No function, just some explicit simple pretty printing by ensure to put a newline at the end.\n   *\n   * @return example: example\\n\n   */\n  std::string line(const std::string &str);\n\n  /**\n   * Convenience function to create a a LUA table that represents a Size object\n   *\n   * @return example: {width, height}\n   */\n  std::string sizeTable(const Size &s);\n\n  /**\n   * Convenience function to create a a LUA table that represents a Pos object (psoition coordinate)\n   * @return example: {x, y}\n   */\n  std::string posTable(const Pos &p);\n\n  /**\n   * Convenience function to define a stratagus unit by calling function() with specific parameters.\n   * What ever you give as parameters will be included. For sure you need to set something useful as \"name\" or \"image\",\n   * but all are optional and the caller has to decide.\n   *\n   * @return example: DefineUnitType(\"unit-type\", {one, two, three})\n   */\n  std::string DefineUnitType(const std::string &id, const std::initializer_list<std::string> &elementsTable);\n\n  /**\n   * Convenience function to define a stratagus unit but with a pre-generated table string as input.\n   */\n  std::string DefineUnitType(const std::string &id, const std::string &unitTable);\n\n\n  /**\n   * Create a stratagus unit by referencing before defined units. This is done on the map format.\n   */\n  std::string CreateUnit(const std::string &id, int playerID, const Pos &pos);\n\n  /**\n   * Create a Tileset definition for stratagus.\n   *\n   * @param slotsTable the slots should be defined by convenience function tilesetSlotEntry() because of complexity\n   *\n   * @return example: DefineTileset(\"name\", \"myname\", \"image\", \"myimage.png\", \"slots\", {slotsTable})\n }},\n   */\n  std::string DefineTileset(const std::string &name, const std::string &image, const std::initializer_list<std::string> &slotsTable);\n\n  /**\n   * Create a single tileset slot entry for usage in DefineTileset()\n   *\n   * @param type \"mixed\" or \"solid\", the parameter is quoted by default\n   * @param propertiesQuotedParams The parameters are quoted by default\n   * @param tilesTable the tiles not quoted by default\n   *\n   * @return example: \"solid\", {\"property1\", \"property2\", {1, 2, 3}}\n }}\n   */\n  std::string tilesetSlotEntry(const std::string &type, const std::initializer_list<std::string> &propertiesQuotedParams, const std::initializer_list<std::string> &tilesTable);\n\n} /* namespace luagen */\n\n#endif /* LUAGEN_H */\n"
  },
  {
    "path": "src/meson.build",
    "content": "\nsubdir('kaitai')\nsubdir('dat')\nsubdir('tileset')\nsubdir('libgrp')\n\nstartool_sources = files(\n\t'startool.cpp'\n)\n\nstarformat_lib_sources = files(\n\t'Casc.cpp',\n\t'FileUtil.cpp',\n\t'Palette.cpp',\n\t'PngExporter.cpp',\n\t'Chk.cpp',\n\t'Font.cpp',\n\t'Grp.cpp',\n\t'Panel.cpp',\n\t'Preferences.cpp',\n\t'Widgets.cpp',\n\t'DataChunk.cpp',\n\t'Hurricane.cpp',\n\t'Pcx.cpp',\n\t'Scm.cpp',\n\t'Storm.cpp',\n\t'WorldMap.cpp',\n\t'Dds.cpp',\n\t'Breeze.cpp',\n\t'Smacker.cpp',\n\t'Converter.cpp',\n\t'KaitaiConverter.cpp',\n\t'Storage.cpp',\n\t'PaletteImage.cpp',\n\t'Color.cpp',\n\t'Wav.cpp',\n\t'Palette2D.cpp',\n\t'StringUtil.cpp',\n\t'luagen.cpp',\n\t'platform.cpp',\n\t'UIConsole.cpp',\n\t'pacman.cpp',\n\t'FileNotFoundException.cpp',\n\t'UnitsConverter.cpp',\n\t'PortraitsConverter.cpp',\n\t'ImagesConverter.cpp',\n\t'SfxConverter.cpp',\n\t'NoValidPaletteException.cpp',\n\t'AbstractPalette.cpp'\n\t)\n\nstratagus_prefix = get_option('prefix')\nstratagus_bin = get_option('STRATAGUS_BIN')\n\nstratagus_includedir = get_option('STRATAGUS_INCLUDE_DIR')\nstratagus_incdir = include_directories(stratagus_includedir)\n\nadd_project_arguments('-DDATA_PATH=\"' + stratagus_prefix + '/share/games/stratagus/stargus\"', language: 'cpp')\nadd_project_arguments('-DSCRIPTS_PATH=\"' + stratagus_prefix + '/share/games/stratagus/stargus\"', language: 'cpp')\nadd_project_arguments('-DSTRATAGUS_BIN=\"' + stratagus_bin + '\"', language: 'cpp')\nadd_project_arguments('-DSOURCE_DIR=\"' + meson.current_source_dir() + '/../\"', language: 'cpp')\nadd_project_arguments('-DKS_STR_ENCODING_NONE', language: 'cpp')\n\n# inform about which stratagus binary is used\nmessage('Using stratagus: ' + stratagus_bin)\n\nstargus_sources = files('stargus.cpp')\n\ninc = include_directories('.')\n\nlibstarformat = static_library('starformat',\n\tstarformat_lib_sources,\n\tstartool_kaitai_sources,\n\tstartool_dat_sources,\n\tstartool_tileset_sources,\n\tlibgrp_sources,\n\tinclude_directories : config_incdir,\n\tdependencies : [casc_dep, storm_dep, zlib_dep, png_dep, imagemagickpp_dep, log4cxx_dep, bzip2_dep, nlohmann_json_dep, iconv_lib],\n\tinstall : true)\n\nlibstarformat_dep = declare_dependency(include_directories : [config_incdir, inc],\n  link_with : libstarformat)\n\nexecutable('startool',\n\tstartool_sources,\n\tinclude_directories : config_incdir,\n\tdependencies : [log4cxx_dep, libstarformat_dep, nlohmann_json_dep, png_dep],\n\tinstall : true)\n\nexecutable('stargus',\n\tstargus_sources,\n\tinclude_directories : [stratagus_incdir, config_incdir],\n\tinstall : true)\n\t\n\n"
  },
  {
    "path": "src/optionparser.h",
    "content": "/*\n * The Lean Mean C++ Option Parser\n *\n * Copyright (C) 2012-2017 Matthias S. Benkmann\n *\n * The \"Software\" in the following 2 paragraphs refers to this file containing\n * the code to The Lean Mean C++ Option Parser.\n * The \"Software\" does NOT refer to any other files which you\n * may have received alongside this file (e.g. as part of a larger project that\n * incorporates The Lean Mean C++ Option Parser).\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software, to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to permit\n * persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n/*\n * NOTE: It is recommended that you read the processed HTML doxygen documentation\n * rather than this source. If you don't know doxygen, it's like javadoc for C++.\n * If you don't want to install doxygen you can find a copy of the processed\n * documentation at\n *\n * http://optionparser.sourceforge.net/\n *\n */\n\n/**\n * @file\n *\n * @brief This is the only file required to use The Lean Mean C++ Option Parser.\n *        Just \\#include it and you're set.\n *\n * The Lean Mean C++ Option Parser handles the program's command line arguments\n * (argc, argv).\n * It supports the short and long option formats of getopt(), getopt_long()\n * and getopt_long_only() but has a more convenient interface.\n *\n * @par Feedback:\n * Send questions, bug reports, feature requests etc. to: <tt><b>optionparser-feedback(a)lists.sourceforge.net</b></tt>\n *\n * @par Highlights:\n * <ul style=\"padding-left:1em;margin-left:0\">\n * <li> It is a header-only library. Just <code>\\#include \"optionparser.h\"</code> and you're set.\n * <li> It is freestanding. There are no dependencies whatsoever, not even the\n *      C or C++ standard library.\n * <li> It has a usage message formatter that supports column alignment and\n *      line wrapping. This aids localization because it adapts to\n *      translated strings that are shorter or longer (even if they contain\n *      Asian wide characters).\n * <li> Unlike getopt() and derivatives it doesn't force you to loop through\n *     options sequentially. Instead you can access options directly like this:\n *     <ul style=\"margin-top:.5em\">\n *     <li> Test for presence of a switch in the argument vector:\n *      @code if ( options[QUIET] ) ... @endcode\n *     <li> Evaluate --enable-foo/--disable-foo pair where the last one used wins:\n *     @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode\n *     <li> Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):\n *     @code int verbosity = options[VERBOSE].count(); @endcode\n *     <li> Iterate over all --file=&lt;fname> arguments:\n *     @code for (Option* opt = options[FILE]; opt; opt = opt->next())\n *   fname = opt->arg; ... @endcode\n *     <li> If you really want to, you can still process all arguments in order:\n *     @code\n *   for (int i = 0; i < p.optionsCount(); ++i) {\n *     Option& opt = buffer[i];\n *     switch(opt.index()) {\n *       case HELP:    ...\n *       case VERBOSE: ...\n *       case FILE:    fname = opt.arg; ...\n *       case UNKNOWN: ...\n *     @endcode\n *     </ul>\n * </ul> @n\n * Despite these features the code size remains tiny.\n * It is smaller than <a href=\"http://uclibc.org\">uClibc</a>'s GNU getopt() and just a\n * couple 100 bytes larger than uClibc's SUSv3 getopt(). @n\n * (This does not include the usage formatter, of course. But you don't have to use that.)\n *\n * @par Download:\n * Tarball with examples and test programs:\n * <a style=\"font-size:larger;font-weight:bold\" href=\"http://sourceforge.net/projects/optionparser/files/optionparser-1.7.tar.gz/download\">optionparser-1.7.tar.gz</a> @n\n * Just the header (this is all you really need):\n * <a style=\"font-size:larger;font-weight:bold\" href=\"http://optionparser.sourceforge.net/optionparser.h\">optionparser.h</a>\n *\n * @par Changelog:\n * <b>Version 1.7:</b> Work on const-correctness. @n\n * <b>Version 1.6:</b> Fix for MSC compiler. @n\n * <b>Version 1.5:</b> Fixed 2 warnings about potentially uninitialized variables. @n\n *                     Added const version of Option::next(). @n\n * <b>Version 1.4:</b> Fixed 2 printUsage() bugs that messed up output with small COLUMNS values. @n\n * <b>Version 1.3:</b> Compatible with Microsoft Visual C++. @n\n * <b>Version 1.2:</b> Added @ref option::Option::namelen \"Option::namelen\" and removed the extraction\n *                     of short option characters into a special buffer. @n\n *                     Changed @ref option::Arg::Optional \"Arg::Optional\" to accept arguments if they are attached\n *                     rather than separate. This is what GNU getopt() does and how POSIX recommends\n *                     utilities should interpret their arguments.@n\n * <b>Version 1.1:</b> Optional mode with argument reordering as done by GNU getopt(), so that\n *                     options and non-options can be mixed. See\n *                     @ref option::Parser::parse() \"Parser::parse()\".\n *\n *\n * @par Example program:\n * (Note: @c option::* identifiers are links that take you to their documentation.)\n * @code\n * #error EXAMPLE SHORTENED FOR READABILITY. BETTER EXAMPLES ARE IN THE .TAR.GZ!\n * #include <iostream>\n * #include \"optionparser.h\"\n *\n * enum  optionIndex { UNKNOWN, HELP, PLUS };\n * const option::Descriptor usage[] =\n * {\n *  {UNKNOWN, 0,\"\" , \"\"    ,option::Arg::None, \"USAGE: example [options]\\n\\n\"\n *                                             \"Options:\" },\n *  {HELP,    0,\"\" , \"help\",option::Arg::None, \"  --help  \\tPrint usage and exit.\" },\n *  {PLUS,    0,\"p\", \"plus\",option::Arg::None, \"  --plus, -p  \\tIncrement count.\" },\n *  {UNKNOWN, 0,\"\" ,  \"\"   ,option::Arg::None, \"\\nExamples:\\n\"\n *                                             \"  example --unknown -- --this_is_no_option\\n\"\n *                                             \"  example -unk --plus -ppp file1 file2\\n\" },\n *  {0,0,0,0,0,0}\n * };\n *\n * int main(int argc, char* argv[])\n * {\n *   argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present\n *   option::Stats  stats(usage, argc, argv);\n *   option::Option options[stats.options_max], buffer[stats.buffer_max];\n *   option::Parser parse(usage, argc, argv, options, buffer);\n *\n *   if (parse.error())\n *     return 1;\n *\n *   if (options[HELP] || argc == 0) {\n *     option::printUsage(std::cout, usage);\n *     return 0;\n *   }\n *\n *   std::cout << \"--plus count: \" <<\n *     options[PLUS].count() << \"\\n\";\n *\n *   for (option::Option* opt = options[UNKNOWN]; opt; opt = opt->next())\n *     std::cout << \"Unknown option: \" << opt->name << \"\\n\";\n *\n *   for (int i = 0; i < parse.nonOptionsCount(); ++i)\n *     std::cout << \"Non-option #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n * }\n * @endcode\n *\n * @par Option syntax:\n * @li The Lean Mean C++ Option Parser follows POSIX <code>getopt()</code> conventions and supports\n *     GNU-style <code>getopt_long()</code> long options as well as Perl-style single-minus\n *     long options (<code>getopt_long_only()</code>).\n * @li short options have the format @c -X where @c X is any character that fits in a char.\n * @li short options can be grouped, i.e. <code>-X -Y</code> is equivalent to @c -XY.\n * @li a short option may take an argument either separate (<code>-X foo</code>) or\n *     attached (@c -Xfoo). You can make the parser accept the additional format @c -X=foo by\n *     registering @c X as a long option (in addition to being a short option) and\n *     enabling single-minus long options.\n * @li an argument-taking short option may be grouped if it is the last in the group, e.g.\n *     @c -ABCXfoo or <code> -ABCX foo </code> (@c foo is the argument to the @c -X option).\n * @li a lone minus character @c '-' is not treated as an option. It is customarily used where\n *     a file name is expected to refer to stdin or stdout.\n * @li long options have the format @c --option-name.\n * @li the option-name of a long option can be anything and include any characters.\n *     Even @c = characters will work, but don't do that.\n * @li [optional] long options may be abbreviated as long as the abbreviation is unambiguous.\n *     You can set a minimum length for abbreviations.\n * @li [optional] long options may begin with a single minus. The double minus form is always\n *     accepted, too.\n * @li a long option may take an argument either separate (<code> --option arg </code>) or\n *     attached (<code> --option=arg </code>). In the attached form the equals sign is mandatory.\n * @li an empty string can be passed as an attached long option argument: <code> --option-name= </code>.\n *     Note the distinction between an empty string as argument and no argument at all.\n * @li an empty string is permitted as separate argument to both long and short options.\n * @li Arguments to both short and long options may start with a @c '-' character. E.g.\n *     <code> -X-X </code>, <code>-X -X</code> or <code> --long-X=-X </code>. If @c -X\n *     and @c --long-X take an argument, that argument will be @c \"-X\" in all 3 cases.\n * @li If using the built-in @ref option::Arg::Optional \"Arg::Optional\", optional arguments must\n *     be attached.\n * @li the special option @c -- (i.e. without a name) terminates the list of\n *     options. Everything that follows is a non-option argument, even if it starts with\n *     a @c '-' character. The @c -- itself will not appear in the parse results.\n * @li the first argument that doesn't start with @c '-' or @c '--' and does not belong to\n *     a preceding argument-taking option, will terminate the option list and is the\n *     first non-option argument. All following command line arguments are treated as\n *     non-option arguments, even if they start with @c '-' . @n\n *     NOTE: This behaviour is mandated by POSIX, but GNU getopt() only honours this if it is\n *     explicitly requested (e.g. by setting POSIXLY_CORRECT). @n\n *     You can enable the GNU behaviour by passing @c true as first argument to\n *     e.g. @ref option::Parser::parse() \"Parser::parse()\".\n * @li Arguments that look like options (i.e. @c '-' followed by at least 1 character) but\n *     aren't, are NOT treated as non-option arguments. They are treated as unknown options and\n *     are collected into a list of unknown options for error reporting. @n\n *     This means that in order to pass a first non-option\n *     argument beginning with the minus character it is required to use the\n *     @c -- special option, e.g.\n *     @code\n *     program -x -- --strange-filename\n *     @endcode\n *     In this example, @c --strange-filename is a non-option argument. If the @c --\n *     were omitted, it would be treated as an unknown option. @n\n *     See @ref option::Descriptor::longopt for information on how to collect unknown options.\n *\n */\n\n#ifndef OPTIONPARSER_H_\n#define OPTIONPARSER_H_\n\n#ifdef _MSC_VER\n#include <intrin.h>\n#pragma intrinsic(_BitScanReverse)\n#endif\n\n/** @brief The namespace of The Lean Mean C++ Option Parser. */\nnamespace option\n{\n\n#ifdef _MSC_VER\nstruct MSC_Builtin_CLZ\n{\n  static int builtin_clz(unsigned x)\n  {\n    unsigned long index;\n    _BitScanReverse(&index, x);\n    return 32-index; // int is always 32bit on Windows, even for target x64\n  }\n};\n#define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x)\n#endif\n\nclass Option;\n\n/**\n * @brief Possible results when checking if an argument is valid for a certain option.\n *\n * In the case that no argument is provided for an option that takes an\n * optional argument, return codes @c ARG_OK and @c ARG_IGNORE are equivalent.\n */\nenum ArgStatus\n{\n  //! The option does not take an argument.\n  ARG_NONE,\n  //! The argument is acceptable for the option.\n  ARG_OK,\n  //! The argument is not acceptable but that's non-fatal because the option's argument is optional.\n  ARG_IGNORE,\n  //! The argument is not acceptable and that's fatal.\n  ARG_ILLEGAL\n};\n\n/**\n * @brief Signature of functions that check if an argument is valid for a certain type of option.\n *\n * Every Option has such a function assigned in its Descriptor.\n * @code\n * Descriptor usage[] = { {UNKNOWN, 0, \"\", \"\", Arg::None, \"\"}, ... };\n * @endcode\n *\n * A CheckArg function has the following signature:\n * @code ArgStatus CheckArg(const Option& option, bool msg); @endcode\n *\n * It is used to check if a potential argument would be acceptable for the option.\n * It will even be called if there is no argument. In that case @c option.arg will be @c NULL.\n *\n * If @c msg is @c true and the function determines that an argument is not acceptable and\n * that this is a fatal error, it should output a message to the user before\n * returning @ref ARG_ILLEGAL. If @c msg is @c false the function should remain silent (or you\n * will get duplicate messages).\n *\n * See @ref ArgStatus for the meaning of the return values.\n *\n * While you can provide your own functions,\n * often the following pre-defined checks (which never return @ref ARG_ILLEGAL) will suffice:\n *\n * @li @c Arg::None @copybrief Arg::None\n * @li @c Arg::Optional @copybrief Arg::Optional\n *\n */\ntypedef ArgStatus (*CheckArg)(const Option& option, bool msg);\n\n/**\n * @brief Describes an option, its help text (usage) and how it should be parsed.\n *\n * The main input when constructing an option::Parser is an array of Descriptors.\n\n * @par Example:\n * @code\n * enum OptionIndex {CREATE, ...};\n * enum OptionType {DISABLE, ENABLE, OTHER};\n *\n * const option::Descriptor usage[] = {\n *   { CREATE,                                            // index\n *     OTHER,                                             // type\n *     \"c\",                                               // shortopt\n *     \"create\",                                          // longopt\n *     Arg::None,                                         // check_arg\n *     \"--create  Tells the program to create something.\" // help\n *   }\n *   , ...\n * };\n * @endcode\n */\nstruct Descriptor\n{\n  /**\n   * @brief Index of this option's linked list in the array filled in by the parser.\n   *\n   * Command line options whose Descriptors have the same index will end up in the same\n   * linked list in the order in which they appear on the command line. If you have\n   * multiple long option aliases that refer to the same option, give their descriptors\n   * the same @c index.\n   *\n   * If you have options that mean exactly opposite things\n   * (e.g. @c --enable-foo and @c --disable-foo ), you should also give them the same\n   * @c index, but distinguish them through different values for @ref type.\n   * That way they end up in the same list and you can just take the last element of the\n   * list and use its type. This way you get the usual behaviour where switches later\n   * on the command line override earlier ones without having to code it manually.\n   *\n   * @par Tip:\n   * Use an enum rather than plain ints for better readability, as shown in the example\n   * at Descriptor.\n   */\n  const unsigned index;\n\n  /**\n   * @brief Used to distinguish between options with the same @ref index.\n   * See @ref index for details.\n   *\n   * It is recommended that you use an enum rather than a plain int to make your\n   * code more readable.\n   */\n  const int type;\n\n  /**\n   * @brief Each char in this string will be accepted as a short option character.\n   *\n   * The string must not include the minus character @c '-' or you'll get undefined\n   * behaviour.\n   *\n   * If this Descriptor should not have short option characters, use the empty\n   * string \"\". NULL is not permitted here!\n   *\n   * See @ref longopt for more information.\n   */\n  const char* const shortopt;\n\n  /**\n   * @brief The long option name (without the leading @c -- ).\n   *\n   * If this Descriptor should not have a long option name, use the empty\n   * string \"\". NULL is not permitted here!\n   *\n   * While @ref shortopt allows multiple short option characters, each\n   * Descriptor can have only a single long option name. If you have multiple\n   * long option names referring to the same option use separate Descriptors\n   * that have the same @ref index and @ref type. You may repeat\n   * short option characters in such an alias Descriptor but there's no need to.\n   *\n   * @par Dummy Descriptors:\n   * You can use dummy Descriptors with an\n   * empty string for both @ref shortopt and @ref longopt to add text to\n   * the usage that is not related to a specific option. See @ref help.\n   * The first dummy Descriptor will be used for unknown options (see below).\n   *\n   * @par Unknown Option Descriptor:\n   * The first dummy Descriptor in the list of Descriptors,\n   * whose @ref shortopt and @ref longopt are both the empty string, will be used\n   * as the Descriptor for unknown options. An unknown option is a string in\n   * the argument vector that is not a lone minus @c '-' but starts with a minus\n   * character and does not match any Descriptor's @ref shortopt or @ref longopt. @n\n   * Note that the dummy descriptor's @ref check_arg function @e will be called and\n   * its return value will be evaluated as usual. I.e. if it returns @ref ARG_ILLEGAL\n   * the parsing will be aborted with <code>Parser::error()==true</code>. @n\n   * if @c check_arg does not return @ref ARG_ILLEGAL the descriptor's\n   * @ref index @e will be used to pick the linked list into which\n   * to put the unknown option. @n\n   * If there is no dummy descriptor, unknown options will be dropped silently.\n   *\n   */\n  const char* const longopt;\n\n  /**\n   * @brief For each option that matches @ref shortopt or @ref longopt this function\n   * will be called to check a potential argument to the option.\n   *\n   * This function will be called even if there is no potential argument. In that case\n   * it will be passed @c NULL as @c arg parameter. Do not confuse this with the empty\n   * string.\n   *\n   * See @ref CheckArg for more information.\n   */\n  const CheckArg check_arg;\n\n  /**\n   * @brief The usage text associated with the options in this Descriptor.\n   *\n   * You can use option::printUsage() to format your usage message based on\n   * the @c help texts. You can use dummy Descriptors where\n   * @ref shortopt and @ref longopt are both the empty string to add text to\n   * the usage that is not related to a specific option.\n   *\n   * See option::printUsage() for special formatting characters you can use in\n   * @c help to get a column layout.\n   *\n   * @attention\n   * Must be UTF-8-encoded. If your compiler supports C++11 you can use the \"u8\"\n   * prefix to make sure string literals are properly encoded.\n   */\n  const char* help;\n};\n\n/**\n * @brief A parsed option from the command line together with its argument if it has one.\n *\n * The Parser chains all parsed options with the same Descriptor::index together\n * to form a linked list. This allows you to easily implement all of the common ways\n * of handling repeated options and enable/disable pairs.\n *\n * @li Test for presence of a switch in the argument vector:\n *      @code if ( options[QUIET] ) ... @endcode\n * @li Evaluate --enable-foo/--disable-foo pair where the last one used wins:\n *     @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode\n * @li Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):\n *     @code int verbosity = options[VERBOSE].count(); @endcode\n * @li Iterate over all --file=&lt;fname> arguments:\n *     @code for (Option* opt = options[FILE]; opt; opt = opt->next())\n *   fname = opt->arg; ... @endcode\n */\nclass Option\n{\n  Option* next_;\n  Option* prev_;\npublic:\n  /**\n   * @brief Pointer to this Option's Descriptor.\n   *\n   * Remember that the first dummy descriptor (see @ref Descriptor::longopt) is used\n   * for unknown options.\n   *\n   * @attention\n   * @c desc==NULL signals that this Option is unused. This is the default state of\n   * elements in the result array. You don't need to test @c desc explicitly. You\n   * can simply write something like this:\n   * @code\n   * if (options[CREATE])\n   * {\n   *   ...\n   * }\n   * @endcode\n   * This works because of <code> operator const Option*() </code>.\n   */\n  const Descriptor* desc;\n\n  /**\n   * @brief The name of the option as used on the command line.\n   *\n   * The main purpose of this string is to be presented to the user in messages.\n   *\n   * In the case of a long option, this is the actual @c argv pointer, i.e. the first\n   * character is a '-'. In the case of a short option this points to the option\n   * character within the @c argv string.\n   *\n   * Note that in the case of a short option group or an attached option argument, this\n   * string will contain additional characters following the actual name. Use @ref namelen\n   * to filter out the actual option name only.\n   *\n   */\n  const char* name;\n\n  /**\n   * @brief Pointer to this Option's argument (if any).\n   *\n   * NULL if this option has no argument. Do not confuse this with the empty string which\n   * is a valid argument.\n   */\n  const char* arg;\n\n  /**\n   * @brief The length of the option @ref name.\n   *\n   * Because @ref name points into the actual @c argv string, the option name may be\n   * followed by more characters (e.g. other short options in the same short option group).\n   * This value is the number of bytes (not characters!) that are part of the actual name.\n   *\n   * For a short option, this length is always 1. For a long option this length is always\n   * at least 2 if single minus long options are permitted and at least 3 if they are disabled.\n   *\n   * @note\n   * In the pathological case of a minus within a short option group (e.g. @c -xf-z), this\n   * length is incorrect, because this case will be misinterpreted as a long option and the\n   * name will therefore extend to the string's 0-terminator or a following '=\" character\n   * if there is one. This is irrelevant for most uses of @ref name and @c namelen. If you\n   * really need to distinguish the case of a long and a short option, compare @ref name to\n   * the @c argv pointers. A long option's @c name is always identical to one of them,\n   * whereas a short option's is never.\n   */\n  int namelen;\n\n  /**\n   * @brief Returns Descriptor::type of this Option's Descriptor, or 0 if this Option\n   * is invalid (unused).\n   *\n   * Because this method (and last(), too) can be used even on unused Options with desc==0, you can (provided\n   * you arrange your types properly) switch on type() without testing validity first.\n   * @code\n   * enum OptionType { UNUSED=0, DISABLED=0, ENABLED=1 };\n   * enum OptionIndex { FOO };\n   * const Descriptor usage[] = {\n   *   { FOO, ENABLED,  \"\", \"enable-foo\",  Arg::None, 0 },\n   *   { FOO, DISABLED, \"\", \"disable-foo\", Arg::None, 0 },\n   *   { 0, 0, 0, 0, 0, 0 } };\n   * ...\n   * switch(options[FOO].last()->type()) // no validity check required!\n   * {\n   *   case ENABLED: ...\n   *   case DISABLED: ...  // UNUSED==DISABLED !\n   * }\n   * @endcode\n   */\n  int type() const\n  {\n    return desc == 0 ? 0 : desc->type;\n  }\n\n  /**\n   * @brief Returns Descriptor::index of this Option's Descriptor, or -1 if this Option\n   * is invalid (unused).\n   */\n  int index() const\n  {\n    return desc == 0 ? -1 : (int)desc->index;\n  }\n\n  /**\n   * @brief Returns the number of times this Option (or others with the same Descriptor::index)\n   * occurs in the argument vector.\n   *\n   * This corresponds to the number of elements in the linked list this Option is part of.\n   * It doesn't matter on which element you call count(). The return value is always the same.\n   *\n   * Use this to implement cumulative options, such as -v, -vv, -vvv for\n   * different verbosity levels.\n   *\n   * Returns 0 when called for an unused/invalid option.\n   */\n  int count() const\n  {\n    int c = (desc == 0 ? 0 : 1);\n    const Option* p = first();\n    while (!p->isLast())\n    {\n      ++c;\n      p = p->next_;\n    };\n    return c;\n  }\n\n  /**\n   * @brief Returns true iff this is the first element of the linked list.\n   *\n   * The first element in the linked list is the first option on the command line\n   * that has the respective Descriptor::index value.\n   *\n   * Returns true for an unused/invalid option.\n   */\n  bool isFirst() const\n  {\n    return isTagged(prev_);\n  }\n\n  /**\n   * @brief Returns true iff this is the last element of the linked list.\n   *\n   * The last element in the linked list is the last option on the command line\n   * that has the respective Descriptor::index value.\n   *\n   * Returns true for an unused/invalid option.\n   */\n  bool isLast() const\n  {\n    return isTagged(next_);\n  }\n\n  /**\n   * @brief Returns a pointer to the first element of the linked list.\n   *\n   * Use this when you want the first occurrence of an option on the command line to\n   * take precedence. Note that this is not the way most programs handle options.\n   * You should probably be using last() instead.\n   *\n   * @note\n   * This method may be called on an unused/invalid option and will return a pointer to the\n   * option itself.\n   */\n  Option* first()\n  {\n    Option* p = this;\n    while (!p->isFirst())\n      p = p->prev_;\n    return p;\n  }\n\n  /**\n  * const version of Option::first().\n  */\n  const Option* first() const\n  {\n    return const_cast<Option*>(this)->first();\n  }\n\n  /**\n   * @brief Returns a pointer to the last element of the linked list.\n   *\n   * Use this when you want the last occurrence of an option on the command line to\n   * take precedence. This is the most common way of handling conflicting options.\n   *\n   * @note\n   * This method may be called on an unused/invalid option and will return a pointer to the\n   * option itself.\n   *\n   * @par Tip:\n   * If you have options with opposite meanings (e.g. @c --enable-foo and @c --disable-foo), you\n   * can assign them the same Descriptor::index to get them into the same list. Distinguish them by\n   * Descriptor::type and all you have to do is check <code> last()->type() </code> to get\n   * the state listed last on the command line.\n   */\n  Option* last()\n  {\n    return first()->prevwrap();\n  }\n\n  /**\n  * const version of Option::last().\n  */\n  const Option* last() const\n  {\n    return first()->prevwrap();\n  }\n\n  /**\n   * @brief Returns a pointer to the previous element of the linked list or NULL if\n   * called on first().\n   *\n   * If called on first() this method returns NULL. Otherwise it will return the\n   * option with the same Descriptor::index that precedes this option on the command\n   * line.\n   */\n  Option* prev()\n  {\n    return isFirst() ? 0 : prev_;\n  }\n\n  /**\n   * @brief Returns a pointer to the previous element of the linked list with wrap-around from\n   * first() to last().\n   *\n   * If called on first() this method returns last(). Otherwise it will return the\n   * option with the same Descriptor::index that precedes this option on the command\n   * line.\n   */\n  Option* prevwrap()\n  {\n    return untag(prev_);\n  }\n\n  /**\n  * const version of Option::prevwrap().\n  */\n  const Option* prevwrap() const\n  {\n    return untag(prev_);\n  }\n\n  /**\n   * @brief Returns a pointer to the next element of the linked list or NULL if called\n   * on last().\n   *\n   * If called on last() this method returns NULL. Otherwise it will return the\n   * option with the same Descriptor::index that follows this option on the command\n   * line.\n   */\n  Option* next()\n  {\n    return isLast() ? 0 : next_;\n  }\n\n  /**\n  * const version of Option::next().\n  */\n  const Option* next() const\n  {\n    return isLast() ? 0 : next_;\n  }\n\n  /**\n   * @brief Returns a pointer to the next element of the linked list with wrap-around from\n   * last() to first().\n   *\n   * If called on last() this method returns first(). Otherwise it will return the\n   * option with the same Descriptor::index that follows this option on the command\n   * line.\n   */\n  Option* nextwrap()\n  {\n    return untag(next_);\n  }\n\n  /**\n   * @brief Makes @c new_last the new last() by chaining it into the list after last().\n   *\n   * It doesn't matter which element you call append() on. The new element will always\n   * be appended to last().\n   *\n   * @attention\n   * @c new_last must not yet be part of a list, or that list will become corrupted, because\n   * this method does not unchain @c new_last from an existing list.\n   */\n  void append(Option* new_last)\n  {\n    Option* p = last();\n    Option* f = first();\n    p->next_ = new_last;\n    new_last->prev_ = p;\n    new_last->next_ = tag(f);\n    f->prev_ = tag(new_last);\n  }\n\n  /**\n   * @brief Casts from Option to const Option* but only if this Option is valid.\n   *\n   * If this Option is valid (i.e. @c desc!=NULL), returns this.\n   * Otherwise returns NULL. This allows testing an Option directly\n   * in an if-clause to see if it is used:\n   * @code\n   * if (options[CREATE])\n   * {\n   *   ...\n   * }\n   * @endcode\n   * It also allows you to write loops like this:\n   * @code for (Option* opt = options[FILE]; opt; opt = opt->next())\n   *   fname = opt->arg; ... @endcode\n   */\n  operator const Option*() const\n  {\n    return desc ? this : 0;\n  }\n\n  /**\n   * @brief Casts from Option to Option* but only if this Option is valid.\n   *\n   * If this Option is valid (i.e. @c desc!=NULL), returns this.\n   * Otherwise returns NULL. This allows testing an Option directly\n   * in an if-clause to see if it is used:\n   * @code\n   * if (options[CREATE])\n   * {\n   *   ...\n   * }\n   * @endcode\n   * It also allows you to write loops like this:\n   * @code for (Option* opt = options[FILE]; opt; opt = opt->next())\n   *   fname = opt->arg; ... @endcode\n   */\n  operator Option*()\n  {\n    return desc ? this : 0;\n  }\n\n  /**\n   * @brief Creates a new Option that is a one-element linked list and has NULL\n   * @ref desc, @ref name, @ref arg and @ref namelen.\n   */\n  Option() :\n      desc(0), name(0), arg(0), namelen(0)\n  {\n    prev_ = tag(this);\n    next_ = tag(this);\n  }\n\n  /**\n   * @brief Creates a new Option that is a one-element linked list and has the given\n   * values for @ref desc, @ref name and @ref arg.\n   *\n   * If @c name_ points at a character other than '-' it will be assumed to refer to a\n   * short option and @ref namelen will be set to 1. Otherwise the length will extend to\n   * the first '=' character or the string's 0-terminator.\n   */\n  Option(const Descriptor* desc_, const char* name_, const char* arg_)\n  {\n    init(desc_, name_, arg_);\n  }\n\n  /**\n   * @brief Makes @c *this a copy of @c orig except for the linked list pointers.\n   *\n   * After this operation @c *this will be a one-element linked list.\n   */\n  void operator=(const Option& orig)\n  {\n    init(orig.desc, orig.name, orig.arg);\n  }\n\n  /**\n   * @brief Makes @c *this a copy of @c orig except for the linked list pointers.\n   *\n   * After this operation @c *this will be a one-element linked list.\n   */\n  Option(const Option& orig)\n  {\n    init(orig.desc, orig.name, orig.arg);\n  }\n\nprivate:\n  /**\n   * @internal\n   * @brief Sets the fields of this Option to the given values (extracting @c name if necessary).\n   *\n   * If @c name_ points at a character other than '-' it will be assumed to refer to a\n   * short option and @ref namelen will be set to 1. Otherwise the length will extend to\n   * the first '=' character or the string's 0-terminator.\n   */\n  void init(const Descriptor* desc_, const char* name_, const char* arg_)\n  {\n    desc = desc_;\n    name = name_;\n    arg = arg_;\n    prev_ = tag(this);\n    next_ = tag(this);\n    namelen = 0;\n    if (name == 0)\n      return;\n    namelen = 1;\n    if (name[0] != '-')\n      return;\n    while (name[namelen] != 0 && name[namelen] != '=')\n      ++namelen;\n  }\n\n  static Option* tag(Option* ptr)\n  {\n    return (Option*) ((unsigned long long) ptr | 1);\n  }\n\n  static Option* untag(Option* ptr)\n  {\n    return (Option*) ((unsigned long long) ptr & ~1ull);\n  }\n\n  static bool isTagged(Option* ptr)\n  {\n    return ((unsigned long long) ptr & 1);\n  }\n};\n\n/**\n * @brief Functions for checking the validity of option arguments.\n *\n * @copydetails CheckArg\n *\n * The following example code\n * can serve as starting place for writing your own more complex CheckArg functions:\n * @code\n * struct Arg: public option::Arg\n * {\n *   static void printError(const char* msg1, const option::Option& opt, const char* msg2)\n *   {\n *     fprintf(stderr, \"ERROR: %s\", msg1);\n *     fwrite(opt.name, opt.namelen, 1, stderr);\n *     fprintf(stderr, \"%s\", msg2);\n *   }\n *\n *   static option::ArgStatus Unknown(const option::Option& option, bool msg)\n *   {\n *     if (msg) printError(\"Unknown option '\", option, \"'\\n\");\n *     return option::ARG_ILLEGAL;\n *   }\n *\n *   static option::ArgStatus Required(const option::Option& option, bool msg)\n *   {\n *     if (option.arg != 0)\n *       return option::ARG_OK;\n *\n *     if (msg) printError(\"Option '\", option, \"' requires an argument\\n\");\n *     return option::ARG_ILLEGAL;\n *   }\n *\n *   static option::ArgStatus NonEmpty(const option::Option& option, bool msg)\n *   {\n *     if (option.arg != 0 && option.arg[0] != 0)\n *       return option::ARG_OK;\n *\n *     if (msg) printError(\"Option '\", option, \"' requires a non-empty argument\\n\");\n *     return option::ARG_ILLEGAL;\n *   }\n *\n *   static option::ArgStatus Numeric(const option::Option& option, bool msg)\n *   {\n *     char* endptr = 0;\n *     if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};\n *     if (endptr != option.arg && *endptr == 0)\n *       return option::ARG_OK;\n *\n *     if (msg) printError(\"Option '\", option, \"' requires a numeric argument\\n\");\n *     return option::ARG_ILLEGAL;\n *   }\n * };\n * @endcode\n */\nstruct Arg\n{\n  //! @brief For options that don't take an argument: Returns ARG_NONE.\n  static ArgStatus None(const Option&, bool)\n  {\n    return ARG_NONE;\n  }\n\n  //! @brief Returns ARG_OK if the argument is attached and ARG_IGNORE otherwise.\n  static ArgStatus Optional(const Option& option, bool)\n  {\n    if (option.arg && option.name[option.namelen] != 0)\n      return ARG_OK;\n    else\n      return ARG_IGNORE;\n  }\n};\n\n/**\n * @brief Determines the minimum lengths of the buffer and options arrays used for Parser.\n *\n * Because Parser doesn't use dynamic memory its output arrays have to be pre-allocated.\n * If you don't want to use fixed size arrays (which may turn out too small, causing\n * command line arguments to be dropped), you can use Stats to determine the correct sizes.\n * Stats work cumulative. You can first pass in your default options and then the real\n * options and afterwards the counts will reflect the union.\n */\nstruct Stats\n{\n  /**\n   * @brief Number of elements needed for a @c buffer[] array to be used for\n   * @ref Parser::parse() \"parsing\" the same argument vectors that were fed\n   * into this Stats object.\n   *\n   * @note\n   * This number is always 1 greater than the actual number needed, to give\n   * you a sentinel element.\n   */\n  unsigned buffer_max;\n\n  /**\n   * @brief Number of elements needed for an @c options[] array to be used for\n   * @ref Parser::parse() \"parsing\" the same argument vectors that were fed\n   * into this Stats object.\n   *\n   * @note\n   * @li This number is always 1 greater than the actual number needed, to give\n   * you a sentinel element.\n   * @li This number depends only on the @c usage, not the argument vectors, because\n   * the @c options array needs exactly one slot for each possible Descriptor::index.\n   */\n  unsigned options_max;\n\n  /**\n   * @brief Creates a Stats object with counts set to 1 (for the sentinel element).\n   */\n  Stats() :\n      buffer_max(1), options_max(1) // 1 more than necessary as sentinel\n  {\n  }\n\n  /**\n   * @brief Creates a new Stats object and immediately updates it for the\n   * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,\n   * if you just want to update @ref options_max.\n   *\n   * @note\n   * The calls to Stats methods must match the later calls to Parser methods.\n   * See Parser::parse() for the meaning of the arguments.\n   */\n  Stats(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //\n        bool single_minus_longopt = false) :\n      buffer_max(1), options_max(1) // 1 more than necessary as sentinel\n  {\n    add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);\n  }\n\n  //! @brief Stats(...) with non-const argv.\n  Stats(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //\n        bool single_minus_longopt = false) :\n      buffer_max(1), options_max(1) // 1 more than necessary as sentinel\n  {\n    add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);\n  }\n\n  //! @brief POSIX Stats(...) (gnu==false).\n  Stats(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //\n        bool single_minus_longopt = false) :\n      buffer_max(1), options_max(1) // 1 more than necessary as sentinel\n  {\n    add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);\n  }\n\n  //! @brief POSIX Stats(...) (gnu==false) with non-const argv.\n  Stats(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //\n        bool single_minus_longopt = false) :\n      buffer_max(1), options_max(1) // 1 more than necessary as sentinel\n  {\n    add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);\n  }\n\n  /**\n   * @brief Updates this Stats object for the\n   * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,\n   * if you just want to update @ref options_max.\n   *\n   * @note\n   * The calls to Stats methods must match the later calls to Parser methods.\n   * See Parser::parse() for the meaning of the arguments.\n   */\n  void add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //\n           bool single_minus_longopt = false);\n\n  //! @brief add() with non-const argv.\n  void add(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //\n           bool single_minus_longopt = false)\n  {\n    add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);\n  }\n\n  //! @brief POSIX add() (gnu==false).\n  void add(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //\n           bool single_minus_longopt = false)\n  {\n    add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);\n  }\n\n  //! @brief POSIX add() (gnu==false) with non-const argv.\n  void add(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //\n           bool single_minus_longopt = false)\n  {\n    add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);\n  }\nprivate:\n  class CountOptionsAction;\n};\n\n/**\n * @brief Checks argument vectors for validity and parses them into data\n * structures that are easier to work with.\n *\n * @par Example:\n * @code\n * int main(int argc, char* argv[])\n * {\n *   argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present\n *   option::Stats  stats(usage, argc, argv);\n *   option::Option options[stats.options_max], buffer[stats.buffer_max];\n *   option::Parser parse(usage, argc, argv, options, buffer);\n *\n *   if (parse.error())\n *     return 1;\n *\n *   if (options[HELP])\n *   ...\n * @endcode\n */\nclass Parser\n{\n  int op_count; //!< @internal @brief see optionsCount()\n  int nonop_count; //!< @internal @brief see nonOptionsCount()\n  const char** nonop_args; //!< @internal @brief see nonOptions()\n  bool err; //!< @internal @brief see error()\npublic:\n\n  /**\n   * @brief Creates a new Parser.\n   */\n  Parser() :\n      op_count(0), nonop_count(0), nonop_args(0), err(false)\n  {\n  }\n\n  /**\n   * @brief Creates a new Parser and immediately parses the given argument vector.\n   * @copydetails parse()\n   */\n  Parser(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],\n         int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :\n      op_count(0), nonop_count(0), nonop_args(0), err(false)\n  {\n    parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);\n  }\n\n  //! @brief Parser(...) with non-const argv.\n  Parser(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],\n         int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :\n      op_count(0), nonop_count(0), nonop_args(0), err(false)\n  {\n    parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);\n  }\n\n  //! @brief POSIX Parser(...) (gnu==false).\n  Parser(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[], int min_abbr_len = 0,\n         bool single_minus_longopt = false, int bufmax = -1) :\n      op_count(0), nonop_count(0), nonop_args(0), err(false)\n  {\n    parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);\n  }\n\n  //! @brief POSIX Parser(...) (gnu==false) with non-const argv.\n  Parser(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,\n         bool single_minus_longopt = false, int bufmax = -1) :\n      op_count(0), nonop_count(0), nonop_args(0), err(false)\n  {\n    parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);\n  }\n\n  /**\n   * @brief Parses the given argument vector.\n   *\n   * @param gnu if true, parse() will not stop at the first non-option argument. Instead it will\n   *            reorder arguments so that all non-options are at the end. This is the default behaviour\n   *            of GNU getopt() but is not conforming to POSIX. @n\n   *            Note, that once the argument vector has been reordered, the @c gnu flag will have\n   *            no further effect on this argument vector. So it is enough to pass @c gnu==true when\n   *            creating Stats.\n   * @param usage Array of Descriptor objects that describe the options to support. The last entry\n   *              of this array must have 0 in all fields.\n   * @param argc The number of elements from @c argv that are to be parsed. If you pass -1, the number\n   *             will be determined automatically. In that case the @c argv list must end with a NULL\n   *             pointer.\n   * @param argv The arguments to be parsed. If you pass -1 as @c argc the last pointer in the @c argv\n   *             list must be NULL to mark the end.\n   * @param options Each entry is the first element of a linked list of Options. Each new option\n   *                that is parsed will be appended to the list specified by that Option's\n   *                Descriptor::index. If an entry is not yet used (i.e. the Option is invalid),\n   *                it will be replaced rather than appended to. @n\n   *                The minimum length of this array is the greatest Descriptor::index value that\n   *                occurs in @c usage @e PLUS ONE.\n   * @param buffer Each argument that is successfully parsed (including unknown arguments, if they\n   *        have a Descriptor whose CheckArg does not return @ref ARG_ILLEGAL) will be stored in this\n   *        array. parse() scans the array for the first invalid entry and begins writing at that\n   *        index. You can pass @c bufmax to limit the number of options stored.\n   * @param min_abbr_len Passing a value <code> min_abbr_len > 0 </code> enables abbreviated long\n   *               options. The parser will match a prefix of a long option as if it was\n   *               the full long option (e.g. @c --foob=10 will be interpreted as if it was\n   *               @c --foobar=10 ), as long as the prefix has at least @c min_abbr_len characters\n   *               (not counting the @c -- ) and is unambiguous.\n   *               @n Be careful if combining @c min_abbr_len=1 with @c single_minus_longopt=true\n   *               because the ambiguity check does not consider short options and abbreviated\n   *               single minus long options will take precedence over short options.\n   * @param single_minus_longopt Passing @c true for this option allows long options to begin with\n   *               a single minus. The double minus form will still be recognized. Note that\n   *               single minus long options take precedence over short options and short option\n   *               groups. E.g. @c -file would be interpreted as @c --file and not as\n   *               <code> -f -i -l -e </code> (assuming a long option named @c \"file\" exists).\n   * @param bufmax The greatest index in the @c buffer[] array that parse() will write to is\n   *               @c bufmax-1. If there are more options, they will be processed (in particular\n   *               their CheckArg will be called) but not stored. @n\n   *               If you used Stats::buffer_max to dimension this array, you can pass\n   *               -1 (or not pass @c bufmax at all) which tells parse() that the buffer is\n   *               \"large enough\".\n   * @attention\n   * Remember that @c options and @c buffer store Option @e objects, not pointers. Therefore it\n   * is not possible for the same object to be in both arrays. For those options that are found in\n   * both @c buffer[] and @c options[] the respective objects are independent copies. And only the\n   * objects in @c options[] are properly linked via Option::next() and Option::prev().\n   * You can iterate over @c buffer[] to\n   * process all options in the order they appear in the argument vector, but if you want access to\n   * the other Options with the same Descriptor::index, then you @e must access the linked list via\n   * @c options[]. You can get the linked list in options from a buffer object via something like\n   * @c options[buffer[i].index()].\n   */\n  void parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],\n             int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1);\n\n  //! @brief parse() with non-const argv.\n  void parse(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],\n             int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)\n  {\n    parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);\n  }\n\n  //! @brief POSIX parse() (gnu==false).\n  void parse(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],\n             int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)\n  {\n    parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);\n  }\n\n  //! @brief POSIX parse() (gnu==false) with non-const argv.\n  void parse(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,\n             bool single_minus_longopt = false, int bufmax = -1)\n  {\n    parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);\n  }\n\n  /**\n   * @brief Returns the number of valid Option objects in @c buffer[].\n   *\n   * @note\n   * @li The returned value always reflects the number of Options in the buffer[] array used for\n   * the most recent call to parse().\n   * @li The count (and the buffer[]) includes unknown options if they are collected\n   * (see Descriptor::longopt).\n   */\n  int optionsCount()\n  {\n    return op_count;\n  }\n\n  /**\n   * @brief Returns the number of non-option arguments that remained at the end of the\n   * most recent parse() that actually encountered non-option arguments.\n   *\n   * @note\n   * A parse() that does not encounter non-option arguments will leave this value\n   * as well as nonOptions() undisturbed. This means you can feed the Parser a\n   * default argument vector that contains non-option arguments (e.g. a default filename).\n   * Then you feed it the actual arguments from the user. If the user has supplied at\n   * least one non-option argument, all of the non-option arguments from the default\n   * disappear and are replaced by the user's non-option arguments. However, if the\n   * user does not supply any non-option arguments the defaults will still be in\n   * effect.\n   */\n  int nonOptionsCount()\n  {\n    return nonop_count;\n  }\n\n  /**\n   * @brief Returns a pointer to an array of non-option arguments (only valid\n   * if <code>nonOptionsCount() >0 </code>).\n   *\n   * @note\n   * @li parse() does not copy arguments, so this pointer points into the actual argument\n   * vector as passed to parse().\n   * @li As explained at nonOptionsCount() this pointer is only changed by parse() calls\n   * that actually encounter non-option arguments. A parse() call that encounters only\n   * options, will not change nonOptions().\n   */\n  const char** nonOptions()\n  {\n    return nonop_args;\n  }\n\n  /**\n   * @brief Returns <b><code>nonOptions()[i]</code></b> (@e without checking if i is in range!).\n   */\n  const char* nonOption(int i)\n  {\n    return nonOptions()[i];\n  }\n\n  /**\n   * @brief Returns @c true if an unrecoverable error occurred while parsing options.\n   *\n   * An illegal argument to an option (i.e. CheckArg returns @ref ARG_ILLEGAL) is an\n   * unrecoverable error that aborts the parse. Unknown options are only an error if\n   * their CheckArg function returns @ref ARG_ILLEGAL. Otherwise they are collected.\n   * In that case if you want to exit the program if either an illegal argument\n   * or an unknown option has been passed, use code like this\n   *\n   * @code\n   * if (parser.error() || options[UNKNOWN])\n   *   exit(1);\n   * @endcode\n   *\n   */\n  bool error()\n  {\n    return err;\n  }\n\nprivate:\n  friend struct Stats;\n  class StoreOptionAction;\n  struct Action;\n\n  /**\n   * @internal\n   * @brief This is the core function that does all the parsing.\n   * @retval false iff an unrecoverable error occurred.\n   */\n  static bool workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,\n                        bool single_minus_longopt, bool print_errors, int min_abbr_len);\n\n  /**\n   * @internal\n   * @brief Returns true iff @c st1 is a prefix of @c st2 and\n   * in case @c st2 is longer than @c st1, then\n   * the first additional character is '='.\n   *\n   * @par Examples:\n   * @code\n   * streq(\"foo\", \"foo=bar\") == true\n   * streq(\"foo\", \"foobar\")  == false\n   * streq(\"foo\", \"foo\")     == true\n   * streq(\"foo=bar\", \"foo\") == false\n   * @endcode\n   */\n  static bool streq(const char* st1, const char* st2)\n  {\n    while (*st1 != 0)\n      if (*st1++ != *st2++)\n        return false;\n    return (*st2 == 0 || *st2 == '=');\n  }\n\n  /**\n   * @internal\n   * @brief Like streq() but handles abbreviations.\n   *\n   * Returns true iff @c st1 and @c st2 have a common\n   * prefix with the following properties:\n   * @li (if min > 0) its length is at least @c min characters or the same length as @c st1 (whichever is smaller).\n   * @li (if min <= 0) its length is the same as that of @c st1\n   * @li within @c st2 the character following the common prefix is either '=' or end-of-string.\n   *\n   * Examples:\n   * @code\n   * streqabbr(\"foo\", \"foo=bar\",<anything>) == true\n   * streqabbr(\"foo\", \"fo=bar\" , 2) == true\n   * streqabbr(\"foo\", \"fo\"     , 2) == true\n   * streqabbr(\"foo\", \"fo\"     , 0) == false\n   * streqabbr(\"foo\", \"f=bar\"  , 2) == false\n   * streqabbr(\"foo\", \"f\"      , 2) == false\n   * streqabbr(\"fo\" , \"foo=bar\",<anything>)  == false\n   * streqabbr(\"foo\", \"foobar\" ,<anything>)  == false\n   * streqabbr(\"foo\", \"fobar\"  ,<anything>)  == false\n   * streqabbr(\"foo\", \"foo\"    ,<anything>)  == true\n   * @endcode\n   */\n  static bool streqabbr(const char* st1, const char* st2, long long min)\n  {\n    const char* st1start = st1;\n    while (*st1 != 0 && (*st1 == *st2))\n    {\n      ++st1;\n      ++st2;\n    }\n\n    return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 == '=');\n  }\n\n  /**\n   * @internal\n   * @brief Returns true iff character @c ch is contained in the string @c st.\n   *\n   * Returns @c true for @c ch==0 .\n   */\n  static bool instr(char ch, const char* st)\n  {\n    while (*st != 0 && *st != ch)\n      ++st;\n    return *st == ch;\n  }\n\n  /**\n   * @internal\n   * @brief Rotates <code>args[-count],...,args[-1],args[0]</code> to become\n   *        <code>args[0],args[-count],...,args[-1]</code>.\n   */\n  static void shift(const char** args, int count)\n  {\n    for (int i = 0; i > -count; --i)\n    {\n      const char* temp = args[i];\n      args[i] = args[i - 1];\n      args[i - 1] = temp;\n    }\n  }\n};\n\n/**\n * @internal\n * @brief Interface for actions Parser::workhorse() should perform for each Option it\n * parses.\n */\nstruct Parser::Action\n{\n  /**\n   * @brief Called by Parser::workhorse() for each Option that has been successfully\n   * parsed (including unknown\n   * options if they have a Descriptor whose Descriptor::check_arg does not return\n   * @ref ARG_ILLEGAL.\n   *\n   * Returns @c false iff a fatal error has occured and the parse should be aborted.\n   */\n  virtual bool perform(Option&)\n  {\n    return true;\n  }\n\n  /**\n   * @brief Called by Parser::workhorse() after finishing the parse.\n   * @param numargs the number of non-option arguments remaining\n   * @param args pointer to the first remaining non-option argument (if numargs > 0).\n   *\n   * @return\n   * @c false iff a fatal error has occurred.\n   */\n  virtual bool finished(int numargs, const char** args)\n  {\n    (void) numargs;\n    (void) args;\n    return true;\n  }\n};\n\n/**\n * @internal\n * @brief An Action to pass to Parser::workhorse() that will increment a counter for\n * each parsed Option.\n */\nclass Stats::CountOptionsAction: public Parser::Action\n{\n  unsigned* buffer_max;\npublic:\n  /**\n   * Creates a new CountOptionsAction that will increase @c *buffer_max_ for each\n   * parsed Option.\n   */\n  CountOptionsAction(unsigned* buffer_max_) :\n      buffer_max(buffer_max_)\n  {\n  }\n\n  bool perform(Option&)\n  {\n    if (*buffer_max == 0x7fffffff)\n      return false; // overflow protection: don't accept number of options that doesn't fit signed int\n    ++*buffer_max;\n    return true;\n  }\n};\n\n/**\n * @internal\n * @brief An Action to pass to Parser::workhorse() that will store each parsed Option in\n * appropriate arrays (see Parser::parse()).\n */\nclass Parser::StoreOptionAction: public Parser::Action\n{\n  Parser& parser;\n  Option* options;\n  Option* buffer;\n  int bufmax; //! Number of slots in @c buffer. @c -1 means \"large enough\".\npublic:\n  /**\n   * @brief Creates a new StoreOption action.\n   * @param parser_ the parser whose op_count should be updated.\n   * @param options_ each Option @c o is chained into the linked list @c options_[o.desc->index]\n   * @param buffer_ each Option is appended to this array as long as there's a free slot.\n   * @param bufmax_ number of slots in @c buffer_. @c -1 means \"large enough\".\n   */\n  StoreOptionAction(Parser& parser_, Option options_[], Option buffer_[], int bufmax_) :\n      parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)\n  {\n    // find first empty slot in buffer (if any)\n    int bufidx = 0;\n    while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])\n      ++bufidx;\n\n    // set parser's optionCount\n    parser.op_count = bufidx;\n  }\n\n  bool perform(Option& option)\n  {\n    if (bufmax < 0 || parser.op_count < bufmax)\n    {\n      if (parser.op_count == 0x7fffffff)\n        return false; // overflow protection: don't accept number of options that doesn't fit signed int\n\n      buffer[parser.op_count] = option;\n      int idx = buffer[parser.op_count].desc->index;\n      if (options[idx])\n        options[idx].append(buffer[parser.op_count]);\n      else\n        options[idx] = buffer[parser.op_count];\n      ++parser.op_count;\n    }\n    return true; // NOTE: an option that is discarded because of a full buffer is not fatal\n  }\n\n  bool finished(int numargs, const char** args)\n  {\n    // only overwrite non-option argument list if there's at least 1\n    // new non-option argument. Otherwise we keep the old list. This\n    // makes it easy to use default non-option arguments.\n    if (numargs > 0)\n    {\n      parser.nonop_count = numargs;\n      parser.nonop_args = args;\n    }\n\n    return true;\n  }\n};\n\ninline void Parser::parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[],\n                          Option buffer[], int min_abbr_len, bool single_minus_longopt, int bufmax)\n{\n  StoreOptionAction action(*this, options, buffer, bufmax);\n  err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt, true, min_abbr_len);\n}\n\ninline void Stats::add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len,\n                       bool single_minus_longopt)\n{\n  // determine size of options array. This is the greatest index used in the usage + 1\n  int i = 0;\n  while (usage[i].shortopt != 0)\n  {\n    if (usage[i].index + 1 >= options_max)\n      options_max = (usage[i].index + 1) + 1; // 1 more than necessary as sentinel\n\n    ++i;\n  }\n\n  CountOptionsAction action(&buffer_max);\n  Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt, false, min_abbr_len);\n}\n\ninline bool Parser::workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,\n                              bool single_minus_longopt, bool print_errors, int min_abbr_len)\n{\n  // protect against NULL pointer\n  if (args == 0)\n    numargs = 0;\n\n  int nonops = 0;\n\n  while (numargs != 0 && *args != 0)\n  {\n    const char* param = *args; // param can be --long-option, -srto or non-option argument\n\n    // in POSIX mode the first non-option argument terminates the option list\n    // a lone minus character is a non-option argument\n    if (param[0] != '-' || param[1] == 0)\n    {\n      if (gnu)\n      {\n        ++nonops;\n        ++args;\n        if (numargs > 0)\n          --numargs;\n        continue;\n      }\n      else\n        break;\n    }\n\n    // -- terminates the option list. The -- itself is skipped.\n    if (param[1] == '-' && param[2] == 0)\n    {\n      shift(args, nonops);\n      ++args;\n      if (numargs > 0)\n        --numargs;\n      break;\n    }\n\n    bool handle_short_options;\n    const char* longopt_name;\n    if (param[1] == '-') // if --long-option\n    {\n      handle_short_options = false;\n      longopt_name = param + 2;\n    }\n    else\n    {\n      handle_short_options = true;\n      longopt_name = param + 1; //for testing a potential -long-option\n    }\n\n    bool try_single_minus_longopt = single_minus_longopt;\n    bool have_more_args = (numargs > 1 || numargs < 0); // is referencing argv[1] valid?\n\n    do // loop over short options in group, for long options the body is executed only once\n    {\n      int idx = 0;\n\n      const char* optarg = 0;\n\n      /******************** long option **********************/\n      if (handle_short_options == false || try_single_minus_longopt)\n      {\n        idx = 0;\n        while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))\n          ++idx;\n\n        if (usage[idx].longopt == 0 && min_abbr_len > 0) // if we should try to match abbreviated long options\n        {\n          int i1 = 0;\n          while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))\n            ++i1;\n          if (usage[i1].longopt != 0)\n          { // now test if the match is unambiguous by checking for another match\n            int i2 = i1 + 1;\n            while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))\n              ++i2;\n\n            if (usage[i2].longopt == 0) // if there was no second match it's unambiguous, so accept i1 as idx\n              idx = i1;\n          }\n        }\n\n        // if we found something, disable handle_short_options (only relevant if single_minus_longopt)\n        if (usage[idx].longopt != 0)\n          handle_short_options = false;\n\n        try_single_minus_longopt = false; // prevent looking for longopt in the middle of shortopt group\n\n        optarg = longopt_name;\n        while (*optarg != 0 && *optarg != '=')\n          ++optarg;\n        if (*optarg == '=') // attached argument\n          ++optarg;\n        else\n          // possibly detached argument\n          optarg = (have_more_args ? args[1] : 0);\n      }\n\n      /************************ short option ***********************************/\n      if (handle_short_options)\n      {\n        if (*++param == 0) // point at the 1st/next option character\n          break; // end of short option group\n\n        idx = 0;\n        while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))\n          ++idx;\n\n        if (param[1] == 0) // if the potential argument is separate\n          optarg = (have_more_args ? args[1] : 0);\n        else\n          // if the potential argument is attached\n          optarg = param + 1;\n      }\n\n      const Descriptor* descriptor = &usage[idx];\n\n      if (descriptor->shortopt == 0) /**************  unknown option ********************/\n      {\n        // look for dummy entry (shortopt == \"\" and longopt == \"\") to use as Descriptor for unknown options\n        idx = 0;\n        while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))\n          ++idx;\n        descriptor = (usage[idx].shortopt == 0 ? 0 : &usage[idx]);\n      }\n\n      if (descriptor != 0)\n      {\n        Option option(descriptor, param, optarg);\n        switch (descriptor->check_arg(option, print_errors))\n        {\n          case ARG_ILLEGAL:\n            return false; // fatal\n          case ARG_OK:\n            // skip one element of the argument vector, if it's a separated argument\n            if (optarg != 0 && have_more_args && optarg == args[1])\n            {\n              shift(args, nonops);\n              if (numargs > 0)\n                --numargs;\n              ++args;\n            }\n\n            // No further short options are possible after an argument\n            handle_short_options = false;\n\n            break;\n          case ARG_IGNORE:\n          case ARG_NONE:\n            option.arg = 0;\n            break;\n        }\n\n        if (!action.perform(option))\n          return false;\n      }\n\n    } while (handle_short_options);\n\n    shift(args, nonops);\n    ++args;\n    if (numargs > 0)\n      --numargs;\n\n  } // while\n\n  if (numargs > 0 && *args == 0) // It's a bug in the caller if numargs is greater than the actual number\n    numargs = 0; // of arguments, but as a service to the user we fix this if we spot it.\n\n  if (numargs < 0) // if we don't know the number of remaining non-option arguments\n  { // we need to count them\n    numargs = 0;\n    while (args[numargs] != 0)\n      ++numargs;\n  }\n\n  return action.finished(numargs + nonops, args - nonops);\n}\n\n/**\n * @internal\n * @brief The implementation of option::printUsage().\n */\nstruct PrintUsageImplementation\n{\n  /**\n   * @internal\n   * @brief Interface for Functors that write (part of) a string somewhere.\n   */\n  struct IStringWriter\n  {\n    /**\n     * @brief Writes the given number of chars beginning at the given pointer somewhere.\n     */\n    virtual void operator()(const char*, int)\n    {\n    }\n  };\n\n  /**\n   * @internal\n   * @brief Encapsulates a function with signature <code>func(string, size)</code> where\n   * string can be initialized with a const char* and size with an int.\n   */\n  template<typename Function>\n  struct FunctionWriter: public IStringWriter\n  {\n    Function* write;\n\n    virtual void operator()(const char* str, int size)\n    {\n      (*write)(str, size);\n    }\n\n    FunctionWriter(Function* w) :\n        write(w)\n    {\n    }\n  };\n\n  /**\n   * @internal\n   * @brief Encapsulates a reference to an object with a <code>write(string, size)</code>\n   * method like that of @c std::ostream.\n   */\n  template<typename OStream>\n  struct OStreamWriter: public IStringWriter\n  {\n    OStream& ostream;\n\n    virtual void operator()(const char* str, int size)\n    {\n      ostream.write(str, size);\n    }\n\n    OStreamWriter(OStream& o) :\n        ostream(o)\n    {\n    }\n  };\n\n  /**\n   * @internal\n   * @brief Like OStreamWriter but encapsulates a @c const reference, which is\n   * typically a temporary object of a user class.\n   */\n  template<typename Temporary>\n  struct TemporaryWriter: public IStringWriter\n  {\n    const Temporary& userstream;\n\n    virtual void operator()(const char* str, int size)\n    {\n      userstream.write(str, size);\n    }\n\n    TemporaryWriter(const Temporary& u) :\n        userstream(u)\n    {\n    }\n  };\n\n  /**\n   * @internal\n   * @brief Encapsulates a function with the signature <code>func(fd, string, size)</code> (the\n   * signature of the @c write() system call)\n   * where fd can be initialized from an int, string from a const char* and size from an int.\n   */\n  template<typename Syscall>\n  struct SyscallWriter: public IStringWriter\n  {\n    Syscall* write;\n    int fd;\n\n    virtual void operator()(const char* str, int size)\n    {\n      (*write)(fd, str, size);\n    }\n\n    SyscallWriter(Syscall* w, int f) :\n        write(w), fd(f)\n    {\n    }\n  };\n\n  /**\n   * @internal\n   * @brief Encapsulates a function with the same signature as @c std::fwrite().\n   */\n  template<typename Function, typename Stream>\n  struct StreamWriter: public IStringWriter\n  {\n    Function* fwrite;\n    Stream* stream;\n\n    virtual void operator()(const char* str, int size)\n    {\n      (*fwrite)(str, size, 1, stream);\n    }\n\n    StreamWriter(Function* w, Stream* s) :\n        fwrite(w), stream(s)\n    {\n    }\n  };\n\n  /**\n   * @internal\n   * @brief Sets <code> i1 = max(i1, i2) </code>\n   */\n  static void upmax(int& i1, int i2)\n  {\n    i1 = (i1 >= i2 ? i1 : i2);\n  }\n\n  /**\n   * @internal\n   * @brief Moves the \"cursor\" to column @c want_x assuming it is currently at column @c x\n   * and sets @c x=want_x .\n   * If <code> x > want_x </code>, a line break is output before indenting.\n   *\n   * @param write Spaces and possibly a line break are written via this functor to get\n   *        the desired indentation @c want_x .\n   * @param[in,out] x the current indentation. Set to @c want_x by this method.\n   * @param want_x the desired indentation.\n   */\n  static void indent(IStringWriter& write, int& x, int want_x)\n  {\n    int indent = want_x - x;\n    if (indent < 0)\n    {\n      write(\"\\n\", 1);\n      indent = want_x;\n    }\n\n    if (indent > 0)\n    {\n      char space = ' ';\n      for (int i = 0; i < indent; ++i)\n        write(&space, 1);\n      x = want_x;\n    }\n  }\n\n  /**\n   * @brief Returns true if ch is the unicode code point of a wide character.\n   *\n   * @note\n   * The following character ranges are treated as wide\n   * @code\n   * 1100..115F\n   * 2329..232A  (just 2 characters!)\n   * 2E80..A4C6  except for 303F\n   * A960..A97C\n   * AC00..D7FB\n   * F900..FAFF\n   * FE10..FE6B\n   * FF01..FF60\n   * FFE0..FFE6\n   * 1B000......\n   * @endcode\n   */\n  static bool isWideChar(unsigned ch)\n  {\n    if (ch == 0x303F)\n      return false;\n\n    return ((0x1100 <= ch && ch <= 0x115F) || (0x2329 <= ch && ch <= 0x232A) || (0x2E80 <= ch && ch <= 0xA4C6)\n        || (0xA960 <= ch && ch <= 0xA97C) || (0xAC00 <= ch && ch <= 0xD7FB) || (0xF900 <= ch && ch <= 0xFAFF)\n        || (0xFE10 <= ch && ch <= 0xFE6B) || (0xFF01 <= ch && ch <= 0xFF60) || (0xFFE0 <= ch && ch <= 0xFFE6)\n        || (0x1B000 <= ch));\n  }\n\n  /**\n   * @internal\n   * @brief Splits a @c Descriptor[] array into tables, rows, lines and columns and\n   * iterates over these components.\n   *\n   * The top-level organizational unit is the @e table.\n   * A table begins at a Descriptor with @c help!=NULL and extends up to\n   * a Descriptor with @c help==NULL.\n   *\n   * A table consists of @e rows. Due to line-wrapping and explicit breaks\n   * a row may take multiple lines on screen. Rows within the table are separated\n   * by \\\\n. They never cross Descriptor boundaries. This means a row ends either\n   * at \\\\n or the 0 at the end of the help string.\n   *\n   * A row consists of columns/cells. Columns/cells within a row are separated by \\\\t.\n   * Line breaks within a cell are marked by \\\\v.\n   *\n   * Rows in the same table need not have the same number of columns/cells. The\n   * extreme case are interjections, which are rows that contain neither \\\\t nor \\\\v.\n   * These are NOT treated specially by LinePartIterator, but they are treated\n   * specially by printUsage().\n   *\n   * LinePartIterator iterates through the usage at 3 levels: table, row and part.\n   * Tables and rows are as described above. A @e part is a line within a cell.\n   * LinePartIterator iterates through 1st parts of all cells, then through the 2nd\n   * parts of all cells (if any),... @n\n   * Example: The row <code> \"1 \\v 3 \\t 2 \\v 4\" </code> has 2 cells/columns and 4 parts.\n   * The parts will be returned in the order 1, 2, 3, 4.\n   *\n   * It is possible that some cells have fewer parts than others. In this case\n   * LinePartIterator will \"fill up\" these cells with 0-length parts. IOW, LinePartIterator\n   * always returns the same number of parts for each column. Note that this is different\n   * from the way rows and columns are handled. LinePartIterator does @e not guarantee that\n   * the same number of columns will be returned for each row.\n   *\n   */\n  class LinePartIterator\n  {\n    const Descriptor* tablestart; //!< The 1st descriptor of the current table.\n    const Descriptor* rowdesc; //!< The Descriptor that contains the current row.\n    const char* rowstart; //!< Ptr to 1st character of current row within rowdesc->help.\n    const char* ptr; //!< Ptr to current part within the current row.\n    int col; //!< Index of current column.\n    int len; //!< Length of the current part (that ptr points at) in BYTES\n    int screenlen; //!< Length of the current part in screen columns (taking narrow/wide chars into account).\n    int max_line_in_block; //!< Greatest index of a line within the block. This is the number of \\\\v within the cell with the most \\\\vs.\n    int line_in_block; //!< Line index within the current cell of the current part.\n    int target_line_in_block; //!< Line index of the parts we should return to the user on this iteration.\n    bool hit_target_line; //!< Flag whether we encountered a part with line index target_line_in_block in the current cell.\n\n    /**\n     * @brief Determines the byte and character lengths of the part at @ref ptr and\n     * stores them in @ref len and @ref screenlen respectively.\n     */\n    void update_length()\n    {\n      screenlen = 0;\n      for (len = 0; ptr[len] != 0 && ptr[len] != '\\v' && ptr[len] != '\\t' && ptr[len] != '\\n'; ++len)\n      {\n        ++screenlen;\n        unsigned ch = (unsigned char) ptr[len];\n        if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte\n        {\n          // int __builtin_clz (unsigned int x)\n          // Returns the number of leading 0-bits in x, starting at the most significant bit\n          unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);\n          ch = ch & mask; // mask out length bits, we don't verify their correctness\n          while (((unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F) // while next byte is continuation byte\n          {\n            ch = (ch << 6) ^ (unsigned char) ptr[len + 1] ^ 0x80; // add continuation to char code\n            ++len;\n          }\n          // ch is the decoded unicode code point\n          if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case\n            ++screenlen;\n        }\n      }\n    }\n\n  public:\n    //! @brief Creates an iterator for @c usage.\n    LinePartIterator(const Descriptor usage[]) :\n        tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), max_line_in_block(0), line_in_block(0),\n        target_line_in_block(0), hit_target_line(true)\n    {\n    }\n\n    /**\n     * @brief Moves iteration to the next table (if any). Has to be called once on a new\n     * LinePartIterator to move to the 1st table.\n     * @retval false if moving to next table failed because no further table exists.\n     */\n    bool nextTable()\n    {\n      // If this is NOT the first time nextTable() is called after the constructor,\n      // then skip to the next table break (i.e. a Descriptor with help == 0)\n      if (rowdesc != 0)\n      {\n        while (tablestart->help != 0 && tablestart->shortopt != 0)\n          ++tablestart;\n      }\n\n      // Find the next table after the break (if any)\n      while (tablestart->help == 0 && tablestart->shortopt != 0)\n        ++tablestart;\n\n      restartTable();\n      return rowstart != 0;\n    }\n\n    /**\n     * @brief Reset iteration to the beginning of the current table.\n     */\n    void restartTable()\n    {\n      rowdesc = tablestart;\n      rowstart = tablestart->help;\n      ptr = 0;\n    }\n\n    /**\n     * @brief Moves iteration to the next row (if any). Has to be called once after each call to\n     * @ref nextTable() to move to the 1st row of the table.\n     * @retval false if moving to next row failed because no further row exists.\n     */\n    bool nextRow()\n    {\n      if (ptr == 0)\n      {\n        restartRow();\n        return rowstart != 0;\n      }\n\n      while (*ptr != 0 && *ptr != '\\n')\n        ++ptr;\n\n      if (*ptr == 0)\n      {\n        if ((rowdesc + 1)->help == 0) // table break\n          return false;\n\n        ++rowdesc;\n        rowstart = rowdesc->help;\n      }\n      else // if (*ptr == '\\n')\n      {\n        rowstart = ptr + 1;\n      }\n\n      restartRow();\n      return true;\n    }\n\n    /**\n     * @brief Reset iteration to the beginning of the current row.\n     */\n    void restartRow()\n    {\n      ptr = rowstart;\n      col = -1;\n      len = 0;\n      screenlen = 0;\n      max_line_in_block = 0;\n      line_in_block = 0;\n      target_line_in_block = 0;\n      hit_target_line = true;\n    }\n\n    /**\n     * @brief Moves iteration to the next part (if any). Has to be called once after each call to\n     * @ref nextRow() to move to the 1st part of the row.\n     * @retval false if moving to next part failed because no further part exists.\n     *\n     * See @ref LinePartIterator for details about the iteration.\n     */\n    bool next()\n    {\n      if (ptr == 0)\n        return false;\n\n      if (col == -1)\n      {\n        col = 0;\n        update_length();\n        return true;\n      }\n\n      ptr += len;\n      while (true)\n      {\n        switch (*ptr)\n        {\n          case '\\v':\n            upmax(max_line_in_block, ++line_in_block);\n            ++ptr;\n            break;\n          case '\\t':\n            if (!hit_target_line) // if previous column did not have the targetline\n            { // then \"insert\" a 0-length part\n              update_length();\n              hit_target_line = true;\n              return true;\n            }\n\n            hit_target_line = false;\n            line_in_block = 0;\n            ++col;\n            ++ptr;\n            break;\n          case 0:\n          case '\\n':\n            if (!hit_target_line) // if previous column did not have the targetline\n            { // then \"insert\" a 0-length part\n              update_length();\n              hit_target_line = true;\n              return true;\n            }\n\n            if (++target_line_in_block > max_line_in_block)\n            {\n              update_length();\n              return false;\n            }\n\n            hit_target_line = false;\n            line_in_block = 0;\n            col = 0;\n            ptr = rowstart;\n            continue;\n          default:\n            ++ptr;\n            continue;\n        } // switch\n\n        if (line_in_block == target_line_in_block)\n        {\n          update_length();\n          hit_target_line = true;\n          return true;\n        }\n      } // while\n    }\n\n    /**\n     * @brief Returns the index (counting from 0) of the column in which\n     * the part pointed to by @ref data() is located.\n     */\n    int column()\n    {\n      return col;\n    }\n\n    /**\n     * @brief Returns the index (counting from 0) of the line within the current column\n     * this part belongs to.\n     */\n    int line()\n    {\n      return target_line_in_block; // NOT line_in_block !!! It would be wrong if !hit_target_line\n    }\n\n    /**\n     * @brief Returns the length of the part pointed to by @ref data() in raw chars (not UTF-8 characters).\n     */\n    int length()\n    {\n      return len;\n    }\n\n    /**\n     * @brief Returns the width in screen columns of the part pointed to by @ref data().\n     * Takes multi-byte UTF-8 sequences and wide characters into account.\n     */\n    int screenLength()\n    {\n      return screenlen;\n    }\n\n    /**\n     * @brief Returns the current part of the iteration.\n     */\n    const char* data()\n    {\n      return ptr;\n    }\n  };\n\n  /**\n   * @internal\n   * @brief Takes input and line wraps it, writing out one line at a time so that\n   * it can be interleaved with output from other columns.\n   *\n   * The LineWrapper is used to handle the last column of each table as well as interjections.\n   * The LineWrapper is called once for each line of output. If the data given to it fits\n   * into the designated width of the last column it is simply written out. If there\n   * is too much data, an appropriate split point is located and only the data up to this\n   * split point is written out. The rest of the data is queued for the next line.\n   * That way the last column can be line wrapped and interleaved with data from\n   * other columns. The following example makes this clearer:\n   * @code\n   * Column 1,1    Column 2,1     This is a long text\n   * Column 1,2    Column 2,2     that does not fit into\n   *                              a single line.\n   * @endcode\n   *\n   * The difficulty in producing this output is that the whole string\n   * \"This is a long text that does not fit into a single line\" is the\n   * 1st and only part of column 3. In order to produce the above\n   * output the string must be output piecemeal, interleaved with\n   * the data from the other columns.\n   */\n  class LineWrapper\n  {\n    static const int bufmask = 15; //!< Must be a power of 2 minus 1.\n    /**\n     * @brief Ring buffer for length component of pair (data, length).\n     */\n    int lenbuf[bufmask + 1];\n    /**\n     * @brief Ring buffer for data component of pair (data, length).\n     */\n    const char* datbuf[bufmask + 1];\n    /**\n     * @brief The indentation of the column to which the LineBuffer outputs. LineBuffer\n     * assumes that the indentation has already been written when @ref process()\n     * is called, so this value is only used when a buffer flush requires writing\n     * additional lines of output.\n     */\n    int x;\n    /**\n     * @brief The width of the column to line wrap.\n     */\n    int width;\n    int head; //!< @brief index for next write\n    int tail; //!< @brief index for next read - 1 (i.e. increment tail BEFORE read)\n\n    /**\n     * @brief Multiple methods of LineWrapper may decide to flush part of the buffer to\n     * free up space. The contract of process() says that only 1 line is output. So\n     * this variable is used to track whether something has output a line. It is\n     * reset at the beginning of process() and checked at the end to decide if\n     * output has already occurred or is still needed.\n     */\n    bool wrote_something;\n\n    bool buf_empty()\n    {\n      return ((tail + 1) & bufmask) == head;\n    }\n\n    bool buf_full()\n    {\n      return tail == head;\n    }\n\n    void buf_store(const char* data, int len)\n    {\n      lenbuf[head] = len;\n      datbuf[head] = data;\n      head = (head + 1) & bufmask;\n    }\n\n    //! @brief Call BEFORE reading ...buf[tail].\n    void buf_next()\n    {\n      tail = (tail + 1) & bufmask;\n    }\n\n    /**\n     * @brief Writes (data,len) into the ring buffer. If the buffer is full, a single line\n     * is flushed out of the buffer into @c write.\n     */\n    void output(IStringWriter& write, const char* data, int len)\n    {\n      if (buf_full())\n        write_one_line(write);\n\n      buf_store(data, len);\n    }\n\n    /**\n     * @brief Writes a single line of output from the buffer to @c write.\n     */\n    void write_one_line(IStringWriter& write)\n    {\n      if (wrote_something) // if we already wrote something, we need to start a new line\n      {\n        write(\"\\n\", 1);\n        int _ = 0;\n        indent(write, _, x);\n      }\n\n      if (!buf_empty())\n      {\n        buf_next();\n        write(datbuf[tail], lenbuf[tail]);\n      }\n\n      wrote_something = true;\n    }\n  public:\n\n    /**\n     * @brief Writes out all remaining data from the LineWrapper using @c write.\n     * Unlike @ref process() this method indents all lines including the first and\n     * will output a \\\\n at the end (but only if something has been written).\n     */\n    void flush(IStringWriter& write)\n    {\n      if (buf_empty())\n        return;\n      int _ = 0;\n      indent(write, _, x);\n      wrote_something = false;\n      while (!buf_empty())\n        write_one_line(write);\n      write(\"\\n\", 1);\n    }\n\n    /**\n     * @brief Process, wrap and output the next piece of data.\n     *\n     * process() will output at least one line of output. This is not necessarily\n     * the @c data passed in. It may be data queued from a prior call to process().\n     * If the internal buffer is full, more than 1 line will be output.\n     *\n     * process() assumes that the a proper amount of indentation has already been\n     * output. It won't write any further indentation before the 1st line. If\n     * more than 1 line is written due to buffer constraints, the lines following\n     * the first will be indented by this method, though.\n     *\n     * No \\\\n is written by this method after the last line that is written.\n     *\n     * @param write where to write the data.\n     * @param data the new chunk of data to write.\n     * @param len the length of the chunk of data to write.\n     */\n    void process(IStringWriter& write, const char* data, int len)\n    {\n      wrote_something = false;\n\n      while (len > 0)\n      {\n        if (len <= width) // quick test that works because utf8width <= len (all wide chars have at least 2 bytes)\n        {\n          output(write, data, len);\n          len = 0;\n        }\n        else // if (len > width)  it's possible (but not guaranteed) that utf8len > width\n        {\n          int utf8width = 0;\n          int maxi = 0;\n          while (maxi < len && utf8width < width)\n          {\n            int charbytes = 1;\n            unsigned ch = (unsigned char) data[maxi];\n            if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte\n            {\n              // int __builtin_clz (unsigned int x)\n              // Returns the number of leading 0-bits in x, starting at the most significant bit\n              unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);\n              ch = ch & mask; // mask out length bits, we don't verify their correctness\n              while ((maxi + charbytes < len) && //\n                  (((unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F)) // while next byte is continuation byte\n              {\n                ch = (ch << 6) ^ (unsigned char) data[maxi + charbytes] ^ 0x80; // add continuation to char code\n                ++charbytes;\n              }\n              // ch is the decoded unicode code point\n              if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case\n              {\n                if (utf8width + 2 > width)\n                  break;\n                ++utf8width;\n              }\n            }\n            ++utf8width;\n            maxi += charbytes;\n          }\n\n          // data[maxi-1] is the last byte of the UTF-8 sequence of the last character that fits\n          // onto the 1st line. If maxi == len, all characters fit on the line.\n\n          if (maxi == len)\n          {\n            output(write, data, len);\n            len = 0;\n          }\n          else // if (maxi < len)  at least 1 character (data[maxi] that is) doesn't fit on the line\n          {\n            int i;\n            for (i = maxi; i >= 0; --i)\n              if (data[i] == ' ')\n                break;\n\n            if (i >= 0)\n            {\n              output(write, data, i);\n              data += i + 1;\n              len -= i + 1;\n            }\n            else // did not find a space to split at => split before data[maxi]\n            { // data[maxi] is always the beginning of a character, never a continuation byte\n              output(write, data, maxi);\n              data += maxi;\n              len -= maxi;\n            }\n          }\n        }\n      }\n      if (!wrote_something) // if we didn't already write something to make space in the buffer\n        write_one_line(write); // write at most one line of actual output\n    }\n\n    /**\n     * @brief Constructs a LineWrapper that wraps its output to fit into\n     * screen columns @c x1 (incl.) to @c x2 (excl.).\n     *\n     * @c x1 gives the indentation LineWrapper uses if it needs to indent.\n     */\n    LineWrapper(int x1, int x2) :\n        x(x1), width(x2 - x1), head(0), tail(bufmask)\n    {\n      if (width < 2) // because of wide characters we need at least width 2 or the code breaks\n        width = 2;\n    }\n  };\n\n  /**\n   * @internal\n   * @brief This is the implementation that is shared between all printUsage() templates.\n   * Because all printUsage() templates share this implementation, there is no template bloat.\n   */\n  static void printUsage(IStringWriter& write, const Descriptor usage[], int width = 80, //\n                         int last_column_min_percent = 50, int last_column_own_line_max_percent = 75)\n  {\n    if (width < 1) // protect against nonsense values\n      width = 80;\n\n    if (width > 10000) // protect against overflow in the following computation\n      width = 10000;\n\n    int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;\n    int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;\n    if (last_column_own_line_max_width == 0)\n      last_column_own_line_max_width = 1;\n\n    LinePartIterator part(usage);\n    while (part.nextTable())\n    {\n\n      /***************** Determine column widths *******************************/\n\n      const int maxcolumns = 8; // 8 columns are enough for everyone\n      int col_width[maxcolumns];\n      int lastcolumn;\n      int leftwidth;\n      int overlong_column_threshold = 10000;\n      do\n      {\n        lastcolumn = 0;\n        for (int i = 0; i < maxcolumns; ++i)\n          col_width[i] = 0;\n\n        part.restartTable();\n        while (part.nextRow())\n        {\n          while (part.next())\n          {\n            if (part.column() < maxcolumns)\n            {\n              upmax(lastcolumn, part.column());\n              if (part.screenLength() < overlong_column_threshold)\n                // We don't let rows that don't use table separators (\\t or \\v) influence\n                // the width of column 0. This allows the user to interject section headers\n                // or explanatory paragraphs that do not participate in the table layout.\n                if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\\t'\n                    || part.data()[part.length()] == '\\v')\n                  upmax(col_width[part.column()], part.screenLength());\n            }\n          }\n        }\n\n        /*\n         * If the last column doesn't fit on the same\n         * line as the other columns, we can fix that by starting it on its own line.\n         * However we can't do this for any of the columns 0..lastcolumn-1.\n         * If their sum exceeds the maximum width we try to fix this by iteratively\n         * ignoring the widest line parts in the width determination until\n         * we arrive at a series of column widths that fit into one line.\n         * The result is a layout where everything is nicely formatted\n         * except for a few overlong fragments.\n         * */\n\n        leftwidth = 0;\n        overlong_column_threshold = 0;\n        for (int i = 0; i < lastcolumn; ++i)\n        {\n          leftwidth += col_width[i];\n          upmax(overlong_column_threshold, col_width[i]);\n        }\n\n      } while (leftwidth > width);\n\n      /**************** Determine tab stops and last column handling **********************/\n\n      int tabstop[maxcolumns];\n      tabstop[0] = 0;\n      for (int i = 1; i < maxcolumns; ++i)\n        tabstop[i] = tabstop[i - 1] + col_width[i - 1];\n\n      int rightwidth = width - tabstop[lastcolumn];\n      bool print_last_column_on_own_line = false;\n      if (rightwidth < last_column_min_width &&  // if we don't have the minimum requested width for the last column\n            ( col_width[lastcolumn] == 0 ||      // and all last columns are > overlong_column_threshold\n              rightwidth < col_width[lastcolumn] // or there is at least one last column that requires more than the space available\n            )\n          )\n      {\n        print_last_column_on_own_line = true;\n        rightwidth = last_column_own_line_max_width;\n      }\n\n      // If lastcolumn == 0 we must disable print_last_column_on_own_line because\n      // otherwise 2 copies of the last (and only) column would be output.\n      // Actually this is just defensive programming. It is currently not\n      // possible that lastcolumn==0 and print_last_column_on_own_line==true\n      // at the same time, because lastcolumn==0 => tabstop[lastcolumn] == 0 =>\n      // rightwidth==width => rightwidth>=last_column_min_width  (unless someone passes\n      // a bullshit value >100 for last_column_min_percent) => the above if condition\n      // is false => print_last_column_on_own_line==false\n      if (lastcolumn == 0)\n        print_last_column_on_own_line = false;\n\n      LineWrapper lastColumnLineWrapper(width - rightwidth, width);\n      LineWrapper interjectionLineWrapper(0, width);\n\n      part.restartTable();\n\n      /***************** Print out all rows of the table *************************************/\n\n      while (part.nextRow())\n      {\n        int x = -1;\n        while (part.next())\n        {\n          if (part.column() > lastcolumn)\n            continue; // drop excess columns (can happen if lastcolumn == maxcolumns-1)\n\n          if (part.column() == 0)\n          {\n            if (x >= 0)\n              write(\"\\n\", 1);\n            x = 0;\n          }\n\n          indent(write, x, tabstop[part.column()]);\n\n          if ((part.column() < lastcolumn)\n              && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\\t'\n                  || part.data()[part.length()] == '\\v'))\n          {\n            write(part.data(), part.length());\n            x += part.screenLength();\n          }\n          else // either part.column() == lastcolumn or we are in the special case of\n               // an interjection that doesn't contain \\v or \\t\n          {\n            // NOTE: This code block is not necessarily executed for\n            // each line, because some rows may have fewer columns.\n\n            LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;\n\n            if (!print_last_column_on_own_line || part.column() != lastcolumn)\n              lineWrapper.process(write, part.data(), part.length());\n          }\n        } // while\n\n        if (print_last_column_on_own_line)\n        {\n          part.restartRow();\n          while (part.next())\n          {\n            if (part.column() == lastcolumn)\n            {\n              write(\"\\n\", 1);\n              int _ = 0;\n              indent(write, _, width - rightwidth);\n              lastColumnLineWrapper.process(write, part.data(), part.length());\n            }\n          }\n        }\n\n        write(\"\\n\", 1);\n        lastColumnLineWrapper.flush(write);\n        interjectionLineWrapper.flush(write);\n      }\n    }\n  }\n\n}\n;\n\n/**\n * @brief Outputs a nicely formatted usage string with support for multi-column formatting\n * and line-wrapping.\n *\n * printUsage() takes the @c help texts of a Descriptor[] array and formats them into\n * a usage message, wrapping lines to achieve the desired output width.\n *\n * <b>Table formatting:</b>\n *\n * Aside from plain strings which are simply line-wrapped, the usage may contain tables. Tables\n * are used to align elements in the output.\n *\n * @code\n * // Without a table. The explanatory texts are not aligned.\n * -c, --create  |Creates something.\n * -k, --kill  |Destroys something.\n *\n * // With table formatting. The explanatory texts are aligned.\n * -c, --create  |Creates something.\n * -k, --kill    |Destroys something.\n * @endcode\n *\n * Table formatting removes the need to pad help texts manually with spaces to achieve\n * alignment. To create a table, simply insert \\\\t (tab) characters to separate the cells\n * within a row.\n *\n * @code\n * const option::Descriptor usage[] = {\n * {..., \"-c, --create  \\tCreates something.\" },\n * {..., \"-k, --kill  \\tDestroys something.\" }, ...\n * @endcode\n *\n * Note that you must include the minimum amount of space desired between cells yourself.\n * Table formatting will insert further spaces as needed to achieve alignment.\n *\n * You can insert line breaks within cells by using \\\\v (vertical tab).\n *\n * @code\n * const option::Descriptor usage[] = {\n * {..., \"-c,\\v--create  \\tCreates\\vsomething.\" },\n * {..., \"-k,\\v--kill  \\tDestroys\\vsomething.\" }, ...\n *\n * // results in\n *\n * -c,       Creates\n * --create  something.\n * -k,       Destroys\n * --kill    something.\n * @endcode\n *\n * You can mix lines that do not use \\\\t or \\\\v with those that do. The plain\n * lines will not mess up the table layout. Alignment of the table columns will\n * be maintained even across these interjections.\n *\n * @code\n * const option::Descriptor usage[] = {\n * {..., \"-c, --create  \\tCreates something.\" },\n * {..., \"----------------------------------\" },\n * {..., \"-k, --kill  \\tDestroys something.\" }, ...\n *\n * // results in\n *\n * -c, --create  Creates something.\n * ----------------------------------\n * -k, --kill    Destroys something.\n * @endcode\n *\n * You can have multiple tables within the same usage whose columns are\n * aligned independently. Simply insert a dummy Descriptor with @c help==0.\n *\n * @code\n * const option::Descriptor usage[] = {\n * {..., \"Long options:\" },\n * {..., \"--very-long-option  \\tDoes something long.\" },\n * {..., \"--ultra-super-mega-long-option  \\tTakes forever to complete.\" },\n * {..., 0 }, // ---------- table break -----------\n * {..., \"Short options:\" },\n * {..., \"-s  \\tShort.\" },\n * {..., \"-q  \\tQuick.\" }, ...\n *\n * // results in\n *\n * Long options:\n * --very-long-option              Does something long.\n * --ultra-super-mega-long-option  Takes forever to complete.\n * Short options:\n * -s  Short.\n * -q  Quick.\n *\n * // Without the table break it would be\n *\n * Long options:\n * --very-long-option              Does something long.\n * --ultra-super-mega-long-option  Takes forever to complete.\n * Short options:\n * -s                              Short.\n * -q                              Quick.\n * @endcode\n *\n * <b>Output methods:</b>\n *\n * Because TheLeanMeanC++Option parser is freestanding, you have to provide the means for\n * output in the first argument(s) to printUsage(). Because printUsage() is implemented as\n * a set of template functions, you have great flexibility in your choice of output\n * method. The following example demonstrates typical uses. Anything that's similar enough\n * will work.\n *\n * @code\n * #include <unistd.h>  // write()\n * #include <iostream>  // cout\n * #include <sstream>   // ostringstream\n * #include <cstdio>    // fwrite()\n * using namespace std;\n *\n * void my_write(const char* str, int size) {\n *   fwrite(str, size, 1, stdout);\n * }\n *\n * struct MyWriter {\n *   void write(const char* buf, size_t size) const {\n *      fwrite(str, size, 1, stdout);\n *   }\n * };\n *\n * struct MyWriteFunctor {\n *   void operator()(const char* buf, size_t size) {\n *      fwrite(str, size, 1, stdout);\n *   }\n * };\n * ...\n * printUsage(my_write, usage);    // custom write function\n * printUsage(MyWriter(), usage);  // temporary of a custom class\n * MyWriter writer;\n * printUsage(writer, usage);      // custom class object\n * MyWriteFunctor wfunctor;\n * printUsage(&wfunctor, usage);   // custom functor\n * printUsage(write, 1, usage);    // write() to file descriptor 1\n * printUsage(cout, usage);        // an ostream&\n * printUsage(fwrite, stdout, usage);  // fwrite() to stdout\n * ostringstream sstr;\n * printUsage(sstr, usage);        // an ostringstream&\n *\n * @endcode\n *\n * @par Notes:\n * @li the @c write() method of a class that is to be passed as a temporary\n *     as @c MyWriter() is in the example, must be a @c const method, because\n *     temporary objects are passed as const reference. This only applies to\n *     temporary objects that are created and destroyed in the same statement.\n *     If you create an object like @c writer in the example, this restriction\n *     does not apply.\n * @li a functor like @c MyWriteFunctor in the example must be passed as a pointer.\n *     This differs from the way functors are passed to e.g. the STL algorithms.\n * @li All printUsage() templates are tiny wrappers around a shared non-template implementation.\n *     So there's no penalty for using different versions in the same program.\n * @li printUsage() always interprets Descriptor::help as UTF-8 and always produces UTF-8-encoded\n *     output. If your system uses a different charset, you must do your own conversion. You\n *     may also need to change the font of the console to see non-ASCII characters properly.\n *     This is particularly true for Windows.\n * @li @b Security @b warning: Do not insert untrusted strings (such as user-supplied arguments)\n *     into the usage. printUsage() has no protection against malicious UTF-8 sequences.\n *\n * @param prn The output method to use. See the examples above.\n * @param usage the Descriptor[] array whose @c help texts will be formatted.\n * @param width the maximum number of characters per output line. Note that this number is\n *        in actual characters, not bytes. printUsage() supports UTF-8 in @c help and will\n *        count multi-byte UTF-8 sequences properly. Asian wide characters are counted\n *        as 2 characters.\n * @param last_column_min_percent (0-100) The minimum percentage of @c width that should be available\n *        for the last column (which typically contains the textual explanation of an option).\n *        If less space is available, the last column will be printed on its own line, indented\n *        according to @c last_column_own_line_max_percent.\n * @param last_column_own_line_max_percent (0-100) If the last column is printed on its own line due to\n *        less than @c last_column_min_percent of the width being available, then only\n *        @c last_column_own_line_max_percent of the extra line(s) will be used for the\n *        last column's text. This ensures an indentation. See example below.\n *\n * @code\n * // width=20, last_column_min_percent=50 (i.e. last col. min. width=10)\n * --3456789 1234567890\n *           1234567890\n *\n * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)\n * // last_column_own_line_max_percent=75\n * --3456789\n *      123456789012345\n *      67890\n *\n * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)\n * // last_column_own_line_max_percent=33 (i.e. max. 5)\n * --3456789\n *                12345\n *                67890\n *                12345\n *                67890\n * @endcode\n */\ntemplate<typename OStream>\nvoid printUsage(OStream& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,\n                int last_column_own_line_max_percent = 75)\n{\n  PrintUsageImplementation::OStreamWriter<OStream> write(prn);\n  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);\n}\n\ntemplate<typename Function>\nvoid printUsage(Function* prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,\n                int last_column_own_line_max_percent = 75)\n{\n  PrintUsageImplementation::FunctionWriter<Function> write(prn);\n  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);\n}\n\ntemplate<typename Temporary>\nvoid printUsage(const Temporary& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,\n                int last_column_own_line_max_percent = 75)\n{\n  PrintUsageImplementation::TemporaryWriter<Temporary> write(prn);\n  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);\n}\n\ntemplate<typename Syscall>\nvoid printUsage(Syscall* prn, int fd, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,\n                int last_column_own_line_max_percent = 75)\n{\n  PrintUsageImplementation::SyscallWriter<Syscall> write(prn, fd);\n  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);\n}\n\ntemplate<typename Function, typename Stream>\nvoid printUsage(Function* prn, Stream* stream, const Descriptor usage[], int width = 80, int last_column_min_percent =\n                    50,\n                int last_column_own_line_max_percent = 75)\n{\n  PrintUsageImplementation::StreamWriter<Function, Stream> write(prn, stream);\n  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);\n}\n\n}\n// namespace option\n\n#endif /* OPTIONPARSER_H_ */\n"
  },
  {
    "path": "src/optparser.h",
    "content": "// as this is 3rd party code I don't fix it ->\n#ifndef _MSC_VER\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wnon-virtual-dtor\"\n#endif\n#include \"optionparser.h\"\n#ifndef _MSC_VER\n#pragma GCC diagnostic pop\n#endif\n// <-\n"
  },
  {
    "path": "src/pacman.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n// system\n#include <cstring>\n#include <cstdlib>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <iostream>\n\n// project\n#include \"pacman.h\"\n#include \"FileNotFoundException.h\"\n#include \"platform.h\"\n\nusing namespace std;\n\nnamespace pacman {\n\nconst std::string searchFile(const std::string &data)\n{\n  vector <string> name_vector;\n\n#ifdef HAVE_CONFIG_H\n  // search in the package directory (e.g. /usr/share/<package>\n  name_vector.push_back(string(PACKAGE_DATA_DIR) + data);\n\n  // if this still fails we assume the developer case and search the data in absolute source folder\n  name_vector.push_back(string(PACKAGE_SOURCE_DIR) + data);\n#endif\n\n  // do this as last as in config.h case relative path is not desired\n  name_vector.push_back(data);\n\n  const string &file = statFile(name_vector);\n\n  if (file.empty())\n  {\n    throw FileNotFoundException(data);\n  }\n\n  return file;\n}\n\nconst std::string searchDir(const std::string &data)\n{\n  const string &file = searchFile(data);\n\n  fs::path p(file);\n\n  return p.remove_filename().string();\n}\n\nconst std::string statFile(std::vector <std::string> &name_vector)\n{\n  struct stat buf;\n\n  for (unsigned int i = 0; i < name_vector.size(); i++)\n  {\n    string &try_name = name_vector[i];\n\n    bool found = !(stat(try_name.c_str(), &buf));\n    //cout << \"try_name: \" << try_name << endl;\n\n    if (found)\n    {\n      return try_name;\n    }\n  }\n\n  return \"\";\n}\n\n}\n\n"
  },
  {
    "path": "src/pacman.h",
    "content": "#ifndef PACMAN_H\n#define PACMAN_H\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <string>\n#include <vector>\n\nnamespace pacman {\n\n// public search functions\nconst std::string searchDir(const std::string &data);\nconst std::string searchFile(const std::string &data);\n\n// helper function\nconst std::string statFile(std::vector <std::string> &name_vector);\n\n}\n\n#endif // PACMAN_H\n"
  },
  {
    "path": "src/platform.cpp",
    "content": "/*\n * platform.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"platform.h\"\n\n#ifdef _MSC_VER\n#define DEBUG _DEBUG\n#define PATH_MAX _MAX_PATH\n#include <direct.h>\n#include <io.h>\n#define dirname(x) PathRemoveFileSpec(x); if (x[strlen(x) - 1] == '\\\\') x[strlen(x) - 1] = '\\0'\n#else\n#include <libgen.h>\n#include <limits.h>\n#include <unistd.h>\n#endif\n\n#ifdef _MSC_VER\n#include <windows.h>\n#include <direct.h>\n#else\n#include <unistd.h>\n#endif\n\n#include <sys/stat.h>\n#include <sys/types.h>\n\n\n#include <cstring>\n\nnamespace platform\n{\n\nint unlink(const std::string &pathname)\n{\n#ifdef _MSC_VER\n  return ::_unlink(pathname.c_str());\n#else\n  return ::unlink(pathname.c_str());\n#endif\n}\n\nchar *strdup(const char *s)\n{\n#ifdef WIN32\n  return ::_strdup(s);\n#else\n  return ::strdup(s);\n#endif\n}\n\nint mkdir(const std::string &pathname, mode_t mode)\n{\n#if defined(_MSC_VER) || defined(WIN32)\n  return ::_mkdir(pathname.c_str());\n#else\n  return ::mkdir(pathname.c_str(), mode);\n#endif\n}\n\n} /* namespace platform */\n"
  },
  {
    "path": "src/platform.h",
    "content": "/*\n * platform.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef PLATFORM_H\n#define PLATFORM_H\n\n// filesystem ->\n#if __has_include(<filesystem>)\n#include <filesystem>\nnamespace fs = std::filesystem;\n#elif __has_include(<experimental/filesystem>)\n#include <experimental/filesystem>\nnamespace fs = std::experimental::filesystem;\n#else\nerror \"Missing the <filesystem> header.\"\n#endif\n// <- filesystem\n\n#include <string>\n\nnamespace platform\n{\n\nint unlink(const std::string &pathname);\n\nchar *strdup(const char *s);\n\n#if defined(_MSC_VER) || defined(WIN32)\ntypedef int mode_t;\n#endif\n\nint mkdir(const std::string &pathname, mode_t mode = 0);\n\n} /* namespace platform */\n\n#endif /* PLATFORM_H */\n"
  },
  {
    "path": "src/stargus.cpp",
    "content": "/*\n stargus.c - Start game engine Stratagus with Stargus data\n Copyright (C) 2010-2012  Pali Rohár <pali.rohar@gmail.com>\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 2 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <iostream>\n\n#define GAME_NAME \"Stargus\"\n#define GAME_CD \"Starcraft CD or installation stardat.mpq or starcraft.mpq file\"\n#define GAME_CD_FILE_PATTERNS \"install.exe\", \"Install.exe\", \"stardat.mpq\", \"StarDat.mpq\", \"starcraft.mpq\", \"StarCraft.mpq\"\n#define GAME \"stargus\"\n#define EXTRACTOR_TOOL \"startool\"\n#define EXTRACTOR_ARGS {\"-v -s\", NULL}\n#define CHECK_EXTRACTED_VERSION 1\n\n// configure here which files/directories will be copied from stargus (e.g. contrib)\n#define CONTRIB_DIRECTORIES { \"mpqlist.txt\", \"mpqlist.txt\", \\\n\t\t\t      \"contrib/fog.png\", \"graphics/tilesets/fog.png\", \\\n\t\t\t      \"contrib/transparent.png\", \"graphics/ui/transparent.png\", \\\n\t\t\t      \"scripts\", \"scripts\", NULL }\n\nconst char *SRC_PATH()\n{\n  std::cout << \"sourcedir:\" << SOURCE_DIR << std::endl;\n  return SOURCE_DIR;\n}\n\n// I still have hope some far day someone will fix this annoying warnings... ->\n#ifndef _MSC_VER\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wmisleading-indentation\"\n#pragma GCC diagnostic ignored \"-Wparentheses\"\n#pragma GCC diagnostic ignored \"-Wunused-variable\"\n#pragma GCC diagnostic ignored \"-Wformat-overflow=\"\n#else\n#define WIN32 1\n#endif\n#include \"stratagus-game-launcher.h\"\n#ifndef _MSC_VER\n#pragma GCC diagnostic pop\n#endif\n// <-\n"
  },
  {
    "path": "src/startool.cpp",
    "content": "//       _________ __                 __\n//      /   _____//  |_____________ _/  |______     ____  __ __  ______\n//      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n//      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ |\n//     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n//             \\/                  \\/          \\//_____/            \\/\n//  ______________________                           ______________________\n//                        T H E   W A R   B E G I N S\n//   Utility for Stratagus - A free fantasy real time strategy game engine\n//\n/**@name startool.c - Extract files from star archives. */\n//\n//      (c) Copyright 2002-2012 by Jimmy Salmon and Pali Rohár\n//\n//      This program is free software; you can redistribute it and/or modify\n//      it under the terms of the GNU General Public License as published by\n//      the Free Software Foundation; version 2 dated June, 1991.\n//\n//      This program is distributed in the hope that it will be useful,\n//      but WITHOUT ANY WARRANTY; without even the implied warranty of\n//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//      GNU General Public License for more details.\n//\n//      You should have received a copy of the GNU General Public License\n//      along with this program; if not, write to the Free Software\n//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n//      02111-1307, USA.\n//\n//@{\n/*----------------------------------------------------------------------------\n --  Includes\n\n ----------------------------------------------------------------------------*/\n\n// project\n#include <UnitsConverter.h>\n#include <PortraitsConverter.h>\n#include \"dat/DataHub.h\"\n#include \"tileset/TilesetHub.h\"\n#include \"PngExporter.h\"\n#include \"Smacker.h\"\n#include \"Palette.h\"\n#include \"endian.h\"\n#include \"startool.h\"\n#include \"Preferences.h\"\n#include \"Scm.h\"\n#include \"FileUtil.h\"\n#include \"Pcx.h\"\n#include \"Font.h\"\n#include \"Grp.h\"\n#include \"Panel.h\"\n#include \"Widgets.h\"\n#include \"DataChunk.h\"\n#include \"Casc.h\"\n#include \"Dds.h\"\n#include \"Logger.h\"\n#include \"Breeze.h\"\n#include \"Storage.h\"\n#include \"Wav.h\"\n#include \"tileset/TilesetHub.h\"\n#include \"platform.h\"\n#include \"UIConsole.h\"\n#include \"StringUtil.h\"\n#include \"pacman.h\"\n#include \"ImagesConverter.h\"\n#include \"SfxConverter.h\"\n#include \"optparser.h\"\n\n// system\n#include <nlohmann/json.hpp>\n#include <fstream>\n#include <map>\n\nusing json = nlohmann::json;\n\n// <-\n\n// System\n#include <memory>\n#include <map>\n\n// activate local debug messages\n#define DEBUG 1\n\nusing namespace std;\n\nstatic Logger logger(\"startool.main\");\n\n// test only\nvoid testHook();\nbool dev_hack = false;\n\n//----------------------------------------------------------------------------\n\n/**\n **  Raw extraction\n **\n **  @param arcfile File identifier in the MPQ file\n **  @param file Place to save the file on the drive (relative)\n */\nbool RawExtract(std::shared_ptr<Hurricane> hurricane, const char *arcfile, Storage storage)\n{\n  bool result = true;\n\n  result = hurricane->extractFile(arcfile, storage.getFullPath(), false);\n\n  return result;\n}\n\nvoid CreatePanels()\n{\n  Panel panel;\n  panel.save(264, 288);\n  panel.save(384, 256);\n  panel.save(312, 312);\n  panel.save(288, 128);\n  panel.save(296, 336);\n}\n\nbool CheckCASCDataFolder(const std::string &dir)\n{\n  return FileExists(dir + \"/.build.info\");\n}\n\n//----------------------------------------------------------------------------\n//  Main loop\n//----------------------------------------------------------------------------\n\n/** option parser **/\nstruct Arg: public option::Arg\n{\n  static void printError(const char *msg1, const option::Option &opt, const char *msg2)\n  {\n    fprintf(stderr, \"%s\", msg1);\n    fwrite(opt.name, opt.namelen, 1, stderr);\n    fprintf(stderr, \"%s\", msg2);\n  }\n\n  static option::ArgStatus Unknown(const option::Option &option, bool msg)\n  {\n    if (msg)\n      printError(\"Unknown option '\", option, \"'\\n\");\n\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Required(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires an argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus NonEmpty(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0 && option.arg[0] != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a non-empty argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Numeric(const option::Option &option, bool msg)\n  {\n    char *endptr = 0;\n    if (option.arg != 0 && strtol(option.arg, &endptr, 10))\n    {\n    };\n    if (endptr != option.arg && *endptr == 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a numeric argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n};\n\nenum optionIndex\n{\n  UNKNOWN, HELP, VIDEO, SOUND, VERSIONPARAM, DEV\n};\nconst option::Descriptor usage[] =\n{\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None, \"USAGE: startool archive-directory [destination-directory]\\n\\n\"\n    \"Options:\"\n  },\n  { HELP, 0, \"h\", \"help\", option::Arg::None, \"  --help, -h  \\t\\tPrint usage and exit\" },\n  { VIDEO, 0, \"v\", \"video\", Arg::None, \"  --video, -v  \\t\\tExtract and convert videos\" },\n  { SOUND, 0, \"s\", \"sound\", Arg::None, \"  --sound, -s  \\t\\tExtract and convert sounds\" },\n  { DEV, 0, \"d\", \"dev\", Arg::None,\n    \"  --dev, -d  \\t\\tSome test hooks while development. Don't use it if you don't know what it does!\"},\n  { VERSIONPARAM, 0, \"V\", \"version\", Arg::None, \"  --version, -V  \\t\\tShow version\" },\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None,\n    \"\\narchive-directory \\t\\tDirectory which include the archive install.exe or stardat.mpq...\\n\"\n    \"destination-directory \\t\\tDirectory where the extracted files are placed.\\n\"\n  },\n  { 0, 0, 0, 0, 0, 0 }\n};\n\nint parseOptions(int argc, const char **argv)\n{\n  Preferences &preferences = Preferences::getInstance();\n  argc -= (argc > 0);\n  argv += (argc > 0); // skip program name argv[0] if present\n  option::Stats stats(usage, argc, argv);\n  std::unique_ptr<option::Option[]> options(new option::Option[stats.options_max]), buffer(new option::Option[stats.buffer_max]);\n  option::Parser parse(usage, argc, argv, options.get(), buffer.get());\n\n  if (parse.error())\n    exit(0);\n\n  if (options[HELP])\n  {\n    option::printUsage(std::cout, usage);\n    exit(0);\n  }\n\n  // parse options\n  if (options[VIDEO].count() > 0)\n  {\n    preferences.setVideoExtraction(true);\n  }\n\n  if (options[SOUND].count() > 0)\n  {\n    preferences.setSoundExtraction(true);\n  }\n\n  if (options[DEV].count() > 0)\n  {\n    testHook();\n  }\n\n  if (options[VERSIONPARAM].count() > 0)\n  {\n    printf(VERSION \"\\n\");\n    exit(0);\n  }\n\n  for (option::Option *opt = options[UNKNOWN]; opt; opt = opt->next())\n    std::cout << \"Unknown option: \" << opt->name << \"\\n\";\n\n  for (int i = 0; i < parse.nonOptionsCount(); ++i)\n  {\n    switch (i)\n    {\n    case 0:\n      cout << \"archive-directory #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      preferences.setArchiveDir(parse.nonOption(i));\n      break;\n    case 1:\n      cout << \"destination-directory #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      preferences.setDestDir(parse.nonOption(i));\n      break;\n    default:\n      break;\n    }\n  }\n\n  if (preferences.getArchiveDir().empty())\n  {\n    cerr << \"Error: 'archive-directory' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  return 0;\n}\n\n\nvoid loadPalettes(std::shared_ptr<Hurricane> hurricane,\n                  Storage palStorage,\n                  std::map<std::string, std::shared_ptr<AbstractPalette>> &paletteMap)\n{\n  // read in the json file\n  std::ifstream json_file(pacman::searchFile(\"dataset/palettes.json\"));\n\n  json palettes_json; //create unitiialized json object\n\n  json_file >> palettes_json; // initialize json object with what was read from file\n\n  //std::cout << units_json << std::endl; // prints json object to screen\n\n  vector<string> wpeNames;\n\n  /** WPE **/\n  auto &wpe_section = palettes_json.at(\"WPE\");\n\n  for(auto &wpe_array : wpe_section)\n  {\n    string name = wpe_array.at(\"name\");\n    string wpe_arcfile = wpe_array.at(\"arcfile\");\n    string pal_palette = wpe_array.at(\"palette\");\n\n    shared_ptr<DataChunk> dataWPE = hurricane->extractDataChunk(wpe_arcfile);\n\n    if (dataWPE) // load from WPE palette\n    {\n      shared_ptr<Palette> pal = make_shared<Palette>(dataWPE);\n      paletteMap[name] = pal;\n      wpeNames.push_back(name);\n\n      string pal_file(palStorage.getFullPath() + pal_palette);\n      CheckPath(pal_file);\n      pal->write(pal_file);\n    }\n    else // load from stored .pal palette\n    {\n      Breeze localPal(palStorage.getFullPath());\n      shared_ptr<DataChunk> dataPal = localPal.extractDataChunk(pal_palette);\n\n      if(dataPal)\n      {\n        std::shared_ptr<Palette> pal = make_shared<Palette>(dataPal);\n        paletteMap[name] = pal;\n      }\n    }\n\n    //cout << wpe_array << endl;\n  }\n\n  /** PCX **/\n  auto &pcx_section = palettes_json.at(\"PCX\");\n\n  for(auto &pcx_array : pcx_section)\n  {\n    string name = pcx_array.at(\"name\");\n    string pcx_arcfile = pcx_array.at(\"arcfile\");\n    string pal_palette = pcx_array.at(\"palette\");\n\n    Pcx pcx(hurricane, pcx_arcfile);\n\n    if(!pcx.getSize().isEmpty()) // load from PCX palette\n    {\n      std::shared_ptr<Palette> pal;\n      try\n      {\n        auto &pcx_mapping = pcx_array.at(\"mapping\");\n\n        int length = pcx_mapping.at(\"length\");\n        int start = pcx_mapping.at(\"start\");\n        int index = pcx_mapping.at(\"index\");\n\n        pal = pcx.mapIndexPalette(length, start, index);\n      }\n      catch (const nlohmann::detail::out_of_range &json_range)\n      {\n        pal = pcx.getPalette();\n      }\n\n      string pal_file(palStorage.getFullPath() + pal_palette);\n      CheckPath(pal_file);\n      pal->write(pal_file);\n\n      paletteMap[name] = pal;\n    }\n    else // load from stored .pal palette\n    {\n      Breeze localPal(palStorage.getFullPath());\n      shared_ptr<DataChunk> dataPal = localPal.extractDataChunk(pal_palette);\n\n      if(dataPal)\n      {\n        std::shared_ptr<Palette> pal = make_shared<Palette>(dataPal);\n        paletteMap[name] = pal;\n      }\n    }\n\n    //cout << pcx_array << endl;\n  }\n\n  /** PCX2D (after WPE block has been read in) **/\n  auto &pcx2d_section = palettes_json.at(\"PCX2D\");\n\n  for(auto &pcx_array : pcx2d_section)\n  {\n    string pcx_name = pcx_array.at(\"name\");\n    string pcx_arcfile = pcx_array.at(\"arcfile\");\n    string pal_palette = pcx_array.at(\"palette\");\n\n    // replace this with the first of the WPE palettes. Which one doesn't care for the palette logic.\n    replaceString(\"<?>\", *wpeNames.begin(), pcx_arcfile);\n\n    Pcx pcx(hurricane, pcx_arcfile);\n\n    std::shared_ptr<Palette2D> pal2D = pcx.map2DPalette();\n\n    string pal_file(palStorage.getFullPath() + pal_palette);\n    CheckPath(pal_file);\n    pal2D->write(pal_file);\n\n    paletteMap[pcx_name] = pal2D;\n\n    //cout << pcx_array << endl;\n  }\n\n\n}\n\n/**\n * The only purpose of this function is to have a hook to develop/test single functions and then exit\n */\nvoid testHook()\n{\n  LOG4CXX_DEBUG(logger, \"testHook()\");\n\n  /*string font_path = \"/home/andreas/src/git/stargus/work_font/classic/files/font/\";\n   string font_path_rm = \"/home/andreas/src/git/stargus/work_font/remastered/SD/font/\";\n   string font_path_hd = \"/home/andreas/src/git/stargus/work_font/remastered/font/\"; // problem!\n\n   shared_ptr<Breeze> breeze = make_shared<Breeze>(font_path_rm);\n\n   Font font(breeze);\n   font.convert(\"font16.fnt\", \"font16\");*/\n\n  shared_ptr<Storm> storm = make_shared<Storm>(\"/home/andreas/Games/DOS/Starcraft/Original_Backup/starcraft_install.exe_MPQ/files/stardat.mpq\");\n  //shared_ptr<Storm> storm = make_shared<Storm>(\"/home/andreas/Games/DOS/Starcraft/Original_Backup/broodwar_install.exe_MPQ/files/broodat.mpq\");\n  //shared_ptr<Breeze> breeze = make_shared<Breeze>(\"/home/andreas/Games/DOS/Starcraft/Original_Backup/starcraft_install.exe_MPQ\");\n  dat::DataHub datahub(storm);\n\n  dat::Unit unit(datahub, 0, \"test\");\n  cout << \"unit: \" << unit.name_tbl().name1() << endl;\n\n  dat::IScript is = unit.flingy_obj().sprite_obj().image_obj().iscript_obj();\n\n  int animation_count = is.getAnimationCount();\n\n  cout << \"animation_count: \" << to_string(animation_count) << endl;\n\n  for(int i = 0; i < animation_count; i++)\n  //int i = 8;\n  {\n    cout << \"animation: \" << i << endl;\n    std::vector<iscript_bin_t::opcode_type_t*> opcode_vec =\n        unit.flingy_obj().sprite_obj().image_obj().iscript_obj().getAnimationScript(i);\n\n    for(auto opcode : opcode_vec)\n    {\n      cout << \"code: \" << hex << opcode->code() << endl;\n    }\n  }\n\n  dat::Sfx sfx = unit.ready_sound_obj();\n  sfx.sound_file_tbl();\n\n  dat::Portrait portrait = unit.portrait_obj();\n\n  portrait.video_talking_tbl();\n  portrait.video_idle_tbl();\n\n  /// Image 1\n  Pcx pcx1(storm, \"game\\\\tunit.pcx\");\n  pcx1.savePNG(\"/tmp/tunit.png\");\n  std::shared_ptr<Palette> pal = pcx1.mapIndexPalette(8, 8, 2);\n  pal->createDataChunk()->write(\"/tmp/tunit.pal\");\n\n  // Image 2\n  Pcx pcx2(storm, \"unit\\\\cmdbtns\\\\ticon.pcx\");\n  pcx2.savePNG(\"/tmp/ticon.png\");\n  std::shared_ptr<Palette> pal2 = pcx2.mapIndexPalette(16, 0, 0);\n  pal2->createDataChunk()->write(\"/tmp/ticon.pal\");\n\n  // Image 3\n  Pcx pcx3(storm, \"tileset\\\\ashworld\\\\ofire.pcx\");\n  pcx3.savePNG(\"/tmp/ofire.png\");\n  std::shared_ptr<Palette2D> pal2D_3 = pcx3.map2DPalette();\n  std::shared_ptr<Palette> pal3 = pcx3.getPalette();\n  pal3->createDataChunk()->write(\"/tmp/ofire.pal\");\n\n  // Image 4\n  Pcx pcx4(storm, \"tileset\\\\ashworld\\\\ofire.pcx\");\n  pcx4.savePNG(\"/tmp/bfire.png\");\n  std::shared_ptr<Palette2D> pal2D_4 = pcx4.map2DPalette();\n  std::shared_ptr<Palette> pal4 = pcx4.getPalette();\n  pal4->createDataChunk()->write(\"/tmp/ofire.pal\");\n  pal2D_4->write(\"/tmp/ofire.pal2d\");\n\n\n  shared_ptr<DataChunk> terrainWPE = storm->extractDataChunk(\"tileset\\\\jungle.wpe\");\n  shared_ptr<Palette> terrainPalette = make_shared<Palette>(terrainWPE);\n  terrainPalette->createDataChunk()->write(\"/tmp/terrainPalette.pal\");\n\n  //string grp_file = \"unit\\\\protoss\\\\pbaGlow.grp\";\n  string grp_file = \"unit\\\\thingy\\\\ofirec.grp\";\n  Grp grp(storm, grp_file);\n  grp.setPalette(pal2D_4);\n  grp.setRGBA(true);\n  //grp.setPalette(terrainPalette);\n  //grp.setTransparent(200);\n  //grp.setRGBA(true);\n\n  // read in the json file\n  std::ifstream json_file(pacman::searchFile(\"dataset/dlgs_race.json\"));\n\n  json dlgsRaceJson; //create unitiialized json object\n\n  json_file >> dlgsRaceJson; // initialize json object with what was read from file\n\n  Widgets widgets(storm);\n  widgets.setPalette(pal);\n  widgets.convert(\"dlgs\\\\terran.grp\", \"/tmp/widgets2/\", dlgsRaceJson);\n\n\n  grp.save(\"/tmp/ofirec.png\");\n\n  cout << \"end testHook()\" << endl;\n  exit(0);\n}\n\n/**\n **\t\tMain\n */\nint main(int argc, const char **argv)\n{\n#ifdef HAVE_LOG4CXX\n  if (FileExists(\"logging.prop\"))\n  {\n    log4cxx::PropertyConfigurator::configure(\"logging.prop\");\n  }\n  else\n  {\n    logger.off();\n  }\n#endif // HAVE_LOG4CXX\n\n  unsigned u;\n  char buf[8192] =\n  { '\\0' };\n  int i;\n  FILE *f;\n\n  Preferences &preferences = Preferences::getInstance();\n  preferences.init(); // initialize all properties once in the beginning of the application\n\n  parseOptions(argc, argv);\n\n  LOG4CXX_INFO(logger, \"Application start\");\n\n  sprintf(buf, \"%s/extracted\", preferences.getDestDir().c_str());\n  f = fopen(buf, \"r\");\n  if (f)\n  {\n    char version[20];\n    int len = 0;\n    if (fgets(version, 20, f))\n      len = 1;\n    fclose(f);\n    if (len != 0 && strcmp(version, VERSION) == 0)\n    {\n      printf(\"Note: Data is already extracted in Dir \\\"%s\\\" with this version of startool\\n\", preferences.getDestDir().c_str());\n      fflush(stdout);\n    }\n  }\n\n  printf(\"Extract from \\\"%s\\\" to \\\"%s\\\"\\n\", preferences.getArchiveDir().c_str(), preferences.getDestDir().c_str());\n  printf(\"Please be patient, the data may take a couple of minutes to extract...\\n\\n\");\n  fflush(stdout);\n\n  // set this to false for activating the SC remastered Casc code while development\n  bool mpq = true;\n\n  Storage graphics;\n  graphics.setDataPath(preferences.getDestDir());\n  graphics.setDataType(\"graphics\");\n\n  Storage videos;\n  videos.setDataPath(preferences.getDestDir());\n  videos.setDataType(\"videos\");\n\n  Storage fonts;\n  fonts.setDataPath(preferences.getDestDir());\n  fonts.setDataType(\"graphics/ui/fonts\");\n\n  Storage sounds;\n  sounds.setDataPath(preferences.getDestDir());\n  sounds.setDataType(\"sounds\");\n\n  Storage tilesets;\n  tilesets.setDataPath(preferences.getDestDir());\n  tilesets.setDataType(\"graphics/tilesets\");\n\n  Storage luagen;\n  luagen.setDataPath(preferences.getDestDir());\n  luagen.setDataType(\"luagen\");\n\n  Storage palStorage;\n  palStorage.setDataPath(preferences.getDestDir());\n  palStorage.setDataType(\"palette\");\n\n  Storage data;\n  data.setDataPath(preferences.getDestDir());\n\n  map<string, shared_ptr<AbstractPalette>> paletteMap;\n\n  if (mpq)\n  {\n    Control *c = nullptr;\n    unsigned int len = 0;\n    bool case_func = false;\n    shared_ptr<Storm> main_storm;\n    shared_ptr<Storm> sub_storm;\n    shared_ptr<Storm> storm;\n\n    c = CDTodo_bootstrap;\n    len = sizeof(CDTodo_bootstrap) / sizeof(*CDTodo_bootstrap);\n    for (u = 0; u < len; ++u)\n    {\n      switch (c[u].Type)\n      {\n      case F:\n      {\n        string archiveFile = preferences.getArchiveDir() + \"/\" + c[u].ArcFile;\n        case_func = FileExists(archiveFile);\n        cout << \"F: \" << c[u].ArcFile << \" : \" << c[u].File << \" : \" << case_func << endl;\n        if (case_func && !main_storm)\n        {\n          main_storm = make_shared<Storm>(archiveFile);\n        }\n      }\n      break;\n      case Q:\n      {\n        cout << \"Q:\" <<  c[u].ArcFile << \" : \" << c[u].File <<  endl;\n        if (main_storm)\n        {\n          string file = preferences.getDestDir() + \"/\" + c[u].File;\n          main_storm->extractFile(c[u].ArcFile, file, false);\n        }\n      }\n      break;\n      default:\n        break;\n      }\n    }\n\n    c = Todo_bootstrap;\n    len = sizeof(Todo_bootstrap) / sizeof(*Todo_bootstrap);\n    for (u = 0; u < len; ++u)\n    {\n      switch (c[u].Type)\n      {\n      case F:\n      {\n        string archiveFile = preferences.getDestDir() + \"/\" + c[u].ArcFile;\n        case_func = FileExists(archiveFile);\n        cout << \"F: \" << c[u].ArcFile << \" : \" << c[u].File << \" : \" << case_func << endl;\n        if (case_func && !sub_storm)\n        {\n          sub_storm = make_shared<Storm>(archiveFile);\n        }\n      }\n      break;\n      default:\n        break;\n      }\n    }\n\n    dat::DataHub datahub(sub_storm);\n\n    // read in the json file\n    std::ifstream json_file(pacman::searchFile(\"dataset/units.json\"));\n\n    json units_json; //create unitiialized json object\n\n    json_file >> units_json; // initialize json object with what was read from file\n\n    //std::cout << units_json << std::endl; // prints json object to screen\n\n    vector<string> unitNames;\n    for(auto &array : units_json)\n    {\n      string unit_name = array.at(\"name\");\n      unitNames.push_back(unit_name);\n    }\n\n    loadPalettes(sub_storm, palStorage, paletteMap);\n\n    if (preferences.getVideoExtraction())\n    {\n      PortraitsConverter portraitsConverter(sub_storm, datahub);\n      portraitsConverter.convert();\n    }\n\n    dat::UnitsConverter unitsConverter(sub_storm, datahub);\n    unitsConverter.convert(units_json);\n\n    ImagesConverter imagesConverter(sub_storm, datahub);\n    imagesConverter.convert(paletteMap);\n\n    if(preferences.getSoundExtraction())\n    {\n      SfxConverter sfxConverter(sub_storm, datahub);\n      sfxConverter.convert();\n    }\n\n    // read in the json file\n    std::ifstream dlgsRaceJsonStream(pacman::searchFile(\"dataset/dlgs_race.json\"));\n    json dlgsRaceJson; //create unitiialized json object\n    dlgsRaceJsonStream >> dlgsRaceJson; // initialize json object with what was read from file\n\n    Widgets widgets(sub_storm);\n    widgets.setPalette(paletteMap[\"tunit\"]);\n    widgets.convert(\"dlgs\\\\terran.grp\", graphics(\"ui/terran\"), dlgsRaceJson);\n    widgets.convert(\"dlgs\\\\zerg.grp\", graphics(\"ui/zerg\"), dlgsRaceJson);\n    widgets.convert(\"dlgs\\\\protoss.grp\", graphics(\"ui/protoss\"), dlgsRaceJson);\n\n    for (i = 0; i <= 1; ++i)\n    {\n      switch (i)\n      {\n      case 0:\n        // StarDat.mpq or stardat.mpq from inside files\\\\stardat.mpq\n        c = Todo;\n        len = sizeof(Todo) / sizeof(*Todo);\n        storm = sub_storm;\n        break;\n      case 1:\n        // CD install.exe renamed to StarCraft.mpq or other main mpq file\n        c = CDTodo;\n        len = sizeof(CDTodo) / sizeof(*CDTodo);\n        storm = main_storm;\n        break;\n      }\n\n      case_func = false;\n      for (u = 0; u < len; ++u)\n      {\n        switch (c[u].Type)\n        {\n        case M: // WORKS!\n        {\n          printf(\"ConvertMap: %s, %s\", c[u].File, c[u].ArcFile);\n          Scm scm(storm);\n          case_func = scm.convert(c[u].ArcFile, unitNames, data(c[u].File));\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }\n        break;\n        case T: // WORKS!\n        {\n          printf(\"ConvertTileset: %s, %s\", c[u].File, c[u].ArcFile);\n          tileset::TilesetHub terrain(storm, c[u].ArcFile);\n          case_func = terrain.convert(paletteMap.at(c[u].File), tilesets(c[u].File));\n\n          string luafile(string(\"tilesets/\") + c[u].File + \".lua\");\n          string pngfile(string(\"tilesets/\") + c[u].File + \"/\" + c[u].File + \".png\");\n          terrain.generateLua(c[u].File, pngfile, luagen(luafile));\n\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }\n        break;\n        case G: // WORKS!\n        {\n          printf(\"ConvertGfx: %s, %s, %d\", c[u].File, c[u].ArcFile, c[u].Arg1);\n          Grp grp(storm, c[u].ArcFile);\n          std::shared_ptr<AbstractPalette> pal;\n\n          if (c[u].Arg1 == 6)\n          {\n            pal = paletteMap.at(\"twire\");\n            grp.setPalette(pal);\n          }\n          else if (c[u].Arg1 == 5)\n          {\n            pal = paletteMap.at(\"ticon-0\");\n            grp.setPalette(pal);\n          }\n          else if (c[u].Arg1 == 4)\n          {\n            pal = paletteMap.at(\"ticon-0\");\n            grp.setPalette(pal);\n            grp.setRGBA(true);\n          }\n          else if (c[u].Arg1 == 3)\n          {\n            pal = paletteMap.at(\"ofire\");\n            grp.setPalette(pal);\n            grp.setRGBA(true);\n          }\n          else if (c[u].Arg1 == 2)\n          {\n            pal = paletteMap.at(\"tselect-0\");\n            grp.setPalette(pal);\n          }\n          else if (c[u].Arg1 == 1)\n          {\n            pal = paletteMap.begin()->second;\n            grp.setPalette(pal);\n          }\n          else // default palette\n          {\n            pal = paletteMap.begin()->second;\n            grp.setPalette(pal);\n          }\n\n          case_func = grp.save(graphics(string(c[u].File) + \".png\"));\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }\n        break;\n        /*case I: // WORKS!\n        {\n          printf(\"ConvertWidgets: %s, %s\", c[u].File, c[u].ArcFile);\n          Widgets widgets(storm);\n          std::shared_ptr<AbstractPalette> pal = paletteMap.at(\"tunit\");\n          widgets.setPalette(pal);\n          case_func = widgets.convert(c[u].ArcFile, c[u].File);\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }*/\n        break;\n        case N: // WORKS!\n        {\n          printf(\"ConvertFont: %s, %s\", c[u].File, c[u].ArcFile);\n          Font font(storm);\n          std::shared_ptr<AbstractPalette> pal = paletteMap.at(\"tfontgam\");\n          font.setPalette(pal);\n          case_func = font.convert(c[u].ArcFile, fonts(string(c[u].File) + \".png\"));\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }\n        break;\n        case W: // WORKS!\n          if (preferences.getSoundExtraction())\n          {\n            printf(\"ConvertWav: %s, %s\", c[u].File, c[u].ArcFile);\n            Wav wav(storm);\n            case_func = wav.convert(c[u].ArcFile, sounds(c[u].File));\n            printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n          }\n          break;\n        case V: // WORKS!\n          if (preferences.getVideoExtraction())\n          {\n            printf(\"ConvertSmacker: %s, %s\", c[u].File, c[u].ArcFile);\n            Smacker video(storm);\n            case_func = video.convertOGV(c[u].ArcFile, videos(c[u].File));\n            printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n          }\n          break;\n        case P: // WORKS!\n          if (preferences.getVideoExtraction())\n          {\n            printf(\"ConvertPortrait: %s, %s\", c[u].File, c[u].ArcFile);\n            Smacker video(storm);\n            case_func = video.convertMNG(c[u].ArcFile, videos(c[u].File));\n            printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n          }\n          break;\n        case H: // WORKS!\n        {\n          printf(\"ConvertPcx: %s, %s\", c[u].File, c[u].ArcFile);\n          Pcx pcx(storm, c[u].ArcFile);\n          case_func = pcx.savePNG(graphics(string(c[u].File) + \".png\"));\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }\n        break;\n        case E: // WORKS\n        {\n          printf(\"Extract text: %s, %s\", c[u].File, c[u].ArcFile);\n          auto chunk = storm->extractDataChunk(c[u].ArcFile);\n          char *utf8 = iconvISO2UTF8(reinterpret_cast<char*>(chunk->getDataPointer()));\n          if (utf8) {\n            chunk->replaceData(reinterpret_cast<unsigned char*>(utf8), strlen(utf8), 0);\n            free(utf8);\n            case_func = chunk->write(data(c[u].File).getFullPath());\n          } else {\n            case_func = false;\n          }\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }\n        break;\n        case L:\n        {\n          printf(\"ConvertCampaign (.chk): %s, %s\", c[u].File, c[u].ArcFile);\n          Chk chk(storm);\n          chk.setUnitNames(unitNames);\n          case_func = chk.convert(c[u].ArcFile, data(c[u].File));\n          printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n        }\n        break;\n        default:\n          break;\n        }\n      }\n    }\n\n    UIConsole uic(sub_storm);\n\n    // Terran console\n    string console = \"ui/tconsole\";\n    //pixel count from left\n    int left = 275;\n    int right = 296;\n\n    printf(\"UIConsole: %s\", console.c_str());\n    uic.convert(graphics(console), left, right);\n    printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n\n    // Zerg console\n    console = \"ui/zconsole\";\n    left = 274;\n    right = 281;\n\n    printf(\"UIConsole: %s\", console.c_str());\n    uic.convert(graphics(console), left, right);\n    printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n\n    // Protoss console\n    console = \"ui/pconsole\";\n    left = 227;\n    right = 265;\n\n    printf(\"UIConsole: %s\", console.c_str());\n    uic.convert(graphics(console), left, right);\n    printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n\n    // remove temporary sub files\n    platform::unlink(sub_storm->getArchiveName());\n\n    CreatePanels();\n  }\n  else // Casc\n  {\n#ifdef HAVE_CASC_tmp\n    unsigned int len = sizeof(RMTodo) / sizeof(*RMTodo);\n    shared_ptr<Casc> hurricane = make_shared<Casc>(\"/home/andreas/BigSpace/Games/StarCraft\");\n    preferences.setDestDir(\"data.Stargus.RM\");\n    Control *c = RMTodo;\n\n    bool case_func = false;\n    for (u = 0; u < len; ++u)\n    {\n      switch (c[u].Type)\n      {\n      case D: // WORKS\n      {\n        printf(\"ConvertDds: %s, %s, %s\", mpqfile.c_str(), c[u].File, c[u].ArcFile);\n\n        Dds dds(hurricane);\n        case_func = dds.convert(c[1].ArcFile, c[1].File);\n        printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n      }\n      break;\n      case N: // WORKS!\n      {\n        printf(\"ConvertFont: %s, %s, %s\", mpqfile.c_str(), c[u].File, c[u].ArcFile);\n\n        Font font(hurricane);\n        case_func = font.convert(c[u].ArcFile, c[u].File);\n        printf(\"...%s\\n\", case_func ? \"ok\" : \"nok\");\n      }\n      break;\n      }\n    }\n#endif /* HAVE_CASC */\n  }\n\n  sprintf(buf, \"%s/extracted\", preferences.getDestDir().c_str());\n  f = fopen(buf, \"w\");\n  fprintf(f, VERSION \"\\n\");\n  fclose(f);\n\n  printf(\"Done startool!\\n\");\n\n  return 0;\n}\n\n"
  },
  {
    "path": "src/startool.h",
    "content": "//       _________ __                 __\n//      /   _____//  |_____________ _/  |______     ____  __ __  ______\n//      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n//      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ |\n//     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n//             \\/                  \\/          \\//_____/            \\/\n//  ______________________                           ______________________\n//                        T H E   W A R   B E G I N S\n//   Utility for Stratagus - A free fantasy real time strategy game engine\n//\n/**@name startool.h - Extract files from war archives. */\n//\n//      (c) Copyright 1999-2016 by Lutz Sammer, Nehal Mistry, Jimmy Salmon,\n//                                 Pali Rohár and cybermind\n//\n//      This program is free software; you can redistribute it and/or modify\n//      it under the terms of the GNU General Public License as published by\n//      the Free Software Foundation; version 2 dated June, 1991.\n//\n//      This program is distributed in the hope that it will be useful,\n//      but WITHOUT ANY WARRANTY; without even the implied warranty of\n//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//      GNU General Public License for more details.\n//\n//      You should have received a copy of the GNU General Public License\n//      along with this program; if not, write to the Free Software\n//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n//      02111-1307, USA.\n//\n#ifndef STARTOOL_H\n#define STARTOOL_H\n\n/*----------------------------------------------------------------------------\n --  General\n ----------------------------------------------------------------------------*/\n\n#define VERSION \"3.3.0\" // Version of extractor startool\n\nconst char NameLine[] =\n    \"startool V\" VERSION \" for Stratagus (c) 2002-2022 by the Stratagus Project.\\n\";\n\n/*----------------------------------------------------------------------------\n --  Includes\n ----------------------------------------------------------------------------*/\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n// C++\n#include <iostream>\n#include <string>\n\n#ifdef _MSC_VER\n#define PATH_MAX _MAX_PATH\n#include <windows.h>\n#include <direct.h>\n#include <io.h>\n#else\n#include <limits.h>\n#include <unistd.h>\n#endif\n#include <ctype.h>\n#include <png.h>\n\n#include \"Storm.h\"\n\n#ifndef __GNUC__\n\t#define __attribute__(args)  // Does nothing for non GNU CC\n#endif\n\n#ifndef O_BINARY\n#define O_BINARY 0\n#endif\n\nusing namespace std;\n\n//----------------------------------------------------------------------------\n//  Config\n//----------------------------------------------------------------------------\n\n/**\n **\t\tPath the sound files. (default=$DIR/sounds)\n */\n#define SOUND_PATH\t\t\"sounds\"\n\n/**\n **  Conversion control sturcture.\n */\ntypedef struct _control_\n{\n  int Type;          /// Entry type\n  int Version;       /// Only in this version\n  const char *File;    /// Save file\n  const char *ArcFile;    /// File name in list file\n  int Arg1;          /// Extra argument 1\n  int Arg2;          /// Extra argument 2\n  int Arg3;          /// Extra argument 3\n  int Arg4;          /// Extra argument 4\n} Control;\n\n/**\n **  Possible entry types of archive file.\n */\nenum _archive_type_\n{\n  S,    // Setup\n  F,    // File                          (name)\n  M,    // Map                           (name)\n  T,    // Tileset                       (name,pal,mega,mini,map)\n  R,    // RGB -> gimp                   (name,rgb)\n  G,    // Graphics                      (name,pal,gfx)\n  U,    // Uncompressed Graphics         (name,pal,gfu)\n  I,    // Widgets                       (name,pal,gfu)\n  N,    // Font                          (name,idx)\n  W,    // Wav                           (name,wav)\n  H,    // Pcx                           (name)\n  E,    // Raw extract                   (name)\n  V,    // SMK Video                     (name,video)\n  L,    // Campaign Levels\n  Q,    // MPQ archive\n  D,    // Graphics in DDS format\n  P,    // SMK Portraits\n  PAL,  // Palette from pcx file\n  WPE   // Palette from wpe file\n};\n\n#define __3 ,0,0,0\n#define __4 ,0,0,0,0\n\n#include \"startool_mpq.h\"\n#include \"startool_cd.h\"\n#include \"startool_rm.h\"\n\n#endif // STARTOOL_H\n"
  },
  {
    "path": "src/startool_cd.h",
    "content": "/*\n * startool_cd.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef STARTOOL_CD_H_\n#define STARTOOL_CD_H_\n\n#include \"startool.h\"\n\nControl CDTodo_bootstrap[] = {\n  {F,0,\"\",\"install.exe\" __4},\n  {F,0,\"\",\"Install.exe\" __4},\n  {F,0,\"\",\"starcraft.mpq\" __4 },\n  {F,0,\"\",\"Starcraft.mpq\" __4 },\n  {F,0,\"\",\"StarCraft.mpq\" __4 },\n  {F,0,\"\",\"installer tome.mpq\" __4 },\n  {F,0,\"\",\"Installer Tome.mpq\" __4 },\n  {F,0,\"\",\"starcraft archive\" __4 },\n  {F,0,\"\",\"StarCraft Archive\" __4 },\n\n  {Q,0,\"remove-stardat.mpq\",\"files\\\\stardat.mpq\" __4},\n  {Q,0,\"remove-broodat.mpq\",\"files\\\\broodat.mpq\" __4}\n};\n\nControl CDTodo[] = {\n\t// Fonts\n\t{N,0,\"font8\",\"files\\\\font\\\\font8.fnt\" __4},\n\t{N,0,\"font10\",\"files\\\\font\\\\font10.fnt\" __4},\n\t{N,0,\"font12\",\"files\\\\font\\\\font12.fnt\" __4},\n\t{N,0,\"font14\",\"files\\\\font\\\\font14.fnt\" __4},\n\t{N,0,\"font16\",\"files\\\\font\\\\font16.fnt\" __4},\n\t{N,0,\"font16x\",\"files\\\\font\\\\font16x.fnt\" __4},\n\t{N,0,\"font32\",\"files\\\\font\\\\font32.fnt\" __4},\n\t{N,0,\"font50\",\"files\\\\font\\\\font50.fnt\" __4},\n\n\t// Maps\n\t// if a map ends with a dot (.) then it adds .sms and .scp otherwise a dir with scenario.sms/scenario.smp\n\t{M,0,\"maps/(2)Challenger.\",\"multimaps\\\\(2)Challenger.scm\" __4},\n\t{M,0,\"maps/(2)River Crossing.\",\"multimaps\\\\(2)River Crossing.scm\" __4},\n\t{M,0,\"maps/(2)Road War.\",\"multimaps\\\\(2)Road War.scm\" __4},\n\t{M,0,\"maps/(2)Space Madness.\",\"multimaps\\\\(2)Space Madness.scm\" __4},\n\t{M,0,\"maps/(2)The Small Divide.\",\"multimaps\\\\(2)The Small Divide.scm\" __4},\n\t{M,0,\"maps/(2)Volcanis.\",\"multimaps\\\\(2)Volcanis.scm\" __4},\n\t{M,0,\"maps/(3)Holy Ground.\",\"multimaps\\\\(3)Holy Ground.scm\" __4},\n\t{M,0,\"maps/(3)Meltdown.\",\"multimaps\\\\(3)Meltdown.scm\" __4},\n\t{M,0,\"maps/(3)Three Kingdoms.\",\"multimaps\\\\(3)Three Kingdoms.scm\" __4},\n\t{M,0,\"maps/(3)Triumvirate.\",\"multimaps\\\\(3)Triumvirate.scm\" __4},\n\t{M,0,\"maps/(4)Alpha Draconis.\",\"multimaps\\\\(4)Alpha Draconis.scm\" __4},\n\t{M,0,\"maps/(4)Bridge Too Near.\",\"multimaps\\\\(4)Bridge Too Near.scm\" __4},\n\t{M,0,\"maps/(4)Cyclone.\",\"multimaps\\\\(4)Cyclone.scm\" __4},\n\t{M,0,\"maps/(4)Dark Crystal.\",\"multimaps\\\\(4)Dark Crystal.scm\" __4},\n\t{M,0,\"maps/(4)Dark Star.\",\"multimaps\\\\(4)Dark Star.scm\" __4},\n\t{M,0,\"maps/(4)Lost Civilization.\",\"multimaps\\\\(4)Lost Civilization.scm\" __4},\n\t{M,0,\"maps/(4)Opposing City States '98.\",\"multimaps\\\\(4)Opposing City States '98.scm\" __4},\n\t{M,0,\"maps/(4)Orbital Relay.\",\"multimaps\\\\(4)Orbital Relay.scm\" __4},\n\t{M,0,\"maps/(4)Power Lines.\",\"multimaps\\\\(4)Power Lines.scm\" __4},\n\t{M,0,\"maps/(4)Ruins of the Ancients.\",\"multimaps\\\\(4)Ruins of the Ancients.scm\" __4},\n\t{M,0,\"maps/(4)Tarsonis Orbital.\",\"multimaps\\\\(4)Tarsonis Orbital.scm\" __4},\n\t{M,0,\"maps/(5)Diablo.\",\"multimaps\\\\(5)Diablo.scm\" __4},\n\t{M,0,\"maps/(5)Island Hop.\",\"multimaps\\\\(5)Island Hop.scm\" __4},\n\t{M,0,\"maps/(5)Jeweled River.\",\"multimaps\\\\(5)Jeweled River.scm\" __4},\n\t{M,0,\"maps/(5)Sherwood Forest.\",\"multimaps\\\\(5)Sherwood Forest.scm\" __4},\n\t{M,0,\"maps/(6)Ground Zero.\",\"multimaps\\\\(6)Ground Zero.scm\" __4},\n\t{M,0,\"maps/(6)Hidden Shrine.\",\"multimaps\\\\(6)Hidden Shrine.scm\" __4},\n\t{M,0,\"maps/(6)New Gettysburg.\",\"multimaps\\\\(6)New Gettysburg.scm\" __4},\n\t{M,0,\"maps/(7)Continental Divide.\",\"multimaps\\\\(7)Continental Divide.scm\" __4},\n\t{M,0,\"maps/(7)River War.\",\"multimaps\\\\(7)River War.scm\" __4},\n\t{M,0,\"maps/(8)Bridge to Bridge '98.\",\"multimaps\\\\(8)Bridge to Bridge '98.scm\" __4},\n\t{M,0,\"maps/(8)Char Magma.\",\"multimaps\\\\(8)Char Magma.scm\" __4},\n\t{M,0,\"maps/(8)Homeworld.\",\"multimaps\\\\(8)Homeworld.scm\" __4},\n\t{M,0,\"maps/(8)Killing Fields.\",\"multimaps\\\\(8)Killing Fields.scm\" __4},\n\t{M,0,\"maps/(8)Orbital Death.\",\"multimaps\\\\(8)Orbital Death.scm\" __4},\n\t{M,0,\"maps/(8)Plains of Snow '98.\",\"multimaps\\\\(8)Plains of Snow '98.scm\" __4},\n\t{M,0,\"maps/(8)Station Unrest.\",\"multimaps\\\\(8)Station Unrest.scm\" __4},\n\t{M,0,\"maps/(8)The Hunters.\",\"multimaps\\\\(8)The Hunters.scm\" __4},\n\n\t// some maps from subdirs\n\t{M,0,\"maps/campaign/(1)enslavers01.\",\"multimaps\\\\campaign\\\\(1)enslavers01.scm\" __4},\n\t{M,0,\"maps/campaign/(1)enslavers02a.\",\"multimaps\\\\campaign\\\\(1)enslavers02a.scm\" __4},\n\t{M,0,\"maps/campaign/(1)enslavers02b.\",\"multimaps\\\\campaign\\\\(1)enslavers02b.scm\" __4},\n\t{M,0,\"maps/campaign/(1)enslavers03a.\",\"multimaps\\\\campaign\\\\(1)enslavers03a.scm\" __4},\n\t{M,0,\"maps/campaign/(1)enslavers03b.\",\"multimaps\\\\campaign\\\\(1)enslavers03b.scm\" __4},\n\n\t{M,0,\"maps/ladder/(2)discovery.\",\"multimaps\\\\ladder\\\\(2)discovery.scm\" __4},\n\t{M,0,\"maps/ladder/(2)river styx.\",\"multimaps\\\\ladder\\\\(2)river styx.scm\" __4},\n\t{M,0,\"maps/ladder/(2)solar station.\",\"multimaps\\\\ladder\\\\(2)solar station.scm\" __4},\n\t{M,0,\"maps/ladder/(4)crusader.\",\"multimaps\\\\ladder\\\\(4)crusader.scm\" __4},\n\t{M,0,\"maps/ladder/(4)dire straits.\",\"multimaps\\\\ladder\\\\(4)dire straits.scm\" __4},\n\t{M,0,\"maps/ladder/(4)rivalry.\",\"multimaps\\\\ladder\\\\(4)rivalry.scm\" __4},\n\t{M,0,\"maps/ladder/(4)lost temple.\",\"multimaps\\\\ladder\\\\(4)lost temple.scm\" __4},\n\n\t{M,0,\"maps/scenario/(2)pro bowl.\",\"multimaps\\\\scenario\\\\(2)pro bowl.scm\" __4},\n\t{M,0,\"maps/scenario/(2)wakka wakka.\",\"multimaps\\\\scenario\\\\(2)wakka wakka.scm\" __4},\n\t{M,0,\"maps/scenario/(3)defenders of the galaxy.\",\"multimaps\\\\scenario\\\\(3)defenders of the galaxy.scm\" __4},\n\t{M,0,\"maps/scenario/(4)king of the hill.\",\"multimaps\\\\scenario\\\\(4)king of the hill.scm\" __4},\n\t{M,0,\"maps/scenario/(4)old faithful.\",\"multimaps\\\\scenario\\\\(4)old faithful.scm\" __4},\n\t{M,0,\"maps/scenario/(4)steal the bacon.\",\"multimaps\\\\scenario\\\\(4)steal the bacon.scm\" __4},\n\t{M,0,\"maps/scenario/(4)zergling round-up.\",\"multimaps\\\\scenario\\\\(4)zergling round-up.scm\" __4},\n\t{M,0,\"maps/scenario/(4)zoo keeper.\",\"multimaps\\\\scenario\\\\(4)zoo keeper.scm\" __4},\n\t{M,0,\"maps/scenario/(5)race of death.\",\"multimaps\\\\scenario\\\\(5)race of death.scm\" __4},\n\t{M,0,\"maps/scenario/(8)starcraft fortress.\",\"multimaps\\\\scenario\\\\(8)starcraft fortress.scm\" __4},\n\n\t// Terran Campaigns\n\t{H,0,\"campaigns/terran/palta-blank\",\"glue\\\\PalTA\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/palta-terrana\",\"glue\\\\palta\\\\TerranA.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/palta-tfont\",\"glue\\\\palta\\\\tfont.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/paltb-blank\",\"glue\\\\paltb\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/paltb-terranb\",\"glue\\\\paltb\\\\TerranB.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/paltb-tfont\",\"glue\\\\paltb\\\\tfont.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/paltc-blank\",\"glue\\\\paltc\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/paltc-terranc\",\"glue\\\\paltc\\\\TerranC.pcx\",0 __3},\n\t{H,0,\"campaigns/terran/paltc-tfont\",\"glue\\\\paltc\\\\tfont.pcx\",0 __3},\n\n\t{L,0,\"campaigns/terran/tutorial/\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/tutorial/ComBeep0\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0B00tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0B01tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0B01tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0B02tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0B02tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0B03tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0B03tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0B04tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0B04tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0B05tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0B05tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0B60tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0B60tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M00tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M01tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M01tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M02tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M02tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M03tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M03tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M04tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M04tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M05tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M05tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M06tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M06tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M07tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M07tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M21tad\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M21tad.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M30tma\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M30tma.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/T0M31tma\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\T0M31tma.wav\" __4},\n\t{W,0,\"campaigns/terran/tutorial/TSCYes01\",\"campaign\\\\terran\\\\tutorial\\\\staredit\\\\wav\\\\TSCYes01.wav\" __4},\n\t{L,0,\"campaigns/terran/01/\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/01/ComBeep0\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/01/ComBeep1\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\ComBeep1.wav\" __4},\n\t{W,0,\"campaigns/terran/01/T0M20tad\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\T0M20tad.wav\" __4},\n\t{W,0,\"campaigns/terran/01/T1B00tad\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\T1B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/01/T1B01udu\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\T1B01udu.wav\" __4},\n\t{W,0,\"campaigns/terran/01/T1B02tad\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\T1B02tad.wav\" __4},\n\t{W,0,\"campaigns/terran/01/T1M01uci\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\T1M01uci.wav\" __4},\n\t{W,0,\"campaigns/terran/01/T1M20ura\",\"campaign\\\\terran\\\\terran01\\\\staredit\\\\wav\\\\T1M20ura.wav\" __4},\n\t{L,0,\"campaigns/terran/02/\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/02/ComBeep0\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/02/ComBeep1\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\ComBeep1.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2B00tad\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2B01ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2B01ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2B02tad\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2B02tad.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2B03udu\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2B03udu.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2B04ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2B04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M00ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M00ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M20ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M20ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M30uci\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M30uci.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M40ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M40ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M60ftb\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M60ftb.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M60tma\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M60tma.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M60ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M60ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M80udu\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M80udu.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M81ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M81ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M82udu\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M82udu.wav\" __4},\n\t{W,0,\"campaigns/terran/02/T2M83ura\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\T2M83ura.wav\" __4},\n\t{W,0,\"campaigns/terran/02/TCB02tad\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\TCB02tad.wav\" __4},\n\t{W,0,\"campaigns/terran/02/tdrTra01\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\tdrTra01.wav\" __4},\n\t{W,0,\"campaigns/terran/02/tfbRdy00\",\"campaign\\\\terran\\\\terran02\\\\staredit\\\\wav\\\\tfbRdy00.wav\" __4},\n\t{L,0,\"campaigns/terran/03/\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/03/ComBeep0\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T0M40tvu\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T0M40tvu.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3B00tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3B01udu\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3B01udu.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3B02tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3B02tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3B03ume\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3B03ume.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3B04ume\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3B04ume.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3B05tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3B05tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3M00tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3M00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3M20tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3M20tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3M21tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3M21tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3M60tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3M60tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3M70tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3M70tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3M80tad\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3M80tad.wav\" __4},\n\t{W,0,\"campaigns/terran/03/T3M90tma\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\T3M90tma.wav\" __4},\n\t{W,0,\"campaigns/terran/03/TDrYes04\",\"campaign\\\\terran\\\\terran03\\\\staredit\\\\wav\\\\TDrYes04.wav\" __4},\n\t{L,0,\"campaigns/terran/04/\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/04/ComBeep0\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/04/ComBeep1\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\ComBeep1.wav\" __4},\n\t{W,0,\"campaigns/terran/04/P6M00tad\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\P6M00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/04/PPwrDown\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\PPwrDown.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4B00tad\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4B01ura\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4B01ura.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4B02ume\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4B02ume.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4B03ume\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4B03ume.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4B04ura\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4B04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4M00uci\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4M00uci.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4M00ura\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4M00ura.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4M01ume\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4M01ume.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4M20uci\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4M20uci.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4M20ura\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4M20ura.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4M30uma\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4M30uma.wav\" __4},\n\t{W,0,\"campaigns/terran/04/T4M70tad\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\T4M70tad.wav\" __4},\n\t{W,0,\"campaigns/terran/04/Z5M00tad\",\"campaign\\\\terran\\\\terran04\\\\staredit\\\\wav\\\\Z5M00tad.wav\" __4},\n\t{L,0,\"campaigns/terran/05/\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/05/ComBeep0\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5B00ura\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5B00ura.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5B01tad\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5B01tad.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5B02ume\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5B02ume.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5B03uke\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5B03uke.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5B04ume\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5B04ume.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M00uke\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M00uke.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M01ura\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M01ura.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M02uke\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M02uke.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M03ura\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M03ura.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M04uke\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M04uke.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M20uke\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M20uke.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M40uma\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M40uma.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M41uke\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M41uke.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M42tad\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M42tad.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M43uke\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M43uke.wav\" __4},\n\t{W,0,\"campaigns/terran/05/T5M44uma\",\"campaign\\\\terran\\\\terran05\\\\staredit\\\\wav\\\\T5M44uma.wav\" __4},\n\t{L,0,\"campaigns/terran/06/\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/06/ComBeep0\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B00tad\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B01udu\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B01udu.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B02ura\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B02ura.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B03ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B03ume.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B04ura\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B05uke\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B05uke.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B06ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B06ume.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B07uke\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B07uke.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B08ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B08ume.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B09uke\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B09uke.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6B10ura\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6B10ura.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M00ura\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M00ura.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M20udu\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M20udu.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M21ura\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M21ura.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M22ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M22ume.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M23udu\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M23udu.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M24ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M24ume.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M25udu\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M25udu.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M26ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M26ume.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M27udu\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M27udu.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M28ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M28ume.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M29ura\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M29ura.wav\" __4},\n\t{W,0,\"campaigns/terran/06/T6M30ume\",\"campaign\\\\terran\\\\terran06\\\\staredit\\\\wav\\\\T6M30ume.wav\" __4},\n\t{L,0,\"campaigns/terran/07/\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/07/ComBeep0\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B00tad\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B01ura\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B01ura.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B02udu\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B02udu.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B03ura\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B03ura.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B04udu\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B04udu.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B05uke\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B05uke.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B06ume\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B06ume.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B07uke\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B07uke.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7B08ume\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7B08ume.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M00udu\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M00udu.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M01ura\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M01ura.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M02udu\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M02udu.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M03ura\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M03ura.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M20tad\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M20tad.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M21ura\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M21ura.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M22uta\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M22uta.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M23ura\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M23ura.wav\" __4},\n\t{W,0,\"campaigns/terran/07/T7M24uta\",\"campaign\\\\terran\\\\terran07\\\\staredit\\\\wav\\\\T7M24uta.wav\" __4},\n\t{L,0,\"campaigns/terran/08/\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/08/ComBeep0\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B00tad\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B01ume\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B01ume.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B02uke\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B02uke.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B03ura\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B03ura.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B04uke\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B04uke.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B05ume\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B05ume.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B06ura\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B06ura.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B07ume\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B07ume.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B08ume\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B08ume.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8B09ume\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8B09ume.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8M00uke\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8M00uke.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8M01ume\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8M01ume.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8M02uke\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8M02uke.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8M40uke\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8M40uke.wav\" __4},\n\t{W,0,\"campaigns/terran/08/T8m41ume\",\"campaign\\\\terran\\\\terran08\\\\staredit\\\\wav\\\\T8m41ume.wav\" __4},\n\t{L,0,\"campaigns/terran/09/\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/09/ComBeep0\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9B00tad\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9B00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9B01ume\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9B01ume.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9B02udu\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9B02udu.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9B03ura\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9B03ura.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9B04udu\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9B04udu.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9B05ura\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9B05ura.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9M00ura\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9M00ura.wav\" __4},\n\t{W,0,\"campaigns/terran/09/T9M20udu\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\T9M20udu.wav\" __4},\n\t{W,0,\"campaigns/terran/09/TAM00udu\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\TAM00udu.wav\" __4},\n\t{W,0,\"campaigns/terran/09/TAM01uke\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\TAM01uke.wav\" __4},\n\t{W,0,\"campaigns/terran/09/TAM02ume\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\TAM02ume.wav\" __4},\n\t{W,0,\"campaigns/terran/09/TAM03uke\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\TAM03uke.wav\" __4},\n\t{W,0,\"campaigns/terran/09/TAM04ura\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\TAM04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/09/TAM05ume\",\"campaign\\\\terran\\\\terran09\\\\staredit\\\\wav\\\\TAM05ume.wav\" __4},\n\t{L,0,\"campaigns/terran/10/\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/10/ComBeep0\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAB00tad\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAB00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAB01ume\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAB01ume.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAB02ume\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAB02ume.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAB03uke\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAB03uke.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAB04udu\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAB04udu.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAB05ura\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAB05ura.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAB06udu\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAB06udu.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAM00udu\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAM00udu.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAM01uke\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAM01uke.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAM02ume\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAM02ume.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAM03uke\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAM03uke.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAM04ura\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAM04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/10/TAM05ume\",\"campaign\\\\terran\\\\terran10\\\\staredit\\\\wav\\\\TAM05ume.wav\" __4},\n\t{L,0,\"campaigns/terran/11/\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/11/ComBeep0\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBB00tad\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBB00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBB01ume\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBB01ume.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBB02ura\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBB02ura.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBB03ume\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBB03ume.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBB04ura\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBB04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBB05uke\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBB05uke.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBB06ura\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBB06ura.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM00ura\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM00ura.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM01uke\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM01uke.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM04ura\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM20ume\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM20ume.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM21uma\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM21uma.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM40tad\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM40tad.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM41uke\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM41uke.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM42ume\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM42ume.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM43ura\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM43ura.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM44ume\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM44ume.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM45uke\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM45uke.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM46ura\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM46ura.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBM47ume\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBM47ume.wav\" __4},\n\t{W,0,\"campaigns/terran/11/TBm48uke\",\"campaign\\\\terran\\\\terran11\\\\staredit\\\\wav\\\\TBm48uke.wav\" __4},\n\t{L,0,\"campaigns/terran/12/\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/terran/12/ComBeep0\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB00tad\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB00tad.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB01ura\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB01ura.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB02tad\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB02tad.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB03ume\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB03ume.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB04ura\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB04ura.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB05ume\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB05ume.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB06ura\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB06ura.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB07ume\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB07ume.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB08tad\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB08tad.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCB09ura\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCB09ura.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCM00ura\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCM00ura.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCM01ura\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCM01ura.wav\" __4},\n\t{W,0,\"campaigns/terran/12/TCM20tad\",\"campaign\\\\terran\\\\terran12\\\\staredit\\\\wav\\\\TCM20tad.wav\" __4},\n\n\t{E,0,\"campaigns/terran/EstT0t.txt\",\"rez\\\\EstT0t.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT01.txt\",\"rez\\\\EstT01.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT02.txt\",\"rez\\\\EstT02.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT03.txt\",\"rez\\\\EstT03.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT04.txt\",\"rez\\\\EstT04.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT05.txt\",\"rez\\\\EstT05.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT06.txt\",\"rez\\\\EstT06.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT07.txt\",\"rez\\\\EstT07.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT08.txt\",\"rez\\\\EstT08.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT09.txt\",\"rez\\\\EstT09.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT10.txt\",\"rez\\\\EstT10.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT11.txt\",\"rez\\\\EstT11.txt\" __4},\n\t{E,0,\"campaigns/terran/EstT12.txt\",\"rez\\\\EstT12.txt\" __4},\n\n\t// Zerg Campaigns\n\t{H,0,\"campaigns/zerg/palza-blank\",\"glue\\\\palza\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palza-tfont\",\"glue\\\\palza\\\\tFont.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palza-zerga\",\"glue\\\\palza\\\\ZergA.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palzb-blank\",\"glue\\\\palzb\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palzb-tfont\",\"glue\\\\palzb\\\\tFont.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palzb-zergb\",\"glue\\\\palzb\\\\ZergB.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palzc-blank\",\"glue\\\\palzc\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palzc-tfont\",\"glue\\\\palzc\\\\tfont.pcx\",0 __3},\n\t{H,0,\"campaigns/zerg/palzc-zergc\",\"glue\\\\palzc\\\\ZergC.pcx\",0 __3},\n\n\t{L,0,\"campaigns/zerg/tutorial/\",\"campaign\\\\zerg\\\\tutorial\\\\staredit\\\\scenario.chk\" __4},\n\t{L,0,\"campaigns/zerg/01/\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/01/ComBeep0\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M01uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M01uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M02uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M02uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M03uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M03uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M04uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M04uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M05uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M05uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M06uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M06uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M07uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M07uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M08uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M08uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z0M09uda\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z0M09uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z1B00zad.wav\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z1B00zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z1B01zad.wav\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z1B01zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z1B02zad\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z1B02zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z1B03zad\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z1B03zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/Z1M00uza\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\Z1M00uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/01/zpwrdown\",\"campaign\\\\zerg\\\\zerg01\\\\staredit\\\\wav\\\\zpwrdown.wav\" __4},\n\t{L,0,\"campaigns/zerg/02/\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/02/ComBeep0\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/02/Z2B00zad\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\Z2B00zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/02/Z2B01zad\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\Z2B01zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/02/Z2B02uza\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\Z2B02uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/02/Z2B03uda\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\Z2B03uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/02/Z2M00uda\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\Z2M00uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/02/Z2M20uza\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\Z2M20uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/02/Z2M21uda\",\"campaign\\\\zerg\\\\zerg02\\\\staredit\\\\wav\\\\Z2M21uda.wav\" __4},\n\t{L,0,\"campaigns/zerg/03/\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/03/ComBeep0\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/Z3B00zad\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\Z3B00zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/Z3B01uza\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\Z3B01uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/Z3B02udu\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\Z3B02udu.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/Z3B03uda\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\Z3B03uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/Z3M00udu\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\Z3M00udu.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/Z3M01uda\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\Z3M01uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/Z3M02uza\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\Z3M02uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/03/zpwrdown\",\"campaign\\\\zerg\\\\zerg03\\\\staredit\\\\wav\\\\zpwrdown.wav\" __4},\n\t{L,0,\"campaigns/zerg/04/\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/04/ComBeep0\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4B00uza\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4B00uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4B01zad\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4B01zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4B02zad\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4B02zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M00ura\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M00ura.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M20uza\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M20uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M40zad\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M40zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M41uki\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M41uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M42zad\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M42zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M43ura\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M43ura.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M60ura\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M60ura.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M61uki\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M61uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M62ura\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M62ura.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M63uki\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M63uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M65ura\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M65ura.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M66uki\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M66uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/04/Z4M67ura\",\"campaign\\\\zerg\\\\zerg04\\\\staredit\\\\wav\\\\Z4M67ura.wav\" __4},\n\t{L,0,\"campaigns/zerg/05/\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/05/ComBeep0\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/ComBeep1\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\ComBeep1.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/P6M00tad\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\P6M00tad.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/PPwrDown\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\PPwrDown.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/T4M70tad\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\T4M70tad.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/TBM21uma\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\TBM21uma.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5B00uki\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5B00uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5B01uki\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5B01uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5B02uza\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5B02uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5B03uki\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5B03uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5B04zad\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5B04zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5B05uza\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5B05uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M00tad\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M00tad.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M00uda\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M00uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M20uci\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M20uci.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M20uki\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M20uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M30uci\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M30uci.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M40uma\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M40uma.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M50uma\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M50uma.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M51uma\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M51uma.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/Z5M60uda\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\Z5M60uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/05/zpwrdown\",\"campaign\\\\zerg\\\\zerg05\\\\staredit\\\\wav\\\\zpwrdown.wav\" __4},\n\t{L,0,\"campaigns/zerg/06/\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/06/ComBeep0\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/ComBeep1\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\ComBeep1.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6B00uki\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6B00uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6B01uki\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6B01uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6B02uta\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6B02uta.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6B03uki\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6B03uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6B04uta\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6B04uta.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6B05uki\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6B05uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6M00uza\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6M00uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6M01uki\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6M01uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6M02uza\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6M02uza.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6M20uki\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6M20uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6M40uta\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6M40uta.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6M60uki\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6M60uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/06/Z6M61uta\",\"campaign\\\\zerg\\\\zerg06\\\\staredit\\\\wav\\\\Z6M61uta.wav\" __4},\n\t{L,0,\"campaigns/zerg/07/\",\"campaign\\\\zerg\\\\zerg07\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/07/Z7B00uki\",\"campaign\\\\zerg\\\\zerg07\\\\staredit\\\\wav\\\\Z7B00uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/07/Z7B01uda\",\"campaign\\\\zerg\\\\zerg07\\\\staredit\\\\wav\\\\Z7B01uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/07/Z7B02uki\",\"campaign\\\\zerg\\\\zerg07\\\\staredit\\\\wav\\\\Z7B02uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/07/Z7B03uda\",\"campaign\\\\zerg\\\\zerg07\\\\staredit\\\\wav\\\\Z7B03uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/07/Z7B04uki\",\"campaign\\\\zerg\\\\zerg07\\\\staredit\\\\wav\\\\Z7B04uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/07/Z7B05uda\",\"campaign\\\\zerg\\\\zerg07\\\\staredit\\\\wav\\\\Z7B05uda.wav\" __4},\n\t{L,0,\"campaigns/zerg/08/\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/08/ComBeep0\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8B00zad\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8B00zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8B01zad\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8B01zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8B02zad\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8B02zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8B03uda\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8B03uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8M00uda\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8M00uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8M20uda\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8M20uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8M40uki\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8M40uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8M41uze\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8M41uze.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8M42uki\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8M42uki.wav\" __4},\n\t{W,0,\"campaigns/zerg/08/Z8M60uki\",\"campaign\\\\zerg\\\\zerg08\\\\staredit\\\\wav\\\\Z8M60uki.wav\" __4},\n\t// \"campaigns/zerg/09/scenario.chk\" => crash in importer with CompaignConverter!\n\t//{L,0,\"campaigns/zerg/09/\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/09/ComBeep0\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/09/Z9B00zad\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\Z9B00zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/09/Z9B01zad\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\Z9B01zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/09/Z9B02zad\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\Z9B02zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/09/Z9M00uda\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\Z9M00uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/09/Z9M01uda\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\Z9M01uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/09/zdrErr00\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\zdrErr00.wav\" __4},\n\t{W,0,\"campaigns/zerg/09/ZDrMin00\",\"campaign\\\\zerg\\\\zerg09\\\\staredit\\\\wav\\\\ZDrMin00.wav\" __4},\n\t{L,0,\"campaigns/zerg/10/\",\"campaign\\\\zerg\\\\zerg10\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/zerg/10/ComBeep0\",\"campaign\\\\zerg\\\\zerg10\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/zerg/10/ZAB00zad\",\"campaign\\\\zerg\\\\zerg10\\\\staredit\\\\wav\\\\ZAB00zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/10/ZAB01zad\",\"campaign\\\\zerg\\\\zerg10\\\\staredit\\\\wav\\\\ZAB01zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/10/ZAB02zad\",\"campaign\\\\zerg\\\\zerg10\\\\staredit\\\\wav\\\\ZAB02zad.wav\" __4},\n\t{W,0,\"campaigns/zerg/10/ZAM00uda\",\"campaign\\\\zerg\\\\zerg10\\\\staredit\\\\wav\\\\ZAM00uda.wav\" __4},\n\t{W,0,\"campaigns/zerg/10/ZAM20zad\",\"campaign\\\\zerg\\\\zerg10\\\\staredit\\\\wav\\\\ZAM20zad.wav\" __4},\n\n\t{E,0,\"campaigns/zerg/EstZ0t.txt\",\"rez\\\\EstZ0t.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ01.txt\",\"rez\\\\EstZ01.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ02.txt\",\"rez\\\\EstZ02.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ03.txt\",\"rez\\\\EstZ03.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ04.txt\",\"rez\\\\EstZ04.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ05.txt\",\"rez\\\\EstZ05.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ06.txt\",\"rez\\\\EstZ06.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ07.txt\",\"rez\\\\EstZ07.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ08.txt\",\"rez\\\\EstZ08.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ09.txt\",\"rez\\\\EstZ09.txt\" __4},\n\t{E,0,\"campaigns/zerg/EstZ10.txt\",\"rez\\\\EstZ10.txt\" __4},\n\n\t// Protoss Campaigns\n\t{H,0,\"campaigns/protoss/palpa-blank\",   \"glue\\\\palpa\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpa-tfont\",   \"glue\\\\palpa\\\\tFont.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpa-protossa\",\"glue\\\\palpa\\\\protossa.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpb-blank\",   \"glue\\\\palpb\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpb-tfont\",   \"glue\\\\palpb\\\\tFont.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpb-protossb\",\"glue\\\\palpb\\\\protossb.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpc-blank\",   \"glue\\\\palpc\\\\Blank.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpc-tfont\",   \"glue\\\\palpc\\\\tfont.pcx\",0 __3},\n\t{H,0,\"campaigns/protoss/palpc-protossc\",\"glue\\\\palpc\\\\protossc.pcx\",0 __3},\n\n\t{L,0,\"campaigns/protoss/tutorial/\",\"campaign\\\\protoss\\\\tutorial\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/tutorial/P1B00pad\",\"campaign\\\\protoss\\\\tutorial\\\\staredit\\\\wav\\\\P1B00pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/tutorial/P1B01pad\",\"campaign\\\\protoss\\\\tutorial\\\\staredit\\\\wav\\\\P1B01pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/tutorial/P1B02pad\",\"campaign\\\\protoss\\\\tutorial\\\\staredit\\\\wav\\\\P1B02pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/tutorial/P1M00ufe\",\"campaign\\\\protoss\\\\tutorial\\\\staredit\\\\wav\\\\P1M00ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/tutorial/P1M20ufe\",\"campaign\\\\protoss\\\\tutorial\\\\staredit\\\\wav\\\\P1M20ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/tutorial/P1M40ufe\",\"campaign\\\\protoss\\\\tutorial\\\\staredit\\\\wav\\\\P1M40ufe.wav\" __4},\n\t{L,0,\"campaigns/protoss/01/\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/01/ComBeep0\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1B00pad\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1B00pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1B01pad\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1B01pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1B02pad\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1B02pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1M00ufe\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1M00ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1M40ufe\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1M40ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1M60ufe\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1M60ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1M61ufe\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1M61ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/01/P1M62ufe\",\"campaign\\\\protoss\\\\protoss01\\\\staredit\\\\wav\\\\P1M62ufe.wav\" __4},\n\t{L,0,\"campaigns/protoss/02/\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/02/ComBeep0\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B00pad\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B00pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B01uta\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B01uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B02pad\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B02pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B03uta\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B03uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B04uta\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B04uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B06pad\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B06pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B07uta\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B07uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B08uta\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B08uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B09pad\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B09pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B10uta\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B10uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2B11ufe\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2B11ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2M00ufe\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2M00ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/02/P2M01ufe\",\"campaign\\\\protoss\\\\protoss02\\\\staredit\\\\wav\\\\P2M01ufe.wav\" __4},\n\t{L,0,\"campaigns/protoss/03/\",\"campaign\\\\protoss\\\\protoss03\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/03/P3B00ufe\",\"campaign\\\\protoss\\\\protoss03\\\\staredit\\\\wav\\\\P3B00ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/03/P3B01pad\",\"campaign\\\\protoss\\\\protoss03\\\\staredit\\\\wav\\\\P3B01pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/03/P3B02pad\",\"campaign\\\\protoss\\\\protoss03\\\\staredit\\\\wav\\\\P3B02pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/03/P3B03ufe\",\"campaign\\\\protoss\\\\protoss03\\\\staredit\\\\wav\\\\P3B03ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/03/P3M00ufe\",\"campaign\\\\protoss\\\\protoss03\\\\staredit\\\\wav\\\\P3M00ufe.wav\" __4},\n\t{W,0,\"campaigns/protoss/03/P3M01pad\",\"campaign\\\\protoss\\\\protoss03\\\\staredit\\\\wav\\\\P3M01pad.wav\" __4},\n\t{L,0,\"campaigns/protoss/04/\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/04/ComBeep0\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4B00pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4B00pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4B01pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4B01pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4B02pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4B02pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4B03pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4B03pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M00uta\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M00uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M01pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M01pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M02uta\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M02uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M03ura\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M03ura.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M04pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M04pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M05ura\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M05ura.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M06pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M06pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M07uta\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M07uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M09pad\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M09pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M10uta\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M10uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M11ute\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M11ute.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/P4M20uta\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\P4M20uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/zhyRdy00\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\zhyRdy00.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/zhyYes03\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\zhyYes03.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/zquRdy00\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\zquRdy00.wav\" __4},\n\t{W,0,\"campaigns/protoss/04/ZZeRdy00\",\"campaign\\\\protoss\\\\protoss04\\\\staredit\\\\wav\\\\ZZeRdy00.wav\" __4},\n\t{L,0,\"campaigns/protoss/05/\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/05/ComBeep0\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B00pad\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B00pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B01uta\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B01uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B02pad\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B02pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B03uta\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B03uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B04uta\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B04uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B05pad\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B05pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B06uta\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B06uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B07uta\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B07uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5B08pad\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5B08pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5M00udu\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5M00udu.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5M03uta\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5M03uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/05/P5M04udu\",\"campaign\\\\protoss\\\\protoss05\\\\staredit\\\\wav\\\\P5M04udu.wav\" __4},\n\t{L,0,\"campaigns/protoss/06/\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/06/ComBeep0\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6B00uta\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6B00uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6B01ura\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6B01ura.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6B02uta\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6B02uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M00tad\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M00tad.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M00uta\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M00uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M01uze\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M01uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M03uta\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M03uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M04uze\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M04uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M20uma\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M20uma.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M30uma\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M30uma.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/P6M40uma\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\P6M40uma.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/pshBld03\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\pshBld03.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/TMaPss00\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\TMaPss00.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/ZBgRdy00\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\ZBgRdy00.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/ZZeRdy00\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\ZZeRdy00.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/ZZeYes01\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\ZZeYes01.wav\" __4},\n\t{W,0,\"campaigns/protoss/06/ZZeYes03\",\"campaign\\\\protoss\\\\protoss06\\\\staredit\\\\wav\\\\ZZeYes03.wav\" __4},\n\t{L,0,\"campaigns/protoss/07/\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/07/ComBeep0\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B00ufd\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B00ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B01uta\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B01uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B02ufd\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B02ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B03uta\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B03uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B04ufd\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B04ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B05ufd\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B05ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B06uta\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B06uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B07ufd\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B07ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7B08uta\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7B08uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7M00pad\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7M00pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7M01uta\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7M01uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7M20uta\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7M20uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7M21pad\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7M21pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/P7M23uta\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\P7M23uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/07/pshBld03\",\"campaign\\\\protoss\\\\protoss07\\\\staredit\\\\wav\\\\pshBld03.wav\" __4},\n\t{L,0,\"campaigns/protoss/08/\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/08/ComBeep0\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/ComBeep1\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\ComBeep1.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8B00ufd\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8B00ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8B01ufd\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8B01ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8B02ura\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8B02ura.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8B03ufd\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8B03ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M00ufd\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M00ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M01pad\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M01pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M02uze\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M02uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M03pad\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M03pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M04uze\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M04uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M05pad\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M05pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M06uze\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M06uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/P8M08pad\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\P8M08pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/08/pshBld03\",\"campaign\\\\protoss\\\\protoss08\\\\staredit\\\\wav\\\\pshBld03.wav\" __4},\n\t{L,0,\"campaigns/protoss/09/\",\"campaign\\\\protoss\\\\protoss09\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/09/ComBeep0\",\"campaign\\\\protoss\\\\protoss09\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/09/P9B00uta\",\"campaign\\\\protoss\\\\protoss09\\\\staredit\\\\wav\\\\P9B00uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/09/P9B01uze\",\"campaign\\\\protoss\\\\protoss09\\\\staredit\\\\wav\\\\P9B01uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/09/P9B02uze\",\"campaign\\\\protoss\\\\protoss09\\\\staredit\\\\wav\\\\P9B02uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/09/P9B03uta\",\"campaign\\\\protoss\\\\protoss09\\\\staredit\\\\wav\\\\P9B03uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/09/P9B04ufd\",\"campaign\\\\protoss\\\\protoss09\\\\staredit\\\\wav\\\\P9B04ufd.wav\" __4},\n\t{L,0,\"campaigns/protoss/10/\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\scenario.chk\" __4},\n\t{W,0,\"campaigns/protoss/10/ComBeep0\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\ComBeep0.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/P9M00pad\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\P9M00pad.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/P9M02ura\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\P9M02ura.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/PAB00ufd\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\PAB00ufd.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/PAB01uta\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\PAB01uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/PAB02uta\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\PAB02uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/PAB03uze\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\PAB03uze.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/PAB05ura\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\PAB05ura.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/PAB06uta\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\PAB06uta.wav\" __4},\n\t{W,0,\"campaigns/protoss/10/PAM00uta\",\"campaign\\\\protoss\\\\protoss10\\\\staredit\\\\wav\\\\PAM00uta.wav\" __4},\n\n\t{E,0,\"campaigns/protoss/EstP0t.txt\",\"rez\\\\EstP0t.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP01.txt\",\"rez\\\\EstP01.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP02.txt\",\"rez\\\\EstP02.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP03.txt\",\"rez\\\\EstP03.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP04.txt\",\"rez\\\\EstP04.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP05.txt\",\"rez\\\\EstP05.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP06.txt\",\"rez\\\\EstP06.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP07.txt\",\"rez\\\\EstP07.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP08.txt\",\"rez\\\\EstP08.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP09.txt\",\"rez\\\\EstP09.txt\" __4},\n\t{E,0,\"campaigns/protoss/EstP10.txt\",\"rez\\\\EstP10.txt\" __4},\n\n\t// Music\n\t{W,0,\"music/title\",\"music\\\\title.wav\" __4},\n\t{W,0,\"music/terran/defeat\",\"music\\\\tdefeat.wav\" __4},\n\t{W,0,\"music/terran/1\",\"music\\\\terran1.wav\" __4},\n\t{W,0,\"music/terran/2\",\"music\\\\terran2.wav\" __4},\n\t{W,0,\"music/terran/3\",\"music\\\\terran3.wav\" __4},\n\t{W,0,\"music/terran/ready room\",\"music\\\\trdyroom.wav\" __4},\n\t{W,0,\"music/terran/victory\",\"music\\\\tvict.wav\" __4},\n\t{W,0,\"music/zerg/defeat\",\"music\\\\zdefeat.wav\" __4},\n\t{W,0,\"music/zerg/1\",\"music\\\\zerg1.wav\" __4},\n\t{W,0,\"music/zerg/2\",\"music\\\\zerg2.wav\" __4},\n\t{W,0,\"music/zerg/3\",\"music\\\\zerg3.wav\" __4},\n\t{W,0,\"music/zerg/ready room\",\"music\\\\zrdyroom.wav\" __4},\n\t{W,0,\"music/zerg/victory\",\"music\\\\zvict.wav\" __4},\n\t{W,0,\"music/protoss/defeat\",\"music\\\\pdefeat.wav\" __4},\n\t{W,0,\"music/protoss/1\",\"music\\\\protoss1.wav\" __4},\n\t{W,0,\"music/protoss/2\",\"music\\\\protoss2.wav\" __4},\n\t{W,0,\"music/protoss/3\",\"music\\\\protoss3.wav\" __4},\n\t{W,0,\"music/protoss/ready room\",\"music\\\\prdyroom.wav\" __4},\n\t{W,0,\"music/protoss/victory\",\"music\\\\pvict.wav\" __4},\n\n\t//Video\n\t{V,0,\"preprotoss_2\",\"smk\\\\preprotoss_2.smk\" __4},\n\t{V,0,\"prezerg_3\",\"smk\\\\prezerg_3.smk\" __4},\n\t{V,0,\"preterran_4\",\"smk\\\\preterran_4.smk\" __4},\n\t{V,0,\"protoss1\",\"smk\\\\protoss1.smk\" __4},\n\t{V,0,\"terran1\",\"smk\\\\terran1.smk\" __4},\n\t{V,0,\"terran3\",\"smk\\\\terran3.smk\" __4},\n\t{V,0,\"protoss2\",\"smk\\\\protoss2.smk\" __4},\n\t{V,0,\"starintr\",\"smk\\\\starintr.smk\" __4},\n\t{V,0,\"preprotoss_1\",\"smk\\\\preprotoss_1.smk\" __4},\n\t{V,0,\"preprotoss_3\",\"smk\\\\preprotoss_3.smk\" __4},\n\t{V,0,\"prezerg_4\",\"smk\\\\prezerg_4.smk\" __4},\n\t{V,0,\"preterran_3\",\"smk\\\\preterran_3.smk\" __4},\n\t{V,0,\"blizzard\",\"smk\\\\blizzard.smk\" __4},\n\t{V,0,\"preterran_1\",\"smk\\\\preterran_1.smk\" __4},\n\t{V,0,\"terran4\",\"smk\\\\terran4.smk\" __4},\n\t{V,0,\"protoss3\",\"smk\\\\protoss3.smk\" __4},\n\t{V,0,\"protoss4\",\"smk\\\\protoss4.smk\" __4},\n\t{V,0,\"prezerg_2\",\"smk\\\\prezerg_2.smk\" __4},\n\t{V,0,\"preterran_2\",\"smk\\\\preterran_2.smk\" __4},\n\t{V,0,\"terran2\",\"smk\\\\terran2.smk\" __4},\n\t{V,0,\"zerg2\",\"smk\\\\zerg2.smk\" __4},\n\t{V,0,\"zerg3\",\"smk\\\\zerg3.smk\" __4},\n\t{V,0,\"zerg4\",\"smk\\\\zerg4.smk\" __4},\n\t{V,0,\"zerg1\",\"smk\\\\zerg1.smk\" __4},\n\n\n};\n\n#endif /* STARTOOL_CD_H_ */\n"
  },
  {
    "path": "src/startool_mpq.h",
    "content": "/*\n * startool_mpq.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef STARTOOL_MPQ_H_\n#define STARTOOL_MPQ_H_\n\n#include \"startool.h\"\n\nControl Todo_bootstrap[] = {\n\n  {F,0,\"\",\"stardat.mpq\" __4},\n  {F,0,\"\",\"StarDat.mpq\" __4},\n  {F,0,\"\",\"broodat.mpq\" __4},\n  {F,0,\"\",\"BrooDat.mpq\" __4},\n  {F,0,\"\",\"remove-stardat.mpq\" __4},\n  {F,0,\"\",\"remove-broodat.mpq\" __4},\n};\n\nControl Todo[] = {\n\n//\t{G,0,\"ui/blink\",\"game\\\\blink.grp\",0 __3},\n\n\t//Video\n\t{V,0,\"blizzard\",\"smk\\\\blizzard.smk\" __4},\n\n\t// Fonts\n\t/*{N,0,\"font10\",\"font\\\\font10.fnt\" __4},\n\t{N,0,\"font12\",\"font\\\\font12.fnt\" __4},\n\t{N,0,\"font14\",\"font\\\\font14.fnt\" __4},\n\t{N,0,\"font16\",\"font\\\\font16.fnt\" __4},\n\t{N,0,\"font16x\",\"font\\\\font16x.fnt\" __4},\n\t{N,0,\"font32\",\"font\\\\font32.fnt\" __4},\n\t{N,0,\"font50\",\"font\\\\font50.fnt\" __4},\n\t{N,0,\"font8\",\"font\\\\font8.fnt\" __4},*/\n\n\t// UI\n\t{G,0,\"ui/icons\",\"game\\\\icons.grp\",5 __3},\n\t{I,0,\"ui/protoss\",\"dlgs\\\\protoss.grp\",0 __3},\n\t{I,0,\"ui/terran\",\"dlgs\\\\terran.grp\",0 __3},\n\t{I,0,\"ui/zerg\",\"dlgs\\\\zerg.grp\",0 __3},\n\n\t{H,0,\"ui/aggicons\",\"game\\\\aggicons.pcx\",0 __3},\n\t{H,0,\"ui/pconover\",\"game\\\\pconover.pcx\",0 __3},\n\t{H,0,\"ui/pconsole\",\"game\\\\pconsole.pcx\",0 __3},\n\t{H,0,\"ui/ppbrempt\",\"game\\\\ppbrempt.pcx\",0 __3},\n\t{H,0,\"ui/ppbrfull\",\"game\\\\ppbrfull.pcx\",0 __3},\n\t{H,0,\"ui/tconover\",\"game\\\\tconover.pcx\",0 __3},\n\t{H,0,\"ui/tconsole\",\"game\\\\tconsole.pcx\",0 __3},\n\t{H,0,\"ui/tpbrempt\",\"game\\\\tpbrempt.pcx\",0 __3},\n\t{H,0,\"ui/tpbrfull\",\"game\\\\tpbrfull.pcx\",0 __3},\n\t{H,0,\"ui/zconover\",\"game\\\\zconover.pcx\",0 __3},\n\t{H,0,\"ui/zconsole\",\"game\\\\zconsole.pcx\",0 __3},\n\t{H,0,\"ui/zpbrempt\",\"game\\\\zpbrempt.pcx\",0 __3},\n\t{H,0,\"ui/zpbrfull\",\"game\\\\zpbrfull.pcx\",0 __3},\n\t{H,0,\"ui/tfont\",\"glue\\\\title\\\\tFont.pcx\",0 __3},\n\t{H,0,\"ui/title\",\"glue\\\\title\\\\title.pcx\",0 __3},\n\t{H,0,\"ui/Menu background without title\",\"glue\\\\PalMm\\\\Backgnd.pcx\",0 __3},\n\n\t//mainmenu videos\n\t{P,0,\"mainmenu/editoronde\",\"glue\\\\mainmenu\\\\editoronde.smk\" __4},\n\t{P,0,\"mainmenu/editor\",\"glue\\\\mainmenu\\\\editor.smk\" __4},\n\t{P,0,\"mainmenu/exiton\",\"glue\\\\mainmenu\\\\exiton.smk\" __4},\n\t{P,0,\"mainmenu/multionit\",\"glue\\\\mainmenu\\\\multionit.smk\" __4},\n\t{P,0,\"mainmenu/singleonfr\",\"glue\\\\mainmenu\\\\singleonfr.smk\" __4},\n\t{P,0,\"mainmenu/editorones\",\"glue\\\\mainmenu\\\\editorones.smk\" __4},\n\t{P,0,\"mainmenu/exitonde\",\"glue\\\\mainmenu\\\\exitonde.smk\" __4},\n\t{P,0,\"mainmenu/exit\",\"glue\\\\mainmenu\\\\exit.smk\" __4},\n\t{P,0,\"mainmenu/multion\",\"glue\\\\mainmenu\\\\multion.smk\" __4},\n\t{P,0,\"mainmenu/singleonit\",\"glue\\\\mainmenu\\\\singleonit.smk\" __4},\n\t{P,0,\"mainmenu/editoronfr\",\"glue\\\\mainmenu\\\\editoronfr.smk\" __4},\n\t{P,0,\"mainmenu/exitones\",\"glue\\\\mainmenu\\\\exitones.smk\" __4},\n\t{P,0,\"mainmenu/multionde\",\"glue\\\\mainmenu\\\\multionde.smk\" __4},\n\t{P,0,\"mainmenu/multi\",\"glue\\\\mainmenu\\\\multi.smk\" __4},\n\t{P,0,\"mainmenu/singleon\",\"glue\\\\mainmenu\\\\singleon.smk\" __4},\n\t{P,0,\"mainmenu/editoronit\",\"glue\\\\mainmenu\\\\editoronit.smk\" __4},\n\t{P,0,\"mainmenu/exitonfr\",\"glue\\\\mainmenu\\\\exitonfr.smk\" __4},\n\t{P,0,\"mainmenu/multiones\",\"glue\\\\mainmenu\\\\multiones.smk\" __4},\n\t{P,0,\"mainmenu/singleonde\",\"glue\\\\mainmenu\\\\singleonde.smk\" __4},\n\t{P,0,\"mainmenu/single\",\"glue\\\\mainmenu\\\\single.smk\" __4},\n\t{P,0,\"mainmenu/editoron\",\"glue\\\\mainmenu\\\\editoron.smk\" __4},\n\t{P,0,\"mainmenu/exitonit\",\"glue\\\\mainmenu\\\\exitonit.smk\" __4},\n\t{P,0,\"mainmenu/multionfr\",\"glue\\\\mainmenu\\\\multionfr.smk\" __4},\n\t{P,0,\"mainmenu/singleones\",\"glue\\\\mainmenu\\\\singleones.smk\" __4},\n\n\t//race ready videos\n\t{P,0,\"readyp/ring\",\"glue\\\\readyp\\\\ring.smk\" __4},\n\t{P,0,\"readyp/glow\",\"glue\\\\readyp\\\\glow.smk\" __4},\n\t{P,0,\"readyz/start\",\"glue\\\\readyz\\\\start.smk\" __4},\n\t{P,0,\"readyz/starton\",\"glue\\\\readyz\\\\starton.smk\" __4},\n\t{P,0,\"readyz/drip\",\"glue\\\\readyz\\\\drip.smk\" __4},\n\t{P,0,\"readyt/start\",\"glue\\\\readyt\\\\start.smk\" __4},\n\t{P,0,\"readyt/starton\",\"glue\\\\readyt\\\\starton.smk\" __4},\n\t{P,0,\"readyt/proj\",\"glue\\\\readyt\\\\proj.smk\" __4},\n\t{P,0,\"readyt/proloop\",\"glue\\\\readyt\\\\proloop.smk\" __4},\n\n\t//campaign videos\n\t{P,0,\"campaign/protonde\",\"glue\\\\campaign\\\\protonde.smk\" __4},\n\t{P,0,\"campaign/terr\",\"glue\\\\campaign\\\\terr.smk\" __4},\n\t{P,0,\"campaign/protonfr\",\"glue\\\\campaign\\\\protonfr.smk\" __4},\n\t{P,0,\"campaign/terron\",\"glue\\\\campaign\\\\terron.smk\" __4},\n\t{P,0,\"campaign/terronit\",\"glue\\\\campaign\\\\terronit.smk\" __4},\n\t{P,0,\"campaign/zergon\",\"glue\\\\campaign\\\\zergon.smk\" __4},\n\t{P,0,\"campaign/zergonde\",\"glue\\\\campaign\\\\zergonde.smk\" __4},\n\t{P,0,\"campaign/terrones\",\"glue\\\\campaign\\\\terrones.smk\" __4},\n\t{P,0,\"campaign/zergones\",\"glue\\\\campaign\\\\zergones.smk\" __4},\n\t{P,0,\"campaign/terronde\",\"glue\\\\campaign\\\\terronde.smk\" __4},\n\t{P,0,\"campaign/proton\",\"glue\\\\campaign\\\\proton.smk\" __4},\n\t{P,0,\"campaign/prot\",\"glue\\\\campaign\\\\prot.smk\" __4},\n  {P,0,\"campaign/disk\",\"glue\\\\campaign\\\\disk.smk\" __4},\n  {P,0,\"campaign/zergonit\",\"glue\\\\campaign\\\\zergonit.smk\" __4},\n  {P,0,\"campaign/terronfr\",\"glue\\\\campaign\\\\terronfr.smk\" __4},\n  {P,0,\"campaign/protonit\",\"glue\\\\campaign\\\\protonit.smk\" __4},\n  {P,0,\"campaign/protones\",\"glue\\\\campaign\\\\protones.smk\" __4},\n  {P,0,\"campaign/zergonfr\",\"glue\\\\campaign\\\\zergonfr.smk\" __4},\n  {P,0,\"campaign/zerg\",\"glue\\\\campaign\\\\zerg.smk\" __4},\n\n\t// those selectors are not needed as they're drawn from the engine, remove them later\n\t/*{G,0,\"ui/o022\",\"unit\\\\thingy\\\\o022.grp\",2 __3},\n\t{G,0,\"ui/o032\",\"unit\\\\thingy\\\\o032.grp\",2 __3},\n\t{G,0,\"ui/o048\",\"unit\\\\thingy\\\\o048.grp\",2 __3},\n\t{G,0,\"ui/o062\",\"unit\\\\thingy\\\\o062.grp\",2 __3},\n\t{G,0,\"ui/o072\",\"unit\\\\thingy\\\\o072.grp\",2 __3},\n\t{G,0,\"ui/o094\",\"unit\\\\thingy\\\\o094.grp\",2 __3},\n\t{G,0,\"ui/o110\",\"unit\\\\thingy\\\\o110.grp\",2 __3},\n\t{G,0,\"ui/o122\",\"unit\\\\thingy\\\\o122.grp\",2 __3},\n\t{G,0,\"ui/o146\",\"unit\\\\thingy\\\\o146.grp\",2 __3},\n\t{G,0,\"ui/o224\",\"unit\\\\thingy\\\\o224.grp\",2 __3},\n#if 0\n\t{G,0,\"ui/od022\",\"unit\\\\thingy\\\\od022.grp\",2 __3},\n\t{G,0,\"ui/od032\",\"unit\\\\thingy\\\\od032.grp\",2 __3},\n\t{G,0,\"ui/od048\",\"unit\\\\thingy\\\\od048.grp\",2 __3},\n\t{G,0,\"ui/od062\",\"unit\\\\thingy\\\\od062.grp\",2 __3},\n\t{G,0,\"ui/od072\",\"unit\\\\thingy\\\\od072.grp\",2 __3},\n\t{G,0,\"ui/od094\",\"unit\\\\thingy\\\\od094.grp\",2 __3},\n\t{G,0,\"ui/od110\",\"unit\\\\thingy\\\\od110.grp\",2 __3},\n\t{G,0,\"ui/od122\",\"unit\\\\thingy\\\\od122.grp\",2 __3},\n\t{G,0,\"ui/od146\",\"unit\\\\thingy\\\\od146.grp\",2 __3},\n\t{G,0,\"ui/od224\",\"unit\\\\thingy\\\\od224.grp\",2 __3},\n#endif*/\n\n\t{H,0,\"terran/briefing room\",\"glue\\\\PalRt\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"terran/victory screen\",\"glue\\\\PalTv\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"terran/defeat screen\",\"glue\\\\PalTd\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"protoss/briefing room\",\"glue\\\\PalRp\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"protoss/victory screen\",\"glue\\\\PalPv\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"protoss/defeat screen\",\"glue\\\\PalPd\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"zerg/briefing room\",\"glue\\\\PalRz\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"zerg/victory screen\",\"glue\\\\PalZv\\\\Backgnd.pcx\",0 __3},\n\t{H,0,\"zerg/defeat screen\",\"glue\\\\PalZd\\\\Backgnd.pcx\",0 __3},\n\n\t{H,0,\"ui/readyt/butterr\",\"Glue\\\\ReadyT\\\\ButTerr.pcx\",0 __3},\n\t{H,0,\"ui/readyt/objterr\",\"Glue\\\\ReadyT\\\\ObjTerr.pcx\",0 __3},\n\t{H,0,\"ui/readyt/p1terr\",\"Glue\\\\ReadyT\\\\P1Terr.pcx\",0 __3},\n\t{H,0,\"ui/readyt/p2terr\",\"Glue\\\\ReadyT\\\\P2Terr.pcx\",0 __3},\n\t{H,0,\"ui/readyt/p3terr\",\"Glue\\\\ReadyT\\\\P3Terr.pcx\",0 __3},\n\t{H,0,\"ui/readyt/p4terr\",\"Glue\\\\ReadyT\\\\P4Terr.pcx\",0 __3},\n\t{H,0,\"ui/readyt/terrframe\",\"glue\\\\readyt\\\\TerrFrame.pcx\",0 __3},\n\t{H,0,\"ui/readyt/terrframeh\",\"glue\\\\readyt\\\\TerrFrameh.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframe1\",\"glue\\\\ReadyT\\\\TFrame1.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframe2\",\"glue\\\\ReadyT\\\\TFrame2.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframe3\",\"glue\\\\ReadyT\\\\TFrame3.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframe4\",\"glue\\\\ReadyT\\\\TFrame4.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframeh1\",\"glue\\\\ReadyT\\\\TFrameH1.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframeh2\",\"glue\\\\ReadyT\\\\TFrameH2.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframeh3\",\"glue\\\\ReadyT\\\\TFrameH3.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tframeh4\",\"glue\\\\ReadyT\\\\TFrameH4.pcx\",0 __3},\n\t{H,0,\"ui/readyt/tutbtn\",\"Glue\\\\ReadyT\\\\TutBtn.pcx\",0 __3},\n\n\t{G,0,\"cmdicons\",\"unit\\\\cmdbtns\\\\cmdicons.grp\",4 __3},\n\t{G,0,\"pcmdbtns\",\"unit\\\\cmdbtns\\\\pcmdbtns.grp\",4 __3},\n\t{G,0,\"tcmdbtns\",\"unit\\\\cmdbtns\\\\tcmdbtns.grp\",4 __3},\n\t{G,0,\"zcmdbtns\",\"unit\\\\cmdbtns\\\\zcmdbtns.grp\",4 __3},\n\n\t//wireframes\n\t{G,0,\"wirefram\",\"unit\\\\wirefram\\\\wirefram.grp\",6 __3},\n\t{G,0,\"tranwire\",\"unit\\\\wirefram\\\\tranwire.grp\",6 __3},\n\t{G,0,\"grpwire\",\"unit\\\\wirefram\\\\grpwire.grp\",6 __3},\n\n\t// Cursors\n\t{G,0,\"ui/cursors/arrow\",\"cursor\\\\arrow.grp\",0 __3},\n\t{G,0,\"ui/cursors/drag\",\"cursor\\\\Drag.grp\",0 __3},\n\t{G,0,\"ui/cursors/illegal\",\"cursor\\\\Illegal.grp\",0 __3},\n\t{G,0,\"ui/cursors/magg\",\"cursor\\\\MagG.grp\",0 __3},\n\t{G,0,\"ui/cursors/magr\",\"cursor\\\\MagR.grp\",0 __3},\n\t{G,0,\"ui/cursors/magy\",\"cursor\\\\MagY.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrolld\",\"cursor\\\\ScrollD.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrolldl\",\"cursor\\\\ScrollDL.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrolldr\",\"cursor\\\\ScrollDR.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrolll\",\"cursor\\\\ScrollL.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrollr\",\"cursor\\\\ScrollR.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrollu\",\"cursor\\\\ScrollU.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrollul\",\"cursor\\\\ScrollUL.grp\",0 __3},\n\t{G,0,\"ui/cursors/scrollur\",\"cursor\\\\ScrollUR.grp\",0 __3},\n\t{G,0,\"ui/cursors/targg\",\"cursor\\\\TargG.grp\",0 __3},\n\t{G,0,\"ui/cursors/targn\",\"cursor\\\\TargN.grp\",0 __3},\n\t{G,0,\"ui/cursors/targr\",\"cursor\\\\TargR.grp\",0 __3},\n\t{G,0,\"ui/cursors/targy\",\"cursor\\\\TargY.grp\",0 __3},\n\t{G,0,\"ui/cursors/time\",\"cursor\\\\Time.grp\",0 __3},\n\n\t// Game sounds\n\t{W,0,\"ui/button\",\"sound\\\\misc\\\\button.wav\" __4},\n\t{W,0,\"ui/buzz\",\"sound\\\\misc\\\\buzz.wav\" __4},\n\n\t// Tilesets\n\t{T,0,\"ashworld\",\"tileset\\\\AshWorld\" __4},\n\t{G,0,\"tilesets/ashworld/creep\",\"tileset\\\\AshWorld.grp\",1 __3},\n\n\t{T,0,\"badlands\",\"tileset\\\\badlands\" __4},\n\t{G,0,\"tilesets/badlands/creep\",\"tileset\\\\badlands.grp\",1 __3},\n\n\t{T,0,\"install\",\"tileset\\\\Install\" __4},\n\t{G,0,\"tilesets/install/creep\",\"tileset\\\\Install.grp\",1 __3},\n\n\t{T,0,\"jungle\",\"tileset\\\\Jungle\" __4},\n\t{G,0,\"tilesets/jungle/creep\",\"tileset\\\\Jungle.grp\",1 __3},\n\n\t{T,0,\"platform\",\"tileset\\\\platform\" __4},\n\t{G,0,\"tilesets/platform/creep\",\"tileset\\\\platform.grp\",1 __3},\n\n\t// Neutral\n\t/*{G,0,\"neutral/flamer\",\"unit\\\\thingy\\\\flamer.grp\",3 __3},\n\t{G,0,\"neutral/smoke\",\"unit\\\\thingy\\\\smoke.grp\",3 __3},\n\t{G,0,\"neutral/building burnc\",\"unit\\\\thingy\\\\oFireC.grp\",3 __3},\n\t{G,0,\"neutral/building burnf\",\"unit\\\\thingy\\\\oFireF.grp\",3 __3},\n\t{G,0,\"neutral/building burnv\",\"unit\\\\thingy\\\\oFireV.grp\",3 __3},*/\n\n\t/*{G,0,\"neutral/missiles/blastcan\",\"unit\\\\bullet\\\\blastcan.grp\",1 __3},\n\t{G,0,\"neutral/missiles/circle14\",\"unit\\\\bullet\\\\circle14.grp\",1 __3},\n\t{G,0,\"neutral/missiles/dragbull\",\"unit\\\\bullet\\\\dragbull.grp\",1 __3},\n\t{G,0,\"neutral/missiles/epbbul\",\"unit\\\\bullet\\\\epbBul.grp\",1 __3},\n\t{G,0,\"neutral/missiles/ephfire\",\"unit\\\\bullet\\\\ephFire.grp\",1 __3},\n\t{G,0,\"neutral/missiles/explo1\",\"unit\\\\bullet\\\\explo1.grp\",1 __3},\n\t{G,0,\"neutral/missiles/eycbull\",\"unit\\\\bullet\\\\eycBull.grp\",1 __3},\n\t{G,0,\"neutral/missiles/gemini\",\"unit\\\\bullet\\\\gemini.grp\",1 __3},\n\t{G,0,\"neutral/missiles/grenade\",\"unit\\\\bullet\\\\grenade.grp\",1 __3},\n\t{G,0,\"neutral/missiles/hks\",\"unit\\\\bullet\\\\hks.grp\",1 __3},\n\t{G,0,\"neutral/missiles/parasite\",\"unit\\\\bullet\\\\parasite.grp\",1 __3},\n\t{G,0,\"neutral/missiles/pdriphit\",\"unit\\\\bullet\\\\PDripHit.grp\",1 __3},\n\t{G,0,\"neutral/missiles/psibeam\",\"unit\\\\bullet\\\\PsiBeam.grp\",1 __3},\n\t{G,0,\"neutral/missiles/pspark\",\"unit\\\\bullet\\\\pspark.grp\",1 __3},\n\t{G,0,\"neutral/missiles/scvspark\",\"unit\\\\bullet\\\\scvspark.grp\",1 __3},\n\t{G,0,\"neutral/missiles/shockbmb\",\"unit\\\\bullet\\\\shockbmb.grp\",1 __3},\n\t{G,0,\"neutral/missiles/spore2\",\"unit\\\\bullet\\\\Spore2.grp\",1 __3},\n\t{G,0,\"neutral/missiles/spores\",\"unit\\\\bullet\\\\spores.grp\",1 __3},\n\t{G,0,\"neutral/missiles/squib1\",\"unit\\\\bullet\\\\squib1.grp\",1 __3},\n\t{G,0,\"neutral/missiles/squib2\",\"unit\\\\bullet\\\\squib2.grp\",1 __3},\n\t{G,0,\"neutral/missiles/tentacle\",\"unit\\\\bullet\\\\Tentacle.grp\",1 __3},\n\t{G,0,\"neutral/missiles/tspark\",\"unit\\\\bullet\\\\tspark.grp\",1 __3},\n\t{G,0,\"neutral/missiles/zspark\",\"unit\\\\bullet\\\\zspark.grp\",1 __3},*/\n\n\t/*{G,0,\"neutral/units/ragnasaur ashworld critter shadow\",\"unit\\\\neutral\\\\nacShad.grp\",0 __3},\n\t{G,0,\"neutral/units/rhynadon badlands critter shadow\",\"unit\\\\neutral\\\\nbcShad.grp\",0 __3},\n\t{G,0,\"neutral/units/bengalaas jungle critter shadow\",\"unit\\\\neutral\\\\njcShad.grp\",0 __3},\n\t{G,0,\"neutral/units/geyser shadow\",\"unit\\\\neutral\\\\geyShad.grp\",1 __3},\n\t{G,0,\"neutral/units/mineral1 shadow\",\"unit\\\\neutral\\\\min01Sha.grp\",1 __3},\n\t{G,0,\"neutral/units/mineral2 shadow\",\"unit\\\\neutral\\\\min02Sha.grp\",1 __3},\n\t{G,0,\"neutral/units/mineral3 shadow\",\"unit\\\\neutral\\\\min03Sha.grp\",1 __3},\n\t{G,0,\"neutral/units/crashed battlecruiser shadow\",\"unit\\\\neutral\\\\cbaShad.grp\",1 __3},\n\t{G,0,\"neutral/units/data disk shadow\",\"unit\\\\neutral\\\\nddShad.grp\",1 __3},\n\t{G,0,\"neutral/units/data disk shadow2\",\"unit\\\\neutral\\\\nddSha2.grp\",1 __3},\n\t{G,0,\"neutral/units/flag shadow\",\"unit\\\\neutral\\\\nflShad.grp\",1 __3},\n\t{G,0,\"neutral/units/flag shadow2\",\"unit\\\\neutral\\\\nflSha2.grp\",1 __3},\n\t{G,0,\"neutral/units/gas orb shadow\",\"unit\\\\neutral\\\\ngoShad.grp\",1 __3},\n\t{G,0,\"neutral/units/gas sac shadow\",\"unit\\\\neutral\\\\ngsShad.grp\",1 __3},\n\t{G,0,\"neutral/units/gas tank shadow\",\"unit\\\\neutral\\\\ngcShad.grp\",1 __3},\n\t{G,0,\"neutral/units/kerrigan chrysalis shadow\",\"unit\\\\neutral\\\\nkoShad.grp\",1 __3},\n\t{G,0,\"neutral/units/kerrigan egg shadow\",\"unit\\\\neutral\\\\nkeShad.grp\",1 __3},\n\t{G,0,\"neutral/units/kerrigan egg shadow2\",\"unit\\\\neutral\\\\nkeSha2.grp\",1 __3},\n\t{G,0,\"neutral/units/khaydarin crystal shadow2\",\"unit\\\\neutral\\\\nkhSha2.grp\",1 __3},\n\t{G,0,\"neutral/units/khaydarin crystal shadow\",\"unit\\\\neutral\\\\nkhShad.grp\",1 __3},\n\t{G,0,\"neutral/units/ore chunk shadow\",\"unit\\\\neutral\\\\norShad.grp\",1 __3},\n\t{G,0,\"neutral/units/psi emitter shadow\",\"unit\\\\neutral\\\\npsShad.grp\",1 __3},\n\t{G,0,\"neutral/units/psi emitter shadow2\",\"unit\\\\neutral\\\\npsSha2.grp\",1 __3},\n\t{G,0,\"neutral/units/starbase\",\"unit\\\\neutral\\\\starbase.grp\",1 __3},*/\n/*\n#if 0\n\t{G,0,\"neutral/units/pg1deb\",\"unit\\\\flingy\\\\pg1deb.grp\",1 __3},\n\t{G,0,\"neutral/units/pg2deb\",\"unit\\\\flingy\\\\pg2deb.grp\",1 __3},\n\t{G,0,\"neutral/units/pg3deb\",\"unit\\\\flingy\\\\pg3deb.grp\",1 __3},\n\t{G,0,\"neutral/units/pg4deb\",\"unit\\\\flingy\\\\pg4deb.grp\",1 __3},\n\t{G,0,\"neutral/units/pg5deb\",\"unit\\\\flingy\\\\pg5deb.grp\",1 __3},\n\t{G,0,\"neutral/units/pscdeb\",\"unit\\\\flingy\\\\pscdeb.grp\",1 __3},\n\t{G,0,\"neutral/units/tg5deb\",\"unit\\\\flingy\\\\tg5deb.grp\",1 __3},\n#endif\n*/\n\t/*\n\t{G,0,\"tilesets/badlands/thingy/HDRock01\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock01.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock02\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock02.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock03\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock03.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock04\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock04.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock05\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock05.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock06\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock06.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock07\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock07.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock08\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock08.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock1S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock1S.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock2S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock2S.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock3S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock3S.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDRock4S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDRock4S.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDTree01\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDTree01.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDTree02\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDTree02.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDTree03\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDTree03.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDTree04\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDTree04.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HDVent01\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HDVent01.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/HGTree01\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\HGTree01.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop01\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop01.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop02\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop02.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop03\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop03.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop04\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop04.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop05\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop05.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop06\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop06.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop07\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop07.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop08\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop08.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShop09\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShop09.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCShopAA\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCShopAA.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign01\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign01.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign02\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign02.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign03\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign03.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign04\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign04.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign05\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign05.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign06\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign06.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign07\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign07.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign08\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign08.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSign09\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSign09.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSignAA\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSignAA.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSignBB\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSignBB.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LCSignCC\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LCSignCC.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LDTree1S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LDTree1S.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LDTree2S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LDTree2S.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LDTree3S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LDTree3S.grp\",1 __3},\n\t{G,0,\"tilesets/badlands/thingy/LDTree4S\",\"unit\\\\thingy\\\\tileset\\\\Badlands\\\\LDTree4S.grp\",1 __3},\n\n\t{G,0,\"tilesets/jungle/thingy/dd025\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd025.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd026\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd026.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd027\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd027.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd028\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd028.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd029\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd029.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd030\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd030.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd031\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd031.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd055\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd055.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd056\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd056.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd075\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd075.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd076\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd076.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd077\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd077.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd078\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd078.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd079\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd079.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd080\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd080.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd081\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd081.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd091\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd091.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd203\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd203.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd204\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd204.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd205\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd205.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd206\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd206.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd207\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd207.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd209\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd209.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd210\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd210.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/dd211\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\dd211.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock01\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock01.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock02\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock02.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock03\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock03.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock04\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock04.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock1s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock1s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock2s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock2s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock3s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock3s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/HDRock4s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\HDRock4s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/JUbush01\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\JUbush01.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/JUbush03\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\JUbush03.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/JUbush05\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\JUbush05.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/JUbush1S\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\JUbush1S.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/JUbush3s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\JUbush3s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/JUbush5s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\JUbush5s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree01\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree01.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree02\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree02.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree03\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree03.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree04\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree04.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree1s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree1s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree2s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree2s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree3s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree3s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/LDtree4s\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\LDtree4s.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree01\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree01.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree02\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree02.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree03\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree03.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree04\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree04.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree1sha\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree1sha.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree2sha\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree2sha.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree3sha\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree3sha.grp\",1 __3},\n\t{G,0,\"tilesets/jungle/thingy/tree4sha\",\"unit\\\\thingy\\\\tileset\\\\Jungle\\\\tree4sha.grp\",1 __3},\n*/\n\t// Terran unit graphics\n/*\t{G,0,\"terran/units/civilian shadow\",\"unit\\\\neutral\\\\nciShad.grp\",0 __3},\n\t{G,0,\"terran/units/academy-t\",\"unit\\\\terran\\\\AcademyT.grp\",0 __3},\n\t{G,0,\"terran/units/battlecruiser glow\",\"unit\\\\thingy\\\\tbaGlow.grp\",3 __3},\n\t{G,0,\"terran/units/armory-t\",\"unit\\\\terran\\\\chemlabT.grp\",0 __3},\n\t{G,0,\"terran/units/comsat station-c\",\"unit\\\\terran\\\\ComSatC.grp\",0 __3},\n\t{G,0,\"terran/units/comsat station-t\",\"unit\\\\terran\\\\ComSatT.grp\",0 __3},\n\t{G,0,\"terran/units/command center-t\",\"unit\\\\terran\\\\controlT.grp\",  0 __3},\n\t{G,0,\"terran/units/supply depot-t\",\"unit\\\\terran\\\\DepotT.grp\",0 __3},\n\t{G,0,\"terran/units/dropship glow\",\"unit\\\\thingy\\\\tdrGlow.grp\",3 __3},\n\t{G,0,\"terran/units/control tower-c\",\"unit\\\\terran\\\\DryDockC.grp\",0 __3},\n\t{G,0,\"terran/units/control tower-t\",\"unit\\\\terran\\\\DryDockT.grp\",0 __3},\n\t{G,0,\"terran/units/factory-t\",\"unit\\\\terran\\\\factoryT.grp\",0 __3},\n\t{G,0,\"terran/units/covert ops-c\",\"unit\\\\terran\\\\GeneLabC.grp\",0 __3},\n\t{G,0,\"terran/units/covert ops-t\",\"unit\\\\terran\\\\GeneLabT.grp\",0 __3},\n\t{G,0,\"terran/units/machine shop-c\",\"unit\\\\terran\\\\machineC.grp\",0 __3},\n\t{G,0,\"terran/units/missile turret-t\",\"unit\\\\terran\\\\missileT.grp\",0 __3},\n\t{G,0,\"terran/units/nuke explosion\",\"unit\\\\thingy\\\\NukeHit.grp\",3 __3},\n\t{G,0,\"terran/units/nuclear silo-c\",\"unit\\\\terran\\\\NukeSilC.grp\",0 __3},\n\t{G,0,\"terran/units/nuclear silo-t\",\"unit\\\\terran\\\\NukeSilT.grp\",0 __3},\n\t{G,0,\"terran/units/wraith glow\",\"unit\\\\thingy\\\\tphGlow.grp\",3 __3},\n\t{G,0,\"terran/units/physics lab-c\",\"unit\\\\terran\\\\physicsC.grp\",0 __3},\n\t{G,0,\"terran/units/bunker-t\",\"unit\\\\terran\\\\PillBoxT.grp\",0 __3},\n\t{G,0,\"terran/units/science facility-t\",\"unit\\\\terran\\\\ResearcT.grp\",0 __3},\n\t{G,0,\"terran/units/scv glow\",\"unit\\\\thingy\\\\tscGlow.grp\",3 __3},\n\t{G,0,\"terran/units/starport-t\",\"unit\\\\terran\\\\StarpoT.grp\",0 __3},\n\t{G,0,\"terran/units/academy shadow\",\"unit\\\\terran\\\\tacShad.grp\",0 __3},\n\t{G,0,\"terran/units/barracks shadow\",\"unit\\\\terran\\\\tbrShad.grp\",0 __3},\n\t{G,0,\"terran/units/command center shadow\",\"unit\\\\terran\\\\tccShad.grp\",0 __3},\n\t{G,0,\"terran/units/beacon overlay\",\"unit\\\\terran\\\\tCirGlow.grp\",0 __3},\n\t{G,0,\"terran/units/armory shadow\",\"unit\\\\terran\\\\tclShad.grp\",0 __3},\n\t{G,0,\"terran/units/comsat station shadow\",\"unit\\\\terran\\\\tcsShad.grp\",0 __3},\n\t{G,0,\"terran/units/control tower shadow\",\"unit\\\\terran\\\\tddShad.grp\",0 __3},\n\t{G,0,\"terran/units/supply depot shadow\",\"unit\\\\terran\\\\tdeShad.grp\",0 __3},\n\t{G,0,\"terran/units/factory shadow\",\"unit\\\\terran\\\\tfaShad.grp\",0 __3},\n\t{G,0,\"terran/units/firebat shadow\",\"unit\\\\terran\\\\tfbShad.grp\",0 __3},\n\t{G,0,\"terran/units/ghost death\",\"unit\\\\terran\\\\tghDeath.grp\",0 __3},\n\t{G,0,\"terran/units/ghost shadow\",\"unit\\\\terran\\\\tghShad.grp\",0 __3},\n\t{G,0,\"terran/units/covert ops shadow\",\"unit\\\\terran\\\\tglShad.grp\",0 __3},\n\t{G,0,\"terran/units/goliath shadow\",\"unit\\\\terran\\\\tgoShad.grp\",0 __3},\n\t{G,0,\"terran/units/marine death\",\"unit\\\\terran\\\\tmaDeath.grp\",0 __3},\n\t{G,0,\"terran/units/marine shadow\",\"unit\\\\terran\\\\tmaShad.grp\",0 __3},\n\t{G,0,\"terran/units/missile turret shadow\",\"unit\\\\terran\\\\tmiShad.grp\",0 __3},\n\t{G,0,\"terran/units/machine shop shadow\",\"unit\\\\terran\\\\tmsShad.grp\",0 __3},\n\t{G,0,\"terran/units/nuclear silo shadow\",\"unit\\\\terran\\\\tnsShad.grp\",0 __3},\n\t{G,0,\"terran/units/bunker shadow\",\"unit\\\\terran\\\\tpbShad.grp\",0 __3},\n\t{G,0,\"terran/units/physics lab shadow\",\"unit\\\\terran\\\\tplShad.grp\",0 __3},\n\t{G,0,\"terran/units/refinery shadow\",\"unit\\\\terran\\\\treShad.grp\",0 __3},\n\t{G,0,\"terran/units/science facility shadow\",\"unit\\\\terran\\\\trlShad.grp\",0 __3},\n\t{G,0,\"terran/units/vulture spider mine shadow\",\"unit\\\\terran\\\\tsmShad.grp\",0 __3},\n\t{G,0,\"terran/units/starport shadow\",\"unit\\\\terran\\\\tspShad.grp\",0 __3},\n\t{G,0,\"terran/units/siege tank siege shadow\",\"unit\\\\terran\\\\tstShad.grp\",0 __3},\n\t{G,0,\"terran/units/siege tank tank shadow\",\"unit\\\\terran\\\\ttaShad.grp\",0 __3},\n\t{G,0,\"terran/units/science vessel shadow\",\"unit\\\\terran\\\\tveShad.grp\",0 __3},\n\t{G,0,\"terran/units/engineering bay shadow\",\"unit\\\\terran\\\\twpShad.grp\",0 __3},\n\t{G,0,\"terran/units/kerrigan shadow\",\"unit\\\\terran\\\\ughShad.grp\",0 __3},\n\t{G,0,\"terran/units/engineering bay-t\",\"unit\\\\terran\\\\weaponpT.grp\",0 __3},\n\t{G,0,\"terran/units/science vessel-t\",\"unit\\\\terran\\\\wesselt.grp\",0 __3},\n\n\t{G,0,\"terran/units/building construction large\",\"unit\\\\terran\\\\TBldLrg.grp\",0 __3},\n\t{G,0,\"terran/units/building construction medium\",\"unit\\\\terran\\\\tBldMed.grp\",0 __3},\n\t{G,0,\"terran/units/building construction small\",\"unit\\\\terran\\\\TBldSml.grp\",0 __3},\n\t{G,0,\"terran/units/building construction small shadow\",\"unit\\\\terran\\\\tb1Shad.grp\",0 __3},\n\t{G,0,\"terran/units/building construction large shadow\",\"unit\\\\terran\\\\tb2Shad.grp\",0 __3},\n\t{G,0,\"terran/units/building construction medium shadow\",\"unit\\\\terran\\\\tb3Shad.grp\",0 __3},\n\t{G,0,\"terran/units/rubble large\",\"unit\\\\thingy\\\\RubbleL.grp\",0 __3},\n\t{G,0,\"terran/units/rubble small\",\"unit\\\\thingy\\\\RubbleS.grp\",0 __3},\n\t{G,0,\"terran/explosion small\",\"unit\\\\thingy\\\\tbangs.grp\",3 __3},\n\t{G,0,\"terran/explosion medium\",\"unit\\\\thingy\\\\tbangl.grp\",3 __3},\n\t{G,0,\"terran/explosion large\",\"unit\\\\thingy\\\\tbangx.grp\",3 __3},\n\t{G,0,\"terran/spider mine explosion\",\"unit\\\\thingy\\\\tmnExplo.grp\",3 __3},\n\t{G,0,\"terran/spider mine smoke\",\"unit\\\\thingy\\\\GreSmoke.grp\",0 __3},\n\t{G,0,\"terran/spider mine hit\",\"unit\\\\thingy\\\\efgHit.grp\",3 __3},\n\t{G,0,\"terran/gemini missile trail\",\"unit\\\\thingy\\\\smoke.grp\",3 __3},\n\t{G,0,\"terran/tank turret attack overlay\",\"unit\\\\thingy\\\\esiFire.grp\",3 __3},\n\t{G,0,\"terran/tank turret attack overlay2\",\"unit\\\\thingy\\\\ettFlash.grp\",3 __3},\n\t{G,0,\"terran/laser\",\"unit\\\\thingy\\\\elbfireW.grp\",3 __3},\n\t{G,0,\"terran/laser2\",\"unit\\\\thingy\\\\elbfire.grp\",3 __3},\n*/\n\t/*\n\t// Protoss unit graphics\n\t{G,0,\"protoss/units/rubble large\",\"unit\\\\thingy\\\\prubblel.grp\",0 __3},\n\t{G,0,\"protoss/units/rubble small\",\"unit\\\\thingy\\\\prubbles.grp\",0 __3},\n\t{G,0,\"protoss/units/archon-t\",\"unit\\\\protoss\\\\archonT.grp\",0 __3},\n\t{G,0,\"protoss/units/archon-t2\",\"unit\\\\protoss\\\\archonT2.grp\",0 __3},\n\t{G,0,\"protoss/units/forge-t\",\"unit\\\\protoss\\\\forgeT.grp\",0 __3},\n\t{G,0,\"protoss/units/cybernetics core-t\",\"unit\\\\protoss\\\\gencoreT.grp\",0 __3},\n\t{G,0,\"protoss/units/lowm/texture\",\"unit\\\\protoss\\\\LowM\\\\texture.grp\",0 __3},\n\t{G,0,\"protoss/units/pacshad\",\"unit\\\\protoss\\\\pacShad.grp\",0 __3},\n\t{G,0,\"protoss/units/passhad\",\"unit\\\\protoss\\\\pasShad.grp\",0 __3},\n\t{G,0,\"protoss/units/paushad\",\"unit\\\\protoss\\\\pauShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pb1glow\",\"unit\\\\protoss\\\\pb1Glow.grp\",0 __3},\n\t{G,0,\"protoss/units/pbaglow\",\"unit\\\\protoss\\\\pbaGlow.grp\",0 __3},\n\t{G,0,\"protoss/units/pbashad\",\"unit\\\\protoss\\\\pbaShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pbeshad\",\"unit\\\\protoss\\\\pbeShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pcirglow\",\"unit\\\\protoss\\\\pCirGlow.grp\",0 __3},\n\t{G,0,\"protoss/units/pcishad\",\"unit\\\\protoss\\\\pciShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pdrdeath\",\"unit\\\\protoss\\\\pdrDeath.grp\",0 __3},\n\t{G,0,\"protoss/units/pdrshad\",\"unit\\\\protoss\\\\pdrShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pfoshad\",\"unit\\\\protoss\\\\pfoShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pgashad\",\"unit\\\\protoss\\\\pgaShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pgcshad\",\"unit\\\\protoss\\\\pgcShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pneglow\",\"unit\\\\protoss\\\\pneGlow.grp\",0 __3},\n\t{G,0,\"protoss/units/pneshad\",\"unit\\\\protoss\\\\pneShad.grp\",0 __3},\n\t{G,0,\"protoss/units/ppbshad\",\"unit\\\\protoss\\\\ppbShad.grp\",0 __3},\n\t{G,0,\"protoss/units/ppyshad\",\"unit\\\\protoss\\\\ppyShad.grp\",0 __3},\n\t{G,0,\"protoss/units/proshad\",\"unit\\\\protoss\\\\proShad.grp\",0 __3},\n\t{G,0,\"protoss/units/psgglow\",\"unit\\\\protoss\\\\psgGlow.grp\",0 __3},\n\t{G,0,\"protoss/units/psgshad\",\"unit\\\\protoss\\\\psgShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pstshad\",\"unit\\\\protoss\\\\pstShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pteshad\",\"unit\\\\protoss\\\\pteShad.grp\",0 __3},\n\t{G,0,\"protoss/units/ptrshad\",\"unit\\\\protoss\\\\ptrShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pwashad\",\"unit\\\\protoss\\\\pwaShad.grp\",0 __3},\n\t{G,0,\"protoss/units/pzeshad\",\"unit\\\\protoss\\\\pzeShad.grp\",0 __3},\n\t{G,0,\"protoss/units/texture\",\"unit\\\\protoss\\\\texture.grp\",0 __3},\n\t{G,0,\"protoss/units/shield\",\"unit\\\\thingy\\\\pshield.grp\",0 __3},\n\t{G,0,\"protoss/units/bluetrail\",\"unit\\\\thingy\\\\HKTrail.grp\",0 __3},\n\t{G,0,\"protoss/units/scout glow\",\"unit\\\\thingy\\\\pscGlow.grp\",0 __3},\n\t{G,0,\"protoss/units/shuttle glow\",\"unit\\\\thingy\\\\pshGlow.grp\",0 __3},\n\t{G,0,\"protoss/units/carrier glow\",\"unit\\\\thingy\\\\pcaGlow.grp\",0 __3},\n\t{G,0,\"protoss/units/scarab explode\",\"unit\\\\thingy\\\\psaExplo.grp\",0 __3},\n\t{G,0,\"protoss/units/anti-matter missle\",\"unit\\\\thingy\\\\HKexplod.grp\",0 __3},\n\t{G,0,\"protoss/units/plasma shields\",\"unit\\\\thingy\\\\plasma.grp\",0 __3},\n\t{G,0,\"protoss/units/psionic shock wave\",\"unit\\\\thingy\\\\emsHit.grp\",0 __3},\n\t{G,0,\"protoss/units/haluciantion cast\",\"unit\\\\thingy\\\\eveCast.grp\",0 __3},\n\t{G,0,\"protoss/units/halucination cast 2\",\"unit\\\\thingy\\\\halmind.grp\",0 __3},\n\t{G,0,\"protoss/units/psionic storm\",\"unit\\\\thingy\\\\psiStorm.grp\",0 __3},\n\n\t// Zerg unit graphics\n\t{G,0,\"zerg/units/rubble large\",\"unit\\\\thingy\\\\ZRubbleL.grp\",0 __3},\n\t{G,0,\"zerg/units/rubble small\",\"unit\\\\thingy\\\\ZRubbleS.grp\",0 __3},\n\t{G,0,\"zerg/units/scourge birth\",\"unit\\\\zerg\\\\zavBirth.grp\",0 __3},\n\t{G,0,\"zerg/units/scourge death\",\"unit\\\\zerg\\\\zavDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/scourge explosion\",\"unit\\\\zerg\\\\zavExplo.grp\",0 __3},\n\t{G,0,\"zerg/units/broodling shadow\",\"unit\\\\zerg\\\\zbrShad.grp\",0 __3},\n\t{G,0,\"zerg/units/broodling death\",\"unit\\\\zerg\\\\zbrDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/infested terran shadow\",\"unit\\\\zerg\\\\zbgShad.grp\",0 __3},\n\t{G,0,\"zerg/units/evolution chamber shadow\",\"unit\\\\zerg\\\\zceShad.grp\",0 __3},\n\t{G,0,\"zerg/units/spawning pool shadow\",\"unit\\\\zerg\\\\zchShad.grp\",0 __3},\n\t{G,0,\"zerg/units/defiler birth\",\"unit\\\\zerg\\\\zdebirth.grp\",0 __3},\n\t{G,0,\"zerg/units/defiler death\",\"unit\\\\zerg\\\\zdeDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/drone birth\",\"unit\\\\zerg\\\\zdrbirth.grp\",0 __3},\n\t{G,0,\"zerg/units/drone death\",\"unit\\\\zerg\\\\zdrDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/egg shadow\",\"unit\\\\zerg\\\\zegShad.grp\",0 __3},\n\t{G,0,\"zerg/units/egg spawn\",\"unit\\\\zerg\\\\zegspawn.grp\",0 __3},\n\t{G,0,\"zerg/units/egg death\",\"unit\\\\zerg\\\\zegDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/extractor shadow\",\"unit\\\\zerg\\\\zreShad.grp\",0 __3},\n\t{G,0,\"zerg/units/creep colony shadow\",\"unit\\\\zerg\\\\zfcShad.grp\",0 __3},\n\t{G,0,\"zerg/units/guardian death\",\"unit\\\\zerg\\\\zguDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/hatchery shadow\",\"unit\\\\zerg\\\\zhaShad.grp\",0 __3},\n\t{G,0,\"zerg/units/hive shadow\",\"unit\\\\zerg\\\\zhiShad.grp\",0 __3},\n\t{G,0,\"zerg/units/hydralisk shadow\",\"unit\\\\zerg\\\\zhyShad.grp\",0 __3},\n\t{G,0,\"zerg/units/hydralisk birth\",\"unit\\\\zerg\\\\zhybirth.grp\",0 __3},\n\t{G,0,\"zerg/units/hydralisk death\",\"unit\\\\zerg\\\\zhyDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/infested command center\",\"unit\\\\zerg\\\\Infest03.grp\",0 __3},\n\t{G,0,\"zerg/units/lair shadow\",\"unit\\\\zerg\\\\zlrShad.grp\",0 __3},\n\t{G,0,\"zerg/units/larva death\",\"unit\\\\zerg\\\\zlaDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/sunken colony shadow\",\"unit\\\\zerg\\\\zluShad.grp\",0 __3},\n\t{G,0,\"zerg/units/greater spire shadow\",\"unit\\\\zerg\\\\zmcShad.grp\",0 __3},\n\t{G,0,\"zerg/units/mutalisk birth\",\"unit\\\\zerg\\\\zmubirth.grp\",0 __3},\n\t{G,0,\"zerg/units/mutalisk death\",\"unit\\\\zerg\\\\zmuDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/defiler mound shadow\",\"unit\\\\zerg\\\\zmhShad.grp\",0 __3},\n\t{G,0,\"zerg/units/queen's nest shadow\",\"unit\\\\zerg\\\\zneShad.grp\",0 __3},\n\t{G,0,\"zerg/units/nydus canal shadow\",\"unit\\\\zerg\\\\znyShad.grp\",0 __3},\n\t{G,0,\"zerg/units/overmind shell shadow\",\"unit\\\\zerg\\\\zo1Shad.grp\",0 __3},\n\t{G,0,\"zerg/units/overmind shadow\",\"unit\\\\zerg\\\\zo2Shad.grp\",0 __3},\n\t{G,0,\"zerg/units/overlord birth\",\"unit\\\\zerg\\\\zovBirth.grp\",0 __3},\n\t{G,0,\"zerg/units/overlord death\",\"unit\\\\zerg\\\\zovDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/queen birth\",\"unit\\\\zerg\\\\zquBirth.grp\",0 __3},\n\t{G,0,\"zerg/units/queen death\",\"unit\\\\zerg\\\\zquDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/ultralisk cavern shadow\",\"unit\\\\zerg\\\\zrcShad.grp\",0 __3},\n\t{G,0,\"zerg/units/spore colony shadow\",\"unit\\\\zerg\\\\zscShad.grp\",0 __3},\n\t{G,0,\"zerg/units/zergling shadow\",\"unit\\\\zerg\\\\zzeShad.grp\",0 __3},\n\t{G,0,\"zerg/units/zergling birth\",\"unit\\\\zerg\\\\zzebirth.grp\",0 __3},\n\t{G,0,\"zerg/units/zergling death\",\"unit\\\\zerg\\\\zzeDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/hydralisk den shadow\",\"unit\\\\zerg\\\\zsbShad.grp\",0 __3},\n\t{G,0,\"zerg/units/spire shadow\",\"unit\\\\zerg\\\\zspShad.grp\",0 __3},\n\t{G,0,\"zerg/units/cerebrate shadow\",\"unit\\\\zerg\\\\zucShad.grp\",0 __3},\n\t{G,0,\"zerg/units/infested kerrigan shadow\",\"unit\\\\zerg\\\\uikShad.grp\",0 __3},\n\t{G,0,\"zerg/units/ultralisk shadow\",\"unit\\\\zerg\\\\zulShad.grp\",0 __3},\n\t{G,0,\"zerg/units/ultralisk birth\",\"unit\\\\zerg\\\\zulbirth.grp\",0 __3},\n\t{G,0,\"zerg/units/ultralisk death\",\"unit\\\\zerg\\\\zulDeath.grp\",0 __3},\n\t{G,0,\"zerg/units/building morph\",\"unit\\\\zerg\\\\ZBuild.grp\",0 __3},\n\t{G,0,\"zerg/units/building morph shadow\",\"unit\\\\zerg\\\\ZBShad.grp\",0 __3},\n\t{G,0,\"zerg/units/beacon overlay\",\"unit\\\\zerg\\\\zCirGlow.grp\",0 __3},\n\t{G,0,\"zerg/units/building spawn1\",\"unit\\\\zerg\\\\zSpawn01.grp\",0 __3},\n\t{G,0,\"zerg/units/building spawn2\",\"unit\\\\zerg\\\\zSpawn02.grp\",0 __3},\n\t{G,0,\"zerg/units/building spawn3\",\"unit\\\\zerg\\\\zSpawn03.grp\",0 __3},\n\t{G,0,\"zerg/units/building blood1\",\"unit\\\\thingy\\\\bblood01.grp\",0 __3},\n\t{G,0,\"zerg/units/building blood2\",\"unit\\\\thingy\\\\bblood02.grp\",0 __3},\n\t{G,0,\"zerg/units/building blood3\",\"unit\\\\thingy\\\\bblood03.grp\",0 __3},\n\t{G,0,\"zerg/units/building blood4\",\"unit\\\\thingy\\\\bblood04.grp\",0 __3},\n\t{G,0,\"zerg/units/bdust\",\"unit\\\\thingy\\\\bDust.grp\",0 __3},\n\t{G,0,\"zerg/units/spores\",\"unit\\\\thingy\\\\gSmoke.grp\",0 __3},\n\t{G,0,\"zerg/units/glave wurm\",\"unit\\\\thingy\\\\SpoTrail.grp\",0 __3},\n\t{G,0,\"zerg/units/guardian attack overlay\",\"unit\\\\thingy\\\\eplMuzz.grp\",0 __3},\n*/\n\t// Terran sounds\n\t{W,0,\"terran/building place\",\"sound\\\\misc\\\\tbldgplc.wav\" __4},\n\t{W,0,\"terran/on fire large\",\"sound\\\\terran\\\\bldg\\\\onfirlrg.wav\" __4},\n\t{W,0,\"terran/land\",\"sound\\\\misc\\\\land.wav\" __4},\n\t{W,0,\"terran/liftoff\",\"sound\\\\misc\\\\liftoff.wav\" __4},\n\t{W,0,\"terran/power down\",\"sound\\\\misc\\\\tpwrdown.wav\" __4},\n\t{W,0,\"terran/rescue\",\"sound\\\\misc\\\\trescue.wav\" __4},\n\t{W,0,\"terran/units/advisor/err00\",\"sound\\\\terran\\\\advisor\\\\taderr00.wav\" __4},\n\t{W,0,\"terran/units/advisor/err01\",\"sound\\\\terran\\\\advisor\\\\taderr01.wav\" __4},\n\t{W,0,\"terran/units/advisor/err02\",\"sound\\\\terran\\\\advisor\\\\taderr02.wav\" __4},\n\t{W,0,\"terran/units/advisor/err03\",\"sound\\\\terran\\\\advisor\\\\taderr03.wav\" __4},\n\t{W,0,\"terran/units/advisor/err04\",\"sound\\\\terran\\\\advisor\\\\taderr04.wav\" __4},\n\t{W,0,\"terran/units/advisor/err06\",\"sound\\\\terran\\\\advisor\\\\taderr06.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd00\",\"sound\\\\terran\\\\advisor\\\\tadupd00.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd01\",\"sound\\\\terran\\\\advisor\\\\tadupd01.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd02\",\"sound\\\\terran\\\\advisor\\\\tadupd02.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd03\",\"sound\\\\terran\\\\advisor\\\\tadupd03.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd04\",\"sound\\\\terran\\\\advisor\\\\tadupd04.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd05\",\"sound\\\\terran\\\\advisor\\\\tadupd05.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd06\",\"sound\\\\terran\\\\advisor\\\\tadupd06.wav\" __4},\n\t{W,0,\"terran/units/advisor/upd07\",\"sound\\\\terran\\\\advisor\\\\tadupd07.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/death/1\",\"sound\\\\terran\\\\battle\\\\tbadth00.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/pissed/1\",\"sound\\\\terran\\\\battle\\\\tbapss00.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/pissed/2\",\"sound\\\\terran\\\\battle\\\\tbapss01.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/pissed/3\",\"sound\\\\terran\\\\battle\\\\tbapss02.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/pissed/4\",\"sound\\\\terran\\\\battle\\\\tbapss03.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/pissed/5\",\"sound\\\\terran\\\\battle\\\\tbapss04.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/ready\",\"sound\\\\terran\\\\battle\\\\tbardy00.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/selected/1\",\"sound\\\\terran\\\\battle\\\\tbawht00.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/selected/2\",\"sound\\\\terran\\\\battle\\\\tbawht01.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/selected/3\",\"sound\\\\terran\\\\battle\\\\tbawht02.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/selected/4\",\"sound\\\\terran\\\\battle\\\\tbawht03.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/yam01\",\"sound\\\\terran\\\\battle\\\\tbayam01.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/yam02\",\"sound\\\\terran\\\\battle\\\\tbayam02.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/acknowledgement/1\",\"sound\\\\terran\\\\battle\\\\tbayes00.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/acknowledgement/2\",\"sound\\\\terran\\\\battle\\\\tbayes01.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/acknowledgement/3\",\"sound\\\\Terran\\\\BATTLE\\\\tbayes02.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/acknowledgement/4\",\"sound\\\\terran\\\\battle\\\\tbayes03.wav\" __4},\n\t{W,0,\"terran/units/battlecruiser/yamato\",\"sound\\\\Bullet\\\\tbaYam00.wav\" __4},\n\t{W,0,\"terran/units/civilian/death/1\",\"sound\\\\terran\\\\civilian\\\\tcvdth00.wav\" __4},\n\t{W,0,\"terran/units/civilian/pissed/1\",\"sound\\\\terran\\\\civilian\\\\tcvpss00.wav\" __4},\n\t{W,0,\"terran/units/civilian/pissed/2\",\"sound\\\\terran\\\\civilian\\\\tcvpss01.wav\" __4},\n\t{W,0,\"terran/units/civilian/pissed/3\",\"sound\\\\terran\\\\civilian\\\\tcvpss02.wav\" __4},\n\t{W,0,\"terran/units/civilian/pissed/4\",\"sound\\\\terran\\\\civilian\\\\tcvpss03.wav\" __4},\n\t{W,0,\"terran/units/civilian/pissed/5\",\"sound\\\\terran\\\\civilian\\\\tcvpss04.wav\" __4},\n\t{W,0,\"terran/units/civilian/ready\",\"sound\\\\terran\\\\civilian\\\\tcvrdy00.wav\" __4},\n\t{W,0,\"terran/units/civilian/selected/1\",\"sound\\\\terran\\\\civilian\\\\tcvwht00.wav\" __4},\n\t{W,0,\"terran/units/civilian/selected/2\",\"sound\\\\terran\\\\civilian\\\\tcvwht01.wav\" __4},\n\t{W,0,\"terran/units/civilian/selected/3\",\"sound\\\\terran\\\\civilian\\\\tcvwht02.wav\" __4},\n\t{W,0,\"terran/units/civilian/selected/4\",\"sound\\\\terran\\\\civilian\\\\tcvwht03.wav\" __4},\n\t{W,0,\"terran/units/civilian/acknowledgement/1\",\"sound\\\\terran\\\\civilian\\\\tcvyes00.wav\" __4},\n\t{W,0,\"terran/units/civilian/acknowledgement/2\",\"sound\\\\terran\\\\civilian\\\\tcvyes01.wav\" __4},\n\t{W,0,\"terran/units/civilian/acknowledgement/3\",\"sound\\\\terran\\\\civilian\\\\tcvyes02.wav\" __4},\n\t{W,0,\"terran/units/civilian/acknowledgement/4\",\"sound\\\\terran\\\\civilian\\\\tcvyes03.wav\" __4},\n\t{W,0,\"terran/units/civilian/acknowledgement/5\",\"sound\\\\terran\\\\civilian\\\\tcvyes04.wav\" __4},\n\t{W,0,\"terran/units/dropship/death/1\",\"sound\\\\terran\\\\dropship\\\\tdrdth00.wav\" __4},\n\t{W,0,\"terran/units/dropship/pissed/1\",\"sound\\\\terran\\\\dropship\\\\tdrpss00.wav\" __4},\n\t{W,0,\"terran/units/dropship/pissed/2\",\"sound\\\\terran\\\\dropship\\\\tdrpss01.wav\" __4},\n\t{W,0,\"terran/units/dropship/pissed/3\",\"sound\\\\terran\\\\dropship\\\\tdrpss02.wav\" __4},\n\t{W,0,\"terran/units/dropship/pissed/4\",\"sound\\\\terran\\\\dropship\\\\tdrpss03.wav\" __4},\n\t{W,0,\"terran/units/dropship/ready\",\"sound\\\\terran\\\\dropship\\\\tdrrdy00.wav\" __4},\n\t{W,0,\"terran/units/dropship/selected/1\",\"sound\\\\terran\\\\dropship\\\\tdrwht00.wav\" __4},\n\t{W,0,\"terran/units/dropship/selected/2\",\"sound\\\\terran\\\\dropship\\\\tdrwht01.wav\" __4},\n\t{W,0,\"terran/units/dropship/selected/3\",\"sound\\\\terran\\\\dropship\\\\tdrwht02.wav\" __4},\n\t{W,0,\"terran/units/dropship/selected/4\",\"sound\\\\terran\\\\dropship\\\\tdrwht03.wav\" __4},\n\t{W,0,\"terran/units/dropship/acknowledgement/1\",\"sound\\\\terran\\\\dropship\\\\tdryes00.wav\" __4},\n\t{W,0,\"terran/units/dropship/acknowledgement/2\",\"sound\\\\terran\\\\dropship\\\\tdryes01.wav\" __4},\n\t{W,0,\"terran/units/dropship/acknowledgement/3\",\"sound\\\\terran\\\\dropship\\\\tdryes02.wav\" __4},\n\t{W,0,\"terran/units/dropship/acknowledgement/4\",\"sound\\\\terran\\\\dropship\\\\tdryes03.wav\" __4},\n\t{W,0,\"terran/units/dropship/acknowledgement/5\",\"sound\\\\terran\\\\dropship\\\\tdryes04.wav\" __4},\n\t{W,0,\"terran/units/dropship/acknowledgement/6\",\"sound\\\\terran\\\\dropship\\\\tdryes05.wav\" __4},\n\t{W,0,\"terran/units/dropship/load\",\"sound\\\\Misc\\\\TDrTra00.wav\" __4},\n\t{W,0,\"terran/units/dropship/unload\",\"sound\\\\Misc\\\\TDrTra01.wav\" __4},\n\t{W,0,\"terran/units/dukeb/death/1\",\"sound\\\\terran\\\\dukeb\\\\ududth00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/1\",\"sound\\\\terran\\\\dukeb\\\\udupss00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/2\",\"sound\\\\terran\\\\dukeb\\\\udupss01.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/3\",\"sound\\\\terran\\\\dukeb\\\\udupss02.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/4\",\"sound\\\\terran\\\\dukeb\\\\udupss03.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/5\",\"sound\\\\terran\\\\dukeb\\\\udupss04.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/1\",\"sound\\\\terran\\\\dukeb\\\\uduwht00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/2\",\"sound\\\\terran\\\\dukeb\\\\uduwht01.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/3\",\"sound\\\\terran\\\\dukeb\\\\uduwht02.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/4\",\"sound\\\\terran\\\\dukeb\\\\uduwht03.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/1\",\"sound\\\\terran\\\\dukeb\\\\uduyes00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/2\",\"sound\\\\terran\\\\dukeb\\\\uduyes01.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/3\",\"sound\\\\terran\\\\dukeb\\\\uduyes02.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/4\",\"sound\\\\terran\\\\dukeb\\\\uduyes03.wav\" __4},\n\t{W,0,\"terran/units/dukeb/death/1\",\"sound\\\\terran\\\\duket\\\\udtdth00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/1\",\"sound\\\\terran\\\\duket\\\\udtpss00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/2\",\"sound\\\\terran\\\\duket\\\\udtpss01.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/3\",\"sound\\\\terran\\\\duket\\\\udtpss02.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/4\",\"sound\\\\terran\\\\duket\\\\udtpss03.wav\" __4},\n\t{W,0,\"terran/units/dukeb/pissed/5\",\"sound\\\\terran\\\\duket\\\\udtpss04.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/1\",\"sound\\\\terran\\\\duket\\\\udtwht00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/2\",\"sound\\\\terran\\\\duket\\\\udtwht01.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/3\",\"sound\\\\terran\\\\duket\\\\udtwht02.wav\" __4},\n\t{W,0,\"terran/units/dukeb/selected/4\",\"sound\\\\terran\\\\duket\\\\udtwht03.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/1\",\"sound\\\\terran\\\\duket\\\\udtyes00.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/2\",\"sound\\\\terran\\\\duket\\\\udtyes01.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/3\",\"sound\\\\terran\\\\duket\\\\udtyes02.wav\" __4},\n\t{W,0,\"terran/units/dukeb/acknowledgement/4\",\"sound\\\\terran\\\\duket\\\\udtyes03.wav\" __4},\n\t{W,0,\"terran/units/firebat/death/1\",\"sound\\\\terran\\\\firebat\\\\tfbdth00.wav\" __4},\n\t{W,0,\"terran/units/firebat/death/2\",\"sound\\\\terran\\\\firebat\\\\tfbdth01.wav\" __4},\n\t{W,0,\"terran/units/firebat/death/3\",\"sound\\\\terran\\\\firebat\\\\tfbdth02.wav\" __4},\n\t{W,0,\"terran/units/firebat/fire1\",\"sound\\\\terran\\\\firebat\\\\tfbfir00.wav\" __4},\n\t{W,0,\"terran/units/firebat/fire2\",\"sound\\\\terran\\\\firebat\\\\tfbfir01.wav\" __4},\n\t{W,0,\"terran/units/firebat/pissed/1\",\"sound\\\\terran\\\\firebat\\\\tfbpss00.wav\" __4},\n\t{W,0,\"terran/units/firebat/pissed/2\",\"sound\\\\terran\\\\firebat\\\\tfbpss01.wav\" __4},\n\t{W,0,\"terran/units/firebat/pissed/3\",\"sound\\\\terran\\\\firebat\\\\tfbpss02.wav\" __4},\n\t{W,0,\"terran/units/firebat/pissed/4\",\"sound\\\\terran\\\\firebat\\\\tfbpss03.wav\" __4},\n\t{W,0,\"terran/units/firebat/pissed/5\",\"sound\\\\terran\\\\firebat\\\\tfbpss04.wav\" __4},\n\t{W,0,\"terran/units/firebat/pissed/6\",\"sound\\\\terran\\\\firebat\\\\tfbpss05.wav\" __4},\n\t{W,0,\"terran/units/firebat/pissed/7\",\"sound\\\\terran\\\\firebat\\\\tfbpss06.wav\" __4},\n\t{W,0,\"terran/units/firebat/ready\",\"sound\\\\terran\\\\firebat\\\\tfbrdy00.wav\" __4},\n\t{W,0,\"terran/units/firebat/selected/1\",\"sound\\\\terran\\\\firebat\\\\tfbwht00.wav\" __4},\n\t{W,0,\"terran/units/firebat/selected/2\",\"sound\\\\terran\\\\firebat\\\\tfbwht01.wav\" __4},\n\t{W,0,\"terran/units/firebat/selected/3\",\"sound\\\\terran\\\\firebat\\\\tfbwht02.wav\" __4},\n\t{W,0,\"terran/units/firebat/selected/4\",\"sound\\\\terran\\\\firebat\\\\tfbwht03.wav\" __4},\n\t{W,0,\"terran/units/firebat/acknowledgement/1\",\"sound\\\\terran\\\\firebat\\\\tfbyes00.wav\" __4},\n\t{W,0,\"terran/units/firebat/acknowledgement/2\",\"sound\\\\terran\\\\firebat\\\\tfbyes01.wav\" __4},\n\t{W,0,\"terran/units/firebat/acknowledgement/3\",\"sound\\\\terran\\\\firebat\\\\tfbyes02.wav\" __4},\n\t{W,0,\"terran/units/firebat/acknowledgement/4\",\"sound\\\\terran\\\\firebat\\\\tfbyes03.wav\" __4},\n\t{W,0,\"terran/units/ghost/death/1\",\"sound\\\\terran\\\\ghost\\\\tghdth00.wav\" __4},\n\t{W,0,\"terran/units/ghost/death/2\",\"sound\\\\terran\\\\ghost\\\\tghdth01.wav\" __4},\n\t{W,0,\"terran/units/ghost/las00\",\"sound\\\\terran\\\\ghost\\\\tghlas00.wav\" __4},\n\t{W,0,\"terran/units/ghost/lockdown\",\"sound\\\\terran\\\\ghost\\\\tghlkd00.wav\" __4},\n\t{W,0,\"terran/units/ghost/pissed/1\",\"sound\\\\terran\\\\ghost\\\\tghpss00.wav\" __4},\n\t{W,0,\"terran/units/ghost/pissed/2\",\"sound\\\\terran\\\\ghost\\\\tghpss01.wav\" __4},\n\t{W,0,\"terran/units/ghost/pissed/3\",\"sound\\\\terran\\\\ghost\\\\tghpss02.wav\" __4},\n\t{W,0,\"terran/units/ghost/pissed/4\",\"sound\\\\terran\\\\ghost\\\\tghpss03.wav\" __4},\n\t{W,0,\"terran/units/ghost/ready\",\"sound\\\\terran\\\\ghost\\\\tghrdy00.wav\" __4},\n\t{W,0,\"terran/units/ghost/selected/1\",\"sound\\\\terran\\\\ghost\\\\tghwht00.wav\" __4},\n\t{W,0,\"terran/units/ghost/selected/2\",\"sound\\\\terran\\\\ghost\\\\tghwht01.wav\" __4},\n\t{W,0,\"terran/units/ghost/selected/3\",\"sound\\\\terran\\\\ghost\\\\tghwht02.wav\" __4},\n\t{W,0,\"terran/units/ghost/selected/4\",\"sound\\\\Terran\\\\GHOST\\\\TGhWht03.wav\" __4},\n\t{W,0,\"terran/units/ghost/acknowledgement/1\",\"sound\\\\terran\\\\ghost\\\\tghyes00.wav\" __4},\n\t{W,0,\"terran/units/ghost/acknowledgement/2\",\"sound\\\\terran\\\\ghost\\\\tghyes01.wav\" __4},\n\t{W,0,\"terran/units/ghost/acknowledgement/3\",\"sound\\\\terran\\\\ghost\\\\tghyes02.wav\" __4},\n\t{W,0,\"terran/units/ghost/acknowledgement/4\",\"sound\\\\terran\\\\ghost\\\\tghyes03.wav\" __4},\n\t{W,0,\"terran/units/ghost/fire\",\"sound\\\\bullet\\\\tghfir00.wav\" __4},\n\t{W,0,\"terran/units/goliath/death/1\",\"sound\\\\terran\\\\goliath\\\\tgodth00.wav\" __4},\n\t{W,0,\"terran/units/goliath/pissed/1\",\"sound\\\\terran\\\\goliath\\\\tgopss00.wav\" __4},\n\t{W,0,\"terran/units/goliath/pissed/2\",\"sound\\\\terran\\\\goliath\\\\tgopss01.wav\" __4},\n\t{W,0,\"terran/units/goliath/pissed/3\",\"sound\\\\terran\\\\goliath\\\\tgopss02.wav\" __4},\n\t{W,0,\"terran/units/goliath/pissed/4\",\"sound\\\\terran\\\\goliath\\\\tgopss03.wav\" __4},\n\t{W,0,\"terran/units/goliath/pissed/5\",\"sound\\\\terran\\\\goliath\\\\tgopss04.wav\" __4},\n\t{W,0,\"terran/units/goliath/pissed/6\",\"sound\\\\terran\\\\goliath\\\\tgopss05.wav\" __4},\n\t{W,0,\"terran/units/goliath/ready\",\"sound\\\\Terran\\\\GOLIATH\\\\TGoRdy00.wav\" __4},\n\t{W,0,\"terran/units/goliath/selected/1\",\"sound\\\\terran\\\\goliath\\\\tgowht00.wav\" __4},\n\t{W,0,\"terran/units/goliath/selected/2\",\"sound\\\\terran\\\\goliath\\\\tgowht01.wav\" __4},\n\t{W,0,\"terran/units/goliath/selected/3\",\"sound\\\\terran\\\\goliath\\\\tgowht02.wav\" __4},\n\t{W,0,\"terran/units/goliath/selected/4\",\"sound\\\\terran\\\\goliath\\\\tgowht03.wav\" __4},\n\t{W,0,\"terran/units/goliath/acknowledgement/1\",\"sound\\\\terran\\\\goliath\\\\tgoyes00.wav\" __4},\n\t{W,0,\"terran/units/goliath/acknowledgement/2\",\"sound\\\\terran\\\\goliath\\\\tgoyes01.wav\" __4},\n\t{W,0,\"terran/units/goliath/acknowledgement/3\",\"sound\\\\terran\\\\goliath\\\\tgoyes02.wav\" __4},\n\t{W,0,\"terran/units/goliath/acknowledgement/4\",\"sound\\\\terran\\\\goliath\\\\tgoyes03.wav\" __4},\n\t{W,0,\"terran/units/goliath/fire2\",\"sound\\\\bullet\\\\tgofi200.wav\" __4},\n\t{W,0,\"terran/units/goliath/fire\",\"sound\\\\bullet\\\\tgofir00.wav\" __4},\n\t{W,0,\"terran/units/goliath/hkmissile\",\"sound\\\\bullet\\\\hkmissle.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/death/1\",\"sound\\\\terran\\\\kerrigan\\\\ukedth00.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/death/2\",\"sound\\\\terran\\\\kerrigan\\\\ukedth01.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/pissed/1\",\"sound\\\\terran\\\\kerrigan\\\\ukepss00.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/pissed/2\",\"sound\\\\terran\\\\kerrigan\\\\ukepss01.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/pissed/3\",\"sound\\\\terran\\\\kerrigan\\\\ukepss02.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/pissed/4\",\"sound\\\\terran\\\\kerrigan\\\\ukepss03.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/pissed/5\",\"sound\\\\terran\\\\kerrigan\\\\ukepss04.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/selected/1\",\"sound\\\\terran\\\\kerrigan\\\\ukewht00.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/selected/2\",\"sound\\\\terran\\\\kerrigan\\\\ukewht01.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/selected/3\",\"sound\\\\terran\\\\kerrigan\\\\ukewht02.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/selected/4\",\"sound\\\\terran\\\\kerrigan\\\\ukewht03.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/acknowledgement/1\",\"sound\\\\terran\\\\kerrigan\\\\ukeyes00.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/acknowledgement/2\",\"sound\\\\terran\\\\kerrigan\\\\ukeyes01.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/acknowledgement/3\",\"sound\\\\terran\\\\kerrigan\\\\ukeyes02.wav\" __4},\n\t{W,0,\"terran/units/kerrigan/acknowledgement/4\",\"sound\\\\terran\\\\kerrigan\\\\ukeyes03.wav\" __4},\n\t{W,0,\"terran/units/marine/death/1\",\"sound\\\\terran\\\\marine\\\\tmadth00.wav\" __4},\n\t{W,0,\"terran/units/marine/death/2\",\"sound\\\\terran\\\\marine\\\\tmadth01.wav\" __4},\n\t{W,0,\"terran/units/marine/pissed/1\",\"sound\\\\terran\\\\marine\\\\tmapss00.wav\" __4},\n\t{W,0,\"terran/units/marine/pissed/2\",\"sound\\\\terran\\\\marine\\\\tmapss01.wav\" __4},\n\t{W,0,\"terran/units/marine/pissed/3\",\"sound\\\\terran\\\\marine\\\\tmapss02.wav\" __4},\n\t{W,0,\"terran/units/marine/pissed/4\",\"sound\\\\terran\\\\marine\\\\tmapss03.wav\" __4},\n\t{W,0,\"terran/units/marine/pissed/5\",\"sound\\\\terran\\\\marine\\\\tmapss04.wav\" __4},\n\t{W,0,\"terran/units/marine/pissed/6\",\"sound\\\\terran\\\\marine\\\\tmapss05.wav\" __4},\n\t{W,0,\"terran/units/marine/pissed/7\",\"sound\\\\terran\\\\marine\\\\tmapss06.wav\" __4},\n\t{W,0,\"terran/units/marine/ready\",\"sound\\\\terran\\\\marine\\\\tmardy00.wav\" __4},\n\t{W,0,\"terran/units/marine/sti00\",\"sound\\\\terran\\\\marine\\\\tmasti00.wav\" __4},\n\t{W,0,\"terran/units/marine/sti01\",\"sound\\\\terran\\\\marine\\\\tmasti01.wav\" __4},\n\t{W,0,\"terran/units/marine/selected/1\",\"sound\\\\terran\\\\marine\\\\tmawht00.wav\" __4},\n\t{W,0,\"terran/units/marine/selected/2\",\"sound\\\\terran\\\\marine\\\\tmawht01.wav\" __4},\n\t{W,0,\"terran/units/marine/selected/3\",\"sound\\\\terran\\\\marine\\\\tmawht02.wav\" __4},\n\t{W,0,\"terran/units/marine/selected/4\",\"sound\\\\terran\\\\marine\\\\tmawht03.wav\" __4},\n\t{W,0,\"terran/units/marine/acknowledgement/1\",\"sound\\\\terran\\\\marine\\\\tmayes00.wav\" __4},\n\t{W,0,\"terran/units/marine/acknowledgement/2\",\"sound\\\\terran\\\\marine\\\\tmayes01.wav\" __4},\n\t{W,0,\"terran/units/marine/acknowledgement/3\",\"sound\\\\terran\\\\marine\\\\tmayes02.wav\" __4},\n\t{W,0,\"terran/units/marine/acknowledgement/4\",\"sound\\\\terran\\\\marine\\\\tmayes03.wav\" __4},\n\t{W,0,\"terran/units/marine/fire\",\"sound\\\\bullet\\\\tmafir00.wav\" __4},\n\t{W,0,\"terran/units/wraith/clo00\",\"sound\\\\terran\\\\phoenix\\\\tphclo00.wav\" __4},\n\t{W,0,\"terran/units/wraith/clo01\",\"sound\\\\terran\\\\phoenix\\\\tphclo01.wav\" __4},\n\t{W,0,\"terran/units/wraith/death/1\",\"sound\\\\terran\\\\phoenix\\\\tphdth00.wav\" __4},\n\t{W,0,\"terran/units/wraith/pissed/1\",\"sound\\\\terran\\\\phoenix\\\\tphpss00.wav\" __4},\n\t{W,0,\"terran/units/wraith/pissed/2\",\"sound\\\\terran\\\\phoenix\\\\tphpss01.wav\" __4},\n\t{W,0,\"terran/units/wraith/pissed/3\",\"sound\\\\terran\\\\phoenix\\\\tphpss02.wav\" __4},\n\t{W,0,\"terran/units/wraith/pissed/4\",\"sound\\\\terran\\\\phoenix\\\\tphpss03.wav\" __4},\n\t{W,0,\"terran/units/wraith/pissed/5\",\"sound\\\\terran\\\\phoenix\\\\tphpss04.wav\" __4},\n\t{W,0,\"terran/units/wraith/pissed/6\",\"sound\\\\terran\\\\phoenix\\\\tphpss05.wav\" __4},\n\t{W,0,\"terran/units/wraith/pissed/7\",\"sound\\\\terran\\\\phoenix\\\\tphpss06.wav\" __4},\n\t{W,0,\"terran/units/wraith/ready\",\"sound\\\\terran\\\\phoenix\\\\tphrdy00.wav\" __4},\n\t{W,0,\"terran/units/wraith/selected/1\",\"sound\\\\terran\\\\phoenix\\\\tphwht00.wav\" __4},\n\t{W,0,\"terran/units/wraith/selected/2\",\"sound\\\\terran\\\\phoenix\\\\tphwht01.wav\" __4},\n\t{W,0,\"terran/units/wraith/selected/3\",\"sound\\\\terran\\\\phoenix\\\\tphwht02.wav\" __4},\n\t{W,0,\"terran/units/wraith/selected/4\",\"sound\\\\terran\\\\phoenix\\\\tphwht03.wav\" __4},\n\t{W,0,\"terran/units/wraith/acknowledgement/1\",\"sound\\\\terran\\\\phoenix\\\\tphyes00.wav\" __4},\n\t{W,0,\"terran/units/wraith/acknowledgement/2\",\"sound\\\\terran\\\\phoenix\\\\tphyes01.wav\" __4},\n\t{W,0,\"terran/units/wraith/acknowledgement/3\",\"sound\\\\terran\\\\phoenix\\\\tphyes02.wav\" __4},\n\t{W,0,\"terran/units/wraith/acknowledgement/4\",\"sound\\\\terran\\\\phoenix\\\\tphyes03.wav\" __4},\n\t{W,0,\"terran/units/wraith/fire100\",\"sound\\\\bullet\\\\tphfi100.wav\" __4},\n\t{W,0,\"terran/units/wraith/fire200\",\"sound\\\\bullet\\\\tphfi200.wav\" __4},\n\t{W,0,\"terran/units/wraith/fire201\",\"sound\\\\bullet\\\\tphfi201.wav\" __4},\n\t{W,0,\"terran/units/raynorm/death/1\",\"sound\\\\terran\\\\raynorm\\\\uradth00.wav\" __4},\n\t{W,0,\"terran/units/raynorm/death/2\",\"sound\\\\Terran\\\\RAYNORM\\\\URaDth01.wav\" __4},\n\t{W,0,\"terran/units/raynorm/pissed/1\",\"sound\\\\terran\\\\raynorm\\\\urapss00.wav\" __4},\n\t{W,0,\"terran/units/raynorm/pissed/2\",\"sound\\\\terran\\\\raynorm\\\\urapss01.wav\" __4},\n\t{W,0,\"terran/units/raynorm/pissed/3\",\"sound\\\\terran\\\\raynorm\\\\urapss02.wav\" __4},\n\t{W,0,\"terran/units/raynorm/pissed/4\",\"sound\\\\terran\\\\raynorm\\\\urapss03.wav\" __4},\n\t{W,0,\"terran/units/raynorm/selected/1\",\"sound\\\\terran\\\\raynorm\\\\urawht00.wav\" __4},\n\t{W,0,\"terran/units/raynorm/selected/2\",\"sound\\\\terran\\\\raynorm\\\\urawht01.wav\" __4},\n\t{W,0,\"terran/units/raynorm/selected/3\",\"sound\\\\terran\\\\raynorm\\\\urawht02.wav\" __4},\n\t{W,0,\"terran/units/raynorm/selected/4\",\"sound\\\\terran\\\\raynorm\\\\urawht03.wav\" __4},\n\t{W,0,\"terran/units/raynorm/acknowledgement/1\",\"sound\\\\terran\\\\raynorm\\\\urayes00.wav\" __4},\n\t{W,0,\"terran/units/raynorm/acknowledgement/2\",\"sound\\\\terran\\\\raynorm\\\\urayes01.wav\" __4},\n\t{W,0,\"terran/units/raynorm/acknowledgement/3\",\"sound\\\\terran\\\\raynorm\\\\urayes02.wav\" __4},\n\t{W,0,\"terran/units/raynorm/acknowledgement/4\",\"sound\\\\terran\\\\raynorm\\\\urayes03.wav\" __4},\n\t{W,0,\"terran/units/raynorv/death/1\",\"sound\\\\terran\\\\raynorv\\\\urvdth00.wav\" __4},\n\t{W,0,\"terran/units/raynorv/pissed/1\",\"sound\\\\terran\\\\raynorv\\\\urvpss00.wav\" __4},\n\t{W,0,\"terran/units/raynorv/pissed/2\",\"sound\\\\terran\\\\raynorv\\\\urvpss01.wav\" __4},\n\t{W,0,\"terran/units/raynorv/pissed/3\",\"sound\\\\terran\\\\raynorv\\\\urvpss02.wav\" __4},\n\t{W,0,\"terran/units/raynorv/pissed/4\",\"sound\\\\terran\\\\raynorv\\\\urvpss03.wav\" __4},\n\t{W,0,\"terran/units/raynorv/selected/1\",\"sound\\\\terran\\\\raynorv\\\\urvwht00.wav\" __4},\n\t{W,0,\"terran/units/raynorv/selected/2\",\"sound\\\\terran\\\\raynorv\\\\urvwht01.wav\" __4},\n\t{W,0,\"terran/units/raynorv/selected/3\",\"sound\\\\terran\\\\raynorv\\\\urvwht02.wav\" __4},\n\t{W,0,\"terran/units/raynorv/selected/4\",\"sound\\\\terran\\\\raynorv\\\\urvwht03.wav\" __4},\n\t{W,0,\"terran/units/raynorv/acknowledgement/1\",\"sound\\\\terran\\\\raynorv\\\\urvyes00.wav\" __4},\n\t{W,0,\"terran/units/raynorv/acknowledgement/2\",\"sound\\\\terran\\\\raynorv\\\\urvyes01.wav\" __4},\n\t{W,0,\"terran/units/raynorv/acknowledgement/3\",\"sound\\\\terran\\\\raynorv\\\\urvyes02.wav\" __4},\n\t{W,0,\"terran/units/raynorv/acknowledgement/4\",\"sound\\\\terran\\\\raynorv\\\\urvyes03.wav\" __4},\n\t{W,0,\"terran/units/scv/edrrep00\",\"sound\\\\terran\\\\scv\\\\edrrep00.wav\" __4},\n\t{W,0,\"terran/units/scv/edrrep01\",\"sound\\\\terran\\\\scv\\\\edrrep01.wav\" __4},\n\t{W,0,\"terran/units/scv/edrrep02\",\"sound\\\\terran\\\\scv\\\\edrrep02.wav\" __4},\n\t{W,0,\"terran/units/scv/edrrep03\",\"sound\\\\terran\\\\scv\\\\edrrep03.wav\" __4},\n\t{W,0,\"terran/units/scv/edrrep04\",\"sound\\\\terran\\\\scv\\\\edrrep04.wav\" __4},\n\t{W,0,\"terran/units/scv/death/1\",\"sound\\\\terran\\\\scv\\\\tscdth00.wav\" __4},\n\t{W,0,\"terran/units/scv/err00\",\"sound\\\\terran\\\\scv\\\\tscerr00.wav\" __4},\n\t{W,0,\"terran/units/scv/err01\",\"sound\\\\terran\\\\scv\\\\tscerr01.wav\" __4},\n\t{W,0,\"terran/units/scv/min00\",\"sound\\\\terran\\\\scv\\\\tscmin00.wav\" __4},\n\t{W,0,\"terran/units/scv/min01\",\"sound\\\\terran\\\\scv\\\\tscmin01.wav\" __4},\n\t{W,0,\"terran/units/scv/pissed/1\",\"sound\\\\terran\\\\scv\\\\tscpss00.wav\" __4},\n\t{W,0,\"terran/units/scv/pissed/2\",\"sound\\\\terran\\\\scv\\\\tscpss01.wav\" __4},\n\t{W,0,\"terran/units/scv/pissed/3\",\"sound\\\\terran\\\\scv\\\\tscpss02.wav\" __4},\n\t{W,0,\"terran/units/scv/pissed/4\",\"sound\\\\terran\\\\scv\\\\tscpss03.wav\" __4},\n\t{W,0,\"terran/units/scv/pissed/5\",\"sound\\\\terran\\\\scv\\\\tscpss04.wav\" __4},\n\t{W,0,\"terran/units/scv/pissed/6\",\"sound\\\\terran\\\\scv\\\\tscpss05.wav\" __4},\n\t{W,0,\"terran/units/scv/pissed/7\",\"sound\\\\terran\\\\scv\\\\tscpss06.wav\" __4},\n\t{W,0,\"terran/units/scv/ready\",\"sound\\\\terran\\\\scv\\\\tscrdy00.wav\" __4},\n\t{W,0,\"terran/units/scv/tra00\",\"sound\\\\terran\\\\scv\\\\tsctra00.wav\" __4},\n\t{W,0,\"terran/units/scv/upd00\",\"sound\\\\terran\\\\scv\\\\tscupd00.wav\" __4},\n\t{W,0,\"terran/units/scv/selected/1\",\"sound\\\\terran\\\\scv\\\\tscwht00.wav\" __4},\n\t{W,0,\"terran/units/scv/selected/2\",\"sound\\\\terran\\\\scv\\\\tscwht01.wav\" __4},\n\t{W,0,\"terran/units/scv/selected/3\",\"sound\\\\terran\\\\scv\\\\tscwht02.wav\" __4},\n\t{W,0,\"terran/units/scv/selected/4\",\"sound\\\\terran\\\\scv\\\\tscwht03.wav\" __4},\n\t{W,0,\"terran/units/scv/acknowledgement/1\",\"sound\\\\terran\\\\scv\\\\tscyes00.wav\" __4},\n\t{W,0,\"terran/units/scv/acknowledgement/2\",\"sound\\\\terran\\\\scv\\\\tscyes01.wav\" __4},\n\t{W,0,\"terran/units/scv/acknowledgement/3\",\"sound\\\\terran\\\\scv\\\\tscyes02.wav\" __4},\n\t{W,0,\"terran/units/scv/acknowledgement/4\",\"sound\\\\terran\\\\scv\\\\tscyes03.wav\" __4},\n\t{W,0,\"terran/units/tank/death/1\",\"sound\\\\terran\\\\tank\\\\ttadth00.wav\" __4},\n\t{W,0,\"terran/units/tank/pissed/1\",\"sound\\\\terran\\\\tank\\\\ttapss00.wav\" __4},\n\t{W,0,\"terran/units/tank/pissed/2\",\"sound\\\\terran\\\\tank\\\\ttapss01.wav\" __4},\n\t{W,0,\"terran/units/tank/pissed/3\",\"sound\\\\terran\\\\tank\\\\ttapss02.wav\" __4},\n\t{W,0,\"terran/units/tank/pissed/4\",\"sound\\\\terran\\\\tank\\\\ttapss03.wav\" __4},\n\t{W,0,\"terran/units/tank/ready\",\"sound\\\\terran\\\\tank\\\\ttardy00.wav\" __4},\n\t{W,0,\"terran/units/tank/tra00\",\"sound\\\\terran\\\\tank\\\\ttatra00.wav\" __4},\n\t{W,0,\"terran/units/tank/tra01\",\"sound\\\\terran\\\\tank\\\\ttatra01.wav\" __4},\n\t{W,0,\"terran/units/tank/selected/1\",\"sound\\\\terran\\\\tank\\\\ttawht00.wav\" __4},\n\t{W,0,\"terran/units/tank/selected/2\",\"sound\\\\terran\\\\tank\\\\ttawht01.wav\" __4},\n\t{W,0,\"terran/units/tank/selected/3\",\"sound\\\\terran\\\\tank\\\\ttawht02.wav\" __4},\n\t{W,0,\"terran/units/tank/selected/4\",\"sound\\\\terran\\\\tank\\\\ttawht03.wav\" __4},\n\t{W,0,\"terran/units/tank/acknowledgement/1\",\"sound\\\\terran\\\\tank\\\\ttayes00.wav\" __4},\n\t{W,0,\"terran/units/tank/acknowledgement/2\",\"sound\\\\terran\\\\tank\\\\ttayes01.wav\" __4},\n\t{W,0,\"terran/units/tank/acknowledgement/3\",\"sound\\\\terran\\\\tank\\\\ttayes02.wav\" __4},\n\t{W,0,\"terran/units/tank/acknowledgement/4\",\"sound\\\\terran\\\\tank\\\\ttayes03.wav\" __4},\n\t{W,0,\"terran/units/tank/fire2\",\"sound\\\\bullet\\\\ttafi200.wav\" __4},\n\t{W,0,\"terran/units/tank/fire\",\"sound\\\\Bullet\\\\TTaFir00.wav\" __4},\n\t{W,0,\"terran/units/tank/hit2\",\"sound\\\\bullet\\\\TTaHi200.wav\" __4},\n\t{W,0,\"terran/units/tank/hit\",\"sound\\\\bullet\\\\TTahit00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/def00\",\"sound\\\\terran\\\\vessel\\\\tvedef00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/death/1\",\"sound\\\\terran\\\\vessel\\\\tvedth00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/emp00\",\"sound\\\\terran\\\\vessel\\\\tveemp00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/irr00\",\"sound\\\\terran\\\\vessel\\\\tveirr00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/pissed/1\",\"sound\\\\terran\\\\vessel\\\\tvepss00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/pissed/2\",\"sound\\\\terran\\\\vessel\\\\tvepss01.wav\" __4},\n\t{W,0,\"terran/units/science vessel/pissed/3\",\"sound\\\\terran\\\\vessel\\\\tvepss02.wav\" __4},\n\t{W,0,\"terran/units/science vessel/pissed/4\",\"sound\\\\terran\\\\vessel\\\\tvepss03.wav\" __4},\n\t{W,0,\"terran/units/science vessel/pissed/5\",\"sound\\\\terran\\\\vessel\\\\tvepss04.wav\" __4},\n\t{W,0,\"terran/units/science vessel/pissed/6\",\"sound\\\\terran\\\\vessel\\\\tvepss05.wav\" __4},\n\t{W,0,\"terran/units/science vessel/pissed/7\",\"sound\\\\terran\\\\vessel\\\\tvepss06.wav\" __4},\n\t{W,0,\"terran/units/science vessel/ready\",\"sound\\\\terran\\\\vessel\\\\tverdy00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/selected/1\",\"sound\\\\terran\\\\vessel\\\\tvewht00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/selected/2\",\"sound\\\\terran\\\\vessel\\\\tvewht01.wav\" __4},\n\t{W,0,\"terran/units/science vessel/selected/3\",\"sound\\\\terran\\\\vessel\\\\tvewht02.wav\" __4},\n\t{W,0,\"terran/units/science vessel/selected/4\",\"sound\\\\terran\\\\vessel\\\\tvewht03.wav\" __4},\n\t{W,0,\"terran/units/science vessel/acknowledgement/1\",\"sound\\\\terran\\\\vessel\\\\tveyes00.wav\" __4},\n\t{W,0,\"terran/units/science vessel/acknowledgement/2\",\"sound\\\\terran\\\\vessel\\\\tveyes01.wav\" __4},\n\t{W,0,\"terran/units/science vessel/acknowledgement/3\",\"sound\\\\terran\\\\vessel\\\\tveyes02.wav\" __4},\n\t{W,0,\"terran/units/science vessel/acknowledgement/4\",\"sound\\\\terran\\\\vessel\\\\tveyes03.wav\" __4},\n\t{W,0,\"terran/units/vulture/death/1\",\"sound\\\\terran\\\\vulture\\\\tvudth00.wav\" __4},\n\t{W,0,\"terran/units/vulture/min00\",\"sound\\\\terran\\\\vulture\\\\tvumin00.wav\" __4},\n\t{W,0,\"terran/units/vulture/min01\",\"sound\\\\terran\\\\vulture\\\\tvumin01.wav\" __4},\n\t{W,0,\"terran/units/vulture/pissed/1\",\"sound\\\\terran\\\\vulture\\\\tvupss00.wav\" __4},\n\t{W,0,\"terran/units/vulture/pissed/2\",\"sound\\\\terran\\\\vulture\\\\tvupss01.wav\" __4},\n\t{W,0,\"terran/units/vulture/pissed/3\",\"sound\\\\terran\\\\vulture\\\\tvupss02.wav\" __4},\n\t{W,0,\"terran/units/vulture/pissed/4\",\"sound\\\\terran\\\\vulture\\\\tvupss03.wav\" __4},\n\t{W,0,\"terran/units/vulture/ready\",\"sound\\\\terran\\\\vulture\\\\tvurdy00.wav\" __4},\n\t{W,0,\"terran/units/vulture/selected/1\",\"sound\\\\terran\\\\vulture\\\\tvuwht00.wav\" __4},\n\t{W,0,\"terran/units/vulture/selected/2\",\"sound\\\\terran\\\\vulture\\\\tvuwht01.wav\" __4},\n\t{W,0,\"terran/units/vulture/selected/3\",\"sound\\\\terran\\\\vulture\\\\tvuwht02.wav\" __4},\n\t{W,0,\"terran/units/vulture/selected/4\",\"sound\\\\terran\\\\vulture\\\\tvuwht03.wav\" __4},\n\t{W,0,\"terran/units/vulture/acknowledgement/1\",\"sound\\\\terran\\\\vulture\\\\tvuyes00.wav\" __4},\n\t{W,0,\"terran/units/vulture/acknowledgement/2\",\"sound\\\\terran\\\\vulture\\\\tvuyes01.wav\" __4},\n\t{W,0,\"terran/units/vulture/acknowledgement/3\",\"sound\\\\terran\\\\vulture\\\\tvuyes02.wav\" __4},\n\t{W,0,\"terran/units/vulture/acknowledgement/4\",\"sound\\\\terran\\\\vulture\\\\tvuyes03.wav\" __4},\n\t{W,0,\"terran/units/vulture/fire\",\"sound\\\\bullet\\\\tvufir00.wav\" __4},\n\t{W,0,\"terran/units/vulture/hit\",\"sound\\\\bullet\\\\tvuhit00.wav\" __4},\n\t{W,0,\"terran/units/vulture/hit1\",\"sound\\\\bullet\\\\tvuhit01.wav\" __4},\n\t{W,0,\"terran/units/vulture/hit2\",\"sound\\\\bullet\\\\tvuhit02.wav\" __4},\n\t{W,0,\"terran/units/academy\",\"sound\\\\terran\\\\bldg\\\\tacwht00.wav\" __4},\n\t{W,0,\"terran/units/armory\",\"sound\\\\terran\\\\bldg\\\\tclwht00.wav\" __4},\n\t{W,0,\"terran/units/science facility\",\"sound\\\\terran\\\\bldg\\\\tcssca00.wav\" __4},\n\t{W,0,\"terran/units/comsat station\",\"sound\\\\Terran\\\\bldg\\\\tcswht00.wav\" __4},\n\t{W,0,\"terran/units/control tower\",\"sound\\\\terran\\\\bldg\\\\tddwht00.wav\" __4},\n\t{W,0,\"terran/units/covert ops\",\"sound\\\\terran\\\\bldg\\\\tglwht00.wav\" __4},\n\t{W,0,\"terran/units/machine shop\",\"sound\\\\terran\\\\bldg\\\\tmswht00.wav\" __4},\n\t{W,0,\"terran/units/missile turret\",\"sound\\\\terran\\\\bldg\\\\tmtwht00.wav\" __4},\n\t{W,0,\"terran/units/nuclear silo\",\"sound\\\\terran\\\\bldg\\\\tnswht00.wav\" __4},\n\t{W,0,\"terran/units/supply depot\",\"sound\\\\terran\\\\bldg\\\\tpgwht00.wav\" __4},\n\t{W,0,\"terran/units/bunker\",\"sound\\\\terran\\\\bldg\\\\tplwht00.wav\" __4},\n\t{W,0,\"terran/units/refinery\",\"sound\\\\terran\\\\bldg\\\\trewht00.wav\" __4},\n\t{W,0,\"terran/units/rf\",\"sound\\\\terran\\\\bldg\\\\trfwht00.wav\" __4},\n\t{W,0,\"terran/units/factory\",\"sound\\\\terran\\\\bldg\\\\trlwht00.wav\" __4},\n\t{W,0,\"terran/units/engineering bay\",\"sound\\\\terran\\\\bldg\\\\twpwht00.wav\" __4},\n\t{W,0,\"terran/units/nuclear silo/fire\",\"sound\\\\bullet\\\\tnsfir00.wav\" __4},\n\t{W,0,\"terran/units/nuclear silo/hit\",\"sound\\\\bullet\\\\tnshit00.wav\" __4},\n\t{W,0,\"terran/units/tscfir00\",\"sound\\\\bullet\\\\tscfir00.wav\" __4},\n\n\t// Protoss sounds\n\t{W,0,\"protoss/units/advisor/err00\",\"sound\\\\protoss\\\\advisor\\\\paderr00.wav\" __4},\n\t{W,0,\"protoss/units/advisor/err01\",\"sound\\\\protoss\\\\advisor\\\\paderr01.wav\" __4},\n\t{W,0,\"protoss/units/advisor/err02\",\"sound\\\\protoss\\\\advisor\\\\paderr02.wav\" __4},\n\t{W,0,\"protoss/units/advisor/err06\",\"sound\\\\Protoss\\\\Advisor\\\\PAdErr06.wav\" __4},\n\t{W,0,\"protoss/units/advisor/upd00\",\"sound\\\\protoss\\\\advisor\\\\padupd00.wav\" __4},\n\t{W,0,\"protoss/units/advisor/upd01\",\"sound\\\\protoss\\\\advisor\\\\padupd01.wav\" __4},\n\t{W,0,\"protoss/units/advisor/upd02\",\"sound\\\\protoss\\\\advisor\\\\padupd02.wav\" __4},\n\t{W,0,\"protoss/units/advisor/upd04\",\"sound\\\\protoss\\\\advisor\\\\padupd04.wav\" __4},\n\t{W,0,\"protoss/units/advisor/upd06\",\"sound\\\\protoss\\\\advisor\\\\padupd06.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/cag00\",\"sound\\\\protoss\\\\arbiter\\\\pabcag00.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/death/1\",\"sound\\\\protoss\\\\arbiter\\\\pabdth00.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/fol00\",\"sound\\\\protoss\\\\arbiter\\\\pabfol00.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/fol01\",\"sound\\\\protoss\\\\arbiter\\\\pabfol01.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/fol02\",\"sound\\\\protoss\\\\arbiter\\\\pabfol02.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/fol03\",\"sound\\\\protoss\\\\arbiter\\\\pabfol03.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/pissed/1\",\"sound\\\\protoss\\\\arbiter\\\\pabpss00.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/pissed/2\",\"sound\\\\protoss\\\\arbiter\\\\pabpss01.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/pissed/3\",\"sound\\\\protoss\\\\arbiter\\\\pabpss02.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/pissed/4\",\"sound\\\\protoss\\\\arbiter\\\\pabpss03.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/pissed/5\",\"sound\\\\protoss\\\\arbiter\\\\pabpss04.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/ready\",\"sound\\\\protoss\\\\arbiter\\\\pabrdy00.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/selected/1\",\"sound\\\\protoss\\\\arbiter\\\\pabwht00.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/selected/2\",\"sound\\\\protoss\\\\arbiter\\\\pabwht01.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/selected/3\",\"sound\\\\protoss\\\\arbiter\\\\pabwht02.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/selected/4\",\"sound\\\\protoss\\\\arbiter\\\\pabwht03.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/acknowledgement/1\",\"sound\\\\protoss\\\\arbiter\\\\pabyes00.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/acknowledgement/2\",\"sound\\\\protoss\\\\arbiter\\\\pabyes01.wav\" __4},\n\t{W,0,\"protoss/units/arbiter/acknowledgement/3\",\"sound\\\\protoss\\\\arbiter\\\\pabyes02.wav\" __4},\n//\t{W,0,\"protoss/units/arbiter/acknowledgement/4\",\"sound\\\\protoss\\\\arbiter\\\\pabyes03.wav\" __4},\n\t{W,0,\"protoss/units/archon/death/1\",\"sound\\\\protoss\\\\archon\\\\pardth00.wav\" __4},\n\t{W,0,\"protoss/units/archon/min00\",\"sound\\\\Protoss\\\\ARCHON\\\\PArMin00.wav\" __4},\n\t{W,0,\"protoss/units/archon/pissed/1\",\"sound\\\\protoss\\\\archon\\\\parpss00.wav\" __4},\n\t{W,0,\"protoss/units/archon/pissed/2\",\"sound\\\\protoss\\\\archon\\\\parpss01.wav\" __4},\n\t{W,0,\"protoss/units/archon/pissed/3\",\"sound\\\\protoss\\\\archon\\\\parpss02.wav\" __4},\n\t{W,0,\"protoss/units/archon/pissed/4\",\"sound\\\\protoss\\\\archon\\\\parpss03.wav\" __4},\n\t{W,0,\"protoss/units/archon/ready\",\"sound\\\\Protoss\\\\ARCHON\\\\PArRdy00.wav\" __4},\n\t{W,0,\"protoss/units/archon/selected/1\",\"sound\\\\protoss\\\\archon\\\\parwht00.wav\" __4},\n\t{W,0,\"protoss/units/archon/selected/2\",\"sound\\\\protoss\\\\archon\\\\parwht01.wav\" __4},\n\t{W,0,\"protoss/units/archon/selected/3\",\"sound\\\\protoss\\\\archon\\\\parwht02.wav\" __4},\n\t{W,0,\"protoss/units/archon/selected/4\",\"sound\\\\protoss\\\\archon\\\\parwht03.wav\" __4},\n\t{W,0,\"protoss/units/archon/acknowledgement/1\",\"sound\\\\protoss\\\\archon\\\\paryes00.wav\" __4},\n\t{W,0,\"protoss/units/archon/acknowledgement/2\",\"sound\\\\protoss\\\\archon\\\\paryes01.wav\" __4},\n\t{W,0,\"protoss/units/archon/acknowledgement/3\",\"sound\\\\protoss\\\\archon\\\\paryes02.wav\" __4},\n\t{W,0,\"protoss/units/archon/acknowledgement/4\",\"sound\\\\protoss\\\\archon\\\\paryes03.wav\" __4},\n\t{W,0,\"protoss/units/archon/fir00\",\"sound\\\\bullet\\\\parfir00.wav\" __4},\n\t{W,0,\"protoss/units/carrier/death/1\",\"sound\\\\protoss\\\\carrier\\\\pcadth00.wav\" __4},\n\t{W,0,\"protoss/units/carrier/death/2\",\"sound\\\\protoss\\\\carrier\\\\pcadth01.wav\" __4},\n\t{W,0,\"protoss/units/carrier/pissed/1\",\"sound\\\\protoss\\\\carrier\\\\pcapss00.wav\" __4},\n\t{W,0,\"protoss/units/carrier/pissed/2\",\"sound\\\\protoss\\\\carrier\\\\pcapss01.wav\" __4},\n\t{W,0,\"protoss/units/carrier/pissed/3\",\"sound\\\\protoss\\\\carrier\\\\pcapss02.wav\" __4},\n\t{W,0,\"protoss/units/carrier/pissed/4\",\"sound\\\\protoss\\\\carrier\\\\pcapss03.wav\" __4},\n\t{W,0,\"protoss/units/carrier/ready\",\"sound\\\\protoss\\\\carrier\\\\pcardy00.wav\" __4},\n\t{W,0,\"protoss/units/carrier/selected/1\",\"sound\\\\protoss\\\\carrier\\\\pcawht00.wav\" __4},\n\t{W,0,\"protoss/units/carrier/selected/2\",\"sound\\\\protoss\\\\carrier\\\\pcawht01.wav\" __4},\n\t{W,0,\"protoss/units/carrier/selected/3\",\"sound\\\\protoss\\\\carrier\\\\pcawht02.wav\" __4},\n\t{W,0,\"protoss/units/carrier/selected/4\",\"sound\\\\protoss\\\\carrier\\\\pcawht03.wav\" __4},\n\t{W,0,\"protoss/units/carrier/acknowledgement/1\",\"sound\\\\protoss\\\\carrier\\\\pcayes00.wav\" __4},\n\t{W,0,\"protoss/units/carrier/acknowledgement/2\",\"sound\\\\protoss\\\\carrier\\\\pcayes01.wav\" __4},\n\t{W,0,\"protoss/units/carrier/acknowledgement/3\",\"sound\\\\protoss\\\\carrier\\\\pcayes02.wav\" __4},\n\t{W,0,\"protoss/units/carrier/acknowledgement/4\",\"sound\\\\protoss\\\\carrier\\\\pcayes03.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/death/1\",\"sound\\\\protoss\\\\darktemplar\\\\pdtdth00.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/pissed/1\",\"sound\\\\protoss\\\\darktemplar\\\\pdtpss00.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/pissed/2\",\"sound\\\\protoss\\\\darktemplar\\\\pdtpss01.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/pissed/3\",\"sound\\\\protoss\\\\darktemplar\\\\pdtpss02.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/pissed/4\",\"sound\\\\protoss\\\\darktemplar\\\\pdtpss03.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/selected/1\",\"sound\\\\protoss\\\\darktemplar\\\\pdtwht00.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/selected/2\",\"sound\\\\protoss\\\\darktemplar\\\\pdtwht01.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/selected/3\",\"sound\\\\protoss\\\\darktemplar\\\\pdtwht02.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/selected/4\",\"sound\\\\protoss\\\\darktemplar\\\\pdtwht03.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/acknowledgement/1\",\"sound\\\\protoss\\\\darktemplar\\\\pdtyes00.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/acknowledgement/2\",\"sound\\\\protoss\\\\darktemplar\\\\pdtyes01.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/acknowledgement/3\",\"sound\\\\protoss\\\\darktemplar\\\\pdtyes02.wav\" __4},\n\t{W,0,\"protoss/units/dark templar/acknowledgement/4\",\"sound\\\\protoss\\\\darktemplar\\\\pdtyes03.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/death/1\",\"sound\\\\protoss\\\\dragoon\\\\pdrdth00.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/pissed/1\",\"sound\\\\protoss\\\\dragoon\\\\pdrpss00.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/pissed/2\",\"sound\\\\protoss\\\\dragoon\\\\pdrpss01.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/pissed/3\",\"sound\\\\protoss\\\\dragoon\\\\pdrpss02.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/pissed/4\",\"sound\\\\protoss\\\\dragoon\\\\pdrpss03.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/ready\",\"sound\\\\Protoss\\\\DRAGOON\\\\PDrRdy00.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/1\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht00.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/2\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht01.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/3\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht02.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/4\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht03.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/5\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht04.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/6\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht05.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/7\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht06.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/selected/8\",\"sound\\\\protoss\\\\dragoon\\\\pdrwht07.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/acknowledgement/1\",\"sound\\\\protoss\\\\dragoon\\\\pdryes00.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/acknowledgement/2\",\"sound\\\\protoss\\\\dragoon\\\\pdryes01.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/acknowledgement/3\",\"sound\\\\protoss\\\\dragoon\\\\pdryes02.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/acknowledgement/4\",\"sound\\\\protoss\\\\dragoon\\\\pdryes03.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/acknowledgement/5\",\"sound\\\\protoss\\\\dragoon\\\\pdryes04.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/acknowledgement/6\",\"sound\\\\protoss\\\\dragoon\\\\pdryes05.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/acknowledgement/7\",\"sound\\\\protoss\\\\dragoon\\\\pdryes06.wav\" __4},\n\t{W,0,\"protoss/units/dragoon/bull\",\"sound\\\\bullet\\\\dragbull.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/pissed/1\",\"sound\\\\protoss\\\\fenixd\\\\ufdpss00.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/pissed/2\",\"sound\\\\protoss\\\\fenixd\\\\ufdpss01.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/pissed/3\",\"sound\\\\protoss\\\\fenixd\\\\ufdpss02.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/pissed/4\",\"sound\\\\protoss\\\\fenixd\\\\ufdpss03.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/selected/1\",\"sound\\\\protoss\\\\fenixd\\\\ufdwht00.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/selected/2\",\"sound\\\\protoss\\\\fenixd\\\\ufdwht01.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/selected/3\",\"sound\\\\protoss\\\\fenixd\\\\ufdwht02.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/selected/4\",\"sound\\\\protoss\\\\fenixd\\\\ufdwht03.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/acknowledgement/1\",\"sound\\\\protoss\\\\fenixd\\\\ufdyes00.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/acknowledgement/2\",\"sound\\\\protoss\\\\fenixd\\\\ufdyes01.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/acknowledgement/3\",\"sound\\\\protoss\\\\fenixd\\\\ufdyes02.wav\" __4},\n\t{W,0,\"protoss/units/fenixd/acknowledgement/4\",\"sound\\\\protoss\\\\fenixd\\\\ufdyes03.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/death/1\",\"sound\\\\protoss\\\\fenixz\\\\ufedth00.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/pissed/1\",\"sound\\\\protoss\\\\fenixz\\\\ufepss00.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/pissed/2\",\"sound\\\\protoss\\\\fenixz\\\\ufepss01.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/pissed/3\",\"sound\\\\protoss\\\\fenixz\\\\ufepss02.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/pissed/4\",\"sound\\\\protoss\\\\fenixz\\\\ufepss03.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/selected/1\",\"sound\\\\protoss\\\\fenixz\\\\ufewht00.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/selected/2\",\"sound\\\\protoss\\\\fenixz\\\\ufewht01.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/selected/3\",\"sound\\\\protoss\\\\fenixz\\\\ufewht02.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/selected/4\",\"sound\\\\protoss\\\\fenixz\\\\ufewht03.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/acknowledgement/1\",\"sound\\\\protoss\\\\fenixz\\\\ufeyes00.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/acknowledgement/2\",\"sound\\\\protoss\\\\fenixz\\\\ufeyes01.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/acknowledgement/3\",\"sound\\\\protoss\\\\fenixz\\\\ufeyes02.wav\" __4},\n\t{W,0,\"protoss/units/fenixz/acknowledgement/4\",\"sound\\\\protoss\\\\fenixz\\\\ufeyes03.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/pissed/1\",\"sound\\\\protoss\\\\gantrithor\\\\utcpss00.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/pissed/2\",\"sound\\\\protoss\\\\gantrithor\\\\utcpss01.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/pissed/3\",\"sound\\\\protoss\\\\gantrithor\\\\utcpss02.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/pissed/4\",\"sound\\\\protoss\\\\gantrithor\\\\utcpss03.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/selected/1\",\"sound\\\\protoss\\\\gantrithor\\\\utcwht00.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/selected/2\",\"sound\\\\protoss\\\\gantrithor\\\\utcwht01.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/selected/3\",\"sound\\\\protoss\\\\gantrithor\\\\utcwht02.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/selected/4\",\"sound\\\\protoss\\\\gantrithor\\\\utcwht03.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/acknowledgement/1\",\"sound\\\\protoss\\\\gantrithor\\\\utcyes00.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/acknowledgement/2\",\"sound\\\\protoss\\\\gantrithor\\\\utcyes01.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/acknowledgement/3\",\"sound\\\\protoss\\\\gantrithor\\\\utcyes02.wav\" __4},\n\t{W,0,\"protoss/units/gantrithor/acknowledgement/4\",\"sound\\\\protoss\\\\gantrithor\\\\utcyes03.wav\" __4},\n\t{W,0,\"protoss/units/interceptor/inlau00\",\"sound\\\\protoss\\\\intercep\\\\pinlau00.wav\" __4},\n\t{W,0,\"protoss/units/probe/att00\",\"sound\\\\protoss\\\\probe\\\\ppratt00.wav\" __4},\n\t{W,0,\"protoss/units/probe/att01\",\"sound\\\\protoss\\\\probe\\\\ppratt01.wav\" __4},\n\t{W,0,\"protoss/units/probe/death/1\",\"sound\\\\protoss\\\\probe\\\\pprdth00.wav\" __4},\n\t{W,0,\"protoss/units/probe/err00\",\"sound\\\\protoss\\\\probe\\\\pprerr00.wav\" __4},\n\t{W,0,\"protoss/units/probe/err01\",\"sound\\\\protoss\\\\probe\\\\pprerr01.wav\" __4},\n\t{W,0,\"protoss/units/probe/min00\",\"sound\\\\protoss\\\\probe\\\\pprmin00.wav\" __4},\n\t{W,0,\"protoss/units/probe/pissed/1\",\"sound\\\\protoss\\\\probe\\\\pprpss00.wav\" __4},\n\t{W,0,\"protoss/units/probe/pissed/2\",\"sound\\\\protoss\\\\probe\\\\pprpss01.wav\" __4},\n\t{W,0,\"protoss/units/probe/pissed/3\",\"sound\\\\protoss\\\\probe\\\\pprpss02.wav\" __4},\n\t{W,0,\"protoss/units/probe/pissed/4\",\"sound\\\\protoss\\\\probe\\\\pprpss03.wav\" __4},\n\t{W,0,\"protoss/units/probe/ready\",\"sound\\\\protoss\\\\probe\\\\pprrdy00.wav\" __4},\n\t{W,0,\"protoss/units/probe/selected/1\",\"sound\\\\protoss\\\\probe\\\\pprwht00.wav\" __4},\n\t{W,0,\"protoss/units/probe/selected/2\",\"sound\\\\protoss\\\\probe\\\\pprwht01.wav\" __4},\n\t{W,0,\"protoss/units/probe/selected/3\",\"sound\\\\protoss\\\\probe\\\\pprwht02.wav\" __4},\n\t{W,0,\"protoss/units/probe/selected/4\",\"sound\\\\protoss\\\\probe\\\\pprwht03.wav\" __4},\n\t{W,0,\"protoss/units/probe/acknowledgement/1\",\"sound\\\\protoss\\\\probe\\\\ppryes00.wav\" __4},\n\t{W,0,\"protoss/units/probe/acknowledgement/2\",\"sound\\\\protoss\\\\probe\\\\ppryes01.wav\" __4},\n\t{W,0,\"protoss/units/probe/acknowledgement/3\",\"sound\\\\protoss\\\\probe\\\\ppryes02.wav\" __4},\n\t{W,0,\"protoss/units/probe/acknowledgement/4\",\"sound\\\\protoss\\\\probe\\\\ppryes03.wav\" __4},\n\t{W,0,\"protoss/units/scout/death/1\",\"sound\\\\protoss\\\\scout\\\\pscdth00.wav\" __4},\n\t{W,0,\"protoss/units/scout/pissed/1\",\"sound\\\\protoss\\\\scout\\\\pscpss00.wav\" __4},\n\t{W,0,\"protoss/units/scout/pissed/2\",\"sound\\\\protoss\\\\scout\\\\pscpss01.wav\" __4},\n\t{W,0,\"protoss/units/scout/pissed/3\",\"sound\\\\protoss\\\\scout\\\\pscpss02.wav\" __4},\n\t{W,0,\"protoss/units/scout/pissed/4\",\"sound\\\\protoss\\\\scout\\\\pscpss03.wav\" __4},\n\t{W,0,\"protoss/units/scout/pissed/5\",\"sound\\\\protoss\\\\scout\\\\pscpss04.wav\" __4},\n\t{W,0,\"protoss/units/scout/ready\",\"sound\\\\protoss\\\\scout\\\\pscrdy00.wav\" __4},\n\t{W,0,\"protoss/units/scout/selected/1\",\"sound\\\\protoss\\\\scout\\\\pscwht00.wav\" __4},\n\t{W,0,\"protoss/units/scout/selected/2\",\"sound\\\\protoss\\\\scout\\\\pscwht01.wav\" __4},\n\t{W,0,\"protoss/units/scout/selected/3\",\"sound\\\\protoss\\\\scout\\\\pscwht02.wav\" __4},\n\t{W,0,\"protoss/units/scout/selected/4\",\"sound\\\\protoss\\\\scout\\\\pscwht03.wav\" __4},\n\t{W,0,\"protoss/units/scout/acknowledgement/1\",\"sound\\\\protoss\\\\scout\\\\pscyes00.wav\" __4},\n\t{W,0,\"protoss/units/scout/acknowledgement/2\",\"sound\\\\protoss\\\\scout\\\\pscyes01.wav\" __4},\n\t{W,0,\"protoss/units/scout/acknowledgement/3\",\"sound\\\\protoss\\\\scout\\\\pscyes02.wav\" __4},\n\t{W,0,\"protoss/units/scout/acknowledgement/4\",\"sound\\\\protoss\\\\scout\\\\pscyes03.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/bld00\",\"sound\\\\protoss\\\\shuttle\\\\pshbld00.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/bld01\",\"sound\\\\protoss\\\\shuttle\\\\pshbld01.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/bld02\",\"sound\\\\protoss\\\\shuttle\\\\pshbld02.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/bld03\",\"sound\\\\protoss\\\\shuttle\\\\pshbld03.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/bld04\",\"sound\\\\protoss\\\\shuttle\\\\pshbld04.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/death/1\",\"sound\\\\protoss\\\\shuttle\\\\pshdth00.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/pissed/1\",\"sound\\\\protoss\\\\shuttle\\\\pshpss00.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/pissed/2\",\"sound\\\\protoss\\\\shuttle\\\\pshpss01.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/pissed/3\",\"sound\\\\protoss\\\\shuttle\\\\pshpss02.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/pissed/4\",\"sound\\\\protoss\\\\shuttle\\\\pshpss03.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/pissed/5\",\"sound\\\\protoss\\\\shuttle\\\\pshpss04.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/ready\",\"sound\\\\protoss\\\\shuttle\\\\pshrdy00.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/selected/1\",\"sound\\\\protoss\\\\shuttle\\\\pshwht00.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/selected/2\",\"sound\\\\protoss\\\\shuttle\\\\pshwht01.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/selected/3\",\"sound\\\\protoss\\\\shuttle\\\\pshwht02.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/selected/4\",\"sound\\\\protoss\\\\shuttle\\\\pshwht03.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/acknowledgement/1\",\"sound\\\\protoss\\\\shuttle\\\\pshyes00.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/acknowledgement/2\",\"sound\\\\protoss\\\\shuttle\\\\pshyes01.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/acknowledgement/3\",\"sound\\\\protoss\\\\shuttle\\\\pshyes02.wav\" __4},\n\t{W,0,\"protoss/units/shuttle/acknowledgement/4\",\"sound\\\\protoss\\\\shuttle\\\\pshyes03.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/death/1\",\"sound\\\\protoss\\\\tassadar\\\\utadth00.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/pissed/1\",\"sound\\\\protoss\\\\tassadar\\\\utapss00.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/pissed/2\",\"sound\\\\protoss\\\\tassadar\\\\utapss01.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/pissed/3\",\"sound\\\\protoss\\\\tassadar\\\\utapss02.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/pissed/4\",\"sound\\\\protoss\\\\tassadar\\\\utapss03.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/selected/1\",\"sound\\\\protoss\\\\tassadar\\\\utawht00.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/selected/2\",\"sound\\\\protoss\\\\tassadar\\\\utawht01.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/selected/3\",\"sound\\\\protoss\\\\tassadar\\\\utawht02.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/selected/4\",\"sound\\\\protoss\\\\tassadar\\\\utawht03.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/acknowledgement/1\",\"sound\\\\protoss\\\\tassadar\\\\utayes00.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/acknowledgement/2\",\"sound\\\\protoss\\\\tassadar\\\\utayes01.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/acknowledgement/3\",\"sound\\\\protoss\\\\tassadar\\\\utayes02.wav\" __4},\n\t{W,0,\"protoss/units/tassadar/acknowledgement/4\",\"sound\\\\protoss\\\\tassadar\\\\utayes03.wav\" __4},\n\t{W,0,\"protoss/units/templar/death/1\",\"sound\\\\protoss\\\\templar\\\\ptedth00.wav\" __4},\n\t{W,0,\"protoss/units/templar/hal00\",\"sound\\\\protoss\\\\templar\\\\ptehal00.wav\" __4},\n\t{W,0,\"protoss/units/templar/hal01\",\"sound\\\\protoss\\\\templar\\\\ptehal01.wav\" __4},\n\t{W,0,\"protoss/units/templar/mov00\",\"sound\\\\protoss\\\\templar\\\\ptemov00.wav\" __4},\n\t{W,0,\"protoss/units/templar/pissed/1\",\"sound\\\\protoss\\\\templar\\\\ptepss00.wav\" __4},\n\t{W,0,\"protoss/units/templar/pissed/2\",\"sound\\\\protoss\\\\templar\\\\ptepss01.wav\" __4},\n\t{W,0,\"protoss/units/templar/pissed/3\",\"sound\\\\protoss\\\\templar\\\\ptepss02.wav\" __4},\n\t{W,0,\"protoss/units/templar/pissed/4\",\"sound\\\\protoss\\\\templar\\\\ptepss03.wav\" __4},\n\t{W,0,\"protoss/units/templar/ready\",\"sound\\\\protoss\\\\templar\\\\pterdy00.wav\" __4},\n\t{W,0,\"protoss/units/templar/sto00\",\"sound\\\\protoss\\\\templar\\\\ptesto00.wav\" __4},\n\t{W,0,\"protoss/units/templar/sto01\",\"sound\\\\protoss\\\\templar\\\\ptesto01.wav\" __4},\n\t{W,0,\"protoss/units/templar/sum00\",\"sound\\\\protoss\\\\templar\\\\ptesum00.wav\" __4},\n\t{W,0,\"protoss/units/templar/selected/1\",\"sound\\\\protoss\\\\templar\\\\ptewht00.wav\" __4},\n\t{W,0,\"protoss/units/templar/selected/2\",\"sound\\\\protoss\\\\templar\\\\ptewht01.wav\" __4},\n\t{W,0,\"protoss/units/templar/selected/3\",\"sound\\\\protoss\\\\templar\\\\ptewht02.wav\" __4},\n\t{W,0,\"protoss/units/templar/selected/4\",\"sound\\\\protoss\\\\templar\\\\ptewht03.wav\" __4},\n\t{W,0,\"protoss/units/templar/acknowledgement/1\",\"sound\\\\protoss\\\\templar\\\\pteyes00.wav\" __4},\n\t{W,0,\"protoss/units/templar/acknowledgement/2\",\"sound\\\\protoss\\\\templar\\\\pteyes01.wav\" __4},\n\t{W,0,\"protoss/units/templar/acknowledgement/3\",\"sound\\\\protoss\\\\templar\\\\pteyes02.wav\" __4},\n\t{W,0,\"protoss/units/templar/acknowledgement/4\",\"sound\\\\protoss\\\\templar\\\\pteyes03.wav\" __4},\n\t{W,0,\"protoss/units/reaver/death/1\",\"sound\\\\protoss\\\\trilobyte\\\\ptrdth00.wav\" __4},\n\t{W,0,\"protoss/units/reaver/pissed/1\",\"sound\\\\protoss\\\\trilobyte\\\\ptrpss00.wav\" __4},\n\t{W,0,\"protoss/units/reaver/pissed/2\",\"sound\\\\protoss\\\\trilobyte\\\\ptrpss01.wav\" __4},\n\t{W,0,\"protoss/units/reaver/pissed/3\",\"sound\\\\protoss\\\\trilobyte\\\\ptrpss02.wav\" __4},\n\t{W,0,\"protoss/units/reaver/ready\",\"sound\\\\protoss\\\\trilobyte\\\\ptrrdy00.wav\" __4},\n\t{W,0,\"protoss/units/reaver/selected/1\",\"sound\\\\protoss\\\\trilobyte\\\\ptrwht00.wav\" __4},\n\t{W,0,\"protoss/units/reaver/selected/2\",\"sound\\\\protoss\\\\trilobyte\\\\ptrwht01.wav\" __4},\n\t{W,0,\"protoss/units/reaver/selected/3\",\"sound\\\\protoss\\\\trilobyte\\\\ptrwht02.wav\" __4},\n\t{W,0,\"protoss/units/reaver/selected/4\",\"sound\\\\protoss\\\\trilobyte\\\\ptrwht03.wav\" __4},\n\t{W,0,\"protoss/units/reaver/acknowledgement/1\",\"sound\\\\protoss\\\\trilobyte\\\\ptryes00.wav\" __4},\n\t{W,0,\"protoss/units/reaver/acknowledgement/2\",\"sound\\\\protoss\\\\trilobyte\\\\ptryes01.wav\" __4},\n\t{W,0,\"protoss/units/reaver/acknowledgement/3\",\"sound\\\\protoss\\\\trilobyte\\\\ptryes02.wav\" __4},\n\t{W,0,\"protoss/units/reaver/acknowledgement/4\",\"sound\\\\protoss\\\\trilobyte\\\\ptryes03.wav\" __4},\n\t{W,0,\"protoss/units/observer/death/1\",\"sound\\\\protoss\\\\witness\\\\pwidth00.wav\" __4},\n\t{W,0,\"protoss/units/observer/death/2\",\"sound\\\\protoss\\\\witness\\\\pwidth01.wav\" __4},\n\t{W,0,\"protoss/units/observer/pissed/1\",\"sound\\\\protoss\\\\witness\\\\pwipss00.wav\" __4},\n\t{W,0,\"protoss/units/observer/pissed/2\",\"sound\\\\protoss\\\\witness\\\\pwipss01.wav\" __4},\n\t{W,0,\"protoss/units/observer/pissed/3\",\"sound\\\\protoss\\\\witness\\\\pwipss02.wav\" __4},\n\t{W,0,\"protoss/units/observer/pissed/4\",\"sound\\\\protoss\\\\witness\\\\pwipss03.wav\" __4},\n\t{W,0,\"protoss/units/observer/pissed/5\",\"sound\\\\protoss\\\\witness\\\\pwipss04.wav\" __4},\n\t{W,0,\"protoss/units/observer/ready\",\"sound\\\\protoss\\\\witness\\\\pwirdy00.wav\" __4},\n\t{W,0,\"protoss/units/observer/selected/1\",\"sound\\\\protoss\\\\witness\\\\pwiwht00.wav\" __4},\n\t{W,0,\"protoss/units/observer/selected/2\",\"sound\\\\protoss\\\\witness\\\\pwiwht01.wav\" __4},\n\t{W,0,\"protoss/units/observer/acknowledgement/1\",\"sound\\\\protoss\\\\witness\\\\pwiyes00.wav\" __4},\n\t{W,0,\"protoss/units/observer/acknowledgement/2\",\"sound\\\\protoss\\\\witness\\\\pwiyes01.wav\" __4},\n\t{W,0,\"protoss/units/zealot/att00\",\"sound\\\\protoss\\\\zealot\\\\pzeatt00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/att01\",\"sound\\\\protoss\\\\zealot\\\\pzeatt01.wav\" __4},\n\t{W,0,\"protoss/units/zealot/death/1\",\"sound\\\\protoss\\\\zealot\\\\pzedth00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/hit00\",\"sound\\\\protoss\\\\zealot\\\\pzehit00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/pissed/1\",\"sound\\\\protoss\\\\zealot\\\\pzepss00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/pissed/2\",\"sound\\\\protoss\\\\zealot\\\\pzepss01.wav\" __4},\n\t{W,0,\"protoss/units/zealot/pissed/3\",\"sound\\\\protoss\\\\zealot\\\\pzepss02.wav\" __4},\n\t{W,0,\"protoss/units/zealot/rag00\",\"sound\\\\protoss\\\\zealot\\\\pzerag00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/ready\",\"sound\\\\protoss\\\\zealot\\\\pzerdy00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/selected/1\",\"sound\\\\protoss\\\\zealot\\\\pzewht00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/selected/2\",\"sound\\\\protoss\\\\zealot\\\\pzewht01.wav\" __4},\n\t{W,0,\"protoss/units/zealot/selected/3\",\"sound\\\\protoss\\\\zealot\\\\pzewht02.wav\" __4},\n\t{W,0,\"protoss/units/zealot/selected/4\",\"sound\\\\protoss\\\\zealot\\\\pzewht03.wav\" __4},\n\t{W,0,\"protoss/units/zealot/acknowledgement/1\",\"sound\\\\protoss\\\\zealot\\\\pzeyes00.wav\" __4},\n\t{W,0,\"protoss/units/zealot/acknowledgement/2\",\"sound\\\\protoss\\\\zealot\\\\pzeyes01.wav\" __4},\n\t{W,0,\"protoss/units/zealot/acknowledgement/3\",\"sound\\\\protoss\\\\zealot\\\\pzeyes02.wav\" __4},\n\t{W,0,\"protoss/units/zealot/acknowledgement/4\",\"sound\\\\protoss\\\\zealot\\\\pzeyes03.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/death/1\",\"sound\\\\protoss\\\\zeratul\\\\uzedth00.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/pissed/1\",\"sound\\\\protoss\\\\zeratul\\\\uzepss00.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/pissed/2\",\"sound\\\\protoss\\\\zeratul\\\\uzepss01.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/pissed/3\",\"sound\\\\protoss\\\\zeratul\\\\uzepss02.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/pissed/4\",\"sound\\\\protoss\\\\zeratul\\\\uzepss03.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/selected/1\",\"sound\\\\protoss\\\\zeratul\\\\uzewht00.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/selected/2\",\"sound\\\\protoss\\\\zeratul\\\\uzewht01.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/selected/3\",\"sound\\\\protoss\\\\zeratul\\\\uzewht02.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/selected/4\",\"sound\\\\protoss\\\\zeratul\\\\uzewht03.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/acknowledgement/1\",\"sound\\\\protoss\\\\zeratul\\\\uzeyes00.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/acknowledgement/2\",\"sound\\\\protoss\\\\zeratul\\\\uzeyes01.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/acknowledgement/3\",\"sound\\\\protoss\\\\zeratul\\\\uzeyes02.wav\" __4},\n\t{W,0,\"protoss/units/zeratul/acknowledgement/4\",\"sound\\\\protoss\\\\zeratul\\\\uzeyes03.wav\" __4},\n\t{W,0,\"protoss/units/acwht00\",\"sound\\\\protoss\\\\bldg\\\\pacwht00.wav\" __4},\n\t{W,0,\"protoss/units/assimilator\",\"sound\\\\protoss\\\\bldg\\\\paswht00.wav\" __4},\n\t{W,0,\"protoss/units/baact00\",\"sound\\\\Protoss\\\\Bldg\\\\PbaAct00.wav\" __4},\n\t{W,0,\"protoss/units/bawht00\",\"sound\\\\protoss\\\\bldg\\\\pbawht00.wav\" __4},\n\t{W,0,\"protoss/units/observatory\",\"sound\\\\protoss\\\\bldg\\\\pbewht00.wav\" __4},\n\t{W,0,\"protoss/units/citadel\",\"sound\\\\protoss\\\\bldg\\\\pciwht00.wav\" __4},\n\t{W,0,\"protoss/units/forge\",\"sound\\\\protoss\\\\bldg\\\\pfowht00.wav\" __4},\n\t{W,0,\"protoss/units/gateway\",\"sound\\\\protoss\\\\bldg\\\\pgawht00.wav\" __4},\n\t{W,0,\"protoss/units/cybernetics core\",\"sound\\\\protoss\\\\bldg\\\\pgcwht00.wav\" __4},\n\t{W,0,\"protoss/units/nawht00\",\"sound\\\\protoss\\\\bldg\\\\pnawht00.wav\" __4},\n\t{W,0,\"protoss/units/nexus\",\"sound\\\\protoss\\\\bldg\\\\pnewht00.wav\" __4},\n\t{W,0,\"protoss/units/pbwht00\",\"sound\\\\protoss\\\\bldg\\\\ppbwht00.wav\" __4},\n\t{W,0,\"protoss/units/pylon\",\"sound\\\\protoss\\\\bldg\\\\ppywht00.wav\" __4},\n\t{W,0,\"protoss/units/robotics facility\",\"sound\\\\protoss\\\\bldg\\\\prowht00.wav\" __4},\n\t{W,0,\"protoss/units/stwht00\",\"sound\\\\protoss\\\\bldg\\\\pstwht00.wav\" __4},\n\t{W,0,\"protoss/units/trwht00\",\"sound\\\\protoss\\\\bldg\\\\ptrwht00.wav\" __4},\n\t{W,0,\"protoss/units/fleet beacon\",\"sound\\\\protoss\\\\bldg\\\\pwawht00.wav\" __4},\n\t{W,0,\"protoss/units/phofir00\",\"sound\\\\Bullet\\\\Phofir00.wav\" __4},\n\t{W,0,\"protoss/units/phohit00\",\"sound\\\\bullet\\\\phohit00.wav\" __4},\n\t{W,0,\"protoss/units/psahit00\",\"sound\\\\bullet\\\\psahit00.wav\" __4},\n\t{W,0,\"protoss/units/pshield\",\"sound\\\\bullet\\\\pshield.wav\" __4},\n\t{W,0,\"protoss/units/psiblade\",\"sound\\\\bullet\\\\psiblade.wav\" __4},\n\t{W,0,\"protoss/units/psibolt\",\"sound\\\\bullet\\\\psibolt.wav\" __4},\n\t{W,0,\"protoss/units/ptrfir00\",\"sound\\\\bullet\\\\ptrfir00.wav\" __4},\n\t{W,0,\"protoss/units/ptrfir01\",\"sound\\\\bullet\\\\ptrfir01.wav\" __4},\n\n\t// Zerg sounds\n\t{W,0,\"zerg/units/advisor/require minerals\",\"sound\\\\zerg\\\\advisor\\\\zaderr00.wav\" __4},\n\t{W,0,\"zerg/units/advisor/require gas\",\"sound\\\\zerg\\\\advisor\\\\zaderr01.wav\" __4},\n\t{W,0,\"zerg/units/advisor/spawn overlords\",\"sound\\\\zerg\\\\advisor\\\\zaderr02.wav\" __4},\n\t{W,0,\"zerg/units/advisor/not enough energy\",\"sound\\\\Zerg\\\\Advisor\\\\ZAdErr06.wav\" __4},\n\t{W,0,\"zerg/units/advisor/base attacked\",\"sound\\\\zerg\\\\advisor\\\\zadupd00.wav\" __4},\n\t{W,0,\"zerg/units/advisor/units attacked\",\"sound\\\\zerg\\\\advisor\\\\zadupd01.wav\" __4},\n\t{W,0,\"zerg/units/advisor/evolution complete\",\"sound\\\\zerg\\\\advisor\\\\zadupd02.wav\" __4},\n\t{W,0,\"zerg/units/advisor/nuclear launch\",\"sound\\\\zerg\\\\advisor\\\\zadupd04.wav\" __4},\n\t{W,0,\"zerg/units/scourge/att00\",\"sound\\\\Zerg\\\\AVENGER\\\\ZAvAtt00.wav\" __4},\n\t{W,0,\"zerg/units/scourge/death/1\",\"sound\\\\zerg\\\\avenger\\\\zavdth00.wav\" __4},\n\t{W,0,\"zerg/units/scourge/hit00\",\"sound\\\\Zerg\\\\AVENGER\\\\ZAvHit00.wav\" __4},\n\t{W,0,\"zerg/units/scourge/pissed/1\",\"sound\\\\zerg\\\\avenger\\\\zavpss00.wav\" __4},\n\t{W,0,\"zerg/units/scourge/pissed/2\",\"sound\\\\zerg\\\\avenger\\\\zavpss01.wav\" __4},\n\t{W,0,\"zerg/units/scourge/ready\",\"sound\\\\zerg\\\\avenger\\\\zavrdy00.wav\" __4},\n\t{W,0,\"zerg/units/scourge/selected/1\",\"sound\\\\zerg\\\\avenger\\\\zavwht00.wav\" __4},\n\t{W,0,\"zerg/units/scourge/selected/2\",\"sound\\\\zerg\\\\avenger\\\\zavwht01.wav\" __4},\n\t{W,0,\"zerg/units/scourge/acknowledgement/1\",\"sound\\\\zerg\\\\avenger\\\\zavyes00.wav\" __4},\n\t{W,0,\"zerg/units/scourge/acknowledgement/2\",\"sound\\\\zerg\\\\avenger\\\\zavyes01.wav\" __4},\n\t{W,0,\"zerg/units/building death\",\"sound\\\\zerg\\\\bldg\\\\zbldgdth.wav\" __4},\n\t{W,0,\"zerg/units/cb\",\"sound\\\\Zerg\\\\Bldg\\\\ZCbWht00.wav\" __4},\n\t{W,0,\"zerg/units/morph complete\",\"sound\\\\zerg\\\\bldg\\\\zchrdy00.wav\" __4},\n\t{W,0,\"zerg/units/spawning pool selected\",\"sound\\\\zerg\\\\bldg\\\\zchwht00.wav\" __4},\n\t{W,0,\"zerg/units/evolution chamber selected\",\"sound\\\\zerg\\\\bldg\\\\zevwht00.wav\" __4},\n\t{W,0,\"zerg/units/creep colony selected\",\"sound\\\\zerg\\\\bldg\\\\zfcwht00.wav\" __4},\n\t{W,0,\"zerg/units/hatchery selected\",\"sound\\\\zerg\\\\bldg\\\\zhawht00.wav\" __4},\n\t{W,0,\"zerg/units/lair selected\",\"sound\\\\zerg\\\\bldg\\\\zhiwht00.wav\" __4},\n\t{W,0,\"zerg/units/extractor selected\",\"sound\\\\zerg\\\\bldg\\\\zigwht00.wav\" __4},\n\t{W,0,\"zerg/units/hive selected\",\"sound\\\\zerg\\\\bldg\\\\zlrwht00.wav\" __4},\n\t{W,0,\"zerg/units/sunken colony selected\",\"sound\\\\zerg\\\\bldg\\\\zluwht00.wav\" __4},\n\t{W,0,\"zerg/units/greater spire selected\",\"sound\\\\zerg\\\\bldg\\\\zmcwht00.wav\" __4},\n\t{W,0,\"zerg/units/defiler mound selected\",\"sound\\\\zerg\\\\bldg\\\\zmhwht00.wav\" __4},\n\t{W,0,\"zerg/units/queens nest selected\",\"sound\\\\zerg\\\\bldg\\\\znewht00.wav\" __4},\n\t{W,0,\"zerg/units/nydus canal selected\",\"sound\\\\zerg\\\\bldg\\\\znywht00.wav\" __4},\n\t{W,0,\"zerg/units/o1\",\"sound\\\\zerg\\\\bldg\\\\zo1wht00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk cavern selected\",\"sound\\\\zerg\\\\bldg\\\\zrcwht00.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk den selected\",\"sound\\\\zerg\\\\bldg\\\\zsbwht00.wav\" __4},\n\t{W,0,\"zerg/units/spore colony selected\",\"sound\\\\zerg\\\\bldg\\\\zscwht00.wav\" __4},\n\t{W,0,\"zerg/units/spire selected\",\"sound\\\\zerg\\\\bldg\\\\zspwht00.wav\" __4},\n\t{W,0,\"zerg/units/broodling/att00\",\"sound\\\\zerg\\\\broodling\\\\zbratt00.wav\" __4},\n\t{W,0,\"zerg/units/broodling/death/1\",\"sound\\\\zerg\\\\broodling\\\\zbrdth00.wav\" __4},\n\t{W,0,\"zerg/units/broodling/pissed/1\",\"sound\\\\zerg\\\\broodling\\\\zbrpss00.wav\" __4},\n\t{W,0,\"zerg/units/broodling/pissed/2\",\"sound\\\\zerg\\\\broodling\\\\zbrpss01.wav\" __4},\n\t{W,0,\"zerg/units/broodling/pissed/3\",\"sound\\\\zerg\\\\broodling\\\\zbrpss02.wav\" __4},\n\t{W,0,\"zerg/units/broodling/pissed/4\",\"sound\\\\zerg\\\\broodling\\\\zbrpss03.wav\" __4},\n\t{W,0,\"zerg/units/broodling/ready\",\"sound\\\\zerg\\\\broodling\\\\zbrrdy00.wav\" __4},\n\t{W,0,\"zerg/units/broodling/selected/1\",\"sound\\\\zerg\\\\broodling\\\\zbrwht00.wav\" __4},\n\t{W,0,\"zerg/units/broodling/selected/2\",\"sound\\\\zerg\\\\broodling\\\\zbrwht01.wav\" __4},\n\t{W,0,\"zerg/units/broodling/selected/3\",\"sound\\\\zerg\\\\broodling\\\\zbrwht02.wav\" __4},\n\t{W,0,\"zerg/units/broodling/selected/4\",\"sound\\\\zerg\\\\broodling\\\\zbrwht03.wav\" __4},\n\t{W,0,\"zerg/units/broodling/acknowledgement/1\",\"sound\\\\zerg\\\\broodling\\\\zbryes00.wav\" __4},\n\t{W,0,\"zerg/units/broodling/acknowledgement/2\",\"sound\\\\zerg\\\\broodling\\\\zbryes01.wav\" __4},\n\t{W,0,\"zerg/units/broodling/acknowledgement/3\",\"sound\\\\zerg\\\\broodling\\\\zbryes02.wav\" __4},\n\t{W,0,\"zerg/units/broodling/acknowledgement/4\",\"sound\\\\zerg\\\\broodling\\\\zbryes03.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/pissed/1\",\"sound\\\\zerg\\\\bugguy\\\\zbgpss00.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/pissed/2\",\"sound\\\\zerg\\\\bugguy\\\\zbgpss01.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/pissed/3\",\"sound\\\\zerg\\\\bugguy\\\\zbgpss02.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/pissed/4\",\"sound\\\\zerg\\\\bugguy\\\\zbgpss03.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/ready\",\"sound\\\\zerg\\\\bugguy\\\\zbgrdy00.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/selected/1\",\"sound\\\\zerg\\\\bugguy\\\\zbgwht00.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/selected/2\",\"sound\\\\zerg\\\\bugguy\\\\zbgwht01.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/selected/3\",\"sound\\\\zerg\\\\bugguy\\\\zbgwht02.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/selected/4\",\"sound\\\\zerg\\\\bugguy\\\\zbgwht03.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/acknowledgement/1\",\"sound\\\\zerg\\\\bugguy\\\\zbgyes00.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/acknowledgement/2\",\"sound\\\\zerg\\\\bugguy\\\\zbgyes01.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/acknowledgement/3\",\"sound\\\\zerg\\\\bugguy\\\\zbgyes02.wav\" __4},\n\t{W,0,\"zerg/units/infested terran/acknowledgement/4\",\"sound\\\\zerg\\\\bugguy\\\\zbgyes03.wav\" __4},\n\t{W,0,\"zerg/units/defiler/plague cast\",\"sound\\\\zerg\\\\defiler\\\\zdeblo00.wav\" __4},\n\t{W,0,\"zerg/units/defiler/plague selected\",\"sound\\\\zerg\\\\defiler\\\\zdeblo01.wav\" __4},\n\t{W,0,\"zerg/units/defiler/consume\",\"sound\\\\zerg\\\\defiler\\\\zdecon00.wav\" __4},\n\t{W,0,\"zerg/units/defiler/death/1\",\"sound\\\\zerg\\\\defiler\\\\zdedth00.wav\" __4},\n\t{W,0,\"zerg/units/defiler/pissed/1\",\"sound\\\\zerg\\\\defiler\\\\zdepss00.wav\" __4},\n\t{W,0,\"zerg/units/defiler/pissed/2\",\"sound\\\\zerg\\\\defiler\\\\zdepss01.wav\" __4},\n\t{W,0,\"zerg/units/defiler/pissed/3\",\"sound\\\\zerg\\\\defiler\\\\zdepss02.wav\" __4},\n\t{W,0,\"zerg/units/defiler/pissed/4\",\"sound\\\\zerg\\\\defiler\\\\zdepss03.wav\" __4},\n\t{W,0,\"zerg/units/defiler/ready\",\"sound\\\\zerg\\\\defiler\\\\zderdy00.wav\" __4},\n\t{W,0,\"zerg/units/defiler/selected/1\",\"sound\\\\zerg\\\\defiler\\\\zdewht00.wav\" __4},\n\t{W,0,\"zerg/units/defiler/selected/2\",\"sound\\\\zerg\\\\defiler\\\\zdewht01.wav\" __4},\n\t{W,0,\"zerg/units/defiler/selected/3\",\"sound\\\\zerg\\\\defiler\\\\zdewht02.wav\" __4},\n\t{W,0,\"zerg/units/defiler/selected/4\",\"sound\\\\zerg\\\\defiler\\\\zdewht03.wav\" __4},\n\t{W,0,\"zerg/units/defiler/acknowledgement/1\",\"sound\\\\zerg\\\\defiler\\\\zdeyes00.wav\" __4},\n\t{W,0,\"zerg/units/defiler/acknowledgement/2\",\"sound\\\\zerg\\\\defiler\\\\zdeyes01.wav\" __4},\n\t{W,0,\"zerg/units/defiler/acknowledgement/3\",\"sound\\\\zerg\\\\defiler\\\\zdeyes02.wav\" __4},\n\t{W,0,\"zerg/units/defiler/acknowledgement/4\",\"sound\\\\zerg\\\\defiler\\\\zdeyes03.wav\" __4},\n\t{W,0,\"zerg/units/drone/death/1\",\"sound\\\\Zerg\\\\DRONE\\\\ZDrDth00.wav\" __4},\n\t{W,0,\"zerg/units/drone/err00\",\"sound\\\\zerg\\\\drone\\\\zdrerr00.wav\" __4},\n\t{W,0,\"zerg/units/drone/min00\",\"sound\\\\zerg\\\\drone\\\\zdrmin00.wav\" __4},\n\t{W,0,\"zerg/units/drone/pissed/1\",\"sound\\\\Zerg\\\\DRONE\\\\ZDrPss00.wav\" __4},\n\t{W,0,\"zerg/units/drone/pissed/2\",\"sound\\\\Zerg\\\\DRONE\\\\ZDrPss01.wav\" __4},\n\t{W,0,\"zerg/units/drone/pissed/3\",\"sound\\\\Zerg\\\\DRONE\\\\ZDrPss02.wav\" __4},\n\t{W,0,\"zerg/units/drone/ready\",\"sound\\\\zerg\\\\drone\\\\zdrrdy00.wav\" __4},\n\t{W,0,\"zerg/units/drone/selected/1\",\"sound\\\\zerg\\\\drone\\\\zdrwht00.wav\" __4},\n\t{W,0,\"zerg/units/drone/selected/2\",\"sound\\\\zerg\\\\drone\\\\zdrwht01.wav\" __4},\n\t{W,0,\"zerg/units/drone/selected/3\",\"sound\\\\zerg\\\\drone\\\\zdrwht02.wav\" __4},\n\t{W,0,\"zerg/units/drone/selected/4\",\"sound\\\\zerg\\\\drone\\\\zdrwht03.wav\" __4},\n\t{W,0,\"zerg/units/drone/selected/5\",\"sound\\\\zerg\\\\drone\\\\zdrwht04.wav\" __4},\n\t{W,0,\"zerg/units/drone/acknowledgement/1\",\"sound\\\\zerg\\\\drone\\\\zdryes00.wav\" __4},\n\t{W,0,\"zerg/units/drone/acknowledgement/2\",\"sound\\\\zerg\\\\drone\\\\zdryes01.wav\" __4},\n\t{W,0,\"zerg/units/drone/acknowledgement/3\",\"sound\\\\zerg\\\\drone\\\\zdryes02.wav\" __4},\n\t{W,0,\"zerg/units/drone/acknowledgement/4\",\"sound\\\\zerg\\\\drone\\\\zdryes03.wav\" __4},\n\t{W,0,\"zerg/units/drone/acknowledgement/5\",\"sound\\\\zerg\\\\drone\\\\zdryes04.wav\" __4},\n\t{W,0,\"zerg/units/egg/death/1\",\"sound\\\\zerg\\\\egg\\\\zegdth00.wav\" __4},\n\t{W,0,\"zerg/units/egg/pissed/1\",\"sound\\\\Zerg\\\\Egg\\\\ZEgPss00.wav\" __4},\n\t{W,0,\"zerg/units/egg/ready\",\"sound\\\\zerg\\\\egg\\\\zegrdy00.wav\" __4},\n\t{W,0,\"zerg/units/egg/selected/1\",\"sound\\\\zerg\\\\egg\\\\zegwht00.wav\" __4},\n\t{W,0,\"zerg/units/egg/selected/2\",\"sound\\\\zerg\\\\egg\\\\zegwht01.wav\" __4},\n\t{W,0,\"zerg/units/guardian/death/1\",\"sound\\\\zerg\\\\guardian\\\\zgudth00.wav\" __4},\n\t{W,0,\"zerg/units/guardian/pissed/1\",\"sound\\\\zerg\\\\guardian\\\\zgupss00.wav\" __4},\n\t{W,0,\"zerg/units/guardian/pissed/2\",\"sound\\\\zerg\\\\guardian\\\\zgupss01.wav\" __4},\n\t{W,0,\"zerg/units/guardian/pissed/3\",\"sound\\\\zerg\\\\guardian\\\\zgupss02.wav\" __4},\n\t{W,0,\"zerg/units/guardian/pissed/4\",\"sound\\\\zerg\\\\guardian\\\\zgupss03.wav\" __4},\n\t{W,0,\"zerg/units/guardian/ready\",\"sound\\\\zerg\\\\guardian\\\\zgurdy00.wav\" __4},\n\t{W,0,\"zerg/units/guardian/selected/1\",\"sound\\\\zerg\\\\guardian\\\\zguwht00.wav\" __4},\n\t{W,0,\"zerg/units/guardian/selected/2\",\"sound\\\\zerg\\\\guardian\\\\zguwht01.wav\" __4},\n\t{W,0,\"zerg/units/guardian/selected/3\",\"sound\\\\zerg\\\\guardian\\\\zguwht02.wav\" __4},\n\t{W,0,\"zerg/units/guardian/selected/4\",\"sound\\\\zerg\\\\guardian\\\\zguwht03.wav\" __4},\n\t{W,0,\"zerg/units/guardian/acknowledgement/1\",\"sound\\\\zerg\\\\guardian\\\\zguyes00.wav\" __4},\n\t{W,0,\"zerg/units/guardian/acknowledgement/2\",\"sound\\\\zerg\\\\guardian\\\\zguyes01.wav\" __4},\n\t{W,0,\"zerg/units/guardian/acknowledgement/3\",\"sound\\\\zerg\\\\guardian\\\\zguyes02.wav\" __4},\n\t{W,0,\"zerg/units/guardian/acknowledgement/4\",\"sound\\\\zerg\\\\guardian\\\\zguyes03.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/fir00\",\"Sound\\\\Zerg\\\\Hydra\\\\SpiFir00.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/death/1\",\"sound\\\\zerg\\\\hydra\\\\zhydth00.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/pissed/1\",\"sound\\\\zerg\\\\hydra\\\\zhypss00.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/pissed/2\",\"sound\\\\zerg\\\\hydra\\\\zhypss01.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/ready\",\"sound\\\\zerg\\\\hydra\\\\zhyrdy00.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/selected/1\",\"sound\\\\zerg\\\\hydra\\\\zhywht00.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/selected/2\",\"sound\\\\zerg\\\\hydra\\\\zhywht01.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/selected/3\",\"sound\\\\zerg\\\\hydra\\\\zhywht02.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/acknowledgement/1\",\"sound\\\\zerg\\\\hydra\\\\zhyyes00.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/acknowledgement/2\",\"sound\\\\zerg\\\\hydra\\\\zhyyes01.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/acknowledgement/3\",\"sound\\\\zerg\\\\hydra\\\\zhyyes02.wav\" __4},\n\t{W,0,\"zerg/units/hydralisk/acknowledgement/4\",\"sound\\\\zerg\\\\hydra\\\\zhyyes03.wav\" __4},\n\t{W,0,\"zerg/units/larva/death/1\",\"sound\\\\zerg\\\\larva\\\\zladth00.wav\" __4},\n\t{W,0,\"zerg/units/larva/pissed/1\",\"sound\\\\zerg\\\\larva\\\\zlapss00.wav\" __4},\n\t{W,0,\"zerg/units/larva/selected/1\",\"sound\\\\zerg\\\\larva\\\\zlawht00.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/death/1\",\"sound\\\\zerg\\\\mutalid\\\\zmudth00.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/pissed/1\",\"sound\\\\zerg\\\\mutalid\\\\zmupss00.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/pissed/2\",\"sound\\\\zerg\\\\mutalid\\\\zmupss01.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/pissed/3\",\"sound\\\\zerg\\\\mutalid\\\\zmupss02.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/pissed/4\",\"sound\\\\zerg\\\\mutalid\\\\zmupss03.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/ready\",\"sound\\\\zerg\\\\mutalid\\\\zmurdy00.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/selected/1\",\"sound\\\\zerg\\\\mutalid\\\\zmuwht00.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/selected/2\",\"sound\\\\zerg\\\\mutalid\\\\zmuwht01.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/selected/3\",\"sound\\\\zerg\\\\mutalid\\\\zmuwht02.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/selected/4\",\"sound\\\\zerg\\\\mutalid\\\\zmuwht03.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/acknowledgement/1\",\"sound\\\\zerg\\\\mutalid\\\\zmuyes00.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/acknowledgement/2\",\"sound\\\\zerg\\\\mutalid\\\\zmuyes01.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/acknowledgement/3\",\"sound\\\\zerg\\\\mutalid\\\\zmuyes02.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/acknowledgement/4\",\"sound\\\\zerg\\\\mutalid\\\\zmuyes03.wav\" __4},\n\t{W,0,\"zerg/units/overlord/death/1\",\"sound\\\\zerg\\\\overlord\\\\zovdth00.wav\" __4},\n\t{W,0,\"zerg/units/overlord/pissed/1\",\"sound\\\\zerg\\\\overlord\\\\zovpss00.wav\" __4},\n\t{W,0,\"zerg/units/overlord/pissed/2\",\"sound\\\\zerg\\\\overlord\\\\zovpss01.wav\" __4},\n\t{W,0,\"zerg/units/overlord/pissed/3\",\"sound\\\\zerg\\\\overlord\\\\zovpss02.wav\" __4},\n\t{W,0,\"zerg/units/overlord/pissed/4\",\"sound\\\\zerg\\\\overlord\\\\zovpss03.wav\" __4},\n\t{W,0,\"zerg/units/overlord/ready\",\"sound\\\\zerg\\\\overlord\\\\zovrdy00.wav\" __4},\n\t{W,0,\"zerg/units/overlord/selected/1\",\"sound\\\\zerg\\\\overlord\\\\zovwht00.wav\" __4},\n\t{W,0,\"zerg/units/overlord/selected/2\",\"sound\\\\zerg\\\\overlord\\\\zovwht01.wav\" __4},\n\t{W,0,\"zerg/units/overlord/selected/3\",\"sound\\\\zerg\\\\overlord\\\\zovwht02.wav\" __4},\n\t{W,0,\"zerg/units/overlord/selected/4\",\"sound\\\\zerg\\\\overlord\\\\zovwht03.wav\" __4},\n\t{W,0,\"zerg/units/overlord/acknowledgement/1\",\"sound\\\\zerg\\\\overlord\\\\zovyes00.wav\" __4},\n\t{W,0,\"zerg/units/overlord/acknowledgement/2\",\"sound\\\\zerg\\\\overlord\\\\zovyes01.wav\" __4},\n\t{W,0,\"zerg/units/overlord/acknowledgement/3\",\"sound\\\\zerg\\\\overlord\\\\zovyes02.wav\" __4},\n\t{W,0,\"zerg/units/overlord/acknowledgement/4\",\"sound\\\\zerg\\\\overlord\\\\zovyes03.wav\" __4},\n\t{W,0,\"zerg/units/queen/death/1\",\"sound\\\\zerg\\\\queen\\\\zqudth00.wav\" __4},\n\t{W,0,\"zerg/units/queen/death/2\",\"sound\\\\zerg\\\\queen\\\\zqudth01.wav\" __4},\n\t{W,0,\"zerg/units/queen/death/3\",\"sound\\\\zerg\\\\queen\\\\zqudth02.wav\" __4},\n\t{W,0,\"zerg/units/queen/ensnare cast\",\"sound\\\\Zerg\\\\Queen\\\\ZQuEns00.wav\" __4},\n\t{W,0,\"zerg/units/queen/pissed/1\",\"sound\\\\zerg\\\\queen\\\\zqupss00.wav\" __4},\n\t{W,0,\"zerg/units/queen/pissed/2\",\"sound\\\\zerg\\\\queen\\\\zqupss01.wav\" __4},\n\t{W,0,\"zerg/units/queen/pissed/3\",\"sound\\\\zerg\\\\queen\\\\zqupss02.wav\" __4},\n\t{W,0,\"zerg/units/queen/pissed/4\",\"sound\\\\zerg\\\\queen\\\\zqupss03.wav\" __4},\n\t{W,0,\"zerg/units/queen/ready\",\"sound\\\\zerg\\\\queen\\\\zqurdy00.wav\" __4},\n\t{W,0,\"zerg/units/queen/swm00\",\"sound\\\\zerg\\\\queen\\\\zquswm00.wav\" __4},\n\t{W,0,\"zerg/units/queen/swm01\",\"sound\\\\zerg\\\\queen\\\\zquswm01.wav\" __4},\n\t{W,0,\"zerg/units/queen/tag00\",\"sound\\\\zerg\\\\queen\\\\zqutag00.wav\" __4},\n\t{W,0,\"zerg/units/queen/parasite cast\",\"sound\\\\zerg\\\\queen\\\\zqutag01.wav\" __4},\n\t{W,0,\"zerg/units/queen/selected/1\",\"sound\\\\zerg\\\\queen\\\\zquwht00.wav\" __4},\n\t{W,0,\"zerg/units/queen/selected/2\",\"sound\\\\zerg\\\\queen\\\\zquwht01.wav\" __4},\n\t{W,0,\"zerg/units/queen/selected/3\",\"sound\\\\zerg\\\\queen\\\\zquwht02.wav\" __4},\n\t{W,0,\"zerg/units/queen/selected/4\",\"sound\\\\zerg\\\\queen\\\\zquwht03.wav\" __4},\n\t{W,0,\"zerg/units/queen/acknowledgement/1\",\"sound\\\\zerg\\\\queen\\\\zquyes00.wav\" __4},\n\t{W,0,\"zerg/units/queen/acknowledgement/2\",\"sound\\\\zerg\\\\queen\\\\zquyes01.wav\" __4},\n\t{W,0,\"zerg/units/queen/acknowledgement/3\",\"sound\\\\zerg\\\\queen\\\\zquyes02.wav\" __4},\n\t{W,0,\"zerg/units/queen/acknowledgement/4\",\"sound\\\\zerg\\\\queen\\\\zquyes03.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/att00\",\"sound\\\\zerg\\\\ultra\\\\zulatt00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/att01\",\"sound\\\\zerg\\\\ultra\\\\zulatt01.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/att02\",\"sound\\\\zerg\\\\ultra\\\\zulatt02.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/death/1\",\"sound\\\\zerg\\\\ultra\\\\zuldth00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/hit00\",\"sound\\\\zerg\\\\ultra\\\\zulhit00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/hit01\",\"sound\\\\zerg\\\\ultra\\\\zulhit01.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/pissed/1\",\"sound\\\\zerg\\\\ultra\\\\zulpss00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/pissed/2\",\"sound\\\\zerg\\\\ultra\\\\zulpss01.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/pissed/3\",\"sound\\\\zerg\\\\ultra\\\\zulpss02.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/ready\",\"sound\\\\zerg\\\\ultra\\\\zulrdy00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/ror00\",\"sound\\\\zerg\\\\ultra\\\\zulror00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/selected/1\",\"sound\\\\zerg\\\\ultra\\\\zulwht00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/selected/2\",\"sound\\\\zerg\\\\ultra\\\\zulwht01.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/selected/3\",\"sound\\\\zerg\\\\ultra\\\\zulwht02.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/selected/1\",\"sound\\\\zerg\\\\ultra\\\\zulwht03.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/acknowledgement/1\",\"sound\\\\zerg\\\\ultra\\\\zulyes00.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/acknowledgement/2\",\"sound\\\\zerg\\\\ultra\\\\zulyes01.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/acknowledgement/3\",\"sound\\\\zerg\\\\ultra\\\\zulyes02.wav\" __4},\n\t{W,0,\"zerg/units/ultralisk/acknowledgement/4\",\"sound\\\\zerg\\\\ultra\\\\zulyes03.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/death/1\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiDth00.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/pissed/1\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiPss00.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/pissed/2\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiPss01.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/pissed/3\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiPss02.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/pissed/4\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiPss03.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/selected/1\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiWht00.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/selected/2\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiWht01.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/selected/3\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiWht02.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/selected/4\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiWht03.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/acknowledgement/1\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiYes00.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/acknowledgement/2\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiYes01.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/acknowledgement/3\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiYes02.wav\" __4},\n\t{W,0,\"zerg/units/kerrigan/acknowledgement/4\",\"sound\\\\Zerg\\\\ZERGKERRI\\\\UKiYes03.wav\" __4},\n\t{W,0,\"zerg/units/zergling/death/1\",\"sound\\\\zerg\\\\zergling\\\\zzedth00.wav\" __4},\n\t{W,0,\"zerg/units/zergling/pissed/1\",\"sound\\\\zerg\\\\zergling\\\\zzepss00.wav\" __4},\n\t{W,0,\"zerg/units/zergling/pissed/2\",\"sound\\\\zerg\\\\zergling\\\\zzepss01.wav\" __4},\n\t{W,0,\"zerg/units/zergling/pissed/3\",\"sound\\\\zerg\\\\zergling\\\\zzepss02.wav\" __4},\n\t{W,0,\"zerg/units/zergling/ready\",\"sound\\\\zerg\\\\zergling\\\\zzerdy00.wav\" __4},\n\t{W,0,\"zerg/units/zergling/selected/1\",\"sound\\\\zerg\\\\zergling\\\\zzewht00.wav\" __4},\n\t{W,0,\"zerg/units/zergling/selected/2\",\"sound\\\\zerg\\\\zergling\\\\zzewht01.wav\" __4},\n\t{W,0,\"zerg/units/zergling/selected/3\",\"sound\\\\zerg\\\\zergling\\\\zzewht02.wav\" __4},\n\t{W,0,\"zerg/units/zergling/selected/4\",\"sound\\\\zerg\\\\zergling\\\\zzewht03.wav\" __4},\n\t{W,0,\"zerg/units/zergling/acknowledgement/1\",\"sound\\\\zerg\\\\zergling\\\\zzeyes00.wav\" __4},\n\t{W,0,\"zerg/units/zergling/acknowledgement/2\",\"sound\\\\zerg\\\\zergling\\\\zzeyes01.wav\" __4},\n\t{W,0,\"zerg/units/zergling/acknowledgement/3\",\"sound\\\\zerg\\\\zergling\\\\zzeyes02.wav\" __4},\n\t{W,0,\"zerg/units/zergling/acknowledgement/4\",\"sound\\\\zerg\\\\zergling\\\\zzeyes03.wav\" __4},\n\t{W,0,\"zerg/units/bghit00\",\"sound\\\\Bullet\\\\ZBGHit00.wav\" __4},\n\t{W,0,\"zerg/units/deatt00\",\"sound\\\\bullet\\\\zdeatt00.wav\" __4},\n\t{W,0,\"zerg/units/drhit00\",\"sound\\\\bullet\\\\zdrhit00.wav\" __4},\n\t{W,0,\"zerg/units/guardian/fir00\",\"sound\\\\Bullet\\\\ZGuFir00.wav\" __4},\n\t{W,0,\"zerg/units/guardian/hit00\",\"sound\\\\Bullet\\\\ZGuHit00.wav\" __4},\n\t{W,0,\"zerg/units/hyfir00\",\"sound\\\\bullet\\\\zhyfir00.wav\" __4},\n\t{W,0,\"zerg/units/hyhit00\",\"sound\\\\bullet\\\\zhyhit00.wav\" __4},\n\t{W,0,\"zerg/units/lufir00\",\"sound\\\\bullet\\\\zlufir00.wav\" __4},\n\t{W,0,\"zerg/units/luhit00\",\"sound\\\\bullet\\\\zluhit00.wav\" __4},\n\t{W,0,\"zerg/units/mutalisk/fir00\",\"sound\\\\bullet\\\\zmufir00.wav\" __4},\n\t{W,0,\"zerg/units/qufir00\",\"sound\\\\bullet\\\\zqufir00.wav\" __4},\n\t{W,0,\"zerg/units/quhit00\",\"sound\\\\bullet\\\\zquhit00.wav\" __4},\n\t{W,0,\"zerg/units/quhit01\",\"sound\\\\bullet\\\\zquhit01.wav\" __4},\n\t{W,0,\"zerg/units/quhit02\",\"sound\\\\bullet\\\\zquhit02.wav\" __4},\n\n\t// Misc sounds\n\t{W,0,\"misc/explo1\",\"sound\\\\misc\\\\explo1.wav\" __4},\n\t{W,0,\"misc/explo2\",\"sound\\\\misc\\\\explo2.wav\" __4},\n\t{W,0,\"misc/explo3\",\"sound\\\\misc\\\\explo3.wav\" __4},\n\t{W,0,\"misc/explo4\",\"sound\\\\misc\\\\explo4.wav\" __4},\n\t{W,0,\"misc/explo5\",\"sound\\\\misc\\\\explo5.wav\" __4},\n\t{W,0,\"misc/explolrg\",\"sound\\\\misc\\\\explolrg.wav\" __4},\n\t{W,0,\"misc/explomed\",\"sound\\\\misc\\\\explomed.wav\" __4},\n\t{W,0,\"misc/explosm\",\"sound\\\\misc\\\\explosm.wav\" __4},\n\n\t//Portrait Videos\n\t/*{P,0,\"portrait/uflag8/uf8fid00\",\"portrait\\\\uflag8\\\\uf8fid00.smk\" __4},\n\t{P,0,\"portrait/uflag8/uf8tlk00\",\"portrait\\\\uflag8\\\\uf8tlk00.smk\" __4},\n\t{P,0,\"portrait/zlarva/zlafid00\",\"portrait\\\\zlarva\\\\zlafid00.smk\" __4},\n\t{P,0,\"portrait/zlarva/zlatlk00\",\"portrait\\\\zlarva\\\\zlatlk00.smk\" __4},\n\t{P,0,\"portrait/ufenzeal/ufefid01\",\"portrait\\\\ufenzeal\\\\ufefid01.smk\" __4},\n\t{P,0,\"portrait/ufenzeal/ufefid02\",\"portrait\\\\ufenzeal\\\\ufefid02.smk\" __4},\n\t{P,0,\"portrait/ufenzeal/ufetlk02\",\"portrait\\\\ufenzeal\\\\ufetlk02.smk\" __4},\n\t{P,0,\"portrait/ufenzeal/ufetlk01\",\"portrait\\\\ufenzeal\\\\ufetlk01.smk\" __4},\n\t{P,0,\"portrait/ufenzeal/ufefid00\",\"portrait\\\\ufenzeal\\\\ufefid00.smk\" __4},\n\t{P,0,\"portrait/ufenzeal/ufefid03\",\"portrait\\\\ufenzeal\\\\ufefid03.smk\" __4},\n\t{P,0,\"portrait/ufenzeal/ufetlk00\",\"portrait\\\\ufenzeal\\\\ufetlk00.smk\" __4},\n\t{P,0,\"portrait/ttank/ttafid00\",\"portrait\\\\ttank\\\\ttafid00.smk\" __4},\n\t{P,0,\"portrait/ttank/ttatlk01\",\"portrait\\\\ttank\\\\ttatlk01.smk\" __4},\n\t{P,0,\"portrait/ttank/ttatlk00\",\"portrait\\\\ttank\\\\ttatlk00.smk\" __4},\n\t{P,0,\"portrait/ttank/ttafid02\",\"portrait\\\\ttank\\\\ttafid02.smk\" __4},\n\t{P,0,\"portrait/ttank/ttafid03\",\"portrait\\\\ttank\\\\ttafid03.smk\" __4},\n\t{P,0,\"portrait/ttank/ttafid01\",\"portrait\\\\ttank\\\\ttafid01.smk\" __4},\n\t{P,0,\"portrait/ttank/ttatlk02\",\"portrait\\\\ttank\\\\ttatlk02.smk\" __4},\n\t{P,0,\"portrait/zmutalid/zmufid00\",\"portrait\\\\zmutalid\\\\zmufid00.smk\" __4},\n\t{P,0,\"portrait/zmutalid/zmufid03\",\"portrait\\\\zmutalid\\\\zmufid03.smk\" __4},\n\t{P,0,\"portrait/zmutalid/zmufid02\",\"portrait\\\\zmutalid\\\\zmufid02.smk\" __4},\n\t{P,0,\"portrait/zmutalid/zmutlk02\",\"portrait\\\\zmutalid\\\\zmutlk02.smk\" __4},\n\t{P,0,\"portrait/zmutalid/zmufid01\",\"portrait\\\\zmutalid\\\\zmufid01.smk\" __4},\n\t{P,0,\"portrait/zmutalid/zmutlk00\",\"portrait\\\\zmutalid\\\\zmutlk00.smk\" __4},\n\t{P,0,\"portrait/zmutalid/zmutlk01\",\"portrait\\\\zmutalid\\\\zmutlk01.smk\" __4},\n\t{P,0,\"portrait/zqueen/zqutlk00\",\"portrait\\\\zqueen\\\\zqutlk00.smk\" __4},\n\t{P,0,\"portrait/zqueen/zqufid00\",\"portrait\\\\zqueen\\\\zqufid00.smk\" __4},\n\t{P,0,\"portrait/zqueen/zqufid02\",\"portrait\\\\zqueen\\\\zqufid02.smk\" __4},\n\t{P,0,\"portrait/zqueen/zqufid01\",\"portrait\\\\zqueen\\\\zqufid01.smk\" __4},\n\t{P,0,\"portrait/zqueen/zqufid03\",\"portrait\\\\zqueen\\\\zqufid03.smk\" __4},\n\t{P,0,\"portrait/nbadcrit/nbctlk02\",\"portrait\\\\nbadcrit\\\\nbctlk02.smk\" __4},\n\t{P,0,\"portrait/nbadcrit/nbcfid01\",\"portrait\\\\nbadcrit\\\\nbcfid01.smk\" __4},\n\t{P,0,\"portrait/nbadcrit/nbctlk01\",\"portrait\\\\nbadcrit\\\\nbctlk01.smk\" __4},\n\t{P,0,\"portrait/nbadcrit/nbcfid00\",\"portrait\\\\nbadcrit\\\\nbcfid00.smk\" __4},\n\t{P,0,\"portrait/nbadcrit/nbctlk00\",\"portrait\\\\nbadcrit\\\\nbctlk00.smk\" __4},\n\t{P,0,\"portrait/nbadcrit/nbcfid03\",\"portrait\\\\nbadcrit\\\\nbcfid03.smk\" __4},\n\t{P,0,\"portrait/nbadcrit/nbcfid02\",\"portrait\\\\nbadcrit\\\\nbcfid02.smk\" __4},\n\t{P,0,\"portrait/uikerr/uiktlk01\",\"portrait\\\\uikerr\\\\uiktlk01.smk\" __4},\n\t{P,0,\"portrait/uikerr/uikfid02\",\"portrait\\\\uikerr\\\\uikfid02.smk\" __4},\n\t{P,0,\"portrait/uikerr/uikfid01\",\"portrait\\\\uikerr\\\\uikfid01.smk\" __4},\n\t{P,0,\"portrait/uikerr/uiktlk00\",\"portrait\\\\uikerr\\\\uiktlk00.smk\" __4},\n\t{P,0,\"portrait/uikerr/uiktlk02\",\"portrait\\\\uikerr\\\\uiktlk02.smk\" __4},\n\t{P,0,\"portrait/uikerr/uikfid00\",\"portrait\\\\uikerr\\\\uikfid00.smk\" __4},\n\t{P,0,\"portrait/tbattlec/tbatlk02\",\"portrait\\\\tbattlec\\\\tbatlk02.smk\" __4},\n\t{P,0,\"portrait/tbattlec/tbafid03\",\"portrait\\\\tbattlec\\\\tbafid03.smk\" __4},\n\t{P,0,\"portrait/tbattlec/tbafid02\",\"portrait\\\\tbattlec\\\\tbafid02.smk\" __4},\n\t{P,0,\"portrait/tbattlec/tbafid00\",\"portrait\\\\tbattlec\\\\tbafid00.smk\" __4},\n\t{P,0,\"portrait/tbattlec/tbatlk01\",\"portrait\\\\tbattlec\\\\tbatlk01.smk\" __4},\n\t{P,0,\"portrait/tbattlec/tbafid01\",\"portrait\\\\tbattlec\\\\tbafid01.smk\" __4},\n\t{P,0,\"portrait/tbattlec/tbatlk00\",\"portrait\\\\tbattlec\\\\tbatlk00.smk\" __4},\n\t{P,0,\"portrait/pcarrier/pcafid02\",\"portrait\\\\pcarrier\\\\pcafid02.smk\" __4},\n\t{P,0,\"portrait/pcarrier/pcafid01\",\"portrait\\\\pcarrier\\\\pcafid01.smk\" __4},\n\t{P,0,\"portrait/pcarrier/pcatlk02\",\"portrait\\\\pcarrier\\\\pcatlk02.smk\" __4},\n\t{P,0,\"portrait/pcarrier/pcafid00\",\"portrait\\\\pcarrier\\\\pcafid00.smk\" __4},\n\t{P,0,\"portrait/pcarrier/pcatlk00\",\"portrait\\\\pcarrier\\\\pcatlk00.smk\" __4},\n\t{P,0,\"portrait/pcarrier/pcafid03\",\"portrait\\\\pcarrier\\\\pcafid03.smk\" __4},\n\t{P,0,\"portrait/pcarrier/pcatlk01\",\"portrait\\\\pcarrier\\\\pcatlk01.smk\" __4},\n\t{P,0,\"portrait/nore/nocfid00\",\"portrait\\\\nore\\\\nocfid00.smk\" __4},\n\t{P,0,\"portrait/tvessel/tvefid03\",\"portrait\\\\tvessel\\\\tvefid03.smk\" __4},\n\t{P,0,\"portrait/tvessel/tvefid00\",\"portrait\\\\tvessel\\\\tvefid00.smk\" __4},\n\t{P,0,\"portrait/tvessel/tvefid01\",\"portrait\\\\tvessel\\\\tvefid01.smk\" __4},\n\t{P,0,\"portrait/tvessel/tvetlk01\",\"portrait\\\\tvessel\\\\tvetlk01.smk\" __4},\n\t{P,0,\"portrait/tvessel/tvetlk00\",\"portrait\\\\tvessel\\\\tvetlk00.smk\" __4},\n\t{P,0,\"portrait/tvessel/tvefid02\",\"portrait\\\\tvessel\\\\tvefid02.smk\" __4},\n\t{P,0,\"portrait/tvessel/tvetlk02\",\"portrait\\\\tvessel\\\\tvetlk02.smk\" __4},\n\t{P,0,\"portrait/nadvisor/nadfid02\",\"portrait\\\\nadvisor\\\\nadfid02.smk\" __4},\n\t{P,0,\"portrait/nadvisor/nadtlk02\",\"portrait\\\\nadvisor\\\\nadtlk02.smk\" __4},\n\t{P,0,\"portrait/nadvisor/nadfid00\",\"portrait\\\\nadvisor\\\\nadfid00.smk\" __4},\n\t{P,0,\"portrait/nadvisor/nadfid01\",\"portrait\\\\nadvisor\\\\nadfid01.smk\" __4},\n\t{P,0,\"portrait/nadvisor/nadtlk00\",\"portrait\\\\nadvisor\\\\nadtlk00.smk\" __4},\n\t{P,0,\"portrait/nadvisor/nadtlk01\",\"portrait\\\\nadvisor\\\\nadtlk01.smk\" __4},\n\t{P,0,\"portrait/nadvisor/nadfid03\",\"portrait\\\\nadvisor\\\\nadfid03.smk\" __4},\n\t{P,0,\"portrait/tfirebat/tfbtlk00\",\"portrait\\\\tfirebat\\\\tfbtlk00.smk\" __4},\n\t{P,0,\"portrait/tfirebat/tfbtlk01\",\"portrait\\\\tfirebat\\\\tfbtlk01.smk\" __4},\n\t{P,0,\"portrait/tfirebat/tfbfid02\",\"portrait\\\\tfirebat\\\\tfbfid02.smk\" __4},\n\t{P,0,\"portrait/tfirebat/tfbfid03\",\"portrait\\\\tfirebat\\\\tfbfid03.smk\" __4},\n\t{P,0,\"portrait/tfirebat/tfbfid01\",\"portrait\\\\tfirebat\\\\tfbfid01.smk\" __4},\n\t{P,0,\"portrait/tfirebat/tfbfid00\",\"portrait\\\\tfirebat\\\\tfbfid00.smk\" __4},\n\t{P,0,\"portrait/pzealot/pzetlk01\",\"portrait\\\\pzealot\\\\pzetlk01.smk\" __4},\n\t{P,0,\"portrait/pzealot/pzefid02\",\"portrait\\\\pzealot\\\\pzefid02.smk\" __4},\n\t{P,0,\"portrait/pzealot/pzefid00\",\"portrait\\\\pzealot\\\\pzefid00.smk\" __4},\n\t{P,0,\"portrait/pzealot/pzefid01\",\"portrait\\\\pzealot\\\\pzefid01.smk\" __4},\n\t{P,0,\"portrait/pzealot/pzetlk00\",\"portrait\\\\pzealot\\\\pzetlk00.smk\" __4},\n\t{P,0,\"portrait/tvulture/tvutlk01\",\"portrait\\\\tvulture\\\\tvutlk01.smk\" __4},\n\t{P,0,\"portrait/tvulture/tvutlk00\",\"portrait\\\\tvulture\\\\tvutlk00.smk\" __4},\n\t{P,0,\"portrait/tvulture/tvufid01\",\"portrait\\\\tvulture\\\\tvufid01.smk\" __4},\n\t{P,0,\"portrait/tvulture/tvufid03\",\"portrait\\\\tvulture\\\\tvufid03.smk\" __4},\n\t{P,0,\"portrait/tvulture/tvufid02\",\"portrait\\\\tvulture\\\\tvufid02.smk\" __4},\n\t{P,0,\"portrait/tvulture/tvufid00\",\"portrait\\\\tvulture\\\\tvufid00.smk\" __4},\n\t{P,0,\"portrait/zchrysalis/zchfid01\",\"portrait\\\\zchrysalis\\\\zchfid01.smk\" __4},\n\t{P,0,\"portrait/zchrysalis/zchfid00\",\"portrait\\\\zchrysalis\\\\zchfid00.smk\" __4},\n\t{P,0,\"portrait/zchrysalis/zchfid02\",\"portrait\\\\zchrysalis\\\\zchfid02.smk\" __4},\n\t{P,0,\"portrait/ngassac/ngsfid00\",\"portrait\\\\ngassac\\\\ngsfid00.smk\" __4},\n\t{P,0,\"portrait/zover/zovtlk01\",\"portrait\\\\zover\\\\zovtlk01.smk\" __4},\n\t{P,0,\"portrait/zover/zovtlk02\",\"portrait\\\\zover\\\\zovtlk02.smk\" __4},\n\t{P,0,\"portrait/zover/zovtlk00\",\"portrait\\\\zover\\\\zovtlk00.smk\" __4},\n\t{P,0,\"portrait/zover/zovfid01\",\"portrait\\\\zover\\\\zovfid01.smk\" __4},\n\t{P,0,\"portrait/zover/zovfid03\",\"portrait\\\\zover\\\\zovfid03.smk\" __4},\n\t{P,0,\"portrait/zover/zovfid00\",\"portrait\\\\zover\\\\zovfid00.smk\" __4},\n\t{P,0,\"portrait/zover/zovfid02\",\"portrait\\\\zover\\\\zovfid02.smk\" __4},\n\t{P,0,\"portrait/ncivilian/ncifid01\",\"portrait\\\\ncivilian\\\\ncifid01.smk\" __4},\n\t{P,0,\"portrait/ncivilian/ncitlk00\",\"portrait\\\\ncivilian\\\\ncitlk00.smk\" __4},\n\t{P,0,\"portrait/ncivilian/ncitlk01\",\"portrait\\\\ncivilian\\\\ncitlk01.smk\" __4},\n\t{P,0,\"portrait/ncivilian/ncifid00\",\"portrait\\\\ncivilian\\\\ncifid00.smk\" __4},\n\t{P,0,\"portrait/ncivilian/ncifid02\",\"portrait\\\\ncivilian\\\\ncifid02.smk\" __4},\n\t{P,0,\"portrait/ncivilian/ncitlk02\",\"portrait\\\\ncivilian\\\\ncitlk02.smk\" __4},\n\t{P,0,\"portrait/tmarine/tmafid02\",\"portrait\\\\tmarine\\\\tmafid02.smk\" __4},\n\t{P,0,\"portrait/tmarine/tmatlk02\",\"portrait\\\\tmarine\\\\tmatlk02.smk\" __4},\n\t{P,0,\"portrait/tmarine/tmatlk00\",\"portrait\\\\tmarine\\\\tmatlk00.smk\" __4},\n\t{P,0,\"portrait/tmarine/tmafid03\",\"portrait\\\\tmarine\\\\tmafid03.smk\" __4},\n\t{P,0,\"portrait/tmarine/tmatlk01\",\"portrait\\\\tmarine\\\\tmatlk01.smk\" __4},\n\t{P,0,\"portrait/tmarine/tmafid01\",\"portrait\\\\tmarine\\\\tmafid01.smk\" __4},\n\t{P,0,\"portrait/tmarine/tmafid00\",\"portrait\\\\tmarine\\\\tmafid00.smk\" __4},\n\t{P,0,\"portrait/ptrilo/ptrfid01\",\"portrait\\\\ptrilo\\\\ptrfid01.smk\" __4},\n\t{P,0,\"portrait/ptrilo/ptrfid00\",\"portrait\\\\ptrilo\\\\ptrfid00.smk\" __4},\n\t{P,0,\"portrait/ptrilo/ptrfid03\",\"portrait\\\\ptrilo\\\\ptrfid03.smk\" __4},\n\t{P,0,\"portrait/ptrilo/ptrfid02\",\"portrait\\\\ptrilo\\\\ptrfid02.smk\" __4},\n\t{P,0,\"portrait/ptrilo/ptrtlk02\",\"portrait\\\\ptrilo\\\\ptrtlk02.smk\" __4},\n\t{P,0,\"portrait/ptrilo/ptrtlk00\",\"portrait\\\\ptrilo\\\\ptrtlk00.smk\" __4},\n\t{P,0,\"portrait/ptrilo/ptrtlk01\",\"portrait\\\\ptrilo\\\\ptrtlk01.smk\" __4},\n\t{P,0,\"portrait/uflag/ufltlk00\",\"portrait\\\\uflag\\\\ufltlk00.smk\" __4},\n\t{P,0,\"portrait/uflag/uflfid00\",\"portrait\\\\uflag\\\\uflfid00.smk\" __4},\n\t{P,0,\"portrait/pdragoon/pdrfid03\",\"portrait\\\\pdragoon\\\\pdrfid03.smk\" __4},\n\t{P,0,\"portrait/pdragoon/pdrfid01\",\"portrait\\\\pdragoon\\\\pdrfid01.smk\" __4},\n\t{P,0,\"portrait/pdragoon/pdrtlk00\",\"portrait\\\\pdragoon\\\\pdrtlk00.smk\" __4},\n\t{P,0,\"portrait/pdragoon/pdrfid02\",\"portrait\\\\pdragoon\\\\pdrfid02.smk\" __4},\n\t{P,0,\"portrait/pdragoon/pdrfid00\",\"portrait\\\\pdragoon\\\\pdrfid00.smk\" __4},\n\t{P,0,\"portrait/pdragoon/pdrtlk01\",\"portrait\\\\pdragoon\\\\pdrtlk01.smk\" __4},\n\t{P,0,\"portrait/pdragoon/pdrtlk02\",\"portrait\\\\pdragoon\\\\pdrtlk02.smk\" __4},\n\t{P,0,\"portrait/tspider/tmntlk00\",\"portrait\\\\tspider\\\\tmntlk00.smk\" __4},\n\t{P,0,\"portrait/tspider/tmnfid01\",\"portrait\\\\tspider\\\\tmnfid01.smk\" __4},\n\t{P,0,\"portrait/tspider/tmnfid00\",\"portrait\\\\tspider\\\\tmnfid00.smk\" __4},\n\t{P,0,\"portrait/nbiker/nbitlk00\",\"portrait\\\\nbiker\\\\nbitlk00.smk\" __4},\n\t{P,0,\"portrait/nbiker/nbifid03\",\"portrait\\\\nbiker\\\\nbifid03.smk\" __4},\n\t{P,0,\"portrait/nbiker/nbitlk02\",\"portrait\\\\nbiker\\\\nbitlk02.smk\" __4},\n\t{P,0,\"portrait/nbiker/nbitlk01\",\"portrait\\\\nbiker\\\\nbitlk01.smk\" __4},\n\t{P,0,\"portrait/nbiker/nbifid00\",\"portrait\\\\nbiker\\\\nbifid00.smk\" __4},\n\t{P,0,\"portrait/nbiker/nbifid01\",\"portrait\\\\nbiker\\\\nbifid01.smk\" __4},\n\t{P,0,\"portrait/nbiker/nbifid02\",\"portrait\\\\nbiker\\\\nbifid02.smk\" __4},\n\t{P,0,\"portrait/pprobe/pprfid02\",\"portrait\\\\pprobe\\\\pprfid02.smk\" __4},\n\t{P,0,\"portrait/pprobe/pprtlk01\",\"portrait\\\\pprobe\\\\pprtlk01.smk\" __4},\n\t{P,0,\"portrait/pprobe/pprfid00\",\"portrait\\\\pprobe\\\\pprfid00.smk\" __4},\n\t{P,0,\"portrait/pprobe/pprtlk00\",\"portrait\\\\pprobe\\\\pprtlk00.smk\" __4},\n\t{P,0,\"portrait/pprobe/pprfid01\",\"portrait\\\\pprobe\\\\pprfid01.smk\" __4},\n\t{P,0,\"portrait/pprobe/pprfid03\",\"portrait\\\\pprobe\\\\pprfid03.smk\" __4},\n\t{P,0,\"portrait/pprobe/pprtlk02\",\"portrait\\\\pprobe\\\\pprtlk02.smk\" __4},\n\t{P,0,\"portrait/uhunters/uhutlk02\",\"portrait\\\\uhunters\\\\uhutlk02.smk\" __4},\n\t{P,0,\"portrait/uhunters/uhutlk00\",\"portrait\\\\uhunters\\\\uhutlk00.smk\" __4},\n\t{P,0,\"portrait/uhunters/uhufid02\",\"portrait\\\\uhunters\\\\uhufid02.smk\" __4},\n\t{P,0,\"portrait/uhunters/uhufid01\",\"portrait\\\\uhunters\\\\uhufid01.smk\" __4},\n\t{P,0,\"portrait/uhunters/uhutlk01\",\"portrait\\\\uhunters\\\\uhutlk01.smk\" __4},\n\t{P,0,\"portrait/uhunters/uhufid00\",\"portrait\\\\uhunters\\\\uhufid00.smk\" __4},\n\t{P,0,\"portrait/zbrood/zbrfid01\",\"portrait\\\\zbrood\\\\zbrfid01.smk\" __4},\n\t{P,0,\"portrait/zbrood/zbrtlk01\",\"portrait\\\\zbrood\\\\zbrtlk01.smk\" __4},\n\t{P,0,\"portrait/zbrood/zbrfid03\",\"portrait\\\\zbrood\\\\zbrfid03.smk\" __4},\n\t{P,0,\"portrait/zbrood/zbrfid02\",\"portrait\\\\zbrood\\\\zbrfid02.smk\" __4},\n\t{P,0,\"portrait/zbrood/zbrtlk02\",\"portrait\\\\zbrood\\\\zbrtlk02.smk\" __4},\n\t{P,0,\"portrait/zbrood/zbrtlk00\",\"portrait\\\\zbrood\\\\zbrtlk00.smk\" __4},\n\t{P,0,\"portrait/zbrood/zbrfid00\",\"portrait\\\\zbrood\\\\zbrfid00.smk\" __4},\n\t{P,0,\"portrait/ujim/uratlk01\",\"portrait\\\\ujim\\\\uratlk01.smk\" __4},\n\t{P,0,\"portrait/ujim/urafid02\",\"portrait\\\\ujim\\\\urafid02.smk\" __4},\n\t{P,0,\"portrait/ujim/urafid03\",\"portrait\\\\ujim\\\\urafid03.smk\" __4},\n\t{P,0,\"portrait/ujim/urafid00\",\"portrait\\\\ujim\\\\urafid00.smk\" __4},\n\t{P,0,\"portrait/ujim/uratlk02\",\"portrait\\\\ujim\\\\uratlk02.smk\" __4},\n\t{P,0,\"portrait/ujim/urafid01\",\"portrait\\\\ujim\\\\urafid01.smk\" __4},\n\t{P,0,\"portrait/ujim/uratlk00\",\"portrait\\\\ujim\\\\uratlk00.smk\" __4},\n\t{P,0,\"portrait/uzasz/fid02\",\"portrait\\\\uzasz\\\\fid02.smk\" __4},\n\t{P,0,\"portrait/uzasz/fid00\",\"portrait\\\\uzasz\\\\fid00.smk\" __4},\n\t{P,0,\"portrait/uzasz/tlk02\",\"portrait\\\\uzasz\\\\tlk02.smk\" __4},\n\t{P,0,\"portrait/uzasz/tlk00\",\"portrait\\\\uzasz\\\\tlk00.smk\" __4},\n\t{P,0,\"portrait/uzasz/tlk01\",\"portrait\\\\uzasz\\\\tlk01.smk\" __4},\n\t{P,0,\"portrait/uzasz/fid01\",\"portrait\\\\uzasz\\\\fid01.smk\" __4},\n\t{P,0,\"portrait/ushard/ushfid00\",\"portrait\\\\ushard\\\\ushfid00.smk\" __4},\n\t{P,0,\"portrait/ushard/ushtlk00\",\"portrait\\\\ushard\\\\ushtlk00.smk\" __4},\n\t{P,0,\"portrait/uflag1/uf1fid00\",\"portrait\\\\uflag1\\\\uf1fid00.smk\" __4},\n\t{P,0,\"portrait/uflag1/uf1tlk00\",\"portrait\\\\uflag1\\\\uf1tlk00.smk\" __4},\n\t{P,0,\"portrait/ukerr/ukefid03\",\"portrait\\\\ukerr\\\\ukefid03.smk\" __4},\n\t{P,0,\"portrait/ukerr/ukefid00\",\"portrait\\\\ukerr\\\\ukefid00.smk\" __4},\n\t{P,0,\"portrait/ukerr/uketlk02\",\"portrait\\\\ukerr\\\\uketlk02.smk\" __4},\n\t{P,0,\"portrait/ukerr/uketlk01\",\"portrait\\\\ukerr\\\\uketlk01.smk\" __4},\n\t{P,0,\"portrait/ukerr/ukefid01\",\"portrait\\\\ukerr\\\\ukefid01.smk\" __4},\n\t{P,0,\"portrait/ukerr/uketlk00\",\"portrait\\\\ukerr\\\\uketlk00.smk\" __4},\n\t{P,0,\"portrait/ukerr/ukefid02\",\"portrait\\\\ukerr\\\\ukefid02.smk\" __4},\n\t{P,0,\"portrait/zhydra/zhyfid02\",\"portrait\\\\zhydra\\\\zhyfid02.smk\" __4},\n\t{P,0,\"portrait/zhydra/zhyfid01\",\"portrait\\\\zhydra\\\\zhyfid01.smk\" __4},\n\t{P,0,\"portrait/zhydra/zhyfid03\",\"portrait\\\\zhydra\\\\zhyfid03.smk\" __4},\n\t{P,0,\"portrait/zhydra/zhyfid00\",\"portrait\\\\zhydra\\\\zhyfid00.smk\" __4},\n\t{P,0,\"portrait/zhydra/zhytlk02\",\"portrait\\\\zhydra\\\\zhytlk02.smk\" __4},\n\t{P,0,\"portrait/zhydra/zhytlk00\",\"portrait\\\\zhydra\\\\zhytlk00.smk\" __4},\n\t{P,0,\"portrait/zhydra/zhytlk01\",\"portrait\\\\zhydra\\\\zhytlk01.smk\" __4},\n\t{P,0,\"portrait/zdefiler/zdetlk00\",\"portrait\\\\zdefiler\\\\zdetlk00.smk\" __4},\n\t{P,0,\"portrait/zdefiler/zdefid00\",\"portrait\\\\zdefiler\\\\zdefid00.smk\" __4},\n\t{P,0,\"portrait/zdefiler/zdetlk01\",\"portrait\\\\zdefiler\\\\zdetlk01.smk\" __4},\n\t{P,0,\"portrait/zdefiler/zdefid02\",\"portrait\\\\zdefiler\\\\zdefid02.smk\" __4},\n\t{P,0,\"portrait/zdefiler/zdefid03\",\"portrait\\\\zdefiler\\\\zdefid03.smk\" __4},\n\t{P,0,\"portrait/zdefiler/zdefid01\",\"portrait\\\\zdefiler\\\\zdefid01.smk\" __4},\n\t{P,0,\"portrait/parbiter/pabtlk01\",\"portrait\\\\parbiter\\\\pabtlk01.smk\" __4},\n\t{P,0,\"portrait/parbiter/pabtlk02\",\"portrait\\\\parbiter\\\\pabtlk02.smk\" __4},\n\t{P,0,\"portrait/parbiter/pabfid02\",\"portrait\\\\parbiter\\\\pabfid02.smk\" __4},\n\t{P,0,\"portrait/parbiter/pabtlk00\",\"portrait\\\\parbiter\\\\pabtlk00.smk\" __4},\n\t{P,0,\"portrait/parbiter/pabfid00\",\"portrait\\\\parbiter\\\\pabfid00.smk\" __4},\n\t{P,0,\"portrait/parbiter/pabfid03\",\"portrait\\\\parbiter\\\\pabfid03.smk\" __4},\n\t{P,0,\"portrait/parbiter/pabfid01\",\"portrait\\\\parbiter\\\\pabfid01.smk\" __4},\n\t{P,0,\"portrait/uflag6/uf6fid00\",\"portrait\\\\uflag6\\\\uf6fid00.smk\" __4},\n\t{P,0,\"portrait/uflag6/uf6tlk00\",\"portrait\\\\uflag6\\\\uf6tlk00.smk\" __4},\n\t{P,0,\"portrait/uflag3/uf3fid00\",\"portrait\\\\uflag3\\\\uf3fid00.smk\" __4},\n\t{P,0,\"portrait/uflag3/uf3tlk00\",\"portrait\\\\uflag3\\\\uf3tlk00.smk\" __4},\n\t{P,0,\"portrait/udagg/udgtlk01\",\"portrait\\\\udagg\\\\udgtlk01.smk\" __4},\n\t{P,0,\"portrait/udagg/udgtlk00\",\"portrait\\\\udagg\\\\udgtlk00.smk\" __4},\n\t{P,0,\"portrait/udagg/udgfid01\",\"portrait\\\\udagg\\\\udgfid01.smk\" __4},\n\t{P,0,\"portrait/udagg/udgtlk02\",\"portrait\\\\udagg\\\\udgtlk02.smk\" __4},\n\t{P,0,\"portrait/udagg/udgfid02\",\"portrait\\\\udagg\\\\udgfid02.smk\" __4},\n\t{P,0,\"portrait/udagg/udgfid00\",\"portrait\\\\udagg\\\\udgfid00.smk\" __4},\n\t{P,0,\"portrait/pinterce/pintlk00\",\"portrait\\\\pinterce\\\\pintlk00.smk\" __4},\n\t{P,0,\"portrait/pinterce/pinfid01\",\"portrait\\\\pinterce\\\\pinfid01.smk\" __4},\n\t{P,0,\"portrait/pinterce/pinfid02\",\"portrait\\\\pinterce\\\\pinfid02.smk\" __4},\n\t{P,0,\"portrait/pinterce/pinfid03\",\"portrait\\\\pinterce\\\\pinfid03.smk\" __4},\n\t{P,0,\"portrait/pinterce/pintlk02\",\"portrait\\\\pinterce\\\\pintlk02.smk\" __4},\n\t{P,0,\"portrait/pinterce/pinfid00\",\"portrait\\\\pinterce\\\\pinfid00.smk\" __4},\n\t{P,0,\"portrait/pinterce/pintlk01\",\"portrait\\\\pinterce\\\\pintlk01.smk\" __4},\n\t{P,0,\"portrait/pscout/pscfid02\",\"portrait\\\\pscout\\\\pscfid02.smk\" __4},\n\t{P,0,\"portrait/pscout/pscfid01\",\"portrait\\\\pscout\\\\pscfid01.smk\" __4},\n\t{P,0,\"portrait/pscout/psctlk00\",\"portrait\\\\pscout\\\\psctlk00.smk\" __4},\n\t{P,0,\"portrait/pscout/psctlk01\",\"portrait\\\\pscout\\\\psctlk01.smk\" __4},\n\t{P,0,\"portrait/pscout/pscfid03\",\"portrait\\\\pscout\\\\pscfid03.smk\" __4},\n\t{P,0,\"portrait/pscout/pscfid00\",\"portrait\\\\pscout\\\\pscfid00.smk\" __4},\n\t{P,0,\"portrait/utassadar/utafid00\",\"portrait\\\\utassadar\\\\utafid00.smk\" __4},\n\t{P,0,\"portrait/utassadar/utatlk00\",\"portrait\\\\utassadar\\\\utatlk00.smk\" __4},\n\t{P,0,\"portrait/utassadar/utatlk01\",\"portrait\\\\utassadar\\\\utatlk01.smk\" __4},\n\t{P,0,\"portrait/utassadar/utafid02\",\"portrait\\\\utassadar\\\\utafid02.smk\" __4},\n\t{P,0,\"portrait/utassadar/utafid01\",\"portrait\\\\utassadar\\\\utafid01.smk\" __4},\n\t{P,0,\"portrait/pwitness/pwifid02\",\"portrait\\\\pwitness\\\\pwifid02.smk\" __4},\n\t{P,0,\"portrait/pwitness/pwifid01\",\"portrait\\\\pwitness\\\\pwifid01.smk\" __4},\n\t{P,0,\"portrait/pwitness/pwitlk02\",\"portrait\\\\pwitness\\\\pwitlk02.smk\" __4},\n\t{P,0,\"portrait/pwitness/pwifid00\",\"portrait\\\\pwitness\\\\pwifid00.smk\" __4},\n\t{P,0,\"portrait/pwitness/pwifid03\",\"portrait\\\\pwitness\\\\pwifid03.smk\" __4},\n\t{P,0,\"portrait/pwitness/pwitlk01\",\"portrait\\\\pwitness\\\\pwitlk01.smk\" __4},\n\t{P,0,\"portrait/pwitness/pwitlk00\",\"portrait\\\\pwitness\\\\pwitlk00.smk\" __4},\n\t{P,0,\"portrait/zultra/zulfid00\",\"portrait\\\\zultra\\\\zulfid00.smk\" __4},\n\t{P,0,\"portrait/zultra/zulfid02\",\"portrait\\\\zultra\\\\zulfid02.smk\" __4},\n\t{P,0,\"portrait/zultra/zultlk02\",\"portrait\\\\zultra\\\\zultlk02.smk\" __4},\n\t{P,0,\"portrait/zultra/zulfid01\",\"portrait\\\\zultra\\\\zulfid01.smk\" __4},\n\t{P,0,\"portrait/zultra/zultlk00\",\"portrait\\\\zultra\\\\zultlk00.smk\" __4},\n\t{P,0,\"portrait/zultra/zultlk01\",\"portrait\\\\zultra\\\\zultlk01.smk\" __4},\n\t{P,0,\"portrait/uflag2/uf2tlk00\",\"portrait\\\\uflag2\\\\uf2tlk00.smk\" __4},\n\t{P,0,\"portrait/uflag2/uf2fid00\",\"portrait\\\\uflag2\\\\uf2fid00.smk\" __4},\n\t{P,0,\"portrait/upsi/upstlk00\",\"portrait\\\\upsi\\\\upstlk00.smk\" __4},\n\t{P,0,\"portrait/upsi/upsfid00\",\"portrait\\\\upsi\\\\upsfid00.smk\" __4},\n\t{P,0,\"portrait/ptemplar/ptefid03\",\"portrait\\\\ptemplar\\\\ptefid03.smk\" __4},\n\t{P,0,\"portrait/ptemplar/ptefid01\",\"portrait\\\\ptemplar\\\\ptefid01.smk\" __4},\n\t{P,0,\"portrait/ptemplar/ptefid00\",\"portrait\\\\ptemplar\\\\ptefid00.smk\" __4},\n\t{P,0,\"portrait/ptemplar/ptefid02\",\"portrait\\\\ptemplar\\\\ptefid02.smk\" __4},\n\t{P,0,\"portrait/ptemplar/ptetlk01\",\"portrait\\\\ptemplar\\\\ptetlk01.smk\" __4},\n\t{P,0,\"portrait/ptemplar/ptetlk02\",\"portrait\\\\ptemplar\\\\ptetlk02.smk\" __4},\n\t{P,0,\"portrait/ptemplar/ptetlk00\",\"portrait\\\\ptemplar\\\\ptetlk00.smk\" __4},\n\t{P,0,\"portrait/zavenger/zavtlk02\",\"portrait\\\\zavenger\\\\zavtlk02.smk\" __4},\n\t{P,0,\"portrait/zavenger/zavfid02\",\"portrait\\\\zavenger\\\\zavfid02.smk\" __4},\n\t{P,0,\"portrait/zavenger/zavfid00\",\"portrait\\\\zavenger\\\\zavfid00.smk\" __4},\n\t{P,0,\"portrait/zavenger/zavtlk00\",\"portrait\\\\zavenger\\\\zavtlk00.smk\" __4},\n\t{P,0,\"portrait/zavenger/zavfid03\",\"portrait\\\\zavenger\\\\zavfid03.smk\" __4},\n\t{P,0,\"portrait/zavenger/zavtlk01\",\"portrait\\\\zavenger\\\\zavtlk01.smk\" __4},\n\t{P,0,\"portrait/zavenger/zavfid01\",\"portrait\\\\zavenger\\\\zavfid01.smk\" __4},\n\t{P,0,\"portrait/njungcrit/njcfid01\",\"portrait\\\\njungcrit\\\\njcfid01.smk\" __4},\n\t{P,0,\"portrait/njungcrit/njctlk02\",\"portrait\\\\njungcrit\\\\njctlk02.smk\" __4},\n\t{P,0,\"portrait/njungcrit/njcfid00\",\"portrait\\\\njungcrit\\\\njcfid00.smk\" __4},\n\t{P,0,\"portrait/njungcrit/njctlk00\",\"portrait\\\\njungcrit\\\\njctlk00.smk\" __4},\n\t{P,0,\"portrait/njungcrit/njctlk01\",\"portrait\\\\njungcrit\\\\njctlk01.smk\" __4},\n\t{P,0,\"portrait/njungcrit/njcfid03\",\"portrait\\\\njungcrit\\\\njcfid03.smk\" __4},\n\t{P,0,\"portrait/njungcrit/njcfid02\",\"portrait\\\\njungcrit\\\\njcfid02.smk\" __4},\n\t{P,0,\"portrait/ngastank/ngtfid00\",\"portrait\\\\ngastank\\\\ngtfid00.smk\" __4},\n\t{P,0,\"portrait/uflag7/uf7fid00\",\"portrait\\\\uflag7\\\\uf7fid00.smk\" __4},\n\t{P,0,\"portrait/uflag7/uf7tlk00\",\"portrait\\\\uflag7\\\\uf7tlk00.smk\" __4},\n\t{P,0,\"portrait/umengsk/umetlk02\",\"portrait\\\\umengsk\\\\umetlk02.smk\" __4},\n\t{P,0,\"portrait/umengsk/umefid01\",\"portrait\\\\umengsk\\\\umefid01.smk\" __4},\n\t{P,0,\"portrait/umengsk/umefid00\",\"portrait\\\\umengsk\\\\umefid00.smk\" __4},\n\t{P,0,\"portrait/umengsk/umetlk01\",\"portrait\\\\umengsk\\\\umetlk01.smk\" __4},\n\t{P,0,\"portrait/umengsk/umetlk00\",\"portrait\\\\umengsk\\\\umetlk00.smk\" __4},\n\t{P,0,\"portrait/zegg/zegfid02\",\"portrait\\\\zegg\\\\zegfid02.smk\" __4},\n\t{P,0,\"portrait/zegg/zegfid03\",\"portrait\\\\zegg\\\\zegfid03.smk\" __4},\n\t{P,0,\"portrait/zegg/zegfid00\",\"portrait\\\\zegg\\\\zegfid00.smk\" __4},\n\t{P,0,\"portrait/zegg/zegtlk02\",\"portrait\\\\zegg\\\\zegtlk02.smk\" __4},\n\t{P,0,\"portrait/zegg/zegfid01\",\"portrait\\\\zegg\\\\zegfid01.smk\" __4},\n\t{P,0,\"portrait/zegg/zegtlk01\",\"portrait\\\\zegg\\\\zegtlk01.smk\" __4},\n\t{P,0,\"portrait/zegg/zegtlk00\",\"portrait\\\\zegg\\\\zegtlk00.smk\" __4},\n\t{P,0,\"portrait/uduke/udufid02\",\"portrait\\\\uduke\\\\udufid02.smk\" __4},\n\t{P,0,\"portrait/uduke/udufid00\",\"portrait\\\\uduke\\\\udufid00.smk\" __4},\n\t{P,0,\"portrait/uduke/udufid01\",\"portrait\\\\uduke\\\\udufid01.smk\" __4},\n\t{P,0,\"portrait/uduke/udutlk00\",\"portrait\\\\uduke\\\\udutlk00.smk\" __4},\n\t{P,0,\"portrait/uduke/udutlk02\",\"portrait\\\\uduke\\\\udutlk02.smk\" __4},\n\t{P,0,\"portrait/uduke/udutlk01\",\"portrait\\\\uduke\\\\udutlk01.smk\" __4},\n\t{P,0,\"portrait/uduke/udufid03\",\"portrait\\\\uduke\\\\udufid03.smk\" __4},\n\t{P,0,\"portrait/pshuttle/pshfid03\",\"portrait\\\\pshuttle\\\\pshfid03.smk\" __4},\n\t{P,0,\"portrait/pshuttle/pshtlk01\",\"portrait\\\\pshuttle\\\\pshtlk01.smk\" __4},\n\t{P,0,\"portrait/pshuttle/pshfid00\",\"portrait\\\\pshuttle\\\\pshfid00.smk\" __4},\n\t{P,0,\"portrait/pshuttle/pshtlk00\",\"portrait\\\\pshuttle\\\\pshtlk00.smk\" __4},\n\t{P,0,\"portrait/pshuttle/pshfid02\",\"portrait\\\\pshuttle\\\\pshfid02.smk\" __4},\n\t{P,0,\"portrait/pshuttle/pshfid01\",\"portrait\\\\pshuttle\\\\pshfid01.smk\" __4},\n\t{P,0,\"portrait/pshuttle/pshtlk02\",\"portrait\\\\pshuttle\\\\pshtlk02.smk\" __4},\n\t{P,0,\"portrait/ukhadchunk/ncrfid00\",\"portrait\\\\ukhadchunk\\\\ncrfid00.smk\" __4},\n\t{P,0,\"portrait/ukhadchunk/ncrtlk00\",\"portrait\\\\ukhadchunk\\\\ncrtlk00.smk\" __4},\n\t{P,0,\"portrait/zdrone/zdrtlk02\",\"portrait\\\\zdrone\\\\zdrtlk02.smk\" __4},\n\t{P,0,\"portrait/zdrone/zdrfid01\",\"portrait\\\\zdrone\\\\zdrfid01.smk\" __4},\n\t{P,0,\"portrait/zdrone/zdrfid02\",\"portrait\\\\zdrone\\\\zdrfid02.smk\" __4},\n\t{P,0,\"portrait/zdrone/zdrtlk01\",\"portrait\\\\zdrone\\\\zdrtlk01.smk\" __4},\n\t{P,0,\"portrait/zdrone/zdrfid03\",\"portrait\\\\zdrone\\\\zdrfid03.smk\" __4},\n\t{P,0,\"portrait/zdrone/zdrtlk00\",\"portrait\\\\zdrone\\\\zdrtlk00.smk\" __4},\n\t{P,0,\"portrait/zdrone/zdrfid00\",\"portrait\\\\zdrone\\\\zdrfid00.smk\" __4},\n\t{P,0,\"portrait/zinfestt/zbgfid03\",\"portrait\\\\zinfestt\\\\zbgfid03.smk\" __4},\n\t{P,0,\"portrait/zinfestt/zbgtlk01\",\"portrait\\\\zinfestt\\\\zbgtlk01.smk\" __4},\n\t{P,0,\"portrait/zinfestt/zbgfid02\",\"portrait\\\\zinfestt\\\\zbgfid02.smk\" __4},\n\t{P,0,\"portrait/zinfestt/zbgtlk00\",\"portrait\\\\zinfestt\\\\zbgtlk00.smk\" __4},\n\t{P,0,\"portrait/zinfestt/zbgfid01\",\"portrait\\\\zinfestt\\\\zbgfid01.smk\" __4},\n\t{P,0,\"portrait/zinfestt/zbgtlk02\",\"portrait\\\\zinfestt\\\\zbgtlk02.smk\" __4},\n\t{P,0,\"portrait/zinfestt/zbgfid00\",\"portrait\\\\zinfestt\\\\zbgfid00.smk\" __4},\n\t{P,0,\"portrait/ngorb/ngofid00\",\"portrait\\\\ngorb\\\\ngofid00.smk\" __4},\n\t{P,0,\"portrait/static/statin\",\"portrait\\\\static\\\\statin.smk\" __4},\n\t{P,0,\"portrait/static/statout\",\"portrait\\\\static\\\\statout.smk\" __4},\n\t{P,0,\"portrait/uflag5/uf5fid00\",\"portrait\\\\uflag5\\\\uf5fid00.smk\" __4},\n\t{P,0,\"portrait/uflag5/uf5tlk00\",\"portrait\\\\uflag5\\\\uf5tlk00.smk\" __4},\n\t{P,0,\"portrait/tghost/tghfid00\",\"portrait\\\\tghost\\\\tghfid00.smk\" __4},\n\t{P,0,\"portrait/tghost/tghtlk00\",\"portrait\\\\tghost\\\\tghtlk00.smk\" __4},\n\t{P,0,\"portrait/tghost/tghfid01\",\"portrait\\\\tghost\\\\tghfid01.smk\" __4},\n\t{P,0,\"portrait/tghost/tghfid02\",\"portrait\\\\tghost\\\\tghfid02.smk\" __4},\n\t{P,0,\"portrait/tghost/tghfid03\",\"portrait\\\\tghost\\\\tghfid03.smk\" __4},\n\t{P,0,\"portrait/tgoliath/tgotlk00\",\"portrait\\\\tgoliath\\\\tgotlk00.smk\" __4},\n\t{P,0,\"portrait/tgoliath/tgofid00\",\"portrait\\\\tgoliath\\\\tgofid00.smk\" __4},\n\t{P,0,\"portrait/tgoliath/tgofid02\",\"portrait\\\\tgoliath\\\\tgofid02.smk\" __4},\n\t{P,0,\"portrait/tgoliath/tgofid01\",\"portrait\\\\tgoliath\\\\tgofid01.smk\" __4},\n\t{P,0,\"portrait/tgoliath/tgotlk01\",\"portrait\\\\tgoliath\\\\tgotlk01.smk\" __4},\n\t{P,0,\"portrait/padvisor/padfid03\",\"portrait\\\\padvisor\\\\padfid03.smk\" __4},\n\t{P,0,\"portrait/padvisor/padtlk00\",\"portrait\\\\padvisor\\\\padtlk00.smk\" __4},\n\t{P,0,\"portrait/padvisor/padfid00\",\"portrait\\\\padvisor\\\\padfid00.smk\" __4},\n\t{P,0,\"portrait/padvisor/padtlk02\",\"portrait\\\\padvisor\\\\padtlk02.smk\" __4},\n\t{P,0,\"portrait/padvisor/padfid01\",\"portrait\\\\padvisor\\\\padfid01.smk\" __4},\n\t{P,0,\"portrait/padvisor/padfid02\",\"portrait\\\\padvisor\\\\padfid02.smk\" __4},\n\t{P,0,\"portrait/padvisor/padtlk01\",\"portrait\\\\padvisor\\\\padtlk01.smk\" __4},\n\t{P,0,\"portrait/tscv/tsctlk00\",\"portrait\\\\tscv\\\\tsctlk00.smk\" __4},\n\t{P,0,\"portrait/tscv/tscfid02\",\"portrait\\\\tscv\\\\tscfid02.smk\" __4},\n\t{P,0,\"portrait/tscv/tsctlk01\",\"portrait\\\\tscv\\\\tsctlk01.smk\" __4},\n\t{P,0,\"portrait/tscv/tscfid00\",\"portrait\\\\tscv\\\\tscfid00.smk\" __4},\n\t{P,0,\"portrait/tscv/tscfid03\",\"portrait\\\\tscv\\\\tscfid03.smk\" __4},\n\t{P,0,\"portrait/tscv/tscfid01\",\"portrait\\\\tscv\\\\tscfid01.smk\" __4},\n\t{P,0,\"portrait/tscv/tsctlk02\",\"portrait\\\\tscv\\\\tsctlk02.smk\" __4},\n\t{P,0,\"portrait/ukhad/ncrfid00\",\"portrait\\\\ukhad\\\\ncrfid00.smk\" __4},\n\t{P,0,\"portrait/ukhad/ncrtlk00\",\"portrait\\\\ukhad\\\\ncrtlk00.smk\" __4},\n\t{P,0,\"portrait/udtemplar/udttlk01\",\"portrait\\\\udtemplar\\\\udttlk01.smk\" __4},\n\t{P,0,\"portrait/udtemplar/udtfid00\",\"portrait\\\\udtemplar\\\\udtfid00.smk\" __4},\n\t{P,0,\"portrait/udtemplar/udtfid01\",\"portrait\\\\udtemplar\\\\udtfid01.smk\" __4},\n\t{P,0,\"portrait/udtemplar/udttlk02\",\"portrait\\\\udtemplar\\\\udttlk02.smk\" __4},\n\t{P,0,\"portrait/udtemplar/udttlk00\",\"portrait\\\\udtemplar\\\\udttlk00.smk\" __4},\n\t{P,0,\"portrait/udtemplar/udtfid02\",\"portrait\\\\udtemplar\\\\udtfid02.smk\" __4},\n\t{P,0,\"portrait/uzeratul/uzefid00\",\"portrait\\\\uzeratul\\\\uzefid00.smk\" __4},\n\t{P,0,\"portrait/uzeratul/uzefid01\",\"portrait\\\\uzeratul\\\\uzefid01.smk\" __4},\n\t{P,0,\"portrait/uzeratul/uzefid02\",\"portrait\\\\uzeratul\\\\uzefid02.smk\" __4},\n\t{P,0,\"portrait/uzeratul/uzetlk02\",\"portrait\\\\uzeratul\\\\uzetlk02.smk\" __4},\n\t{P,0,\"portrait/uzeratul/uzetlk01\",\"portrait\\\\uzeratul\\\\uzetlk01.smk\" __4},\n\t{P,0,\"portrait/uzeratul/uzefid03\",\"portrait\\\\uzeratul\\\\uzefid03.smk\" __4},\n\t{P,0,\"portrait/uzeratul/uzetlk00\",\"portrait\\\\uzeratul\\\\uzetlk00.smk\" __4},\n\t{P,0,\"portrait/zguard/zgutlk01\",\"portrait\\\\zguard\\\\zgutlk01.smk\" __4},\n\t{P,0,\"portrait/zguard/zgufid00\",\"portrait\\\\zguard\\\\zgufid00.smk\" __4},\n\t{P,0,\"portrait/zguard/zgutlk02\",\"portrait\\\\zguard\\\\zgutlk02.smk\" __4},\n\t{P,0,\"portrait/zguard/zgufid01\",\"portrait\\\\zguard\\\\zgufid01.smk\" __4},\n\t{P,0,\"portrait/zguard/zgutlk00\",\"portrait\\\\zguard\\\\zgutlk00.smk\" __4},\n\t{P,0,\"portrait/zguard/zgufid03\",\"portrait\\\\zguard\\\\zgufid03.smk\" __4},\n\t{P,0,\"portrait/zguard/zgufid02\",\"portrait\\\\zguard\\\\zgufid02.smk\" __4},\n\t{P,0,\"portrait/parchon/parfid01\",\"portrait\\\\parchon\\\\parfid01.smk\" __4},\n\t{P,0,\"portrait/parchon/partlk01\",\"portrait\\\\parchon\\\\partlk01.smk\" __4},\n\t{P,0,\"portrait/parchon/parfid02\",\"portrait\\\\parchon\\\\parfid02.smk\" __4},\n\t{P,0,\"portrait/parchon/partlk02\",\"portrait\\\\parchon\\\\partlk02.smk\" __4},\n\t{P,0,\"portrait/parchon/parfid03\",\"portrait\\\\parchon\\\\parfid03.smk\" __4},\n\t{P,0,\"portrait/parchon/parfid00\",\"portrait\\\\parchon\\\\parfid00.smk\" __4},\n\t{P,0,\"portrait/parchon/partlk00\",\"portrait\\\\parchon\\\\partlk00.smk\" __4},\n\t{P,0,\"portrait/zadvisor/zadfid03\",\"portrait\\\\zadvisor\\\\zadfid03.smk\" __4},\n\t{P,0,\"portrait/zadvisor/zadtlk01\",\"portrait\\\\zadvisor\\\\zadtlk01.smk\" __4},\n\t{P,0,\"portrait/zadvisor/zadfid00\",\"portrait\\\\zadvisor\\\\zadfid00.smk\" __4},\n\t{P,0,\"portrait/zadvisor/zadtlk02\",\"portrait\\\\zadvisor\\\\zadtlk02.smk\" __4},\n\t{P,0,\"portrait/zadvisor/zadfid02\",\"portrait\\\\zadvisor\\\\zadfid02.smk\" __4},\n\t{P,0,\"portrait/zadvisor/zadtlk00\",\"portrait\\\\zadvisor\\\\zadtlk00.smk\" __4},\n\t{P,0,\"portrait/zadvisor/zadfid01\",\"portrait\\\\zadvisor\\\\zadfid01.smk\" __4},\n\t{P,0,\"portrait/uflag4/uf4tlk00\",\"portrait\\\\uflag4\\\\uf4tlk00.smk\" __4},\n\t{P,0,\"portrait/uflag4/uf4fid00\",\"portrait\\\\uflag4\\\\uf4fid00.smk\" __4},\n\t{P,0,\"portrait/tadvisor/tadtlk02\",\"portrait\\\\tadvisor\\\\tadtlk02.smk\" __4},\n\t{P,0,\"portrait/tadvisor/tadfid01\",\"portrait\\\\tadvisor\\\\tadfid01.smk\" __4},\n\t{P,0,\"portrait/tadvisor/tadtlk00\",\"portrait\\\\tadvisor\\\\tadtlk00.smk\" __4},\n\t{P,0,\"portrait/tadvisor/tadfid00\",\"portrait\\\\tadvisor\\\\tadfid00.smk\" __4},\n\t{P,0,\"portrait/tadvisor/tadfid03\",\"portrait\\\\tadvisor\\\\tadfid03.smk\" __4},\n\t{P,0,\"portrait/tadvisor/tadfid02\",\"portrait\\\\tadvisor\\\\tadfid02.smk\" __4},\n\t{P,0,\"portrait/tadvisor/tadtlk01\",\"portrait\\\\tadvisor\\\\tadtlk01.smk\" __4},\n\t{P,0,\"portrait/tphoenix/tphtlk01\",\"portrait\\\\tphoenix\\\\tphtlk01.smk\" __4},\n\t{P,0,\"portrait/tphoenix/tphfid01\",\"portrait\\\\tphoenix\\\\tphfid01.smk\" __4},\n\t{P,0,\"portrait/tphoenix/tphfid02\",\"portrait\\\\tphoenix\\\\tphfid02.smk\" __4},\n\t{P,0,\"portrait/tphoenix/tphtlk00\",\"portrait\\\\tphoenix\\\\tphtlk00.smk\" __4},\n\t{P,0,\"portrait/tphoenix/tphfid00\",\"portrait\\\\tphoenix\\\\tphfid00.smk\" __4},\n\t{P,0,\"portrait/tphoenix/tphtlk02\",\"portrait\\\\tphoenix\\\\tphtlk02.smk\" __4},\n\t{P,0,\"portrait/zcocoon/zcofid02\",\"portrait\\\\zcocoon\\\\zcofid02.smk\" __4},\n\t{P,0,\"portrait/zcocoon/zcofid01\",\"portrait\\\\zcocoon\\\\zcofid01.smk\" __4},\n\t{P,0,\"portrait/zcocoon/zcofid00\",\"portrait\\\\zcocoon\\\\zcofid00.smk\" __4},\n\t{P,0,\"portrait/ufendrag/ufdfid02\",\"portrait\\\\ufendrag\\\\ufdfid02.smk\" __4},\n\t{P,0,\"portrait/ufendrag/ufdtlk01\",\"portrait\\\\ufendrag\\\\ufdtlk01.smk\" __4},\n\t{P,0,\"portrait/ufendrag/ufdtlk00\",\"portrait\\\\ufendrag\\\\ufdtlk00.smk\" __4},\n\t{P,0,\"portrait/ufendrag/ufdtlk02\",\"portrait\\\\ufendrag\\\\ufdtlk02.smk\" __4},\n\t{P,0,\"portrait/ufendrag/ufdfid01\",\"portrait\\\\ufendrag\\\\ufdfid01.smk\" __4},\n\t{P,0,\"portrait/ufendrag/ufdfid00\",\"portrait\\\\ufendrag\\\\ufdfid00.smk\" __4},\n\t{P,0,\"portrait/ufendrag/ufdfid03\",\"portrait\\\\ufendrag\\\\ufdfid03.smk\" __4},\n\t{P,0,\"portrait/tdropshi/tdrfid00\",\"portrait\\\\tdropshi\\\\tdrfid00.smk\" __4},\n\t{P,0,\"portrait/tdropshi/tdrtlk02\",\"portrait\\\\tdropshi\\\\tdrtlk02.smk\" __4},\n\t{P,0,\"portrait/tdropshi/tdrtlk00\",\"portrait\\\\tdropshi\\\\tdrtlk00.smk\" __4},\n\t{P,0,\"portrait/tdropshi/tdrfid01\",\"portrait\\\\tdropshi\\\\tdrfid01.smk\" __4},\n\t{P,0,\"portrait/tdropshi/tdrtlk01\",\"portrait\\\\tdropshi\\\\tdrtlk01.smk\" __4},\n\t{P,0,\"portrait/tdropshi/tdrfid03\",\"portrait\\\\tdropshi\\\\tdrfid03.smk\" __4},\n\t{P,0,\"portrait/tdropshi/tdrfid02\",\"portrait\\\\tdropshi\\\\tdrfid02.smk\" __4},\n\t{P,0,\"portrait/nlavacrit/nlctlk02\",\"portrait\\\\nlavacrit\\\\nlctlk02.smk\" __4},\n\t{P,0,\"portrait/nlavacrit/nlcfid01\",\"portrait\\\\nlavacrit\\\\nlcfid01.smk\" __4},\n\t{P,0,\"portrait/nlavacrit/nlctlk01\",\"portrait\\\\nlavacrit\\\\nlctlk01.smk\" __4},\n\t{P,0,\"portrait/nlavacrit/nlcfid00\",\"portrait\\\\nlavacrit\\\\nlcfid00.smk\" __4},\n\t{P,0,\"portrait/nlavacrit/nlctlk00\",\"portrait\\\\nlavacrit\\\\nlctlk00.smk\" __4},\n\t{P,0,\"portrait/udisk/uddtlk00\",\"portrait\\\\udisk\\\\uddtlk00.smk\" __4},\n\t{P,0,\"portrait/udisk/uddfid00\",\"portrait\\\\udisk\\\\uddfid00.smk\" __4},\n\t{P,0,\"portrait/zzergl/zzetlk02\",\"portrait\\\\zzergl\\\\zzetlk02.smk\" __4},\n\t{P,0,\"portrait/zzergl/zzefid02\",\"portrait\\\\zzergl\\\\zzefid02.smk\" __4},\n\t{P,0,\"portrait/zzergl/zzetlk00\",\"portrait\\\\zzergl\\\\zzetlk00.smk\" __4},\n\t{P,0,\"portrait/zzergl/zzefid00\",\"portrait\\\\zzergl\\\\zzefid00.smk\" __4},\n\t{P,0,\"portrait/zzergl/zzetlk01\",\"portrait\\\\zzergl\\\\zzetlk01.smk\" __4},\n\t{P,0,\"portrait/zzergl/zzefid03\",\"portrait\\\\zzergl\\\\zzefid03.smk\" __4},\n\t{P,0,\"portrait/zzergl/zzefid01\",\"portrait\\\\zzergl\\\\zzefid01.smk\" __4}*/\n};\n\n\n//\t{G,0,\"neutral/smmissile\",\"unit\\\\bullet\\\\sMmissle.grp\",1 __3},\n//\t{G,0,\"neutral/spike\",\"unit\\\\bullet\\\\Spike.grp\",1 __3},\n//\t{G,0,\"neutral/units/Generate\",\"unit\\\\neutral\\\\Generate.grp\",1 __3},\n//\t{G,0,\"neutral/units/Icritter\",\"unit\\\\neutral\\\\Icritter.grp\",0 __3},\n//\t{G,0,\"neutral/units/Kcritter\",\"unit\\\\neutral\\\\Kcritter.grp\",0 __3},\n//\t{G,0,\"neutral/units/khalis\",\"unit\\\\neutral\\\\khalis.grp\",1 __3},\n//\t{G,0,\"neutral/units/ncicShad\",\"unit\\\\neutral\\\\ncicShad.grp\",1 __3},\n//\t{G,0,\"neutral/units/nckShad\",\"unit\\\\neutral\\\\nckShad.grp\",1 __3},\n//\t{G,0,\"neutral/units/NrcDeath\",\"unit\\\\neutral\\\\NrcDeath.grp\",1 __3},\n//\t{G,0,\"neutral/units/psi disruptor\",\"unit\\\\neutral\\\\PsiDisr.grp\",1 __3},\n//\t{G,0,\"neutral/units/Scritter\",\"unit\\\\neutral\\\\Scritter.grp\",0 __3},\n//\t{G,0,\"neutral/units/tgnShad\",\"unit\\\\neutral\\\\tgnShad.grp\",1 __3},\n//\t{G,0,\"neutral/units/tpdShad\",\"unit\\\\neutral\\\\tpdShad.grp\",1 __3},\n//\t{G,0,\"neutral/units/uraj\",\"unit\\\\neutral\\\\uraj.grp\",1 __3},\n\n\n\n#endif /* STARTOOL_MPQ_H_ */\n"
  },
  {
    "path": "src/startool_rm.h",
    "content": "/*\n * startool_rm.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef STARTOOL_RM_H_\n#define STARTOOL_RM_H_\n\n// Local\n#include \"startool.h\"\n\nControl RMTodo[] = {\n\t{D,0,\"game/consoles/protoss/conover.png\",\"game/consoles/protoss/conover.DDS\" __4},\n\t{D,0,\"HD2/game/consoles/protoss/console_center.png\",\"HD2/game/consoles/protoss/console_center.DDS\" __4},\n\n\n\t/*{N,0,\"HD2/font/font14\",\"font/font14.fnt\" __4},\n\t{N,0,\"HD2/font/font16\",\"font/font16.fnt\" __4},\n\t{N,0,\"HD2/font/font16x\",\"font/font16x.fnt\" __4},\n\t{N,0,\"HD2/font/font8\",\"font/font8.fnt\" __4},*/\n\t{N,0,\"SD/font/font10\",\"SD/font/font10.fnt\" __4},\n\t{N,0,\"SD/font/font12\",\"SD/font/font12.fnt\" __4},\n\t{N,0,\"SD/font/font14\",\"SD/font/font14.fnt\" __4},\n\t{N,0,\"SD/font/font16\",\"SD/font/font16.fnt\" __4},\n\t{N,0,\"SD/font/font16x\",\"SD/font/font16x.fnt\" __4},\n\t{N,0,\"SD/font/font32\",\"SD/font/font32.fnt\" __4},\n\t{N,0,\"SD/font/font50\",\"SD/font/font50.fnt\" __4},\n\t{N,0,\"SD/font/font8\",\"SD/font/font8.fnt\" __4},\n};\n\n\n\n\n#endif /* STARTOOL_RM_H_ */\n"
  },
  {
    "path": "src/tileset/MegaTile.cpp",
    "content": "/*\n * MegaTile.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"MegaTile.h\"\n#include \"kaitai/tileset_vr4.h\"\n#include \"kaitai/tileset_vx4.h\"\n#include \"Logger.h\"\n\n// system\n#include <string>\n#include <iostream>\n\nusing namespace std;\n\nnamespace tileset\n{\n\nstatic Logger logger = Logger(\"startool.tileset.MegaTile\");\n\nMegaTile::MegaTile(TilesetHub &tilesethub, size_t element) :\n  mTilesetHub(tilesethub),\n  mElement(element)\n{\n  generateTiles();\n}\n\nMegaTile::~MegaTile()\n{\n\n}\n\nvoid MegaTile::generateTiles()\n{\n  mPaletteImage = make_shared<TiledPaletteImage>(Size(4, 4), Size(8, 8));\n\n  tileset_vx4_t::megatile_type_t *megatile = mTilesetHub.vx4->elements()->at(mElement);\n\n  std::vector<tileset_vx4_t::graphic_ref_type_t *> *vx4_graphic_ref = megatile->graphic_ref();\n\n  unsigned int n = 0;\n  for (auto g : *vx4_graphic_ref)\n  {\n    uint64_t g_ref = g->vr4_ref();\n    bool horizontal_flip = g->horizontal_flip();\n\n    std::vector<tileset_vr4_t::pixel_type_t *> *pixel_ref = mTilesetHub.vr4->elements();\n\n    tileset_vr4_t::pixel_type_t *color_ref = pixel_ref->at(g_ref);\n\n    const string &color = color_ref->minitile();\n\n    PaletteImage palImage(Size(8, 8));\n    unsigned int i = 0;\n    for (auto c : color)\n    {\n      Pos pos = palImage.indexToPosition(i);\n\n      palImage.at(pos) = c;\n\n      i++;\n    }\n\n    mPaletteImage->copyTile(palImage, n, horizontal_flip);\n\n    n++;\n  }\n}\n\nstd::shared_ptr<PaletteImage> MegaTile::getImage()\n{\n  return mPaletteImage;\n}\n} /* namespace tileset */\n"
  },
  {
    "path": "src/tileset/MegaTile.h",
    "content": "/*\n * MegaTile.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef MEGATILE_H\n#define MEGATILE_H\n\n// project\n#include \"TilesetHub.h\"\n#include \"TiledPaletteImage.h\"\n\nnamespace tileset\n{\n\n/**\n * MiniTiles are arranged in a MegaTile as follows:\n * 0 |  1 | 2 | 3\n * 4 |  5 | 6 | 7\n * 8 |  9 |10 |11\n * 12| 13 |14 |15\n */\nclass MegaTile\n{\npublic:\n  MegaTile(TilesetHub &tilesethub, size_t element);\n  virtual ~MegaTile();\n\n  std::shared_ptr<PaletteImage> getImage();\n\nprivate:\n  TilesetHub &mTilesetHub;\n  size_t mElement;\n  std::shared_ptr<TiledPaletteImage> mPaletteImage;\n\n  void generateTiles();\n};\n\n} /* namespace tileset */\n\n#endif /* MEGATILE_H */\n"
  },
  {
    "path": "src/tileset/TiledPaletteImage.cpp",
    "content": "/*\n * TiledPaletteImage.cpp\n *\n *      Author: Andreas Volz\n */\n\n#include \"TiledPaletteImage.h\"\n#include \"Logger.h\"\n\nnamespace tileset\n{\n\nstatic Logger logger = Logger(\"startool.tileset.TiledPaletteImage\");\n\nTiledPaletteImage::TiledPaletteImage(const Size &tileSize, const Size &subtileSize) :\n    PaletteImage(tileSize * subtileSize),\n    mTileSize(tileSize),\n    mSubtileSize(subtileSize)\n{\n\n}\n\nTiledPaletteImage::~TiledPaletteImage()\n{\n\n}\n\nvoid TiledPaletteImage::copyTile(const PaletteImage &palette_image, size_t index, bool horizontal_flip)\n{\n  int y = 0;\n  int x = 0;\n\n  // if index is out of data size that return Pos(0, 0) as fail safe\n  if((int)index < (getSize().getWidth() * getSize().getHeight()) /\n      (palette_image.getSize().getWidth() * palette_image.getSize().getHeight()))\n  {\n    y = index / (getSize().getWidth() / palette_image.getSize().getWidth());\n    x = index % (getSize().getWidth() / palette_image.getSize().getWidth());\n  }\n\n  Pos rel_pos(x,y);\n  copyTile(palette_image, rel_pos, horizontal_flip);\n}\n\nvoid TiledPaletteImage::copyTile(const PaletteImage &palette_image, const Pos &pos, bool horizontal_flip)\n{\n  if(pos.getX() < mTileSize.getWidth() || pos.getY() < mTileSize.getWidth())\n  {\n\n    for(int x = 0; x < palette_image.getSize().getWidth(); x++)\n    {\n      for(int y = 0; y < palette_image.getSize().getHeight(); y++)\n      {\n        unsigned char pixel = palette_image.at(Pos(x, y));\n\n        int x_flip = x;\n        if(horizontal_flip)\n        {\n          x_flip = palette_image.getSize().getWidth() - 1 - x;\n        }\n\n        at(calcAbsolutePos(pos, Pos(x_flip, y))) = pixel;\n      }\n    }\n  }\n  else\n  {\n    LOG4CXX_WARN(logger, \"copyTile() out of range!\");\n  }\n}\n\nconst Pos TiledPaletteImage::calcAbsolutePos(const Pos &tile_pos, const Pos &relative_pos)\n{\n  return Pos(tile_pos.getX() * mSubtileSize.getWidth() + relative_pos.getX(), tile_pos.getY() * mSubtileSize.getHeight() + relative_pos.getY());\n}\n\n} /* namespace tileset */\n"
  },
  {
    "path": "src/tileset/TiledPaletteImage.h",
    "content": "/*\n * TiledPaletteImage.h\n *\n *      Author: Andreas\n */\n\n#ifndef TILEDPALETTEIMAGE_H_\n#define TILEDPALETTEIMAGE_H_\n\n// project\n#include \"PaletteImage.h\"\n\nnamespace tileset\n{\n\n/**\n * A TiledPaletteImage is a special form of a PaletteImage. As child it shares all details,\n * but with the extension that complete other PaletteImages could be added at once to a specific\n * Tile. The pixels are just copied to the target after inserting a tile. So afterwards the\n * TiledPaletteImage could just be used as normal PaletteImage or put into another TiledPaletteImage.\n */\nclass TiledPaletteImage: public PaletteImage\n{\npublic:\n  TiledPaletteImage(const Size &tileSize, const Size &subtileSize);\n\n  virtual ~TiledPaletteImage();\n\n  void copyTile(const PaletteImage &palette_image, size_t index, bool horizontal_flip = false);\n\n  void copyTile(const PaletteImage &palette_image, const Pos &pos, bool horizontal_flip = false);\n\nprivate:\n  const Pos calcAbsolutePos(const Pos &tile_pos, const Pos &relative_pos);\n\n  Size mTileSize;\n  Size mSubtileSize;\n};\n\n} /* namespace tileset */\n\n#endif /* TILEDPALETTEIMAGE_H_ */\n"
  },
  {
    "path": "src/tileset/TilesetHub.cpp",
    "content": "/*\n * TilesetHub.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"TilesetHub.h\"\n#include \"PaletteImage.h\"\n#include \"PngExporter.h\"\n#include \"MegaTile.h\"\n#include \"FileUtil.h\"\n#include \"luagen.h\"\n#include \"Preferences.h\"\n#include \"Hurricane.h\"\n\n// system\n#include <iostream>\n#include <math.h>\n#include <fstream>\n\nusing namespace std;\n\nnamespace tileset\n{\n\nTilesetHub::TilesetHub(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile) :\n  KaitaiConverter(hurricane)\n{\n  init(arcfile);\n}\n\nTilesetHub::~TilesetHub()\n{\n\n}\n\n/*m_iscript_stream = mHurricane->extractStream(sc_iscript_bin);\nm_iscript_ks = make_shared<kaitai::kstream>(&*m_iscript_stream);\n\niscript = make_shared<iscript_bin_t>(m_iscript_ks.get());\n*/\nvoid TilesetHub::init(const std::string &arcfile)\n{\n  m_cv5_stream = mHurricane->extractStream(arcfile + \".cv5\");\n  m_cv5_ks = make_shared<kaitai::kstream>(&*m_cv5_stream);\n  cv5 = make_shared<tileset_cv5_t>(m_cv5_ks.get());\n\n  m_vx4_stream = mHurricane->extractStream(arcfile + \".vx4\");\n  m_vx4_ks = make_shared<kaitai::kstream>(&*m_vx4_stream);\n  vx4 = make_shared<tileset_vx4_t>(m_vx4_ks.get());\n\n  m_vf4_stream = mHurricane->extractStream(arcfile + \".vf4\");\n  m_vf4_ks = make_shared<kaitai::kstream>(&*m_vf4_stream);\n  vf4 = make_shared<tileset_vf4_t>(m_vf4_ks.get());\n\n  m_vr4_stream = mHurricane->extractStream(arcfile + \".vr4\");\n  m_vr4_ks = make_shared<kaitai::kstream>(&*m_vr4_stream);\n  vr4 = make_shared<tileset_vr4_t>(m_vr4_ks.get());\n}\n\nbool TilesetHub::convert(std::shared_ptr<AbstractPalette> palette, Storage storage)\n{\n  if(!vx4) // if it isn't available just return false\n  {\n    return false;\n  }\n\n  if(!palette) // if something wrong with palette just return false\n  {\n    return false;\n  }\n\n  unsigned int num_tiles = vx4->elements()->size();\n  int tiles_width = 16;\n  int tiles_height = static_cast<int>(ceil(static_cast<float>(num_tiles) / static_cast<float>(tiles_width)));\n\n  TiledPaletteImage ultraTile(Size(tiles_width, tiles_height), Size(32,32));\n\n  for(unsigned int i = 0; i < num_tiles; i++)\n  {\n    MegaTile mega(*this, i);\n\n    ultraTile.copyTile(*mega.getImage(), i);\n  }\n\n  // FIXME: I don't like the path handling in this case. Needs to be changed!\n  string save_png(storage.getFullPath() + \"/\" + storage.getFilename() + \".png\");\n  CheckPath(save_png);\n  return PngExporter::save(save_png, ultraTile, palette, 0);\n}\n\nvoid TilesetHub::generateLua(const std::string &name, const std::string &image, Storage luafile)\n{\n  if(!cv5) // if it isn't available just return with no action\n  {\n    return;\n  }\n\n  unsigned int num_cv5 = cv5->elements()->size();\n\n  int num_doodad = 0;\n  int num_normal = 0;\n\n  ofstream lua_tileset_stream;\n  CheckPath(luafile.getFullPath());\n  lua_tileset_stream.open (luafile.getFullPath());\n\n  vector<string> tile_slots_vector;\n\n  for(unsigned int i = 0; i < num_cv5; i++)\n  {\n    tileset_cv5_t::group_t* group = cv5->elements()->at(i);\n\n    if(group->doodad() != 0)\n    {\n      num_doodad++;\n      //cout << \"doodad(\" << i << \"): \";\n    }\n    else\n    {\n      num_normal++;\n      //cout << \"normal(\" << i << \"): \";\n    }\n\n    std::vector<uint16_t>* vx4_vf4_ref = group->megatile_references();\n\n    vector<string> tile_solids_vector;\n\n    for(auto elem : *vx4_vf4_ref)\n    {\n      //cout << to_string(elem);\n\n\n      tileset_vf4_t::minitile_t* minitile = vf4->elements()->at(elem);\n\n      std::string subtilePassableFlags = \"\";\n      for(auto flags : *minitile->flags())\n      {\n        if (flags->walkable()) {\n          subtilePassableFlags += \"p\";\n        } else {\n          subtilePassableFlags += \"u\";\n        }\n      }\n\n      tile_solids_vector.push_back(to_string(elem));\n      tile_solids_vector.push_back(lg::table(lg::quote(subtilePassableFlags)));\n\n      //cout << \", \";\n    }\n    //cout << endl;\n\n    string tile_solids_str = lg::params(tile_solids_vector);\n    string solid_str = lg::line(lg::tilesetSlotEntry(\"solid\", {\"light-grass\", \"land\"}, {tile_solids_str}));\n\n    tile_slots_vector.push_back(solid_str);\n  }\n\n  string tile_slots_str = lg::params(tile_slots_vector);\n  string lua_tileset_str = lg::DefineTileset(name, image, {tile_slots_str});\n\n  //cout << lua_tileset_str << endl;\n\n  lua_tileset_stream << lua_tileset_str;\n  lua_tileset_stream.close();\n\n  //cout << \"num_doodad: \" << num_doodad << endl;\n  //cout << \"num_normal: \" << num_normal << endl;\n}\n\n} /* namespace tileset */\n"
  },
  {
    "path": "src/tileset/TilesetHub.h",
    "content": "/*\n * TilesetHub.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef TILESETHUB_H\n#define TILESETHUB_H\n\n// project\n#include \"Palette.h\"\n#include \"KaitaiConverter.h\"\n#include \"kaitai/tileset_cv5.h\"\n#include \"kaitai/tileset_vx4.h\"\n#include \"kaitai/tileset_vf4.h\"\n#include \"kaitai/tileset_vr4.h\"\n#include \"Storage.h\"\n\n// system\n#include <memory>\n#include <string>\n\nnamespace tileset\n{\n/**\n * The TileSetHub parses the complete data structures inside those files:\n * - tileset\\\\<tileset>.cv5|vx4|vf4|vr4\n *\n * The Kaitai parsed objects in this class are by intension public. There's no benefit in putting dozen silly\n * getter around them. The alternative to put them private means to implement every parser logic\n * inside this class or friend them all.\n *\n * So the design decision is just to let them public and the outside accessing function should only read them!\n * If I ever put this stuff to a general purpose library this design might change.\n *\n *  \"with great power comes great responsibility\" - (Spiderman)\n */\nclass TilesetHub : public KaitaiConverter\n{\npublic:\n  TilesetHub(std::shared_ptr<Hurricane> hurricane, const std::string &arcfile);\n  virtual ~TilesetHub();\n\n  bool convert(std::shared_ptr<AbstractPalette> palette, Storage storage);\n\n  void generateLua(const std::string &name, const std::string &image, Storage luafile);\n\n  std::shared_ptr<tileset_cv5_t> cv5;\n  std::shared_ptr<tileset_vx4_t> vx4;\n  std::shared_ptr<tileset_vf4_t> vf4;\n  std::shared_ptr<tileset_vr4_t> vr4;\n\nprivate:\n  void init(const std::string &arcfile);\n\n  std::shared_ptr<std::istream> m_cv5_stream;\n  std::shared_ptr<std::istream> m_vx4_stream;\n  std::shared_ptr<std::istream> m_vf4_stream;\n  std::shared_ptr<std::istream> m_vr4_stream;\n\n  std::shared_ptr<kaitai::kstream> m_cv5_ks;\n  std::shared_ptr<kaitai::kstream> m_vx4_ks;\n  std::shared_ptr<kaitai::kstream> m_vf4_ks;\n  std::shared_ptr<kaitai::kstream> m_vr4_ks;\n};\n\n} /* namespace tileset */\n\n#endif /* TILESETHUB_H */\n"
  },
  {
    "path": "src/tileset/meson.build",
    "content": "startool_tileset_sources = files(\n\t'MegaTile.cpp',\n\t'TilesetHub.cpp',\n\t'TiledPaletteImage.cpp'\n)\n"
  },
  {
    "path": "stargus.desktop.in",
    "content": "[Desktop Entry]\nName=Stargus - Starcraft\nComment=Starcraft data game set for the Stratagus engine\nExec=@GAMEDIRABS@/stargus\nIcon=stargus\nTerminal=false\nType=Application\nCategories=Game;StrategyGame;\nStartupNotify=false\n"
  },
  {
    "path": "stargus.nsi",
    "content": ";       _________ __                 __\n;      /   _____//  |_____________ _/  |______     ____  __ __  ______\n;      \\_____  \\\\   __\\_  __ \\__  \\\\   __\\__  \\   / ___\\|  |  \\/  ___/\n;      /        \\|  |  |  | \\// __ \\|  |  / __ \\_/ /_/  >  |  /\\___ |\n;     /_______  /|__|  |__|  (____  /__| (____  /\\___  /|____//____  >\n;             \\/                  \\/          \\//_____/            \\/\n;  ______________________                           ______________________\n;                        T H E   W A R   B E G I N S\n;         Stratagus - A free fantasy real time strategy game engine\n;\n;    stargus.nsi - Windows NSIS Installer for stargus\n;    Copyright (C) 2010-2014  Pali Rohar <pali.rohar@gmail.com>, cybermind <cybermindid@gmail.com>\n;\n;    This program is free software: you can redistribute it and/or modify\n;    it under the terms of the GNU General Public License as published by\n;    the Free Software Foundation, either version 2 of the License, or\n;    (at your option) any later version.\n;\n;    This program is distributed in the hope that it will be useful,\n;    but WITHOUT ANY WARRANTY; without even the implied warranty of\n;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;    GNU General Public License for more details.\n;\n;    You should have received a copy of the GNU General Public License\n;    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n;\n;\n\n;--------------------------------\n\n!ifdef QUIET\n!verbose 2\n!endif\n\n!define redefine \"!insertmacro redefine\"\n!macro redefine symbol value\n!undef ${symbol}\n!define ${symbol} \"${value}\"\n!macroend\n\n!include \"MUI2.nsh\"\n!include \"Sections.nsh\"\n\n;--------------------------------\n\n; General variables\n!define NAME \"stargus\"\n!define VERSION \"3.3.0\"\n!define VIVERSION \"${VERSION}.0.0\"\n!define HOMEPAGE \"https://github.com/wargus/stargus\"\n!define LICENSE \"GPL v2\"\n!define COPYRIGHT \"(c) 2002-2022 by The Stratagus Project\"\n!define STRATAGUS_NAME \"Stratagus\"\n!define STRATAGUS_HOMEPAGE \"https://github.com/wargus/stratagus\"\n\n;--------------------------------\n\n!define ICON \"stargus.ico\"\n!define EXE \"stargus.exe\"\n!define MPQLIST \"mpqlist.txt\"\n!define WARTOOL \"startool.exe\"\n; Must copy files from possible subdirs (Debug, Release), because VS puts them there\n!system \"powershell -Command $\\\"& {cp **\\${WARTOOL} ${WARTOOL}}$\\\"\"\n!system \"powershell -Command $\\\"& {cp **\\${EXE} ${EXE}}$\\\"\"\n\n!define INNOEXTRACT \"innoextract.exe\"\n!define FFMPEG \"ffmpeg.exe\"\n!define MAGICK \"magick.exe\"\n\n!define VCREDIST \"vc_redist.x86.exe\"\n!define VCREDISTREGKEY \"SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x86\"\n\n!ifndef PORTABLE\n!define UNINSTALL \"uninstall.exe\"\n!define INSTALLER \"${NAME}-${VERSION}.exe\"\n!define INSTALLDIR \"$PROGRAMFILES\\${NAME}\\\"\n!else\n!define INSTALLER \"${NAME}-portable-${VERSION}.exe\"\n!define INSTALLDIR \"$DESKTOP\\${NAME}\\\"\n!endif\n\n; Installer for x86-64 systems\n!ifdef x86_64\n${redefine} INSTALLER \"${NAME}-${VERSION}-x86_64.exe\"\n${redefine} INSTALLDIR \"$PROGRAMFILES64\\${NAME}\\\"\n${redefine} NAME \"Stargus (64 bit)\"\n${redefine} STRATAGUS_NAME \"Stratagus (64 bit)\"\n${redefine} VCREDIST \"vc_redist.x64.exe\"\n${redefine} VCREDISTREGKEY \"SOFTWARE\\WOW6432Node\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x64\"\n!endif\n\n; Registry paths\n!ifndef PORTABLE\n!define REGKEY \"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${NAME}\"\n!define STRATAGUS_REGKEY \"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${STRATAGUS_NAME}\"\n!endif\n\n;--------------------------------\n\n; Download and extract nessesary 3rd party programs\n!ifndef NO_DOWNLOAD\n!system \"powershell -Command $\\\"& {wget https://github.com/Wargus/stratagus/releases/download/2015-30-11/${INNOEXTRACT} -OutFile ${INNOEXTRACT}}$\\\"\"\n!system \"powershell -Command $\\\"& {wget https://github.com/Wargus/stratagus/releases/download/2015-30-11/${FFMPEG} -OutFile ${FFMPEG}}$\\\"\"\n!system \"powershell -Command $\\\"& {wget https://github.com/Wargus/stratagus/releases/download/2015-30-11/${MAGICK} -OutFile ${MAGICK}}$\\\"\"\n!system \"powershell -Command $\\\"& {wget https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/${VCREDIST} -OutFile ${VCREDIST}}$\\\"\"\n!endif\n\n!addplugindir .\n\n;--------------------------------\n\n!ifndef PORTABLE\nVar STARTMENUDIR\n!endif\n\n!define MUI_ICON \"${ICON}\"\n!define MUI_UNICON \"${ICON}\"\n\n; Installer pages\n\n!define MUI_ABORTWARNING\n!define MUI_LANGDLL_ALLLANGUAGES\n!define MUI_FINISHPAGE_NOAUTOCLOSE\n!define MUI_FINISHPAGE_NOREBOOTSUPPORT\n!define MUI_FINISHPAGE_RUN \"$INSTDIR\\${EXE}\"\n!define MUI_UNFINISHPAGE_NOAUTOCLOSE\n!define MUI_UNFINISHPAGE_NOREBOOTSUPPORT\n!define MUI_STARTMENUPAGE_REGISTRY_ROOT \"HKLM\"\n!define MUI_STARTMENUPAGE_REGISTRY_KEY \"${REGKEY}\"\n!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME \"StartMenu\"\n\n!insertmacro MUI_PAGE_WELCOME\n!insertmacro MUI_PAGE_LICENSE \"COPYING\"\n!insertmacro MUI_PAGE_COMPONENTS\n!insertmacro MUI_PAGE_DIRECTORY\n\n!ifndef PORTABLE\n!insertmacro MUI_PAGE_STARTMENU Application $STARTMENUDIR\n!endif\n!insertmacro MUI_PAGE_INSTFILES\n!insertmacro MUI_PAGE_FINISH\n\n!insertmacro MUI_UNPAGE_CONFIRM\n!insertmacro MUI_UNPAGE_COMPONENTS\n!insertmacro MUI_UNPAGE_INSTFILES\n!insertmacro MUI_UNPAGE_FINISH\n\n;--------------------------------\n; Available languages\n!insertmacro MUI_LANGUAGE \"English\"\n!insertmacro MUI_LANGUAGE \"Russian\"\n\n!insertmacro MUI_RESERVEFILE_LANGDLL\n\n; Language-dependent strings\nLangString INSTALLER_RUNNING ${LANG_ENGLISH} \"${NAME} Installer is already running\"\nLangString INSTALLER_RUNNING ${LANG_RUSSIAN} \"Óñòàíîâùèê ${NAME} óæå çàïóùåí\"\nLangString NO_STRATAGUS ${LANG_ENGLISH} \"${STRATAGUS_NAME} ${VERSION} is not installed.$\\nYou need ${STRATAGUS_NAME} ${VERSION} to run ${NAME}!$\\nFirst install ${STRATAGUS_NAME} ${VERSION} from ${STRATAGUS_HOMEPAGE}\"\nLangString NO_STRATAGUS ${LANG_RUSSIAN} \"${STRATAGUS_NAME} ${VERSION} is not installed.$\\nYou need ${STRATAGUS_NAME} ${VERSION} to run ${NAME}!$\\nFirst install ${STRATAGUS_NAME} ${VERSION} from ${STRATAGUS_HOMEPAGE}\"\nLangString REMOVEPREVIOUS ${LANG_ENGLISH} \"Removing previous installation\"\nLangString REMOVEPREVIOUS ${LANG_RUSSIAN} \"Óäàëÿþòñÿ ôàéëû èç ïðåäûäóùåé óñòàíîâêè\"\nLangString REMOVECONFIGURATION ${LANG_ENGLISH} \"Removing configuration and data files:\"\nLangString REMOVECONFIGURATION ${LANG_RUSSIAN} \"Óäàëÿþòñÿ äàííûå è ôàéëû êîíôèãóðàöèé:\"\nLangString DESC_REMOVEEXE ${LANG_ENGLISH} \"Remove ${NAME} binary executables\"\nLangString DESC_REMOVEEXE ${LANG_RUSSIAN} \"Óäàëÿþòñÿ èñïîëíÿåìûå ôàéëû ${NAME}\"\nLangString DESC_REMOVECONF ${LANG_ENGLISH} \"Remove all other configuration and extracted data files and directories in ${NAME} install directory created by user or ${NAME}\"\nLangString DESC_REMOVECONF ${LANG_RUSSIAN} \"Óäàëèòü âñå ïðî÷èå ôàéëû è äèðåêòîðèè â óñòàíîâî÷íîé ïàïêå ${NAME}, ñîçäàííûå ïîëüçîâàòåëåì ${NAME}\"\n\nLangString STR_VERSION ${LANG_ENGLISH} \"version\"\nLangString STR_VERSION ${LANG_RUSSIAN} \"âåðñèÿ\"\n\n!ifdef x86_64\nLangString x86_64_ONLY ${LANG_ENGLISH} \"This version is for 64 bits computers only\"\nLangString x86_64_ONLY ${LANG_RUSSIAN} \"Ýòà âåðñèÿ ïðåäíàçíà÷åíà äëÿ 64-áèòíûõ ñèñòåì\"\n!endif\n\n;--------------------------------\n\nName \"${NAME}\"\nIcon \"${ICON}\"\nOutFile \"${INSTALLER}\"\nInstallDir \"${INSTALLDIR}\"\nInstallDirRegKey HKLM \"${REGKEY}\" \"InstallLocation\"\n\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"FileDescription\" \"${NAME} Installer\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"FileVersion\" \"${VERSION}\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"InternalName\" \"${NAME} Installer\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"LegalCopyright\" \"${COPYRIGHT}\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"License\" \"${LICENSE}\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"Homepage\" \"${HOMEPAGE}\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"OriginalFilename\" \"${INSTALLER}\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"ProductName\" \"${NAME} Installer\"\nVIAddVersionKey /LANG=${LANG_ENGLISH} \"ProductVersion\" \"${VERSION}\"\nVIProductVersion \"${VIVERSION}\"\n\nBrandingText \"${NAME}, $(STR_VERSION) ${VERSION}  ${HOMEPAGE}\"\nShowInstDetails Show\n!ifndef PORTABLE\nShowUnInstDetails Show\n!endif\nXPStyle on\n!ifndef PORTABLE\nRequestExecutionLevel admin\n!else\nRequestExecutionLevel user\n!endif\n\nReserveFile \"${WARTOOL}\"\n\n;--------------------------------\n\nSection \"${NAME}\"\n\tSectionIn RO\nSectionEnd\n\n!ifndef PORTABLE\nSection \"-${NAME}\" UninstallPrevious\n\n\tSectionIn RO\n\n\tReadRegStr $0 HKLM \"${REGKEY}\" \"InstallLocation\"\n\tStrCmp $0 \"\" +7\n\n\tDetailPrint \"$(REMOVEPREVIOUS)\"\n\tSetDetailsPrint none\n\tExecWait \"$0\\${UNINSTALL} /S _?=$0\"\n\tDelete \"$0\\${UNINSTALL}\"\n\tRMDir $0\n\tSetDetailsPrint lastused\n\nSectionEnd\n!endif\n\nSection \"-${NAME}\"\n\n\tSectionIn RO\n\n\tSetOutPath \"$INSTDIR\"\n\tFile \"${EXE}\"\n\tFile \"${WARTOOL}\"\n\tFile \"${MPQLIST}\"\n\tFile \"${INNOEXTRACT}\"\n\tFile \"${FFMPEG}\"\n\tFile \"${MAGICK}\"\n\n        ; -- XXX TODO: include Stratagus and dependencies some better way\n\tFile \"stratagus.exe\"\n\t;File \"*.dll\"\n\n\tClearErrors\n\n\tReadRegDword $R0 HKLM \"${VCREDISTREGKEY}\" \"Installed\"\n\tIfErrors 0 NoErrors\n\tStrCpy $R0 0\n\tNoErrors:\n\t${If} $R0 == 0\n\t  File \"${VCREDIST}\"\n\t  ExecWait \"$\\\"$INSTDIR\\${VCREDIST}$\\\"  /passive /norestart\"\n\t  Delete \"$\\\"$INSTDIR\\${VCREDIST}$\\\"\"\n    ${EndIf}\n\n\tClearErrors\n\n\t!cd ${CMAKE_CURRENT_SOURCE_DIR}\n\tSetOutPath \"$INSTDIR\\contrib\"\n\tFile /r \"contrib\\\"\n\t; SetOutPath \"$INSTDIR\\maps\"\n\t; File /r \"maps\\\"\n\t; SetOutPath \"$INSTDIR\\shaders\"\n\t; File /r \"shaders\\\"\n\tSetOutPath \"$INSTDIR\\scripts\"\n\tFile /r \"scripts\\\"\n\t; SetOutPath \"$INSTDIR\\campaigns\"\n\t; File /r \"campaigns\\\"\n\n\t!cd ${CMAKE_CURRENT_BINARY_DIR}\n\t\n\t; outpath used for shortcuts \"start in\" directory\n\tSetOutPath \"$INSTDIR\"\n\n!ifndef PORTABLE\n\t!insertmacro MUI_STARTMENU_WRITE_BEGIN Application\n\tCreateDirectory \"$SMPROGRAMS\\$STARTMENUDIR\"\n\tCreateShortCut \"$SMPROGRAMS\\$STARTMENUDIR\\${NAME}.lnk\" \"$INSTDIR\\${EXE}\"\n\tCreateShortCut \"$SMPROGRAMS\\$STARTMENUDIR\\${NAME} (Debug mode).lnk\" \"$INSTDIR\\${EXE}\" \"-p -i\"\n\tCreateShortCut \"$SMPROGRAMS\\$STARTMENUDIR\\${NAME} (Safe graphics mode).lnk\" \"$INSTDIR\\${EXE}\" \"-g -W -v 320x240\"\n\tCreateShortCut \"$SMPROGRAMS\\$STARTMENUDIR\\${NAME} Map Editor.lnk\" \"$INSTDIR\\${EXE}\" \"-e -g -W -v 640x480\"\n\tCreateShortCut \"$SMPROGRAMS\\$STARTMENUDIR\\Uninstall.lnk\" \"$INSTDIR\\${UNINSTALL}\"\n\tCreateShortcut \"$DESKTOP\\${NAME}.lnk\" \"$INSTDIR\\${EXE}\"\n\t!insertmacro MUI_STARTMENU_WRITE_END\n\n\tWriteRegStr HKLM \"${REGKEY}\" \"DisplayName\" \"${NAME}\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"UninstallString\" \"$\\\"$INSTDIR\\${UNINSTALL}$\\\"\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"QuietUninstallString\" \"$\\\"$INSTDIR\\${UNINSTALL}$\\\" /S\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"InstallLocation\" \"$INSTDIR\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"DisplayIcon\" \"$\\\"$INSTDIR\\${EXE}$\\\",0\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"DisplayVersion\" \"${VERSION}\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"HelpLink\" \"${HOMEPAGE}\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"URLUpdateInfo\" \"${HOMEPAGE}\"\n\tWriteRegStr HKLM \"${REGKEY}\" \"URLInfoAbout\" \"${HOMEPAGE}\"\n\tWriteRegDWORD HKLM \"${REGKEY}\" \"NoModify\" 1\n\tWriteRegDWORD HKLM \"${REGKEY}\" \"NoRepair\" 1\n\tWriteRegStr HKLM \"${STRATAGUS_REGKEY}\\Games\" \"${NAME}\" \"${VERSION}\"\n\n\tWriteUninstaller \"$INSTDIR\\${UNINSTALL}\"\n!else\n\t!appendfile \"$%temp%\\compiletimefile\" \"\"\n\tFile \"/oname=$INSTDIR\\portable-install\" \"$%temp%\\compiletimefile\"\n\n\tCreateShortCut \"$INSTDIR\\${NAME}.lnk\" \"$INSTDIR\\${EXE}\"\n\tCreateShortCut \"$INSTDIR\\${NAME} (Debug mode).lnk\" \"$INSTDIR\\${EXE}\" \"-p -i\"\n\tCreateShortCut \"$INSTDIR\\${NAME} (Safe graphics mode).lnk\" \"$INSTDIR\\${EXE}\" \"-g -W -v 320x240\"\n\tCreateShortCut \"$INSTDIR\\${NAME} Map Editor.lnk\" \"$INSTDIR\\${EXE}\" \"-e -g -W -v 640x480\"\n!endif\nSectionEnd\n\n;--------------------------------\n\n!ifndef PORTABLE\nSection \"un.${NAME}\" Executable\n\n\tSectionIn RO\n\n\tDelete \"$INSTDIR\\${EXE}\"\n\tDelete \"$INSTDIR\\${WARTOOL}\"\n\tDelete \"$INSTDIR\\${MPQLIST}\"\n\tDelete \"$INSTDIR\\${INNOEXTRACT}\"\n\tDelete \"$INSTDIR\\${FFMPEG}\"\n\tDelete \"$INSTDIR\\${MAGICK}\"\n\tDelete \"$INSTDIR\\*.exe\"\n\tDelete \"$INSTDIR\\*.dll\"\n\n\tRMDir /r \"$INSTDIR\\music\"\n\tRMDir /r \"$INSTDIR\\contrib\"\n\tRMDir /r \"$INSTDIR\\maps\"\n\tRMDir /r \"$INSTDIR\\videos\"\n\tRMDir /r \"$INSTDIR\\shaders\"\n\tRMDir /r \"$INSTDIR\\scripts\"\n\tRMDir /r \"$INSTDIR\\campaigns\"\n\tRMDir \"$INSTDIR\"\n\n\t!insertmacro MUI_STARTMENU_GETFOLDER Application $STARTMENUDIR\n\tDelete \"$SMPROGRAMS\\$STARTMENUDIR\\${NAME}.lnk\"\n\tDelete \"$SMPROGRAMS\\$STARTMENUDIR\\${NAME} (Retro).lnk\"\n\tDelete \"$SMPROGRAMS\\$STARTMENUDIR\\Uninstall.lnk\"\n\tRMDir \"$SMPROGRAMS\\$STARTMENUDIR\"\n\tDelete \"$DESKTOP\\${NAME}.lnk\"\n\n\tDeleteRegKey HKLM \"${REGKEY}\"\n\tDeleteRegValue HKLM \"${STRATAGUS_REGKEY}\\Games\" \"${NAME}\"\n\n\tClearErrors\n\tEnumRegValue $0 HKLM \"${REGKEY}\\Games\" 0\n\tIfErrors +2\n\n\tDeleteRegKey /ifempty HKLM \"${STRATAGUS_REGKEY}\\Games\"\n\nSectionEnd\n\nSection /o \"un.Configuration\" Configuration\n\n\tDetailPrint \"$(REMOVECONFIGURATION)\"\n\tRMDir /r \"$INSTDIR\"\n\nSectionEnd\n\n!insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN\n!insertmacro MUI_DESCRIPTION_TEXT \"${Executable}\" \"$(DESC_REMOVEEXE)\"\n!insertmacro MUI_DESCRIPTION_TEXT \"${Configuration}\" \"$(DESC_REMOVECONF)\"\n!insertmacro MUI_UNFUNCTION_DESCRIPTION_END\n\n!endif\n;--------------------------------\n\nFunction .onInit\n\t; Check if stargus installer is already running\n\tSystem::Call 'kernel32::CreateMutexA(i 0, i 0, t \"${NAME}\") i .r1 ?e'\n\tPop $0\n\tStrCmp $0 0 +3\n\n\tMessageBox MB_OK|MB_ICONEXCLAMATION \"$(INSTALLER_RUNNING)\"\n\tAbort\n\n!ifdef x86_64\n\n\tSystem::Call \"kernel32::GetCurrentProcess() i .s\"\n\tSystem::Call \"kernel32::IsWow64Process(i s, *i .r0)\"\n\tIntCmp $0 0 0 0 +3\n\n\tMessageBox MB_OK|MB_ICONSTOP \"$(x86_64_ONLY)\"\n\tAbort\n\n!endif\n\n\t!insertmacro MUI_LANGDLL_DISPLAY\nFunctionEnd\n\n;--------------------------------\n\n!ifdef UPX\n\n!ifndef UPX_FLAGS\n!define UPX_FLAGS \"-9\"\n!else\n${redefine} UPX_FLAGS \"${UPX_FLAGS} -9\"\n!endif\n\n!ifdef QUIET\n${redefine} UPX_FLAGS \"${UPX_FLAGS} -q\"\n!endif\n\n!packhdr \"exehead.tmp\" \"${UPX} ${UPX_FLAGS} exehead.tmp\"\n\n!endif\n\n;!finalize \"gpg --armor --sign --detach-sig %1\"\n\n;--------------------------------\n\n!ifndef NO_DOWNLOAD\n!endif\n\n;--------------------------------\n"
  },
  {
    "path": "stargus.rc",
    "content": "#ifdef _WIN64\n#define NAME \"Stargus (64 bit)\"\n#else\n#define NAME \"Stargus\"\n#endif\n\n#define DESCRIPTION NAME\n#define VERSION \"3.3.0\"\n#define VIVERSION 3,3,0,0\n#define HOMEPAGE \"https://github.com/Wargus/stargus\"\n#define LICENSE \"GPL v2\"\n#define COPYRIGHT \"Copyright (c) 2002-2022 by The Stratagus Project and Pali Rohar\"\n\n1 ICON \"stargus.ico\"\n1 VERSIONINFO\nFILEVERSION\tVIVERSION\nPRODUCTVERSION\tVIVERSION\nFILEOS\t\t4\nFILETYPE\t1\n\nBEGIN\n\tBLOCK \"StringFileInfo\"\n\tBEGIN\n\t\tBLOCK \"040904E4\"\n\t\tBEGIN\n\t\t\tVALUE \"FileDescription\",        DESCRIPTION\n\t\t\tVALUE \"FileVersion\",            VERSION\n\t\t\tVALUE \"InternalName\",           NAME\n\t\t\tVALUE \"LegalCopyright\",         COPYRIGHT\n\t\t\tVALUE \"License\",                LICENSE\n\t\t\tVALUE \"Homepage\",               HOMEPAGE\n\t\t\tVALUE \"OriginalFilename\",       \"stargus.exe\"\n\t\t\tVALUE \"ProductName\",            NAME\n\t\t\tVALUE \"ProductVersion\",         VERSION\n\t\tEND\n\tEND\n\n\tBLOCK \"VarFileInfo\"\n\tBEGIN\n\t\tVALUE \"Translation\", 0x409, 1252\n\tEND\nEND\n"
  },
  {
    "path": "subprojects/StormLib.wrap",
    "content": "[wrap-file]\ndirectory = StormLib-9.24\nsource_url = https://github.com/ladislav-zezula/StormLib/archive/refs/tags/v9.24.tar.gz\nsource_filename = StormLib-9.24.tar.gz\nsource_hash = 33e43788f53a9f36ff107a501caaa744fd239f38bb5c6d6af2c845b87c8a2ee1\n"
  },
  {
    "path": "subprojects/bzip2.wrap",
    "content": "[wrap-file]\ndirectory = bzip2-1.0.5\nsource_url = https://github.com/LuaDist/bzip2/archive/refs/tags/1.0.5.tar.gz\nsource_filename = bzip2-1.0.5.tar.gz\nsource_hash = 1190e2877a8d9d4a4fa5b8716b649a2f232976d7e1a8f199861a90c7bc282ce0\ndiff_files = bzip2.patch\n"
  },
  {
    "path": "subprojects/libpng.wrap",
    "content": "[wrap-file]\ndirectory = libpng-1.6.37\nsource_url = https://github.com/glennrp/libpng/archive/v1.6.37.tar.gz\nsource_filename = libpng-1.6.37.tar.gz\nsource_hash = ca74a0dace179a8422187671aee97dd3892b53e168627145271cad5b5ac81307\npatch_filename = libpng_1.6.37-5_patch.zip\npatch_url = https://wrapdb.mesonbuild.com/v2/libpng_1.6.37-5/get_patch\npatch_hash = 822200906ad2e82dc8b44e79fe960e980ccad96263548c35eef721086a9926f1\n\n[provide]\nlibpng = libpng_dep\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/.clang-format",
    "content": "#AccessModifierOffset: 2\nAlignAfterOpenBracket: Align\nAlignConsecutiveAssignments: false\n#AlignConsecutiveBitFields: false\nAlignConsecutiveDeclarations: false\nAlignConsecutiveMacros: false\nAlignEscapedNewlines: Right\n#AlignOperands: AlignAfterOperator\nAlignTrailingComments: true\nAllowAllArgumentsOnNextLine: false\nAllowAllConstructorInitializersOnNextLine: false\nAllowAllParametersOfDeclarationOnNextLine: false\nAllowShortBlocksOnASingleLine: Empty\nAllowShortCaseLabelsOnASingleLine: false\n#AllowShortEnumsOnASingleLine: true\nAllowShortFunctionsOnASingleLine: Empty\nAllowShortIfStatementsOnASingleLine: Never\nAllowShortLambdasOnASingleLine: Empty\nAllowShortLoopsOnASingleLine: false\nAlwaysBreakAfterReturnType: None\nAlwaysBreakBeforeMultilineStrings: false\nAlwaysBreakTemplateDeclarations: Yes\nBinPackArguments: false\nBinPackParameters: false\n#BitFieldColonSpacing: Both\nBreakBeforeBraces: Custom # or Allman\nBraceWrapping:\n  AfterCaseLabel: true\n  AfterClass: true\n  AfterControlStatement: Always\n  AfterEnum: true\n  AfterFunction: true\n  AfterNamespace: false\n  AfterStruct: true\n  AfterUnion: true\n  AfterExternBlock: false\n  BeforeCatch: true\n  BeforeElse: true\n  #BeforeLambdaBody: false\n  #BeforeWhile: false\n  SplitEmptyFunction: false\n  SplitEmptyRecord: false\n  SplitEmptyNamespace: false\nBreakBeforeTernaryOperators: true\nBreakConstructorInitializers: BeforeComma\nBreakStringLiterals: false\nColumnLimit: 0\nCompactNamespaces: false\nConstructorInitializerIndentWidth: 2\nCpp11BracedListStyle: true\nPointerAlignment: Left\nFixNamespaceComments: true\nIncludeBlocks: Preserve\n#IndentCaseBlocks: false\nIndentCaseLabels: true\nIndentGotoLabels: false\nIndentPPDirectives: BeforeHash\nIndentWidth: 4\nKeepEmptyLinesAtTheStartOfBlocks: false\nMaxEmptyLinesToKeep: 1\nNamespaceIndentation: None\nReflowComments: false\nSortIncludes: true\nSortUsingDeclarations: true\nSpaceAfterCStyleCast: false\nSpaceAfterLogicalNot: false\nSpaceAfterTemplateKeyword: false\nSpaceBeforeAssignmentOperators: true\nSpaceBeforeCpp11BracedList: false\nSpaceBeforeParens: ControlStatements\nSpaceBeforeRangeBasedForLoopColon: true\nSpaceBeforeSquareBrackets: false\nSpaceInEmptyBlock: false\nSpaceInEmptyParentheses: false\nSpacesBeforeTrailingComments: 2\nSpacesInAngles: false\nSpacesInCStyleCastParentheses: false\nSpacesInConditionalStatement: false\nSpacesInContainerLiterals: false\nSpacesInParentheses: false\nSpacesInSquareBrackets: false\nStandard: c++11\nTabWidth: 4\nUseTab: Never\n"
  },
  {
    "path": "subprojects/nlohmann_json/.clang-tidy",
    "content": "Checks: '*,\n         -altera-id-dependent-backward-branch,\n         -altera-struct-pack-align,\n         -altera-unroll-loops,\n         -android-cloexec-fopen,\n         -bugprone-easily-swappable-parameters,\n         -concurrency-mt-unsafe,\n         -cppcoreguidelines-avoid-goto,\n         -cppcoreguidelines-avoid-magic-numbers,\n         -cppcoreguidelines-avoid-non-const-global-variables,\n         -cppcoreguidelines-macro-usage,\n         -cppcoreguidelines-pro-bounds-array-to-pointer-decay,\n         -cppcoreguidelines-pro-bounds-constant-array-index,\n         -cppcoreguidelines-pro-bounds-pointer-arithmetic,\n         -cppcoreguidelines-pro-type-reinterpret-cast,\n         -cppcoreguidelines-pro-type-union-access,\n         -cppcoreguidelines-virtual-class-destructor,\n         -fuchsia-default-arguments-calls,\n         -fuchsia-default-arguments-declarations,\n         -fuchsia-overloaded-operator,\n         -google-explicit-constructor,\n         -google-readability-function-size,\n         -google-runtime-int,\n         -google-runtime-references,\n         -hicpp-avoid-goto,\n         -hicpp-explicit-conversions,\n         -hicpp-function-size,\n         -hicpp-no-array-decay,\n         -hicpp-no-assembler,\n         -hicpp-signed-bitwise,\n         -hicpp-uppercase-literal-suffix,\n         -llvm-header-guard,\n         -llvm-include-order,\n         -llvmlibc-*,\n         -misc-no-recursion,\n         -misc-non-private-member-variables-in-classes,\n         -modernize-concat-nested-namespaces,\n         -modernize-use-nodiscard,\n         -modernize-use-trailing-return-type,\n         -readability-function-cognitive-complexity,\n         -readability-function-size,\n         -readability-identifier-length,\n         -readability-magic-numbers,\n         -readability-redundant-access-specifiers,\n         -readability-uppercase-literal-suffix'\n\nCheckOptions:\n  - key: hicpp-special-member-functions.AllowSoleDefaultDtor\n    value: 1\n\nWarningsAsErrors: '*'\n\n#HeaderFilterRegex: '.*nlohmann.*'\nHeaderFilterRegex: '.*hpp$'\n"
  },
  {
    "path": "subprojects/nlohmann_json/.drone.yml",
    "content": "kind: pipeline\nname: test-on-arm64\n\nplatform:\n  arch: arm64\n\nsteps:\n- name: build\n  image: gcc\n  commands:\n  - wget https://github.com/Kitware/CMake/releases/download/v3.20.2/cmake-3.20.2.tar.gz\n  - tar xfz cmake-3.20.2.tar.gz\n  - cd cmake-3.20.2\n  - ./configure\n  - make cmake ctest -j10\n  - cd ..\n  - mkdir build\n  - cd build\n  - ../cmake-3.20.2/bin/cmake .. -DJSON_FastTests=ON\n  - make -j10\n  - cd test\n  - ../../cmake-3.20.2/bin/ctest -j10\n"
  },
  {
    "path": "subprojects/nlohmann_json/.gitignore",
    "content": "json_unit\njson_benchmarks\njson_benchmarks_simple\nfuzz-testing\n\n*.dSYM\n*.o\n*.gcno\n*.gcda\n\nbuild\nbuild_coverage\nclang_analyze_build\n\nbenchmarks/files/numbers/*.json\n\n.wsjcpp-logs/*\n.wsjcpp/*\n\n.idea\n/cmake-build-*\n\ntest/test-*\n/.vs\n\ndoc/html\ndoc/mkdocs/venv/\ndoc/mkdocs/docs/examples\ndoc/mkdocs/site\ndoc/mkdocs/docs/__pycache__/\n/doc/docset/JSON_for_Modern_C++.docset/\n/doc/docset/JSON_for_Modern_C++.tgz\n"
  },
  {
    "path": "subprojects/nlohmann_json/CITATION.cff",
    "content": "cff-version: 1.1.0\nmessage: \"If you use this software, please cite it as below.\"\nauthors: \n  - family-names: Lohmann\n    given-names: Niels\n    orcid: https://orcid.org/0000-0001-9037-795X\n    email: mail@nlohmann.me\n    website: https://nlohmann.me\ntitle: \"JSON for Modern C++\"\nversion: 3.10.5\ndate-released: 2022\nlicense: MIT\nrepository-code: \"https://github.com/nlohmann\"\nurl: https://json.nlohmann.me\n"
  },
  {
    "path": "subprojects/nlohmann_json/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.1)\n\n##\n## PROJECT\n## name and version\n##\nproject(nlohmann_json VERSION 3.10.5 LANGUAGES CXX)\n\n##\n## MAIN_PROJECT CHECK\n## determine if nlohmann_json is built as a subproject (using add_subdirectory) or if it is the main project\n##\nset(MAIN_PROJECT OFF)\nif (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)\n    set(MAIN_PROJECT ON)\nendif()\n\n##\n## INCLUDE\n##\n##\ninclude(ExternalProject)\n\n##\n## OPTIONS\n##\n\nif (POLICY CMP0077)\n    # Allow CMake 3.13+ to override options when using FetchContent / add_subdirectory.\n    cmake_policy(SET CMP0077 NEW)\nendif ()\n\noption(JSON_BuildTests          \"Build the unit tests when BUILD_TESTING is enabled.\" ${MAIN_PROJECT})\noption(JSON_CI                  \"Enable CI build targets.\" OFF)\noption(JSON_Diagnostics         \"Use extended diagnostic messages.\" OFF)\noption(JSON_ImplicitConversions \"Enable implicit conversions.\" ON)\noption(JSON_Install             \"Install CMake targets during install step.\" ${MAIN_PROJECT})\noption(JSON_MultipleHeaders     \"Use non-amalgamated version of the library.\" OFF)\noption(JSON_SystemInclude       \"Include as system headers (skip for clang-tidy).\" OFF)\n\nif (JSON_CI)\n    include(cmake/ci.cmake)\nendif ()\n\n##\n## CONFIGURATION\n##\ninclude(GNUInstallDirs)\n\nset(NLOHMANN_JSON_TARGET_NAME               ${PROJECT_NAME})\nset(NLOHMANN_JSON_CONFIG_INSTALL_DIR        \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\" CACHE INTERNAL \"\")\nset(NLOHMANN_JSON_INCLUDE_INSTALL_DIR       \"${CMAKE_INSTALL_INCLUDEDIR}\")\nset(NLOHMANN_JSON_TARGETS_EXPORT_NAME       \"${PROJECT_NAME}Targets\")\nset(NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE     \"cmake/config.cmake.in\")\nset(NLOHMANN_JSON_CMAKE_CONFIG_DIR          \"${CMAKE_CURRENT_BINARY_DIR}\")\nset(NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE \"${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}ConfigVersion.cmake\")\nset(NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE \"${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Config.cmake\")\nset(NLOHMANN_JSON_CMAKE_PROJECT_TARGETS_FILE \"${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Targets.cmake\")\nset(NLOHMANN_JSON_PKGCONFIG_INSTALL_DIR     \"${CMAKE_INSTALL_LIBDIR}/pkgconfig\")\n\nif (JSON_MultipleHeaders)\n    set(NLOHMANN_JSON_INCLUDE_BUILD_DIR \"${PROJECT_SOURCE_DIR}/include/\")\n    message(STATUS \"Using the multi-header code from ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}\")\nelse()\n    set(NLOHMANN_JSON_INCLUDE_BUILD_DIR \"${PROJECT_SOURCE_DIR}/single_include/\")\n    message(STATUS \"Using the single-header code from ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}\")\nendif()\n\nif (NOT JSON_ImplicitConversions)\n    message(STATUS \"Implicit conversions are disabled\")\nendif()\n\nif (JSON_Diagnostics)\n    message(STATUS \"Diagnostics enabled\")\nendif()\n\nif (JSON_SystemInclude)\n    set(NLOHMANN_JSON_SYSTEM_INCLUDE \"SYSTEM\")\nendif()\n\n##\n## TARGET\n## create target and add include path\n##\nadd_library(${NLOHMANN_JSON_TARGET_NAME} INTERFACE)\nadd_library(${PROJECT_NAME}::${NLOHMANN_JSON_TARGET_NAME} ALIAS ${NLOHMANN_JSON_TARGET_NAME})\nif (${CMAKE_VERSION} VERSION_LESS \"3.8.0\")\n    target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_range_for)\nelse()\n    target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_std_11)\nendif()\n\ntarget_compile_definitions(\n    ${NLOHMANN_JSON_TARGET_NAME}\n    INTERFACE\n    JSON_USE_IMPLICIT_CONVERSIONS=$<BOOL:${JSON_ImplicitConversions}>\n    JSON_DIAGNOSTICS=$<BOOL:${JSON_Diagnostics}>\n)\n\ntarget_include_directories(\n    ${NLOHMANN_JSON_TARGET_NAME}\n    ${NLOHMANN_JSON_SYSTEM_INCLUDE} INTERFACE\n    $<BUILD_INTERFACE:${NLOHMANN_JSON_INCLUDE_BUILD_DIR}>\n    $<INSTALL_INTERFACE:include>\n)\n\n## add debug view definition file for msvc (natvis)\nif (MSVC)\n    set(NLOHMANN_ADD_NATVIS TRUE)\n    set(NLOHMANN_NATVIS_FILE \"nlohmann_json.natvis\")\n    target_sources(\n        ${NLOHMANN_JSON_TARGET_NAME}\n        INTERFACE\n            $<INSTALL_INTERFACE:${NLOHMANN_NATVIS_FILE}>\n            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${NLOHMANN_NATVIS_FILE}>\n    )\nendif()\n\n# Install a pkg-config file, so other tools can find this.\nCONFIGURE_FILE(\n    \"${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc\"\n)\n\n##\n## TESTS\n## create and configure the unit test target\n##\nif (JSON_BuildTests)\n    include(CTest)\n    enable_testing()\n    add_subdirectory(test)\nendif()\n\n##\n## INSTALL\n## install header files, generate and install cmake config files for find_package()\n##\ninclude(CMakePackageConfigHelpers)\n# use a custom package version config file instead of\n# write_basic_package_version_file to ensure that it's architecture-independent\n# https://github.com/nlohmann/json/issues/1697\nconfigure_file(\n    \"cmake/nlohmann_jsonConfigVersion.cmake.in\"\n    ${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE}\n    @ONLY\n)\nconfigure_file(\n    ${NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE}\n    ${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE}\n    @ONLY\n)\n\nif(JSON_Install)\n    install(\n        DIRECTORY ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}\n        DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR}\n    )\n    install(\n        FILES ${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE} ${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE}\n        DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}\n    )\n    if (NLOHMANN_ADD_NATVIS)\n        install(\n            FILES ${NLOHMANN_NATVIS_FILE}\n            DESTINATION .\n    )\n    endif()\n    export(\n        TARGETS ${NLOHMANN_JSON_TARGET_NAME}\n        NAMESPACE ${PROJECT_NAME}::\n        FILE ${NLOHMANN_JSON_CMAKE_PROJECT_TARGETS_FILE}\n    )\n    install(\n        TARGETS ${NLOHMANN_JSON_TARGET_NAME}\n        EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME}\n        INCLUDES DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR}\n    )\n    install(\n        EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME}\n        NAMESPACE ${PROJECT_NAME}::\n        DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}\n    )\n    install(\n        FILES \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc\"\n        DESTINATION ${NLOHMANN_JSON_PKGCONFIG_INSTALL_DIR}\n    )\nendif()\n"
  },
  {
    "path": "subprojects/nlohmann_json/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "subprojects/nlohmann_json/ChangeLog.md",
    "content": "# Changelog\nAll notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).\n\n## [3.10.5](https://github.com/nlohmann/json/releases/tag/3.10.5) (2022-01-02)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.4...3.10.5)\n\n- \\#include \\<filesystem\\> doesn't work with gcc-7 when `-std=c++17` is specified. [\\#3203](https://github.com/nlohmann/json/issues/3203)\n- Not able to use nlohmann json with c++ code built using emscripten to wasm [\\#3200](https://github.com/nlohmann/json/issues/3200)\n- Warning for shadowed variables [\\#3188](https://github.com/nlohmann/json/issues/3188)\n- Accessing missing keys on const json object leads to assert [\\#3183](https://github.com/nlohmann/json/issues/3183)\n- Data member is available, but null is reported, and program throws error [\\#3173](https://github.com/nlohmann/json/issues/3173)\n- serialization problem, from\\_json need construct new object [\\#3169](https://github.com/nlohmann/json/issues/3169)\n- std::filesystem unavailable on macOS lower deployment targets [\\#3156](https://github.com/nlohmann/json/issues/3156)\n- \\[json.exception.type\\_error.305\\] cannot use operator\\[\\] with a string argument with string [\\#3151](https://github.com/nlohmann/json/issues/3151)\n- json::dump\\(\\) is not compatible with C++ standards [\\#3147](https://github.com/nlohmann/json/issues/3147)\n- Issue with json::parse decoding codepoints [\\#3142](https://github.com/nlohmann/json/issues/3142)\n- Simple parse of json object thinks it should be an array [\\#3136](https://github.com/nlohmann/json/issues/3136)\n- How to properly read a Json string that may be null in some cases? [\\#3135](https://github.com/nlohmann/json/issues/3135)\n- Deadlock on create json - windows only [\\#3129](https://github.com/nlohmann/json/issues/3129)\n- Wrong parsing of int64 values nearest of limit [\\#3126](https://github.com/nlohmann/json/issues/3126)\n- ordered\\_json doesn't support range based erase [\\#3108](https://github.com/nlohmann/json/issues/3108)\n- Apple build failed with json/single\\_include/nlohmann/json.hpp:4384:57: 'path' is unavailable [\\#3097](https://github.com/nlohmann/json/issues/3097)\n- GCC 7.5.0 with --std=c++17: filesystem: No such file or directory [\\#3090](https://github.com/nlohmann/json/issues/3090)\n- Drop Travis CI [\\#3087](https://github.com/nlohmann/json/issues/3087)\n- ordered\\_json::reset\\(\\) compile error with nvcc [\\#3013](https://github.com/nlohmann/json/issues/3013)\n- Support for unordered\\_map as object\\_t [\\#2932](https://github.com/nlohmann/json/issues/2932)\n- Compiler warning with Intel compiler, same as \\#755 [\\#2712](https://github.com/nlohmann/json/issues/2712)\n- Compiler warnings with NVCC 11.2 [\\#2676](https://github.com/nlohmann/json/issues/2676)\n- some static analysis warning at line 11317 [\\#1390](https://github.com/nlohmann/json/issues/1390)\n- Compiling with icpc [\\#755](https://github.com/nlohmann/json/issues/755)\n\n- Fix compilation error with NVCC [\\#3234](https://github.com/nlohmann/json/pull/3234) ([nlohmann](https://github.com/nlohmann))\n- Remove Travis CI [\\#3233](https://github.com/nlohmann/json/pull/3233) ([nlohmann](https://github.com/nlohmann))\n- Add build step for NVCC and fix a warning [\\#3227](https://github.com/nlohmann/json/pull/3227) ([nlohmann](https://github.com/nlohmann))\n- Update cpplint [\\#3225](https://github.com/nlohmann/json/pull/3225) ([nlohmann](https://github.com/nlohmann))\n- Fix: Warning for shadowed variables \\(\\#3188\\) [\\#3193](https://github.com/nlohmann/json/pull/3193) ([kernie](https://github.com/kernie))\n- Fix FAQ hyperlink typo in readme [\\#3148](https://github.com/nlohmann/json/pull/3148) ([Prince-Mendiratta](https://github.com/Prince-Mendiratta))\n- Docs: Update `skip_comments` to `ignore_comments` [\\#3145](https://github.com/nlohmann/json/pull/3145) ([daniel-kun](https://github.com/daniel-kun))\n- fix typos in documentation [\\#3140](https://github.com/nlohmann/json/pull/3140) ([striezel](https://github.com/striezel))\n- Fix spelling [\\#3125](https://github.com/nlohmann/json/pull/3125) ([axic](https://github.com/axic))\n- Extend std specializations [\\#3121](https://github.com/nlohmann/json/pull/3121) ([nlohmann](https://github.com/nlohmann))\n- Add missing erase\\(first, last\\) function to ordered\\_map [\\#3109](https://github.com/nlohmann/json/pull/3109) ([nlohmann](https://github.com/nlohmann))\n- Fix typos in operator\\[\\] documentation [\\#3102](https://github.com/nlohmann/json/pull/3102) ([axnsan12](https://github.com/axnsan12))\n- Add C++17 copies of the test binaries [\\#3101](https://github.com/nlohmann/json/pull/3101) ([nlohmann](https://github.com/nlohmann))\n- Add examples for parsing from iterator pair [\\#3100](https://github.com/nlohmann/json/pull/3100) ([nlohmann](https://github.com/nlohmann))\n- Update CI [\\#3088](https://github.com/nlohmann/json/pull/3088) ([nlohmann](https://github.com/nlohmann))\n- Revert invalid fix [\\#3082](https://github.com/nlohmann/json/pull/3082) ([nlohmann](https://github.com/nlohmann))\n- Allow to use get with explicit constructor [\\#3079](https://github.com/nlohmann/json/pull/3079) ([nlohmann](https://github.com/nlohmann))\n- fix std::filesystem::path regression [\\#3073](https://github.com/nlohmann/json/pull/3073) ([theodelrieu](https://github.com/theodelrieu))\n- Consolidate documentation [\\#3071](https://github.com/nlohmann/json/pull/3071) ([nlohmann](https://github.com/nlohmann))\n- Add recursive update function [\\#3069](https://github.com/nlohmann/json/pull/3069) ([nlohmann](https://github.com/nlohmann))\n- Fix Clang version [\\#3040](https://github.com/nlohmann/json/pull/3040) ([nlohmann](https://github.com/nlohmann))\n- Fix assertion failure for JSON\\_DIAGNOSTICS [\\#3037](https://github.com/nlohmann/json/pull/3037) ([carlsmedstad](https://github.com/carlsmedstad))\n- meta: fix is\\_compatible/constructible traits [\\#3020](https://github.com/nlohmann/json/pull/3020) ([theodelrieu](https://github.com/theodelrieu))\n- Set parent pointers for values inserted via update\\(\\) \\(fixes \\#3007\\). [\\#3008](https://github.com/nlohmann/json/pull/3008) ([AnthonyVH](https://github.com/AnthonyVH))\n- Allow allocators for output\\_vector\\_adapter [\\#2989](https://github.com/nlohmann/json/pull/2989) ([nlohmann](https://github.com/nlohmann))\n- Re-add Clang 12 [\\#2986](https://github.com/nlohmann/json/pull/2986) ([nlohmann](https://github.com/nlohmann))\n- Use new Docker image [\\#2981](https://github.com/nlohmann/json/pull/2981) ([nlohmann](https://github.com/nlohmann))\n- Fix -Wunused warnings on JSON\\_DIAGNOSTICS  [\\#2976](https://github.com/nlohmann/json/pull/2976) ([gcerretani](https://github.com/gcerretani))\n- Update docset generation script [\\#2967](https://github.com/nlohmann/json/pull/2967) ([nlohmann](https://github.com/nlohmann))\n\n## [v3.10.4](https://github.com/nlohmann/json/releases/tag/v3.10.4) (2021-10-16)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.3...v3.10.4)\n\n- Compiler error in output serializer due to 'incompatible initializer' [\\#3081](https://github.com/nlohmann/json/issues/3081)\n- Strange behaviour when using std::sort on std::vector\\<json\\> [\\#3080](https://github.com/nlohmann/json/issues/3080)\n- Unhandled exception: nlohmann::detail::parse\\_error [\\#3078](https://github.com/nlohmann/json/issues/3078)\n- explicit constructor with default does not compile [\\#3077](https://github.com/nlohmann/json/issues/3077)\n- Parse an object but get an array using GCC [\\#3076](https://github.com/nlohmann/json/issues/3076)\n- Version 3.10.3 breaks backward-compatibility with 3.10.2 [\\#3070](https://github.com/nlohmann/json/issues/3070)\n- Feature request, Add to\\_json/from\\_json to align with other to/from binary api.  [\\#3067](https://github.com/nlohmann/json/issues/3067)\n- vcpkg is out of date [\\#3066](https://github.com/nlohmann/json/issues/3066)\n\n## [v3.10.3](https://github.com/nlohmann/json/releases/tag/v3.10.3) (2021-10-08)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.2...v3.10.3)\n\n- Parsing an emtpy string returns a string with size 1 instead of expected 0 [\\#3057](https://github.com/nlohmann/json/issues/3057)\n- Linking error  \"duplicate symbol: std::type\\_info::operator==\" on static build with MinGW [\\#3042](https://github.com/nlohmann/json/issues/3042)\n- Yet another assertion failure when inserting into arrays with JSON\\_DIAGNOSTICS set [\\#3032](https://github.com/nlohmann/json/issues/3032)\n- accept and parse function not work well with a pure number string [\\#3029](https://github.com/nlohmann/json/issues/3029)\n- push\\_back doesn't work for serializing containers [\\#3027](https://github.com/nlohmann/json/issues/3027)\n- Strange behaviour when creating array with single element [\\#3025](https://github.com/nlohmann/json/issues/3025)\n- Input ordered\\_json doesn't work [\\#3023](https://github.com/nlohmann/json/issues/3023)\n- Issue iterating through 'items' [\\#3021](https://github.com/nlohmann/json/issues/3021)\n- Cannot spell the namespace right [\\#3015](https://github.com/nlohmann/json/issues/3015)\n- JSON Parse error when reading json object from file [\\#3011](https://github.com/nlohmann/json/issues/3011)\n- Parent pointer not properly set when using update\\(\\) [\\#3007](https://github.com/nlohmann/json/issues/3007)\n- Overwriting terminated null character [\\#3001](https://github.com/nlohmann/json/issues/3001)\n- 'operator =' is ambiguous on VS2017 [\\#2997](https://github.com/nlohmann/json/issues/2997)\n- JSON Patch for Array Elements [\\#2994](https://github.com/nlohmann/json/issues/2994)\n- JSON Parse throwing error [\\#2983](https://github.com/nlohmann/json/issues/2983)\n- to\\_{binary format} does not provide a mechanism for specifying a custom allocator for the returned type. [\\#2982](https://github.com/nlohmann/json/issues/2982)\n- 3.10.1 zip json.hpp has version number 3.10.0 instead of 3.10.1 [\\#2973](https://github.com/nlohmann/json/issues/2973)\n- Assertion failure when serializing array with JSON\\_DIAGNOSTICS set [\\#2926](https://github.com/nlohmann/json/issues/2926)\n\n## [v3.10.2](https://github.com/nlohmann/json/releases/tag/v3.10.2) (2021-08-26)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.1...v3.10.2)\n\n- Annoying -Wundef on new JSON\\_DIAGNOSTICS macro [\\#2975](https://github.com/nlohmann/json/issues/2975)\n- += issue with multiple redirection. [\\#2970](https://github.com/nlohmann/json/issues/2970)\n- \"incomplete type ‘nlohmann::detail::wide\\_string\\_input\\_helper\" compilation error [\\#2969](https://github.com/nlohmann/json/issues/2969)\n\n## [v3.10.1](https://github.com/nlohmann/json/releases/tag/v3.10.1) (2021-08-24)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.10.0...v3.10.1)\n\n- JSON\\_DIAGNOSTICS assertion for ordered\\_json [\\#2962](https://github.com/nlohmann/json/issues/2962)\n- Inserting in unordered json using a pointer retains the leading slash [\\#2958](https://github.com/nlohmann/json/issues/2958)\n- Test  \\#9: test-cbor test case sample.json fails in debug mode - Stack overflow [\\#2955](https://github.com/nlohmann/json/issues/2955)\n- 3.10.0 broke at least the Bear project [\\#2953](https://github.com/nlohmann/json/issues/2953)\n- 2 tests fail in 3.10.0: cmake\\_fetch\\_content\\_configure, cmake\\_fetch\\_content\\_build [\\#2951](https://github.com/nlohmann/json/issues/2951)\n- ctest \\(58+60,/67 cmake\\_import\\_configure\\) fails when build with -D JSON\\_Install:BOOL=OFF because of missing nlohmann\\_jsonTargets.cmake [\\#2946](https://github.com/nlohmann/json/issues/2946)\n- Document vcpkg usage [\\#2944](https://github.com/nlohmann/json/issues/2944)\n- Linker error LNK2005 when compiling \\(x64\\) json-3.10.0.zip with Visual Studio 2019 16.11.1  [\\#2941](https://github.com/nlohmann/json/issues/2941)\n- Move Travis jobs to travis-ci.com [\\#2938](https://github.com/nlohmann/json/issues/2938)\n\n- Fixed typo in docs/api/basic\\_json/parse.md [\\#2968](https://github.com/nlohmann/json/pull/2968) ([mb0202](https://github.com/mb0202))\n- Add link to Homebrew package [\\#2966](https://github.com/nlohmann/json/pull/2966) ([nlohmann](https://github.com/nlohmann))\n- Fix parent update for diagnostics with ordered\\_json [\\#2963](https://github.com/nlohmann/json/pull/2963) ([nlohmann](https://github.com/nlohmann))\n- Set stack size for some unit tests when using MSVC [\\#2961](https://github.com/nlohmann/json/pull/2961) ([nlohmann](https://github.com/nlohmann))\n- Add regression test [\\#2960](https://github.com/nlohmann/json/pull/2960) ([nlohmann](https://github.com/nlohmann))\n- Update Travis badge [\\#2959](https://github.com/nlohmann/json/pull/2959) ([nlohmann](https://github.com/nlohmann))\n- Fix some extra \";\" clang warnings [\\#2957](https://github.com/nlohmann/json/pull/2957) ([Hallot](https://github.com/Hallot))\n- Add documentation for integration via vcpkg [\\#2954](https://github.com/nlohmann/json/pull/2954) ([nlohmann](https://github.com/nlohmann))\n- Avoid duplicate AppVeyor builds [\\#2952](https://github.com/nlohmann/json/pull/2952) ([nlohmann](https://github.com/nlohmann))\n- 🚨 fix gdb\\_pretty\\_printer failure on basic types [\\#2950](https://github.com/nlohmann/json/pull/2950) ([senyai](https://github.com/senyai))\n- Add header to use value\\_t [\\#2948](https://github.com/nlohmann/json/pull/2948) ([nlohmann](https://github.com/nlohmann))\n- Skip some tests if JSON\\_Install is not set [\\#2947](https://github.com/nlohmann/json/pull/2947) ([nlohmann](https://github.com/nlohmann))\n- Remove outdated json\\_unit test binary [\\#2945](https://github.com/nlohmann/json/pull/2945) ([nlohmann](https://github.com/nlohmann))\n- Updating the Homebrew Command [\\#2943](https://github.com/nlohmann/json/pull/2943) ([amirmasoudabdol](https://github.com/amirmasoudabdol))\n\n## [v3.10.0](https://github.com/nlohmann/json/releases/tag/v3.10.0) (2021-08-17)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.9.1...v3.10.0)\n\n- Latest version 3.9.1 uses throw instead of JSON\\_THROW in the amalgamated json.hpp file [\\#2934](https://github.com/nlohmann/json/issues/2934)\n- Copy to a variable inside a Structure [\\#2933](https://github.com/nlohmann/json/issues/2933)\n- warning C4068: unknown pragma 'GCC' on MSVC/cl [\\#2924](https://github.com/nlohmann/json/issues/2924)\n- Errors during ninja test [\\#2918](https://github.com/nlohmann/json/issues/2918)\n- compiler warning: \"not return a value\" [\\#2917](https://github.com/nlohmann/json/issues/2917)\n- Comparison floating points causes warning [\\#2909](https://github.com/nlohmann/json/issues/2909)\n- Why can't I have std::vector\\<json&\\> testList? [\\#2900](https://github.com/nlohmann/json/issues/2900)\n- \\[json.hpp\\] from releases doesnt work [\\#2897](https://github.com/nlohmann/json/issues/2897)\n- g++ \\(11\\) -Wuseless-cast gives lots of warnings [\\#2893](https://github.com/nlohmann/json/issues/2893)\n- Cannot serialize and immediatly deserialize json to/from bson [\\#2892](https://github.com/nlohmann/json/issues/2892)\n- Floating-point precision conversion error [\\#2876](https://github.com/nlohmann/json/issues/2876)\n- How to avoid escaping for an already escaped string in .dump\\(\\) [\\#2870](https://github.com/nlohmann/json/issues/2870)\n- can't parse std::vector\\<std::byte\\> [\\#2869](https://github.com/nlohmann/json/issues/2869)\n- ASAN detects memory leaks [\\#2865](https://github.com/nlohmann/json/issues/2865)\n- Binary subtype field cannot represent all CBOR tags [\\#2863](https://github.com/nlohmann/json/issues/2863)\n- string literals possibly being parsed as another type due to the presence of only digits and full-stops [\\#2852](https://github.com/nlohmann/json/issues/2852)\n- json::parse\\(\\) works only with absolute paths [\\#2851](https://github.com/nlohmann/json/issues/2851)\n- Compiler Warnings on Raspberry Pi OS [\\#2850](https://github.com/nlohmann/json/issues/2850)\n- Braced initialization and aggregate initialization behavior is different for `json::array()` function call. [\\#2848](https://github.com/nlohmann/json/issues/2848)\n- 3.9.1: test suite is failing [\\#2845](https://github.com/nlohmann/json/issues/2845)\n- Documentation for macro JSON\\_NO\\_IO is missing [\\#2842](https://github.com/nlohmann/json/issues/2842)\n- Assertion failure when inserting into arrays with JSON\\_DIAGNOSTICS set [\\#2838](https://github.com/nlohmann/json/issues/2838)\n- HELP! There is a memory leak in the code?! [\\#2837](https://github.com/nlohmann/json/issues/2837)\n- Elegant conversion of a 2-D-json array to a standard C++ array [\\#2805](https://github.com/nlohmann/json/issues/2805)\n- Swift Package Manager support [\\#2802](https://github.com/nlohmann/json/issues/2802)\n- Referencing a subkey which doesn't exist gives crash [\\#2797](https://github.com/nlohmann/json/issues/2797)\n- Failed benchmark due to renamed branch [\\#2796](https://github.com/nlohmann/json/issues/2796)\n- Build Errors with VS 2019 and json Version 3.9.1 when attempting to replicate SAX Example [\\#2782](https://github.com/nlohmann/json/issues/2782)\n- Value with spaces cannot be parsed [\\#2781](https://github.com/nlohmann/json/issues/2781)\n- \\[Question\\] CBOR rfc support. [\\#2779](https://github.com/nlohmann/json/issues/2779)\n- Using JSON.hpp header file in Visual Studio 2013 \\(C++ Project\\) [\\#2775](https://github.com/nlohmann/json/issues/2775)\n- compilation error on clang-8 + C++17 [\\#2759](https://github.com/nlohmann/json/issues/2759)\n- Undefined symbol EOF  [\\#2755](https://github.com/nlohmann/json/issues/2755)\n- Parsing a string into json object behaves differently under g++ and MinGW compilers. [\\#2746](https://github.com/nlohmann/json/issues/2746)\n- big git history size [\\#2742](https://github.com/nlohmann/json/issues/2742)\n- How to get reference of std::vector\\<T\\> [\\#2735](https://github.com/nlohmann/json/issues/2735)\n- CMake failure in VS2019 Community [\\#2734](https://github.com/nlohmann/json/issues/2734)\n- Possibility to use with custom c++ version to use in intel sgx enclaves [\\#2730](https://github.com/nlohmann/json/issues/2730)\n- Possibility to use without the dependency to file io and streams to use in intel sgx enclaves [\\#2728](https://github.com/nlohmann/json/issues/2728)\n- error C2784& error C2839... in my visual studio 2015 compiler [\\#2726](https://github.com/nlohmann/json/issues/2726)\n- `-fno-expection` not respected anymore in 3.9.1 [\\#2725](https://github.com/nlohmann/json/issues/2725)\n- When exceptions disabled with JSON\\_NOEXCEPTION, lib just aborts without any message [\\#2724](https://github.com/nlohmann/json/issues/2724)\n- Critical error detected c0000374 on windows10 msvc 2019 16.8.5 [\\#2710](https://github.com/nlohmann/json/issues/2710)\n- unused parameter error/warning [\\#2706](https://github.com/nlohmann/json/issues/2706)\n- How to store data into a Map from json file [\\#2691](https://github.com/nlohmann/json/issues/2691)\n- Tests do not compile with pre-release glibc [\\#2686](https://github.com/nlohmann/json/issues/2686)\n- compile errors .... chromium-style [\\#2680](https://github.com/nlohmann/json/issues/2680)\n- .dump\\(\\) not allowing compact form [\\#2678](https://github.com/nlohmann/json/issues/2678)\n- error: no matching function for call to ‘nlohmann::basic\\_json\\<\\>::value\\(int, std::set\\<int\\>&\\)’ [\\#2671](https://github.com/nlohmann/json/issues/2671)\n- Compiler warning: unused parameter [\\#2668](https://github.com/nlohmann/json/issues/2668)\n- Deserializing to a struct as shown on the project homepage throws compile time errors [\\#2665](https://github.com/nlohmann/json/issues/2665)\n- Unable to compile on MSVC 2019 with SDL checking enabled: This function or variable may be unsafe [\\#2664](https://github.com/nlohmann/json/issues/2664)\n- terminating with uncaught exception of type nlohmann::detail::type\\_error: \\[json.exception.type\\_error.302\\] type must be array, but is object [\\#2661](https://github.com/nlohmann/json/issues/2661)\n- unused-parameter on OSX when Diagnostics is off [\\#2658](https://github.com/nlohmann/json/issues/2658)\n- std::pair wrong serialization [\\#2655](https://github.com/nlohmann/json/issues/2655)\n- The result of json is\\_number\\_integer\\(\\) function is wrong when read a json file  [\\#2653](https://github.com/nlohmann/json/issues/2653)\n- 2 backslash cause problem [\\#2652](https://github.com/nlohmann/json/issues/2652)\n- No support for using an external/system copy of Hedley [\\#2651](https://github.com/nlohmann/json/issues/2651)\n- error: incomplete type 'qfloat16' used in type trait expression [\\#2650](https://github.com/nlohmann/json/issues/2650)\n- Unused variable in exception class when not using improved diagnostics [\\#2646](https://github.com/nlohmann/json/issues/2646)\n- I am trying to do this - converting from wstring works incorrectly! [\\#2642](https://github.com/nlohmann/json/issues/2642)\n- Exception 207 On ARM Processor During Literal String Parsing [\\#2634](https://github.com/nlohmann/json/issues/2634)\n- double free or corruption \\(!prev\\) error on Json push\\_back and write [\\#2632](https://github.com/nlohmann/json/issues/2632)\n- nlohmann::detail::parse\\_error: syntax error while parsing CBOR string: expected length specification \\(0x60-0x7B\\) or indefinite string type \\(0x7F\\) [\\#2629](https://github.com/nlohmann/json/issues/2629)\n- please allow disabling implicit conversions in non-single-file use [\\#2621](https://github.com/nlohmann/json/issues/2621)\n- Preserve decimal formatting [\\#2618](https://github.com/nlohmann/json/issues/2618)\n- Visual Studio Visual Assist code issues reported by VA code inspection of file json.hpp [\\#2615](https://github.com/nlohmann/json/issues/2615)\n- Missing get function and no viable overloaded '=' on mac [\\#2610](https://github.com/nlohmann/json/issues/2610)\n- corruption when parse from string [\\#2603](https://github.com/nlohmann/json/issues/2603)\n- Parse from byte-vector results in compile error [\\#2602](https://github.com/nlohmann/json/issues/2602)\n- Memory leak when working on ARM Linux [\\#2601](https://github.com/nlohmann/json/issues/2601)\n- Unhandled exception in test-cbor.exe Stack overflow when debugging project with Visual Studio 2019 16.7.7 compiled with c++17 or c++latest [\\#2598](https://github.com/nlohmann/json/issues/2598)\n- Error in download\\_test\\_data.vcxproj when compiling with Visual Studio 2019 16.7.7 Professional msbuild on Windows 10 2004 Professional [\\#2594](https://github.com/nlohmann/json/issues/2594)\n- Warnings  C4715 and C4127 when building json-3.9.1 with Visual Studio 2019 16.7.7 [\\#2592](https://github.com/nlohmann/json/issues/2592)\n- I tried some change to dump\\(\\) for \\[1,2,3...\\] [\\#2584](https://github.com/nlohmann/json/issues/2584)\n- try/catch block does not catch parsing error [\\#2579](https://github.com/nlohmann/json/issues/2579)\n- Serializing uint64\\_t is broken for large values [\\#2578](https://github.com/nlohmann/json/issues/2578)\n- deserializing arrays should be part of the library [\\#2575](https://github.com/nlohmann/json/issues/2575)\n- Deserialization to std::array with non-default constructable types fails [\\#2574](https://github.com/nlohmann/json/issues/2574)\n- Compilation error when trying to use same type for number\\_integer\\_t and number\\_unsigned\\_t in basic\\_json template specification. [\\#2573](https://github.com/nlohmann/json/issues/2573)\n- compiler error: directive output may be truncated writing between 2 and 8 bytes [\\#2572](https://github.com/nlohmann/json/issues/2572)\n- Incorrect convert map to json when key cannot construct an string i.e. int  [\\#2564](https://github.com/nlohmann/json/issues/2564)\n- no matching function for call to ‘nlohmann::basic\\_json\\<\\>::basic\\_json\\(\\<brace-enclosed initializer list\\>\\)’ [\\#2559](https://github.com/nlohmann/json/issues/2559)\n- type\\_error factory creates a dangling pointer \\(in VisualStudio 2019\\) [\\#2535](https://github.com/nlohmann/json/issues/2535)\n- Cannot assign from ordered\\_json vector\\<CustomStruct\\> to value in not ordered json [\\#2528](https://github.com/nlohmann/json/issues/2528)\n- Qt6: Break changes [\\#2519](https://github.com/nlohmann/json/issues/2519)\n- valgrind memcheck Illegal instruction when use nlohmann::json::parse [\\#2518](https://github.com/nlohmann/json/issues/2518)\n- Buffer overflow [\\#2515](https://github.com/nlohmann/json/issues/2515)\n- Including CTest in the top-level CMakeLists.txt sets BUILD\\_TESTING=ON for parent projects [\\#2513](https://github.com/nlohmann/json/issues/2513)\n- Compilation error when using NLOHMANN\\_JSON\\_SERIALIZE\\_ENUM ordered\\_json on libc++ [\\#2491](https://github.com/nlohmann/json/issues/2491)\n- Missing \"void insert\\( InputIt first, InputIt last \\);\" overload in nlohmann::ordered\\_map [\\#2490](https://github.com/nlohmann/json/issues/2490)\n- Could not find a package configuration file provided by \"nlohmann\\_json\" [\\#2482](https://github.com/nlohmann/json/issues/2482)\n- json becomes empty for unknown reason [\\#2470](https://github.com/nlohmann/json/issues/2470)\n- Using std::wstring as StringType fails compiling [\\#2459](https://github.com/nlohmann/json/issues/2459)\n- Sample code in GIF slide outdated \\(cannot use emplace\\(\\) with array\\) [\\#2457](https://github.com/nlohmann/json/issues/2457)\n- from\\_json\\<std::wstring\\> is treated as an array on latest MSVC [\\#2453](https://github.com/nlohmann/json/issues/2453)\n- MemorySanitizer: use-of-uninitialized-value [\\#2449](https://github.com/nlohmann/json/issues/2449)\n- I need help [\\#2441](https://github.com/nlohmann/json/issues/2441)\n- type conversion failing with clang ext\\_vector\\_type  [\\#2436](https://github.com/nlohmann/json/issues/2436)\n- json::parse\\(\\) can't be resolved under specific circumstances [\\#2427](https://github.com/nlohmann/json/issues/2427)\n- from\\_\\*\\(ptr, len\\) deprecation [\\#2426](https://github.com/nlohmann/json/issues/2426)\n- Error ONLY in release mode [\\#2425](https://github.com/nlohmann/json/issues/2425)\n- \"Custom data source\" exemple make no sense [\\#2423](https://github.com/nlohmann/json/issues/2423)\n- Compile errors [\\#2421](https://github.com/nlohmann/json/issues/2421)\n- Refuses to compile in project [\\#2419](https://github.com/nlohmann/json/issues/2419)\n- Compilation failure of tests with C++20 standard \\(caused by change of u8 literals\\)  [\\#2413](https://github.com/nlohmann/json/issues/2413)\n- No matching function for call to 'input\\_adapter' under Xcode of with nlohmann version 3.9.1 [\\#2412](https://github.com/nlohmann/json/issues/2412)\n- Git tags are not valid semvers [\\#2409](https://github.com/nlohmann/json/issues/2409)\n- after dump, stderr output disappear [\\#2403](https://github.com/nlohmann/json/issues/2403)\n- Using custom string. [\\#2398](https://github.com/nlohmann/json/issues/2398)\n- value\\(\\) throws unhandled exception for partially specified json object [\\#2393](https://github.com/nlohmann/json/issues/2393)\n- assertion on runtime causes program to stop when accessing const json with missing key [\\#2392](https://github.com/nlohmann/json/issues/2392)\n- Usage with -fno-elide-constructors causes dump\\(\\) output to be array of `null`s [\\#2387](https://github.com/nlohmann/json/issues/2387)\n- Build fails with clang-cl due to override of CMAKE\\_CXX\\_COMPILER\\(?\\) [\\#2384](https://github.com/nlohmann/json/issues/2384)\n- std::optional not working with primitive types [\\#2383](https://github.com/nlohmann/json/issues/2383)\n- Unexpected array when initializing a json const& on gcc 4.8.5 using uniform syntax [\\#2370](https://github.com/nlohmann/json/issues/2370)\n- setprecision support [\\#2362](https://github.com/nlohmann/json/issues/2362)\n- json::parse\\(allow\\_exceptions = false\\) documentation is misleading. [\\#2360](https://github.com/nlohmann/json/issues/2360)\n- std::begin and std::end usage without specifying std namespace [\\#2359](https://github.com/nlohmann/json/issues/2359)\n- Custom object conversion to json hangs in background thread [\\#2358](https://github.com/nlohmann/json/issues/2358)\n- Add support of nullable fields to NLOHMANN\\_DEFINE\\_TYPE\\_NON\\_INTRUSIVE and NLOHMANN\\_DEFINE\\_TYPE\\_INTRUSIVE [\\#2356](https://github.com/nlohmann/json/issues/2356)\n- the portfile for the vcpkg is not working. [\\#2351](https://github.com/nlohmann/json/issues/2351)\n- Compiler warns of implicit fallthrough when defining preprocessor macro NDEBUG [\\#2348](https://github.com/nlohmann/json/issues/2348)\n- Compile error on Intel compiler running in Windows [\\#2346](https://github.com/nlohmann/json/issues/2346)\n- Build error caused by overwriting CMAKE\\_CXX\\_COMPILER [\\#2343](https://github.com/nlohmann/json/issues/2343)\n- Error: an attribute list cannot appear here     JSON\\_HEDLEY\\_DEPRECATED\\_FOR [\\#2342](https://github.com/nlohmann/json/issues/2342)\n- compiler warning [\\#2341](https://github.com/nlohmann/json/issues/2341)\n- 3.9.0: tests make build non-reproducible [\\#2324](https://github.com/nlohmann/json/issues/2324)\n- Initialization different between gcc/clang [\\#2311](https://github.com/nlohmann/json/issues/2311)\n- Attempt to `get()` a numeric value as a type which cannot represent it should throw [\\#2310](https://github.com/nlohmann/json/issues/2310)\n- Surprising behaviour with overloaded operators [\\#2256](https://github.com/nlohmann/json/issues/2256)\n- ADL issue in input\\_adapter [\\#2248](https://github.com/nlohmann/json/issues/2248)\n- Output adapters should be templated. [\\#2172](https://github.com/nlohmann/json/issues/2172)\n- error when using nlohmann::json, std::function and std::bind [\\#2147](https://github.com/nlohmann/json/issues/2147)\n- Remove undefined behavior for const operator\\[\\] [\\#2111](https://github.com/nlohmann/json/issues/2111)\n- json\\({}\\) gives null instead of empty object with GCC and -std=c++17 [\\#2046](https://github.com/nlohmann/json/issues/2046)\n- GDB pretty printing support [\\#1952](https://github.com/nlohmann/json/issues/1952)\n- Always compile tests with all warnings enabled and error out on warnings [\\#1798](https://github.com/nlohmann/json/issues/1798)\n- Fixes Cppcheck warnings [\\#1759](https://github.com/nlohmann/json/issues/1759)\n- How to get position info or parser context with custom from\\_json\\(\\) that may throw exceptions? [\\#1508](https://github.com/nlohmann/json/issues/1508)\n- Suggestion to improve value\\(\\) accessors with respect to move semantics [\\#1275](https://github.com/nlohmann/json/issues/1275)\n- Add Key name to Exception [\\#932](https://github.com/nlohmann/json/issues/932)\n\n- Overwork warning flags [\\#2936](https://github.com/nlohmann/json/pull/2936) ([nlohmann](https://github.com/nlohmann))\n- Treat MSVC warnings as errors [\\#2930](https://github.com/nlohmann/json/pull/2930) ([nlohmann](https://github.com/nlohmann))\n- All: fix warnings when compiling with -Wswitch-enum [\\#2927](https://github.com/nlohmann/json/pull/2927) ([fhuberts](https://github.com/fhuberts))\n- Guard GCC pragmas [\\#2925](https://github.com/nlohmann/json/pull/2925) ([nlohmann](https://github.com/nlohmann))\n- Supress -Wfloat-equal on intended float comparisions [\\#2911](https://github.com/nlohmann/json/pull/2911) ([Finkman](https://github.com/Finkman))\n- Fix binary subtypes [\\#2908](https://github.com/nlohmann/json/pull/2908) ([nlohmann](https://github.com/nlohmann))\n- Fix useless-cast warnings [\\#2902](https://github.com/nlohmann/json/pull/2902) ([nlohmann](https://github.com/nlohmann))\n- Add regression test [\\#2898](https://github.com/nlohmann/json/pull/2898) ([nlohmann](https://github.com/nlohmann))\n- Refactor Unicode tests [\\#2889](https://github.com/nlohmann/json/pull/2889) ([nlohmann](https://github.com/nlohmann))\n- CMake cleanup [\\#2885](https://github.com/nlohmann/json/pull/2885) ([nlohmann](https://github.com/nlohmann))\n- Avoid string in case of empty CBOR objects [\\#2879](https://github.com/nlohmann/json/pull/2879) ([nlohmann](https://github.com/nlohmann))\n- Suppress C4127 warning in unit-json\\_pointer.cpp [\\#2875](https://github.com/nlohmann/json/pull/2875) ([nlohmann](https://github.com/nlohmann))\n- Fix truncation warning [\\#2874](https://github.com/nlohmann/json/pull/2874) ([nlohmann](https://github.com/nlohmann))\n- Fix memory leak in to\\_json [\\#2872](https://github.com/nlohmann/json/pull/2872) ([nlohmann](https://github.com/nlohmann))\n- Fix assertion failure in diagnostics [\\#2866](https://github.com/nlohmann/json/pull/2866) ([nlohmann](https://github.com/nlohmann))\n- Update documentation [\\#2861](https://github.com/nlohmann/json/pull/2861) ([nlohmann](https://github.com/nlohmann))\n- Consistency with `using` in README.md [\\#2826](https://github.com/nlohmann/json/pull/2826) ([justanotheranonymoususer](https://github.com/justanotheranonymoususer))\n- Properly constrain the basic\\_json conversion operator [\\#2825](https://github.com/nlohmann/json/pull/2825) ([ldionne](https://github.com/ldionne))\n- Fix CI [\\#2817](https://github.com/nlohmann/json/pull/2817) ([nlohmann](https://github.com/nlohmann))\n- Specified git branch for google benchmark fetch in benchmark test [\\#2795](https://github.com/nlohmann/json/pull/2795) ([grafail](https://github.com/grafail))\n- Add C++ standards to macOS matrix [\\#2790](https://github.com/nlohmann/json/pull/2790) ([nlohmann](https://github.com/nlohmann))\n- Update URLs to HTTPS [\\#2789](https://github.com/nlohmann/json/pull/2789) ([TotalCaesar659](https://github.com/TotalCaesar659))\n- Link to Conan Center package added [\\#2771](https://github.com/nlohmann/json/pull/2771) ([offa](https://github.com/offa))\n- Keep consistent formatting [\\#2770](https://github.com/nlohmann/json/pull/2770) ([jasmcaus](https://github.com/jasmcaus))\n- Add a cmake option to use SYSTEM in target\\_include\\_directories [\\#2762](https://github.com/nlohmann/json/pull/2762) ([jpl-mac](https://github.com/jpl-mac))\n- replace EOF with std::char\\_traits\\<char\\>::eof\\(\\) [\\#2756](https://github.com/nlohmann/json/pull/2756) ([nlohmann](https://github.com/nlohmann))\n- Fix typo in README [\\#2754](https://github.com/nlohmann/json/pull/2754) ([mortenfyhn](https://github.com/mortenfyhn))\n- Update documentation [\\#2749](https://github.com/nlohmann/json/pull/2749) ([nlohmann](https://github.com/nlohmann))\n- Add documentation for numbers [\\#2747](https://github.com/nlohmann/json/pull/2747) ([nlohmann](https://github.com/nlohmann))\n- Use Clang 12 in CI [\\#2737](https://github.com/nlohmann/json/pull/2737) ([nlohmann](https://github.com/nlohmann))\n- Fixes \\#2730 [\\#2731](https://github.com/nlohmann/json/pull/2731) ([theShmoo](https://github.com/theShmoo))\n- Possibility to use without the dependency to file io and streams to use in intel sgx enclaves [\\#2729](https://github.com/nlohmann/json/pull/2729) ([theShmoo](https://github.com/theShmoo))\n- Update json.hpp [\\#2707](https://github.com/nlohmann/json/pull/2707) ([raduteo](https://github.com/raduteo))\n- pkg-config.pc.in: Don't concatenate paths [\\#2690](https://github.com/nlohmann/json/pull/2690) ([doronbehar](https://github.com/doronbehar))\n- add more CI steps [\\#2689](https://github.com/nlohmann/json/pull/2689) ([nlohmann](https://github.com/nlohmann))\n- Update doctest from 2.4.4 to 2.4.6 \\(fixes \\#2686\\) [\\#2687](https://github.com/nlohmann/json/pull/2687) ([musicinmybrain](https://github.com/musicinmybrain))\n- License fix [\\#2683](https://github.com/nlohmann/json/pull/2683) ([nlohmann](https://github.com/nlohmann))\n- Update parse\\_exceptions.md - correct `json::exception::parse_error` [\\#2679](https://github.com/nlohmann/json/pull/2679) ([frasermarlow](https://github.com/frasermarlow))\n- Remove HEDLEY annotation from exception::what\\(\\) [\\#2673](https://github.com/nlohmann/json/pull/2673) ([remyjette](https://github.com/remyjette))\n- Fix amount of entries in the json object [\\#2659](https://github.com/nlohmann/json/pull/2659) ([abbaswasim](https://github.com/abbaswasim))\n- Fix missing 1.78 in example in README.md [\\#2625](https://github.com/nlohmann/json/pull/2625) ([wawiesel](https://github.com/wawiesel))\n- Add GDB pretty printer [\\#2607](https://github.com/nlohmann/json/pull/2607) ([nlohmann](https://github.com/nlohmann))\n- readme: fix tilde character display [\\#2582](https://github.com/nlohmann/json/pull/2582) ([bl-ue](https://github.com/bl-ue))\n- Add support for deserialization of STL containers of non-default constructable types \\(fixes \\#2574\\). [\\#2576](https://github.com/nlohmann/json/pull/2576) ([AnthonyVH](https://github.com/AnthonyVH))\n- Better diagnostics [\\#2562](https://github.com/nlohmann/json/pull/2562) ([nlohmann](https://github.com/nlohmann))\n- CI targets [\\#2561](https://github.com/nlohmann/json/pull/2561) ([nlohmann](https://github.com/nlohmann))\n- Add switch to skip non-reproducible tests. [\\#2560](https://github.com/nlohmann/json/pull/2560) ([nlohmann](https://github.com/nlohmann))\n- Fix compilation of input\\_adapter\\(container\\) in edge cases [\\#2553](https://github.com/nlohmann/json/pull/2553) ([jasujm](https://github.com/jasujm))\n- Allow parsing from std::byte containers [\\#2550](https://github.com/nlohmann/json/pull/2550) ([nlohmann](https://github.com/nlohmann))\n- Travis doesn't run any tests in C++17 mode [\\#2540](https://github.com/nlohmann/json/pull/2540) ([karzhenkov](https://github.com/karzhenkov))\n- Doctest is updated to v2.4.3 [\\#2538](https://github.com/nlohmann/json/pull/2538) ([YarikTH](https://github.com/YarikTH))\n- Fix warnings [\\#2537](https://github.com/nlohmann/json/pull/2537) ([nlohmann](https://github.com/nlohmann))\n- Fix a shadowing warning [\\#2536](https://github.com/nlohmann/json/pull/2536) ([nlohmann](https://github.com/nlohmann))\n- Clarify license of is\\_complete\\_type implementation [\\#2534](https://github.com/nlohmann/json/pull/2534) ([nlohmann](https://github.com/nlohmann))\n- Do not unconditionally redefine C++14 constructs [\\#2533](https://github.com/nlohmann/json/pull/2533) ([nlohmann](https://github.com/nlohmann))\n- Doctest is updated to v2.4.1 [\\#2525](https://github.com/nlohmann/json/pull/2525) ([YarikTH](https://github.com/YarikTH))\n- Add MAIN\\_PROJECT check for test and install options [\\#2514](https://github.com/nlohmann/json/pull/2514) ([globberwops](https://github.com/globberwops))\n- Ranged insert test section is added in unit-ordered\\_json.cpp [\\#2512](https://github.com/nlohmann/json/pull/2512) ([YarikTH](https://github.com/YarikTH))\n- Add asserts to suppress C28020 [\\#2447](https://github.com/nlohmann/json/pull/2447) ([jbzdarkid](https://github.com/jbzdarkid))\n- Change argument name \"subtype\" in byte\\_container\\_with\\_subtype [\\#2444](https://github.com/nlohmann/json/pull/2444) ([linev](https://github.com/linev))\n- 📝  add CPM.Cmake example [\\#2406](https://github.com/nlohmann/json/pull/2406) ([leozz37](https://github.com/leozz37))\n- Fix move constructor of json\\_ref [\\#2405](https://github.com/nlohmann/json/pull/2405) ([karzhenkov](https://github.com/karzhenkov))\n- Properly select \"Release\" build for Travis [\\#2375](https://github.com/nlohmann/json/pull/2375) ([karzhenkov](https://github.com/karzhenkov))\n- Update Hedley [\\#2367](https://github.com/nlohmann/json/pull/2367) ([nlohmann](https://github.com/nlohmann))\n- Fix and extend documentation of discarded values [\\#2363](https://github.com/nlohmann/json/pull/2363) ([nlohmann](https://github.com/nlohmann))\n- Fix typos in documentation [\\#2354](https://github.com/nlohmann/json/pull/2354) ([rbuch](https://github.com/rbuch))\n- Remove \"\\#define private public\" from tests [\\#2352](https://github.com/nlohmann/json/pull/2352) ([nlohmann](https://github.com/nlohmann))\n- Remove -Wimplicit-fallthrough warning [\\#2349](https://github.com/nlohmann/json/pull/2349) ([nlohmann](https://github.com/nlohmann))\n- Fix code to work without exceptions [\\#2347](https://github.com/nlohmann/json/pull/2347) ([nlohmann](https://github.com/nlohmann))\n- fix cmake script overwriting compiler path [\\#2344](https://github.com/nlohmann/json/pull/2344) ([ongjunjie](https://github.com/ongjunjie))\n\n## [v3.9.1](https://github.com/nlohmann/json/releases/tag/v3.9.1) (2020-08-06)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.9.0...v3.9.1)\n\n- Can't parse not formatted JSON. [\\#2340](https://github.com/nlohmann/json/issues/2340)\n- parse returns desired array contained in array when JSON text begins with square bracket on gcc 7.5.0 [\\#2339](https://github.com/nlohmann/json/issues/2339)\n- Unexpected deserialization difference between Mac and Linux [\\#2338](https://github.com/nlohmann/json/issues/2338)\n- Reading ordered\\_json from file causes compile error [\\#2331](https://github.com/nlohmann/json/issues/2331)\n- ignore\\_comment=true fails on multiple consecutive lines starting with comments [\\#2330](https://github.com/nlohmann/json/issues/2330)\n- Update documentation about Homebrew installation and CMake integration - Homebrew [\\#2326](https://github.com/nlohmann/json/issues/2326)\n- Chinese character initialize error [\\#2325](https://github.com/nlohmann/json/issues/2325)\n- json.update and vector\\<pair\\>does not work with ordered\\_json [\\#2315](https://github.com/nlohmann/json/issues/2315)\n- Ambiguous call to overloaded function [\\#2210](https://github.com/nlohmann/json/issues/2210)\n\n- Fix fallthrough warning [\\#2333](https://github.com/nlohmann/json/pull/2333) ([nlohmann](https://github.com/nlohmann))\n- Fix lexer to properly cope with repeated comments [\\#2332](https://github.com/nlohmann/json/pull/2332) ([nlohmann](https://github.com/nlohmann))\n- Fix name of Homebrew formula in documentation [\\#2327](https://github.com/nlohmann/json/pull/2327) ([nlohmann](https://github.com/nlohmann))\n- fix typo [\\#2320](https://github.com/nlohmann/json/pull/2320) ([wx257osn2](https://github.com/wx257osn2))\n- Fix a bug due to missing overloads in ordered\\_map container [\\#2319](https://github.com/nlohmann/json/pull/2319) ([nlohmann](https://github.com/nlohmann))\n- cmake: install pkg-config file relative to current\\_binary\\_dir [\\#2318](https://github.com/nlohmann/json/pull/2318) ([eli-schwartz](https://github.com/eli-schwartz))\n- Fixed installation of pkg-config file on other than Ubuntu [\\#2314](https://github.com/nlohmann/json/pull/2314) ([xvitaly](https://github.com/xvitaly))\n\n## [v3.9.0](https://github.com/nlohmann/json/releases/tag/v3.9.0) (2020-07-27)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.8.0...v3.9.0)\n\n- Unknown Type Name clang error when using NLOHMANN\\_DEFINE\\_TYPE\\_NON\\_INTRUSIVE [\\#2313](https://github.com/nlohmann/json/issues/2313)\n- Clang 10.0 / GCC 10.1 warnings on disabled exceptions [\\#2304](https://github.com/nlohmann/json/issues/2304)\n- Application stalls indefinitely with message byte size 10 [\\#2293](https://github.com/nlohmann/json/issues/2293)\n- linker error [\\#2292](https://github.com/nlohmann/json/issues/2292)\n- Add support for high-precision numbers in UBJSON encoding [\\#2286](https://github.com/nlohmann/json/issues/2286)\n- NLOHMANN\\_DEFINE\\_TYPE\\_NON\\_INTRUSIVE fails if the length of the argument is 10 [\\#2280](https://github.com/nlohmann/json/issues/2280)\n- Custom types : MACRO expansion bug [\\#2267](https://github.com/nlohmann/json/issues/2267)\n- to/from\\_json Failing To Convert String [\\#2238](https://github.com/nlohmann/json/issues/2238)\n- clang 9.0 report warning: unused type alias 'size\\_type' \\[-Wunused-local-typedef\\] [\\#2221](https://github.com/nlohmann/json/issues/2221)\n- Enormous array created when working with map\\<int,T\\> [\\#2220](https://github.com/nlohmann/json/issues/2220)\n- Can I disable sorting of json values [\\#2219](https://github.com/nlohmann/json/issues/2219)\n- Getting Qt types to work [\\#2217](https://github.com/nlohmann/json/issues/2217)\n- Convert to Qt QVariant  [\\#2216](https://github.com/nlohmann/json/issues/2216)\n- How to custom serialize same data type of vector? [\\#2215](https://github.com/nlohmann/json/issues/2215)\n- json constructor does not support std::optional [\\#2214](https://github.com/nlohmann/json/issues/2214)\n- Failing to Parse Valid JSON [\\#2209](https://github.com/nlohmann/json/issues/2209)\n- \\(De-\\)Serialization of std::variant with namespaces [\\#2208](https://github.com/nlohmann/json/issues/2208)\n- Addint support for complex type [\\#2207](https://github.com/nlohmann/json/issues/2207)\n- array\\_index possible out of range [\\#2205](https://github.com/nlohmann/json/issues/2205)\n- Object deserialized as array [\\#2204](https://github.com/nlohmann/json/issues/2204)\n- Sending to a function a reference to a sub-branch [\\#2200](https://github.com/nlohmann/json/issues/2200)\n- How to Serialize derived class to JSON object?  [\\#2199](https://github.com/nlohmann/json/issues/2199)\n- JSON incorrectly serialized [\\#2198](https://github.com/nlohmann/json/issues/2198)\n- Exception Unhandled out\\_of\\_range error [\\#2197](https://github.com/nlohmann/json/issues/2197)\n- msgpack serialisation : float is treated as 64bit float, not 32bit float. [\\#2196](https://github.com/nlohmann/json/issues/2196)\n- Is it possible to use compile-time type guarantees for JSON structures? [\\#2195](https://github.com/nlohmann/json/issues/2195)\n- Question : performance against python dict [\\#2194](https://github.com/nlohmann/json/issues/2194)\n- vs2017 compile error [\\#2192](https://github.com/nlohmann/json/issues/2192)\n- Check if a key exists [\\#2191](https://github.com/nlohmann/json/issues/2191)\n- Failed to run tests due to missing test data on builders without Internet access [\\#2190](https://github.com/nlohmann/json/issues/2190)\n- 3.8.0: unit-cbor.cpp test failures [\\#2189](https://github.com/nlohmann/json/issues/2189)\n- 'nlohmann/json.hpp' file not found [\\#2188](https://github.com/nlohmann/json/issues/2188)\n- How to send json data over the wire? [\\#2185](https://github.com/nlohmann/json/issues/2185)\n- Ubuntu 16 not supporting nlohmann/json? [\\#2184](https://github.com/nlohmann/json/issues/2184)\n- .get\\<std::string\\> causing emdash errors [\\#2180](https://github.com/nlohmann/json/issues/2180)\n- Object properties should not be re-sorted alphabetically [\\#2179](https://github.com/nlohmann/json/issues/2179)\n- Custom type registration : instrusive API [\\#2175](https://github.com/nlohmann/json/issues/2175)\n- Many version of the function \"void to\\_json\\(json& j, const MyStruct& struct\\)\" [\\#2171](https://github.com/nlohmann/json/issues/2171)\n- How should strings be escaped? [\\#2155](https://github.com/nlohmann/json/issues/2155)\n- Adding a value to an existing json puts it at the beginning instead of the end [\\#2149](https://github.com/nlohmann/json/issues/2149)\n- The header file is big, can we use what we need. [\\#2134](https://github.com/nlohmann/json/issues/2134)\n- Changing the default format for unordered\\_map \\(or other set\\) [\\#2132](https://github.com/nlohmann/json/issues/2132)\n- Getting size of deserialized bson document [\\#2131](https://github.com/nlohmann/json/issues/2131)\n- implicit conversion failure [\\#2128](https://github.com/nlohmann/json/issues/2128)\n- Error thrown when parsing in a subclass [\\#2124](https://github.com/nlohmann/json/issues/2124)\n- explicit conversion to string not considered for std::map keys in GCC8 [\\#2096](https://github.com/nlohmann/json/issues/2096)\n- Add support for JSONC [\\#2061](https://github.com/nlohmann/json/issues/2061)\n- Library provides template arg for string\\_type but assumes std::string in some places [\\#2059](https://github.com/nlohmann/json/issues/2059)\n- incremental parsing with sax\\_parser [\\#2030](https://github.com/nlohmann/json/issues/2030)\n- Question about flatten and unflatten [\\#1989](https://github.com/nlohmann/json/issues/1989)\n- CBOR parser doesn't skip tags [\\#1968](https://github.com/nlohmann/json/issues/1968)\n- Compilation failure using Clang on Windows [\\#1898](https://github.com/nlohmann/json/issues/1898)\n- Fail to build when including json.hpp as a system include [\\#1818](https://github.com/nlohmann/json/issues/1818)\n- Parsing string into json doesn't preserve the order correctly. [\\#1817](https://github.com/nlohmann/json/issues/1817)\n- \\[C++17\\] Allow std::optional to convert to nlohmann::json [\\#1749](https://github.com/nlohmann/json/issues/1749)\n- How can I save json object in file in order?  [\\#1717](https://github.com/nlohmann/json/issues/1717)\n- Support for Comments [\\#1513](https://github.com/nlohmann/json/issues/1513)\n- clang compiler: error : unknown type name 'not' [\\#1119](https://github.com/nlohmann/json/issues/1119)\n- dump\\(\\) without alphabetical order [\\#1106](https://github.com/nlohmann/json/issues/1106)\n- operator T\\(\\) considered harmful [\\#958](https://github.com/nlohmann/json/issues/958)\n- Order of the elements in JSON object [\\#952](https://github.com/nlohmann/json/issues/952)\n- How to prevent alphabetical sorting of data? [\\#727](https://github.com/nlohmann/json/issues/727)\n- Why is an object ordering values by Alphabetical Order?  [\\#660](https://github.com/nlohmann/json/issues/660)\n- Feature request: Comments [\\#597](https://github.com/nlohmann/json/issues/597)\n- Head Elements Sorting [\\#543](https://github.com/nlohmann/json/issues/543)\n- Automatic ordered JSON [\\#424](https://github.com/nlohmann/json/issues/424)\n- Support for comments. [\\#376](https://github.com/nlohmann/json/issues/376)\n- Optional comment support. [\\#363](https://github.com/nlohmann/json/issues/363)\n- Strip comments / Minify [\\#294](https://github.com/nlohmann/json/issues/294)\n- maintaining order of keys during iteration [\\#106](https://github.com/nlohmann/json/issues/106)\n\n- Update documentation [\\#2312](https://github.com/nlohmann/json/pull/2312) ([nlohmann](https://github.com/nlohmann))\n- Fix bug in CBOR tag handling [\\#2308](https://github.com/nlohmann/json/pull/2308) ([nlohmann](https://github.com/nlohmann))\n- added inline to NLOHMANN\\_DEFINE\\_TYPE\\_NON\\_INTRUSIVE macro [\\#2306](https://github.com/nlohmann/json/pull/2306) ([jwittbrodt](https://github.com/jwittbrodt))\n- fixes unused variable 'ex' for \\#2304 [\\#2305](https://github.com/nlohmann/json/pull/2305) ([AODQ](https://github.com/AODQ))\n- Cleanup [\\#2303](https://github.com/nlohmann/json/pull/2303) ([nlohmann](https://github.com/nlohmann))\n- Add test with multiple translation units [\\#2301](https://github.com/nlohmann/json/pull/2301) ([nlohmann](https://github.com/nlohmann))\n- Merge GitHub actions [\\#2300](https://github.com/nlohmann/json/pull/2300) ([nlohmann](https://github.com/nlohmann))\n- Fix unused parameter [\\#2299](https://github.com/nlohmann/json/pull/2299) ([nlohmann](https://github.com/nlohmann))\n- Add support for high-precision numbers in UBJSON encoding [\\#2297](https://github.com/nlohmann/json/pull/2297) ([nlohmann](https://github.com/nlohmann))\n- fix eof for get\\_binary and get\\_string [\\#2294](https://github.com/nlohmann/json/pull/2294) ([jprochazk](https://github.com/jprochazk))\n- Serialisation macros: increase upper bound on number of member variables [\\#2287](https://github.com/nlohmann/json/pull/2287) ([pfeatherstone](https://github.com/pfeatherstone))\n- add inline specifier for detail::combine [\\#2285](https://github.com/nlohmann/json/pull/2285) ([T0b1-iOS](https://github.com/T0b1-iOS))\n- Add static assertion for missing binary function in SAX interface [\\#2282](https://github.com/nlohmann/json/pull/2282) ([nlohmann](https://github.com/nlohmann))\n- Add test for target\\_include\\_directories [\\#2279](https://github.com/nlohmann/json/pull/2279) ([nlohmann](https://github.com/nlohmann))\n- Clean up maintainer Makefiles and fix some linter warnings [\\#2274](https://github.com/nlohmann/json/pull/2274) ([nlohmann](https://github.com/nlohmann))\n- Add option to ignore CBOR tags [\\#2273](https://github.com/nlohmann/json/pull/2273) ([nlohmann](https://github.com/nlohmann))\n- Hash function without allocation [\\#2269](https://github.com/nlohmann/json/pull/2269) ([nlohmann](https://github.com/nlohmann))\n- Add ClangCL for MSVC [\\#2268](https://github.com/nlohmann/json/pull/2268) ([t-b](https://github.com/t-b))\n- Makefile: Always use SED variable [\\#2264](https://github.com/nlohmann/json/pull/2264) ([t-b](https://github.com/t-b))\n- Add Xcode 12 CI [\\#2262](https://github.com/nlohmann/json/pull/2262) ([nlohmann](https://github.com/nlohmann))\n- Make library work with Clang on Windows [\\#2259](https://github.com/nlohmann/json/pull/2259) ([nlohmann](https://github.com/nlohmann))\n- Add ordered\\_json specialization with ordered object keys [\\#2258](https://github.com/nlohmann/json/pull/2258) ([nlohmann](https://github.com/nlohmann))\n- Add pkg-config file [\\#2253](https://github.com/nlohmann/json/pull/2253) ([ericonr](https://github.com/ericonr))\n- Fix regression from \\#2181 [\\#2251](https://github.com/nlohmann/json/pull/2251) ([nlohmann](https://github.com/nlohmann))\n- Tag binary values in cbor if set [\\#2244](https://github.com/nlohmann/json/pull/2244) ([matthewbauer](https://github.com/matthewbauer))\n- Make assert configurable via JSON\\_ASSERT [\\#2242](https://github.com/nlohmann/json/pull/2242) ([nlohmann](https://github.com/nlohmann))\n- Add specialization of get\\_to [\\#2233](https://github.com/nlohmann/json/pull/2233) ([nlohmann](https://github.com/nlohmann))\n- Refine documentation of error\\_handler parameter [\\#2232](https://github.com/nlohmann/json/pull/2232) ([nlohmann](https://github.com/nlohmann))\n- Simplify conversion from/to custom types [\\#2225](https://github.com/nlohmann/json/pull/2225) ([nlohmann](https://github.com/nlohmann))\n- Remove unused typedefs [\\#2224](https://github.com/nlohmann/json/pull/2224) ([nlohmann](https://github.com/nlohmann))\n- Enable CMake policy CMP0077 [\\#2222](https://github.com/nlohmann/json/pull/2222) ([alexreinking](https://github.com/alexreinking))\n- Add option to ignore comments in parse/accept functions [\\#2212](https://github.com/nlohmann/json/pull/2212) ([nlohmann](https://github.com/nlohmann))\n- Fix Clang-Tidy warnings [\\#2211](https://github.com/nlohmann/json/pull/2211) ([nlohmann](https://github.com/nlohmann))\n- Simple ordered\\_json that works on all supported compilers [\\#2206](https://github.com/nlohmann/json/pull/2206) ([gatopeich](https://github.com/gatopeich))\n- Use unsigned indizies for array index in json pointer [\\#2203](https://github.com/nlohmann/json/pull/2203) ([t-b](https://github.com/t-b))\n- Add option to not rely on Internet connectivity during test stage [\\#2202](https://github.com/nlohmann/json/pull/2202) ([nlohmann](https://github.com/nlohmann))\n- Serialize floating-point numbers with 32 bit when possible \\(MessagePack\\) [\\#2201](https://github.com/nlohmann/json/pull/2201) ([nlohmann](https://github.com/nlohmann))\n- Fix consistency in function `int_to_string()` [\\#2193](https://github.com/nlohmann/json/pull/2193) ([dota17](https://github.com/dota17))\n- Fix issue\\#1275 [\\#2181](https://github.com/nlohmann/json/pull/2181) ([dota17](https://github.com/dota17))\n- C++20 support by removing swap specialization [\\#2176](https://github.com/nlohmann/json/pull/2176) ([gracicot](https://github.com/gracicot))\n- Feat/explicit conversion operator [\\#1559](https://github.com/nlohmann/json/pull/1559) ([theodelrieu](https://github.com/theodelrieu))\n\n## [v3.8.0](https://github.com/nlohmann/json/releases/tag/v3.8.0) (2020-06-14)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.3...v3.8.0)\n\n- sorry delete this issue, i'm stupid [\\#2187](https://github.com/nlohmann/json/issues/2187)\n- Append to a std::nlohmann::json type [\\#2186](https://github.com/nlohmann/json/issues/2186)\n- Some troubles to compile the last revision [\\#2177](https://github.com/nlohmann/json/issues/2177)\n- ​\\#​ Top level CMakeLists.txt​\n​project​\\(FOO\\)\n...\n​option​\\(FOO\\_USE\\_EXTERNAL\\_JSON ​\"Use an external JSON library\"​ ​OFF​\\)\n...\n​add\\_subdirectory​\\(thirdparty\\)\n...\n​add\\_library​\\(foo ...\\)\n...\n​\\#​ Note that the namespaced target will always be available regardless of the​\n​\\#​ import method​\n​target\\_link\\_libraries​\\(foo ​PRIVATE​ nlohmann\\_json::nlohmann\\_json\\) [\\#2170](https://github.com/nlohmann/json/issues/2170)\n- https://www.github.com/nlohmann/json/tree/develop/include%2Fnlohmann%2Fjson\\_fwd.hpp [\\#2169](https://github.com/nlohmann/json/issues/2169)\n- templated from\\_json of non primitive types causes gcc error [\\#2168](https://github.com/nlohmann/json/issues/2168)\n- few warnings/errors in copy assignment [\\#2167](https://github.com/nlohmann/json/issues/2167)\n- Different output when upgrading from clang 9 to clang 10 [\\#2166](https://github.com/nlohmann/json/issues/2166)\n- Cannot build with VS 2019 / C++17 [\\#2163](https://github.com/nlohmann/json/issues/2163)\n- Q: When I received an illegal string,How the program knows? [\\#2162](https://github.com/nlohmann/json/issues/2162)\n- Problem while reading a json file [\\#2161](https://github.com/nlohmann/json/issues/2161)\n- converting std::chrono::system\\_clock::time\\_point to json. [\\#2159](https://github.com/nlohmann/json/issues/2159)\n-  how to parse vector\\<struct\\> format [\\#2157](https://github.com/nlohmann/json/issues/2157)\n- nlohmann::json and =nullptr [\\#2156](https://github.com/nlohmann/json/issues/2156)\n- test-cbor fails [\\#2154](https://github.com/nlohmann/json/issues/2154)\n- Accessing array inside array syntax?  [\\#2151](https://github.com/nlohmann/json/issues/2151)\n- Best way to catch errors when querying json [\\#2150](https://github.com/nlohmann/json/issues/2150)\n- JSON Data Mapping Key-Value from other Key-Value [\\#2148](https://github.com/nlohmann/json/issues/2148)\n- Conflicts with std \\<any\\> compiling with GCC 10 [\\#2146](https://github.com/nlohmann/json/issues/2146)\n- Incorrect CMake FetchContent example [\\#2142](https://github.com/nlohmann/json/issues/2142)\n- Help for a Beginner? [\\#2141](https://github.com/nlohmann/json/issues/2141)\n- Read Json from File [\\#2139](https://github.com/nlohmann/json/issues/2139)\n- How to feed a predefined integer value into json string [\\#2138](https://github.com/nlohmann/json/issues/2138)\n- getting json array inside json object [\\#2135](https://github.com/nlohmann/json/issues/2135)\n- Add .contains example to doc [\\#2133](https://github.com/nlohmann/json/issues/2133)\n- Is it safe to return string.c\\_str\\(\\) received from get\\(\\)? [\\#2130](https://github.com/nlohmann/json/issues/2130)\n- GCC 10: Compilation error when including any before including json header in C++17 mode [\\#2129](https://github.com/nlohmann/json/issues/2129)\n- Intersection of two json files [\\#2127](https://github.com/nlohmann/json/issues/2127)\n- App crashes when dump method called for non ascii chars. [\\#2126](https://github.com/nlohmann/json/issues/2126)\n- iterator based erase method [\\#2122](https://github.com/nlohmann/json/issues/2122)\n- quick and convenient api to get/set nested json values [\\#2120](https://github.com/nlohmann/json/issues/2120)\n- assigning nullptr to std::string [\\#2118](https://github.com/nlohmann/json/issues/2118)\n- usless\\_cast warnings with gcc 9.3 and 10.1 \\(C++17\\) [\\#2114](https://github.com/nlohmann/json/issues/2114)\n- clang 10 warning [\\#2113](https://github.com/nlohmann/json/issues/2113)\n- Possible incorrect \\_MSC\\_VER reference [\\#2112](https://github.com/nlohmann/json/issues/2112)\n- warning under gcc 10.1 [\\#2110](https://github.com/nlohmann/json/issues/2110)\n- Wdeprecated-declarations from GCC v10.1.0 [\\#2109](https://github.com/nlohmann/json/issues/2109)\n- Global std::vector from json [\\#2108](https://github.com/nlohmann/json/issues/2108)\n- heap-buffer-overflow when using nlohmann/json, ASAN, and gtest [\\#2107](https://github.com/nlohmann/json/issues/2107)\n- exception 0x770DC5AF when i read an special char in json file [\\#2106](https://github.com/nlohmann/json/issues/2106)\n- json::parse\\(\\) fails to parse a dump\\(2,' '\\) output, yet does successfully parse dump\\(\\) [\\#2105](https://github.com/nlohmann/json/issues/2105)\n- run test-udt error  in MSVC 19.16.27034.0 [\\#2103](https://github.com/nlohmann/json/issues/2103)\n- Unable to dump to stringstream [\\#2102](https://github.com/nlohmann/json/issues/2102)\n- Can't ad an object in another objet [\\#2101](https://github.com/nlohmann/json/issues/2101)\n- Implicit conversion causes \"cannot use operator\\[\\] with a string argument with string\" [\\#2098](https://github.com/nlohmann/json/issues/2098)\n- C++20: char8\\_t [\\#2097](https://github.com/nlohmann/json/issues/2097)\n- Compilation issues when included in project [\\#2094](https://github.com/nlohmann/json/issues/2094)\n- string value with null character causes infinite loop [\\#2093](https://github.com/nlohmann/json/issues/2093)\n- corrupted size vs. prev\\_size \\(aborted\\) [\\#2092](https://github.com/nlohmann/json/issues/2092)\n- Get string field content without return std::string copy  [\\#2091](https://github.com/nlohmann/json/issues/2091)\n- JSON Comments \\(JSON 5\\) [\\#2090](https://github.com/nlohmann/json/issues/2090)\n- Remove \\#include \\<ciso646\\> [\\#2089](https://github.com/nlohmann/json/issues/2089)\n- JSON library as a git submodule [\\#2088](https://github.com/nlohmann/json/issues/2088)\n- Apple Clang 11.0.3 on MacOS Catalina 10.15.4 not compiling [\\#2087](https://github.com/nlohmann/json/issues/2087)\n- Value function return empty object even if it exist [\\#2086](https://github.com/nlohmann/json/issues/2086)\n- Cannot debug but Run works [\\#2085](https://github.com/nlohmann/json/issues/2085)\n- Question about serialization. [\\#2084](https://github.com/nlohmann/json/issues/2084)\n- How to include in an external project [\\#2083](https://github.com/nlohmann/json/issues/2083)\n- Missing tests for binary values [\\#2082](https://github.com/nlohmann/json/issues/2082)\n- How to override default string serialization? [\\#2079](https://github.com/nlohmann/json/issues/2079)\n- Can't have a json type as a property in an arbitrary type [\\#2078](https://github.com/nlohmann/json/issues/2078)\n- New release? [\\#2075](https://github.com/nlohmann/json/issues/2075)\n- CMake FetchContent \\> Updating the documentation? [\\#2073](https://github.com/nlohmann/json/issues/2073)\n- How to convert STL Vector \\(of user defined type\\) to Json [\\#2072](https://github.com/nlohmann/json/issues/2072)\n- how to make an array of objects [\\#2070](https://github.com/nlohmann/json/issues/2070)\n- ‘\\_\\_int64’ was not declared [\\#2068](https://github.com/nlohmann/json/issues/2068)\n- \\[json.exception.type\\_error.317\\] cannot serialize binary data to text JSON [\\#2067](https://github.com/nlohmann/json/issues/2067)\n- Unexpected end of input; expected '\\[', '{', or a literal [\\#2066](https://github.com/nlohmann/json/issues/2066)\n- Json structure can be nested? [\\#2065](https://github.com/nlohmann/json/issues/2065)\n- Bug: returning reference to local temporary object [\\#2064](https://github.com/nlohmann/json/issues/2064)\n- Allow to use non strict parsing [\\#2063](https://github.com/nlohmann/json/issues/2063)\n- Crashing on json::at [\\#2062](https://github.com/nlohmann/json/issues/2062)\n- How to convert a const std::vector\\<char8\\_t\\> message to a json, to be able to parse it and extract information from it? Can you point to any examples? [\\#2058](https://github.com/nlohmann/json/issues/2058)\n- Nice library [\\#2057](https://github.com/nlohmann/json/issues/2057)\n- json.hpp:15372:22: error: expected unqualified-id if \\(not std::isfinite\\(x\\)\\): Started getting this bug after updating my XCode [\\#2056](https://github.com/nlohmann/json/issues/2056)\n- Confused as how I can extract the values from the JSON object. [\\#2055](https://github.com/nlohmann/json/issues/2055)\n- Warnings with GCC 10 [\\#2052](https://github.com/nlohmann/json/issues/2052)\n- Warnings with Clang 10 [\\#2049](https://github.com/nlohmann/json/issues/2049)\n- Update doctest [\\#2048](https://github.com/nlohmann/json/issues/2048)\n- Unclear error message: \"cannot use operator\\[\\] with a string argument with array\" [\\#2047](https://github.com/nlohmann/json/issues/2047)\n- Serializing std::variant\\<T, std::vector\\<T\\>\\> [\\#2045](https://github.com/nlohmann/json/issues/2045)\n- Crash when parse big jsonfile [\\#2042](https://github.com/nlohmann/json/issues/2042)\n- How to check if a key exists without silently generating null objects on the path [\\#2041](https://github.com/nlohmann/json/issues/2041)\n- Crash when traversing over items\\(\\) of temporary json objects [\\#2040](https://github.com/nlohmann/json/issues/2040)\n- How to parse multiple line value ? [\\#2039](https://github.com/nlohmann/json/issues/2039)\n- SAX API uses unsigned std::size\\_t but  -1 if element size is not known; [\\#2037](https://github.com/nlohmann/json/issues/2037)\n- How to parse big decimal data [\\#2036](https://github.com/nlohmann/json/issues/2036)\n- how use   template \\<typename T\\> struct adl\\_serializer  [\\#2035](https://github.com/nlohmann/json/issues/2035)\n- auto iterator returned by find to handle value depending if is string or numeric. [\\#2032](https://github.com/nlohmann/json/issues/2032)\n- pass find returned iterator to numeric variable. [\\#2031](https://github.com/nlohmann/json/issues/2031)\n- Parse error on valid json file [\\#2029](https://github.com/nlohmann/json/issues/2029)\n- Is here any elegant way to combine serialization and deserialization code? [\\#2028](https://github.com/nlohmann/json/issues/2028)\n- Notes about dump function [\\#2027](https://github.com/nlohmann/json/issues/2027)\n- Different JSON printouts for empty dictionary on Linux and Mac. [\\#2026](https://github.com/nlohmann/json/issues/2026)\n- easier way to get exception reason out of json\\_sax\\_dom\\_callback\\_parser without exceptions [\\#2024](https://github.com/nlohmann/json/issues/2024)\n- Using fifo\\_map with base class and derived class [\\#2023](https://github.com/nlohmann/json/issues/2023)\n- Error reading JSON File  [\\#2022](https://github.com/nlohmann/json/issues/2022)\n- Parse causing crash on android.  Cannot catch. [\\#2021](https://github.com/nlohmann/json/issues/2021)\n- Extra backslashes in nested json [\\#2020](https://github.com/nlohmann/json/issues/2020)\n- How to create patch for merge\\_patch input ? [\\#2018](https://github.com/nlohmann/json/issues/2018)\n- CppUTest/include/CppUTestExt/MockSupport.h:40: error: default argument for ‘MockFailureReporter\\* failureReporterForThisCall’ has type ‘void\\*’ [\\#2017](https://github.com/nlohmann/json/issues/2017)\n- including another file [\\#2016](https://github.com/nlohmann/json/issues/2016)\n- GNU PREREQ Error with gcc 9.3.0 [\\#2015](https://github.com/nlohmann/json/issues/2015)\n- Parse error: json.exception.parse\\_error.101 - invalid string: ill-formed UTF-8 byte [\\#2014](https://github.com/nlohmann/json/issues/2014)\n- Add more flexibility to basic\\_json's ObjectType \\(and ArrayType\\) [\\#2013](https://github.com/nlohmann/json/issues/2013)\n- afl persistent mode [\\#2012](https://github.com/nlohmann/json/issues/2012)\n- Compiler Errors under VS2019 in Appveyor CI [\\#2009](https://github.com/nlohmann/json/issues/2009)\n- Another compilation failure with Visual Studio [\\#2007](https://github.com/nlohmann/json/issues/2007)\n- Implicit cast to std::string broken again with VS2019 16.5.0 [\\#2006](https://github.com/nlohmann/json/issues/2006)\n- error: no matching member function for call to 'AddRaw' [\\#2005](https://github.com/nlohmann/json/issues/2005)\n- When I re-create an object again after the network request, an error is reported [\\#2003](https://github.com/nlohmann/json/issues/2003)\n- How to merge \\(and not replace\\) different Json::Value objects in jsoncpp [\\#2001](https://github.com/nlohmann/json/issues/2001)\n- scalar transforms to list [\\#2000](https://github.com/nlohmann/json/issues/2000)\n- Dump JSON containing multibyte characters [\\#1999](https://github.com/nlohmann/json/issues/1999)\n- Build error  when modify value [\\#1998](https://github.com/nlohmann/json/issues/1998)\n- How do i include a vector of pointers in my json? [\\#1997](https://github.com/nlohmann/json/issues/1997)\n- Compiler error wrt incomplete types changed in gcc8.3.0-26 [\\#1996](https://github.com/nlohmann/json/issues/1996)\n- NaN-like comparison behavior of discarded is inconvenient [\\#1988](https://github.com/nlohmann/json/issues/1988)\n- Maintaining JSON package in my CMake [\\#1987](https://github.com/nlohmann/json/issues/1987)\n- reading int number and string number [\\#1986](https://github.com/nlohmann/json/issues/1986)\n- Build error: keyword is hidden by macro definition! [\\#1985](https://github.com/nlohmann/json/issues/1985)\n- JSON patch diff for op=add formation is not as per standard \\(RFC 6902\\) [\\#1983](https://github.com/nlohmann/json/issues/1983)\n- json\\_pointer.contains\\(\\) exception is incorrectly raised [\\#1982](https://github.com/nlohmann/json/issues/1982)\n- Error with non existing key [\\#1981](https://github.com/nlohmann/json/issues/1981)\n- Closed [\\#1978](https://github.com/nlohmann/json/issues/1978)\n- Where is the library built and what is the name? [\\#1977](https://github.com/nlohmann/json/issues/1977)\n- The cmake\\_import example does not build [\\#1976](https://github.com/nlohmann/json/issues/1976)\n- Dumping core when reading invalid file [\\#1975](https://github.com/nlohmann/json/issues/1975)\n- Abort in dump\\(\\) method [\\#1973](https://github.com/nlohmann/json/issues/1973)\n- Unclear docs regarding parser\\_callback\\_t callbacks [\\#1972](https://github.com/nlohmann/json/issues/1972)\n- Possible memory leak on push\\_back [\\#1971](https://github.com/nlohmann/json/issues/1971)\n- Is it possible to get a safe mutable reference/pointer to internal variant used in nlohmann json?  [\\#1970](https://github.com/nlohmann/json/issues/1970)\n- Getting a flatten json to map\\<string, string\\> [\\#1957](https://github.com/nlohmann/json/issues/1957)\n- forced type conversion or lexical cast without exception. [\\#1955](https://github.com/nlohmann/json/issues/1955)\n- Add json\\_view type support to avoid excessive copying [\\#1954](https://github.com/nlohmann/json/issues/1954)\n- Adding \"examples\" section for real-life usages [\\#1953](https://github.com/nlohmann/json/issues/1953)\n- Add nlohmann::json::key\\_type [\\#1951](https://github.com/nlohmann/json/issues/1951)\n- cannot use operator\\[\\] with a string argument with string [\\#1949](https://github.com/nlohmann/json/issues/1949)\n- std::ifstream \\>\\> json error [\\#1948](https://github.com/nlohmann/json/issues/1948)\n- Cannot update json data in an iterator? [\\#1947](https://github.com/nlohmann/json/issues/1947)\n- How can i build this library in VS 2017? [\\#1943](https://github.com/nlohmann/json/issues/1943)\n- json\\_pointer.contains\\(\\) exceptions when path not found [\\#1942](https://github.com/nlohmann/json/issues/1942)\n- Nested objects serialize/deserialize [\\#1941](https://github.com/nlohmann/json/issues/1941)\n- Compile warning on architectures that are not x86 [\\#1939](https://github.com/nlohmann/json/issues/1939)\n- Version of nlohmann-json-dev in debian packages [\\#1938](https://github.com/nlohmann/json/issues/1938)\n- Create a json object for every cycle  [\\#1937](https://github.com/nlohmann/json/issues/1937)\n- How to get the object name? [\\#1936](https://github.com/nlohmann/json/issues/1936)\n- Reserve and resize function for basic json [\\#1935](https://github.com/nlohmann/json/issues/1935)\n- How to use json parse in tsl::ordread\\_map? [\\#1934](https://github.com/nlohmann/json/issues/1934)\n- C++14 support is not enabled with msvc2015 [\\#1932](https://github.com/nlohmann/json/issues/1932)\n- Need help with to\\_json for derived class, keep getting \"cannot use operator\" [\\#1931](https://github.com/nlohmann/json/issues/1931)\n- How to handle std::vector\\<std::uint8\\_t\\> [\\#1930](https://github.com/nlohmann/json/issues/1930)\n- Heap corruption issue [\\#1929](https://github.com/nlohmann/json/issues/1929)\n- Add `std::wistream` support. [\\#1928](https://github.com/nlohmann/json/issues/1928)\n- This i can write and read any file thanks [\\#1927](https://github.com/nlohmann/json/issues/1927)\n- How can I get this simple example working? [\\#1926](https://github.com/nlohmann/json/issues/1926)\n- emplace\\_back does not seems to work with the int 0 [\\#1925](https://github.com/nlohmann/json/issues/1925)\n- Why nlohmann does not release memory [\\#1924](https://github.com/nlohmann/json/issues/1924)\n- Is it possible to have template `json::parse` with `noexcept` specifier? [\\#1922](https://github.com/nlohmann/json/issues/1922)\n- JSON to wstring? [\\#1921](https://github.com/nlohmann/json/issues/1921)\n- GCC 10 tests build failure [\\#1920](https://github.com/nlohmann/json/issues/1920)\n- Size of binary json representations [\\#1919](https://github.com/nlohmann/json/issues/1919)\n- Accessing strings \\(for example in keys or values\\) without having the lib create a copy of it. [\\#1916](https://github.com/nlohmann/json/issues/1916)\n- operator== documentation should show how to apply custom comparison function [\\#1915](https://github.com/nlohmann/json/issues/1915)\n- char8\\_t and std::u8string support [\\#1914](https://github.com/nlohmann/json/issues/1914)\n- std::is\\_pod is deprecated in C++20 [\\#1913](https://github.com/nlohmann/json/issues/1913)\n- Incomplete types reported by \\(experimental\\) GCC10 [\\#1912](https://github.com/nlohmann/json/issues/1912)\n- Compile warnings on MSVC 14.2 [\\#1911](https://github.com/nlohmann/json/issues/1911)\n- How to parse json file with   type composition  of std::optional  and std::variant [\\#1910](https://github.com/nlohmann/json/issues/1910)\n- why root\\_schema be  implemented as unique\\_ptr in json-validator.cpp，could I use it as shared\\_ptr? [\\#1908](https://github.com/nlohmann/json/issues/1908)\n- compile error in gcc-6.3.0 [\\#1906](https://github.com/nlohmann/json/issues/1906)\n- Scalar constexpr is odr-used when used as json initializer [\\#1905](https://github.com/nlohmann/json/issues/1905)\n- install Slack app [\\#1904](https://github.com/nlohmann/json/issues/1904)\n- typo in a comment [\\#1903](https://github.com/nlohmann/json/issues/1903)\n- Watch JSON variables in Debug [\\#1902](https://github.com/nlohmann/json/issues/1902)\n- does Json sdk cares about dfc dfd utf8 issue? [\\#1901](https://github.com/nlohmann/json/issues/1901)\n- Allow multiple line string value in JSON [\\#1897](https://github.com/nlohmann/json/issues/1897)\n- Writing map to json file  [\\#1896](https://github.com/nlohmann/json/issues/1896)\n- Small documentation mistake [\\#1895](https://github.com/nlohmann/json/issues/1895)\n- why static function `parse` cann't find in visual studio 2019 [\\#1894](https://github.com/nlohmann/json/issues/1894)\n- Best way to handle json files with missing key value pairs. [\\#1893](https://github.com/nlohmann/json/issues/1893)\n- accessing json object as multimap [\\#1892](https://github.com/nlohmann/json/issues/1892)\n- What is the best way to parse vec3s into glm::vec3 [\\#1891](https://github.com/nlohmann/json/issues/1891)\n- Get array of items without using vector [\\#1890](https://github.com/nlohmann/json/issues/1890)\n- Build errors \\(clang 11.0.0\\) on macOS 10.15.2 [\\#1889](https://github.com/nlohmann/json/issues/1889)\n- Multiple arrays to vectors help [\\#1888](https://github.com/nlohmann/json/issues/1888)\n- json::parse\\(begin, end\\) parse error on first character using uchar\\* [\\#1887](https://github.com/nlohmann/json/issues/1887)\n- issue in free\\(\\) [\\#1886](https://github.com/nlohmann/json/issues/1886)\n- is\\_number\\_unsigned\\(\\) returns false for positive integers \\(int or 0 or 1 literals\\) [\\#1885](https://github.com/nlohmann/json/issues/1885)\n- MSVC build failure with /Zc:\\_\\_cplusplus and C++17 [\\#1883](https://github.com/nlohmann/json/issues/1883)\n- RFC 6901 op:replace & arrays [\\#1882](https://github.com/nlohmann/json/issues/1882)\n- Problem with serialization of my custom template doubly-linked list [\\#1881](https://github.com/nlohmann/json/issues/1881)\n- is\\_array\\(\\) is True, but raise 'cannot use operator\\[\\] for object iterators' [\\#1880](https://github.com/nlohmann/json/issues/1880)\n- Serialize dynamic array [\\#1879](https://github.com/nlohmann/json/issues/1879)\n- Serialization of struct object. [\\#1877](https://github.com/nlohmann/json/issues/1877)\n- warning:c4503 [\\#1875](https://github.com/nlohmann/json/issues/1875)\n- Why are flattened empty objects/arrays not representable? [\\#1874](https://github.com/nlohmann/json/issues/1874)\n- Container Overflow \\(ASAN\\) when using operator \\>\\> on an ifs [\\#1873](https://github.com/nlohmann/json/issues/1873)\n- Sub-array to vector or map object? [\\#1870](https://github.com/nlohmann/json/issues/1870)\n- WIP: QT \\(cute\\) type supports [\\#1869](https://github.com/nlohmann/json/issues/1869)\n- Compiler flags to disable features and shrink code size [\\#1868](https://github.com/nlohmann/json/issues/1868)\n- null strings [\\#1867](https://github.com/nlohmann/json/issues/1867)\n- Struct with array of struct and \\_\\_attribute\\_\\_\\(\\(packed\\)\\) [\\#1866](https://github.com/nlohmann/json/issues/1866)\n- Best way to extract numbers in the string? [\\#1865](https://github.com/nlohmann/json/issues/1865)\n- Displaying \\\\?\\Volume{guid} from string to json giving error [\\#1864](https://github.com/nlohmann/json/issues/1864)\n- not working when compiling as x86 [\\#1863](https://github.com/nlohmann/json/issues/1863)\n- Skipping evaluation of log line expressions with a macro, is it possible? [\\#1862](https://github.com/nlohmann/json/issues/1862)\n- Suppress warnings [\\#1861](https://github.com/nlohmann/json/issues/1861)\n- conflit with g++ compile option -mwindows [\\#1860](https://github.com/nlohmann/json/issues/1860)\n- How to serialize nested classes to semi-flat JSON object? [\\#1859](https://github.com/nlohmann/json/issues/1859)\n- Memory Requirement for large json file [\\#1858](https://github.com/nlohmann/json/issues/1858)\n- Query a binary format \\(BSON, CBOR, MessagePack, UBJSON\\) [\\#1856](https://github.com/nlohmann/json/issues/1856)\n- Documentation on operator\\[\\] behavior with missing keys [\\#1855](https://github.com/nlohmann/json/issues/1855)\n- Problem in converting string into JSON; Can't parse successfully. [\\#1854](https://github.com/nlohmann/json/issues/1854)\n- json.at\\_or\\_default\\(key, defaultval\\) [\\#1852](https://github.com/nlohmann/json/issues/1852)\n- please improve the enum conversion documentation \\(my example gist provided\\) [\\#1851](https://github.com/nlohmann/json/issues/1851)\n- Default value returned on ValueType nlohmann::basic\\_json::value \\(const typename object\\_t::key\\_type& key, const ValueType& default\\_value\\) \t [\\#1850](https://github.com/nlohmann/json/issues/1850)\n- Accounting for arbitrary precision numerical literals [\\#1849](https://github.com/nlohmann/json/issues/1849)\n- While trying to make a simple array, I get a nested array instead [\\#1848](https://github.com/nlohmann/json/issues/1848)\n- How to reuse the parser and serializer intermediate storage? [\\#1847](https://github.com/nlohmann/json/issues/1847)\n- Too much content in json.hpp leads to slow compilation [\\#1845](https://github.com/nlohmann/json/issues/1845)\n- Cannot read some data in json file [\\#1843](https://github.com/nlohmann/json/issues/1843)\n- Precompiled JSON library? [\\#1842](https://github.com/nlohmann/json/issues/1842)\n- Please change assert into throw\\(maybe\\) in line 17946 [\\#1841](https://github.com/nlohmann/json/issues/1841)\n- JSON for modern C++ ECCN information [\\#1840](https://github.com/nlohmann/json/issues/1840)\n- CI: reduce build time for Travis valgrind [\\#1836](https://github.com/nlohmann/json/issues/1836)\n- How do I traverse a json object and add new elements into the hierarchy [\\#1834](https://github.com/nlohmann/json/issues/1834)\n- Invalid UTF-8 byte at index 1: 0x65 [\\#1831](https://github.com/nlohmann/json/issues/1831)\n- Serialize big data in json [\\#1828](https://github.com/nlohmann/json/issues/1828)\n- Backslash '\\' in value causes exception [\\#1827](https://github.com/nlohmann/json/issues/1827)\n- from\\_json for non default constructible class with dependency injection [\\#1819](https://github.com/nlohmann/json/issues/1819)\n- Semi-frequent timeouts in `test-unicode_all` with 3.6.1 \\(aarch64\\) [\\#1816](https://github.com/nlohmann/json/issues/1816)\n- input\\_adapter not user extensible [\\#1813](https://github.com/nlohmann/json/issues/1813)\n- crash at json::destroy on android  [\\#1812](https://github.com/nlohmann/json/issues/1812)\n- Logs are repeating while cmake [\\#1809](https://github.com/nlohmann/json/issues/1809)\n- Add a the possibility to add dynamic json objects [\\#1795](https://github.com/nlohmann/json/issues/1795)\n- Unnecessary test data file in the release [\\#1790](https://github.com/nlohmann/json/issues/1790)\n- Add support for parse stack limiting [\\#1788](https://github.com/nlohmann/json/issues/1788)\n- GCC -Wuseless-cast warnings [\\#1777](https://github.com/nlohmann/json/issues/1777)\n- compilation issue with NVCC 9.0 [\\#1773](https://github.com/nlohmann/json/issues/1773)\n- Unexpected behavior with fifo\\_map json when copy and append  [\\#1763](https://github.com/nlohmann/json/issues/1763)\n- Parse error [\\#1761](https://github.com/nlohmann/json/issues/1761)\n- Assignment \\(using value\\(\\)\\) to nonexistent element behaves differently on Xcode 8 vs Xcode 10 [\\#1758](https://github.com/nlohmann/json/issues/1758)\n- Readme out of date [\\#1756](https://github.com/nlohmann/json/issues/1756)\n- cmake\\_\\* tests don't use the build system's compiler [\\#1747](https://github.com/nlohmann/json/issues/1747)\n- Static assertions for template type properties required [\\#1729](https://github.com/nlohmann/json/issues/1729)\n- Use float and possibly half in json::to\\_cbor [\\#1719](https://github.com/nlohmann/json/issues/1719)\n- json::from\\_cbor does not respect allow\\_exceptions = false when input is string literal [\\#1715](https://github.com/nlohmann/json/issues/1715)\n- /Zc:\\_\\_cplusplus leads to C2416 [\\#1695](https://github.com/nlohmann/json/issues/1695)\n- `unflatten` vs objects with number-ish keys [\\#1575](https://github.com/nlohmann/json/issues/1575)\n- A \"thinner\" source code tar as part of release? [\\#1572](https://github.com/nlohmann/json/issues/1572)\n- Repository is almost 450MB [\\#1497](https://github.com/nlohmann/json/issues/1497)\n- Substantial performance penalty caused by polymorphic input adapter  [\\#1457](https://github.com/nlohmann/json/issues/1457)\n- Move tests to a separate repo [\\#1235](https://github.com/nlohmann/json/issues/1235)\n- reduce repos size [\\#1185](https://github.com/nlohmann/json/issues/1185)\n- CMakeLists.txt in release zips? [\\#1184](https://github.com/nlohmann/json/issues/1184)\n- Minimal branch? [\\#1066](https://github.com/nlohmann/json/issues/1066)\n- Move test blobs to a submodule? [\\#732](https://github.com/nlohmann/json/issues/732)\n- \\[Question\\] When using this as git submodule, will it clone the whole thing include test data and benchmark? [\\#620](https://github.com/nlohmann/json/issues/620)\n- Need to improve ignores.. [\\#567](https://github.com/nlohmann/json/issues/567)\n- Minimal repository \\(current size very large\\) [\\#556](https://github.com/nlohmann/json/issues/556)\n- For a header-only library you have to clone 214MB [\\#482](https://github.com/nlohmann/json/issues/482)\n- 17 MB / 90 MB repo size!? [\\#96](https://github.com/nlohmann/json/issues/96)\n\n- Improve parse\\_ubjson\\_fuzzer [\\#2182](https://github.com/nlohmann/json/pull/2182) ([tanuj208](https://github.com/tanuj208))\n- Add input adapter tests [\\#2178](https://github.com/nlohmann/json/pull/2178) ([nlohmann](https://github.com/nlohmann))\n- Fix warnings [\\#2174](https://github.com/nlohmann/json/pull/2174) ([nlohmann](https://github.com/nlohmann))\n- Fix PR\\#1006 [\\#2158](https://github.com/nlohmann/json/pull/2158) ([dota17](https://github.com/dota17))\n- Fix issue\\#1972 [\\#2153](https://github.com/nlohmann/json/pull/2153) ([dota17](https://github.com/dota17))\n- Update URLs to HTTPS [\\#2152](https://github.com/nlohmann/json/pull/2152) ([TotalCaesar659](https://github.com/TotalCaesar659))\n- Fix Issue\\#1813: user defined input adapters [\\#2145](https://github.com/nlohmann/json/pull/2145) ([FrancoisChabot](https://github.com/FrancoisChabot))\n- Fix issue\\#1939: Cast character to unsigned for comparison [\\#2144](https://github.com/nlohmann/json/pull/2144) ([XyFreak](https://github.com/XyFreak))\n- Fix issue\\#2142: readme: fix typo in CMake FetchContent example [\\#2143](https://github.com/nlohmann/json/pull/2143) ([quentin-dev](https://github.com/quentin-dev))\n- Respect allow\\_exceptions=false for binary formats [\\#2140](https://github.com/nlohmann/json/pull/2140) ([nlohmann](https://github.com/nlohmann))\n- Fix issue 2112 [\\#2137](https://github.com/nlohmann/json/pull/2137) ([dota17](https://github.com/dota17))\n- Add bleeding edge GCC to CI [\\#2136](https://github.com/nlohmann/json/pull/2136) ([aokellermann](https://github.com/aokellermann))\n- Clean up implementation of binary type [\\#2125](https://github.com/nlohmann/json/pull/2125) ([nlohmann](https://github.com/nlohmann))\n- Fixed a compilation error in MSVC [\\#2121](https://github.com/nlohmann/json/pull/2121) ([gistrec](https://github.com/gistrec))\n- Overwork CI [\\#2119](https://github.com/nlohmann/json/pull/2119) ([nlohmann](https://github.com/nlohmann))\n- Fix warnings from Clang 10 and GCC 9 [\\#2116](https://github.com/nlohmann/json/pull/2116) ([nlohmann](https://github.com/nlohmann))\n- Do not include \\<ciso646\\> when using C++17 [\\#2115](https://github.com/nlohmann/json/pull/2115) ([nlohmann](https://github.com/nlohmann))\n- Fix issue\\#2086: disallow json::value\\_t type parameter in value\\(\\) [\\#2104](https://github.com/nlohmann/json/pull/2104) ([dota17](https://github.com/dota17))\n- Fix Coveralls integration [\\#2100](https://github.com/nlohmann/json/pull/2100) ([nlohmann](https://github.com/nlohmann))\n- Add tests for binary values [\\#2099](https://github.com/nlohmann/json/pull/2099) ([nlohmann](https://github.com/nlohmann))\n- Use external test data [\\#2081](https://github.com/nlohmann/json/pull/2081) ([nlohmann](https://github.com/nlohmann))\n- Remove Doozer CI [\\#2080](https://github.com/nlohmann/json/pull/2080) ([nlohmann](https://github.com/nlohmann))\n- Fix README.md. Missing ``` [\\#2077](https://github.com/nlohmann/json/pull/2077) ([ArthurSonzogni](https://github.com/ArthurSonzogni))\n- Fix error message about invalid surrogate pairs [\\#2076](https://github.com/nlohmann/json/pull/2076) ([rmisev](https://github.com/rmisev))\n- Add CMake fetchcontent documentation and tests [\\#2074](https://github.com/nlohmann/json/pull/2074) ([ArthurSonzogni](https://github.com/ArthurSonzogni))\n- Properly pass serialize\\_binary to dump function [\\#2071](https://github.com/nlohmann/json/pull/2071) ([nlohmann](https://github.com/nlohmann))\n- Fix returning reference to local temporary object [\\#2069](https://github.com/nlohmann/json/pull/2069) ([nlohmann](https://github.com/nlohmann))\n- updated wandbox link [\\#2060](https://github.com/nlohmann/json/pull/2060) ([alexandermyasnikov](https://github.com/alexandermyasnikov))\n- Fix bug in diff function [\\#2054](https://github.com/nlohmann/json/pull/2054) ([nlohmann](https://github.com/nlohmann))\n- Fix GCC compiler warnings [\\#2053](https://github.com/nlohmann/json/pull/2053) ([nlohmann](https://github.com/nlohmann))\n- Fix Clang compiler warnings [\\#2051](https://github.com/nlohmann/json/pull/2051) ([nlohmann](https://github.com/nlohmann))\n- Update doctest to 2.3.7 [\\#2050](https://github.com/nlohmann/json/pull/2050) ([nlohmann](https://github.com/nlohmann))\n- Fix issue\\#1719 [\\#2044](https://github.com/nlohmann/json/pull/2044) ([dota17](https://github.com/dota17))\n- Add missing testcase about NaN in unit-constructor1.cpp [\\#2043](https://github.com/nlohmann/json/pull/2043) ([dota17](https://github.com/dota17))\n- Templatize basic\\_json constructor from json\\_ref [\\#2034](https://github.com/nlohmann/json/pull/2034) ([ArtemSarmini](https://github.com/ArtemSarmini))\n- Replace deprecated std::is\\_pod [\\#2033](https://github.com/nlohmann/json/pull/2033) ([nlohmann](https://github.com/nlohmann))\n- Fixes \\#1971 \\(memory leak in basic\\_json::push\\_back\\) [\\#2025](https://github.com/nlohmann/json/pull/2025) ([ArtemSarmini](https://github.com/ArtemSarmini))\n- fix \\#1982:json\\_pointer.contains\\(\\) exception is incorrectly raised [\\#2019](https://github.com/nlohmann/json/pull/2019) ([dota17](https://github.com/dota17))\n- Update LICENSE.MIT [\\#2010](https://github.com/nlohmann/json/pull/2010) ([magamig](https://github.com/magamig))\n- PR for \\#2006 to test in AppVeyor. [\\#2008](https://github.com/nlohmann/json/pull/2008) ([garethsb](https://github.com/garethsb))\n- Added wsjcpp.yml [\\#2004](https://github.com/nlohmann/json/pull/2004) ([sea-kg](https://github.com/sea-kg))\n- fix error 'setw' is not a member of 'std' in Wandbox example [\\#2002](https://github.com/nlohmann/json/pull/2002) ([alexandermyasnikov](https://github.com/alexandermyasnikov))\n- catch exceptions for json\\_pointer : ..../+99 [\\#1990](https://github.com/nlohmann/json/pull/1990) ([dota17](https://github.com/dota17))\n- Modify the document about operator== [\\#1984](https://github.com/nlohmann/json/pull/1984) ([dota17](https://github.com/dota17))\n- Rename argument array\\_index to array\\_indx in json\\_pointer methods [\\#1980](https://github.com/nlohmann/json/pull/1980) ([linev](https://github.com/linev))\n- README: Fix string representation of `dump`ed `json` [\\#1979](https://github.com/nlohmann/json/pull/1979) ([alexweej](https://github.com/alexweej))\n- fix warnings in serializer.hpp for VS2019 [\\#1969](https://github.com/nlohmann/json/pull/1969) ([dota17](https://github.com/dota17))\n- Fix C26451 warnnings in to\\_chars.hpp [\\#1967](https://github.com/nlohmann/json/pull/1967) ([dota17](https://github.com/dota17))\n- appveyor.yml: Compile and test with latest version for \\_\\_cplusplus ma… [\\#1958](https://github.com/nlohmann/json/pull/1958) ([t-b](https://github.com/t-b))\n- Fix typo in examples [\\#1956](https://github.com/nlohmann/json/pull/1956) ([dota17](https://github.com/dota17))\n- templated input adapters [\\#1950](https://github.com/nlohmann/json/pull/1950) ([FrancoisChabot](https://github.com/FrancoisChabot))\n- Update README.md : add a FAQ about memory release [\\#1933](https://github.com/nlohmann/json/pull/1933) ([dota17](https://github.com/dota17))\n- Some typos [\\#1923](https://github.com/nlohmann/json/pull/1923) ([Coeur](https://github.com/Coeur))\n- Fix link to parse function in README [\\#1918](https://github.com/nlohmann/json/pull/1918) ([kastiglione](https://github.com/kastiglione))\n- Readme: Updated links to hunter repo & docs [\\#1917](https://github.com/nlohmann/json/pull/1917) ([jothepro](https://github.com/jothepro))\n- Adds instruction for using Build2's package manager [\\#1909](https://github.com/nlohmann/json/pull/1909) ([Klaim](https://github.com/Klaim))\n- Update README.md [\\#1907](https://github.com/nlohmann/json/pull/1907) ([pauljurczak](https://github.com/pauljurczak))\n- Fix warning: ignoring return value [\\#1871](https://github.com/nlohmann/json/pull/1871) ([sonulohani](https://github.com/sonulohani))\n- docs: add central repository as conan source to readme [\\#1857](https://github.com/nlohmann/json/pull/1857) ([gocarlos](https://github.com/gocarlos))\n- README: Package in MSYS2 renamed to nlohmann-json [\\#1853](https://github.com/nlohmann/json/pull/1853) ([podsvirov](https://github.com/podsvirov))\n- Fix msvc warnings [\\#1846](https://github.com/nlohmann/json/pull/1846) ([MBalszun](https://github.com/MBalszun))\n- Update tests that generate CMake projects to use main project's C++ compiler [\\#1844](https://github.com/nlohmann/json/pull/1844) ([Tridacnid](https://github.com/Tridacnid))\n- make CMake's version config file architecture-independent [\\#1746](https://github.com/nlohmann/json/pull/1746) ([uhoreg](https://github.com/uhoreg))\n- Add binary type support to all binary file formats, as well as an internally represented binary type [\\#1662](https://github.com/nlohmann/json/pull/1662) ([OmnipotentEntity](https://github.com/OmnipotentEntity))\n\n## [v3.7.3](https://github.com/nlohmann/json/releases/tag/v3.7.3) (2019-11-17)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.2...v3.7.3)\n\n- Project branches [\\#1839](https://github.com/nlohmann/json/issues/1839)\n- Quadratic destruction complexity introduced in \\#1436 [\\#1837](https://github.com/nlohmann/json/issues/1837)\n- Trying to open a file [\\#1814](https://github.com/nlohmann/json/issues/1814)\n- Comparing data type with value\\_t::number\\_integer fails [\\#1783](https://github.com/nlohmann/json/issues/1783)\n- CMake version config file is architecture-dependent [\\#1697](https://github.com/nlohmann/json/issues/1697)\n\n- Fix quadratic destruction complexity [\\#1838](https://github.com/nlohmann/json/pull/1838) ([nickaein](https://github.com/nickaein))\n\n## [v3.7.2](https://github.com/nlohmann/json/releases/tag/v3.7.2) (2019-11-10)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.1...v3.7.2)\n\n- Segmentation fault in destructor in case of large inputs [\\#1835](https://github.com/nlohmann/json/issues/1835)\n- type\\_name\\(\\) is not consistent with type\\(\\) [\\#1833](https://github.com/nlohmann/json/issues/1833)\n- json::parse is not a member [\\#1832](https://github.com/nlohmann/json/issues/1832)\n- How do you deal with json\\* ? [\\#1829](https://github.com/nlohmann/json/issues/1829)\n- Combined find\\_package/add\\_subdirectory not linking libraries [\\#1771](https://github.com/nlohmann/json/issues/1771)\n- example code for ifstream reading a json file results in no operator error [\\#1766](https://github.com/nlohmann/json/issues/1766)\n- Warning: unsequenced modification and access to 'range' [\\#1674](https://github.com/nlohmann/json/issues/1674)\n- Segmentation fault \\(stack overflow\\) due to unbounded recursion [\\#1419](https://github.com/nlohmann/json/issues/1419)\n- Stack-overflow \\(OSS-Fuzz 4234\\) [\\#832](https://github.com/nlohmann/json/issues/832)\n\n- Configure WhiteSource Bolt for GitHub [\\#1830](https://github.com/nlohmann/json/pull/1830) ([whitesource-bolt-for-github[bot]](https://github.com/apps/whitesource-bolt-for-github))\n- Prevent stackoverflow caused by recursive deconstruction [\\#1436](https://github.com/nlohmann/json/pull/1436) ([nickaein](https://github.com/nickaein))\n\n## [v3.7.1](https://github.com/nlohmann/json/releases/tag/v3.7.1) (2019-11-06)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.7.0...v3.7.1)\n\n- std::is\\_constructible is always true with tuple [\\#1825](https://github.com/nlohmann/json/issues/1825)\n- Can't compile from\\_json\\(std::valarray\\<T\\>\\). [\\#1824](https://github.com/nlohmann/json/issues/1824)\n- json class should have a get\\_or member function [\\#1823](https://github.com/nlohmann/json/issues/1823)\n- NLOHMANN\\_JSON\\_SERIALIZE\\_ENUM macro capture's json objects by value [\\#1822](https://github.com/nlohmann/json/issues/1822)\n- Parse fails when number literals start with zero [\\#1820](https://github.com/nlohmann/json/issues/1820)\n- Weird behaviour of `contains` with `json_pointer` [\\#1815](https://github.com/nlohmann/json/issues/1815)\n- strange behaviour with json\\_pointer and .contains\\(\\) [\\#1811](https://github.com/nlohmann/json/issues/1811)\n- Can \\#1695 be re-opened? [\\#1808](https://github.com/nlohmann/json/issues/1808)\n- Merge two json objects [\\#1807](https://github.com/nlohmann/json/issues/1807)\n- std::is\\_constructible\\<json, std::unordered\\_map\\<std::string, Data\\>\\> when to\\_json not defined [\\#1805](https://github.com/nlohmann/json/issues/1805)\n- Private data on parsing [\\#1802](https://github.com/nlohmann/json/issues/1802)\n- Capturing Line and Position when querying [\\#1800](https://github.com/nlohmann/json/issues/1800)\n- json error on parsing DBL\\_MAX from string [\\#1796](https://github.com/nlohmann/json/issues/1796)\n- De/Serialisation of vector of tupple object with nested obect need Help please [\\#1794](https://github.com/nlohmann/json/issues/1794)\n- Output json is corrupted [\\#1793](https://github.com/nlohmann/json/issues/1793)\n- variable name byte sometimes used as a \\#define [\\#1792](https://github.com/nlohmann/json/issues/1792)\n- Can't read json file [\\#1791](https://github.com/nlohmann/json/issues/1791)\n- Problems with special German letters [\\#1789](https://github.com/nlohmann/json/issues/1789)\n- Support for trailing commas [\\#1787](https://github.com/nlohmann/json/issues/1787)\n- json\\_pointer construction bug [\\#1786](https://github.com/nlohmann/json/issues/1786)\n- Visual Studio 2017 warning [\\#1784](https://github.com/nlohmann/json/issues/1784)\n- ciso646 header become obsolete [\\#1782](https://github.com/nlohmann/json/issues/1782)\n- Migrate LGTM.com installation from OAuth to GitHub App [\\#1781](https://github.com/nlohmann/json/issues/1781)\n- JSON comparison, contains and operator& [\\#1778](https://github.com/nlohmann/json/issues/1778)\n- pass a json object to a class contructor adds an array around the object [\\#1776](https://github.com/nlohmann/json/issues/1776)\n- 'Float' number\\_float\\_function\\_t template parameter name conflicts with C '\\#define Float float' [\\#1775](https://github.com/nlohmann/json/issues/1775)\n- A weird building problem :-\\( [\\#1774](https://github.com/nlohmann/json/issues/1774)\n- What is this json\\_ref? [\\#1772](https://github.com/nlohmann/json/issues/1772)\n- Interoperability with other languages [\\#1770](https://github.com/nlohmann/json/issues/1770)\n- Json dump [\\#1768](https://github.com/nlohmann/json/issues/1768)\n- json\\_pointer\\<\\>::back\\(\\) should be const [\\#1764](https://github.com/nlohmann/json/issues/1764)\n- How to get value from array [\\#1762](https://github.com/nlohmann/json/issues/1762)\n- Merge two jsons [\\#1757](https://github.com/nlohmann/json/issues/1757)\n- Unable to locate nlohmann\\_jsonConfig.cmake [\\#1755](https://github.com/nlohmann/json/issues/1755)\n- json.hpp won;t compile VS2019 CLR/CLI app but does in console app [\\#1754](https://github.com/nlohmann/json/issues/1754)\n- \\[Nested Json Objects\\] Segmentation fault [\\#1753](https://github.com/nlohmann/json/issues/1753)\n- remove/replace assert with exceptions [\\#1752](https://github.com/nlohmann/json/issues/1752)\n- Add array support for update\\(\\) function [\\#1751](https://github.com/nlohmann/json/issues/1751)\n- Is there a reason the `get_to` method is defined in `include/nlohmann/json.hpp` but not in `single_include/nlohmann/json.hpp`? [\\#1750](https://github.com/nlohmann/json/issues/1750)\n- how to validate json object before calling dump\\(\\) [\\#1748](https://github.com/nlohmann/json/issues/1748)\n- Unable to invoke accessors on json objects in lldb [\\#1745](https://github.com/nlohmann/json/issues/1745)\n- Escaping string before parsing [\\#1743](https://github.com/nlohmann/json/issues/1743)\n- Construction in a member initializer list using curly braces is set as 'array' [\\#1742](https://github.com/nlohmann/json/issues/1742)\n- Read a subkey from json object [\\#1740](https://github.com/nlohmann/json/issues/1740)\n- Serialize vector of glm:vec2 [\\#1739](https://github.com/nlohmann/json/issues/1739)\n- Support nlohmann::basic\\_json::value with JSON\\_NOEXCEPTION [\\#1738](https://github.com/nlohmann/json/issues/1738)\n- how to know the parse is error [\\#1737](https://github.com/nlohmann/json/issues/1737)\n- How to check if a given key exists in a JSON object [\\#1736](https://github.com/nlohmann/json/issues/1736)\n- Allow The Colon Key-Value Delimiter To Have A Space Before It \\[@ READ ONLY\\] [\\#1735](https://github.com/nlohmann/json/issues/1735)\n- Allow Tail { \"Key\": \"Value\" } Comma \\[@ READ ONLY\\] [\\#1734](https://github.com/nlohmann/json/issues/1734)\n- No-throw json::value\\(\\) [\\#1733](https://github.com/nlohmann/json/issues/1733)\n- JsonObject.dump\\(\\)  [\\#1732](https://github.com/nlohmann/json/issues/1732)\n- basic\\_json has no member \"parse\" [\\#1731](https://github.com/nlohmann/json/issues/1731)\n- Exception \"type must be string, but is array\" [\\#1730](https://github.com/nlohmann/json/issues/1730)\n- json::contains usage to find a path [\\#1727](https://github.com/nlohmann/json/issues/1727)\n- How to create JSON Object from my Structures of Data and Json File from that Object [\\#1726](https://github.com/nlohmann/json/issues/1726)\n- please provide an API to read JSON from file directly. [\\#1725](https://github.com/nlohmann/json/issues/1725)\n- How to modify a value stored at a key? [\\#1723](https://github.com/nlohmann/json/issues/1723)\n- CMake not correctly finding the configuration package for 3.7.0  [\\#1721](https://github.com/nlohmann/json/issues/1721)\n- name typo in the \"spack package management\" section of README.md [\\#1720](https://github.com/nlohmann/json/issues/1720)\n- How to add json to another json? [\\#1718](https://github.com/nlohmann/json/issues/1718)\n- json::parse\\(\\) ubsan regression with v3.7.0 [\\#1716](https://github.com/nlohmann/json/issues/1716)\n- What I am doing wrong?!? [\\#1714](https://github.com/nlohmann/json/issues/1714)\n- Potential memory leak detected by Valgrind [\\#1713](https://github.com/nlohmann/json/issues/1713)\n- json::parse is not thread safe? [\\#1712](https://github.com/nlohmann/json/issues/1712)\n- static analysis alarm by cppcheck [\\#1711](https://github.com/nlohmann/json/issues/1711)\n- The compilation time is slow [\\#1710](https://github.com/nlohmann/json/issues/1710)\n- not linking properly with cmake [\\#1709](https://github.com/nlohmann/json/issues/1709)\n- Error in dump\\(\\) with int64\\_t minimum value [\\#1708](https://github.com/nlohmann/json/issues/1708)\n- Crash on trying to deserialize json string on 3ds homebrew [\\#1707](https://github.com/nlohmann/json/issues/1707)\n- Can't compile VS2019. 13 Errors  [\\#1706](https://github.com/nlohmann/json/issues/1706)\n- find an object that matches the search criteria [\\#1705](https://github.com/nlohmann/json/issues/1705)\n- IntelliSense goes crazy on VS2019 [\\#1704](https://github.com/nlohmann/json/issues/1704)\n- Installing on Ubuntu 16.04 [\\#1703](https://github.com/nlohmann/json/issues/1703)\n- Where is json::parse now? [\\#1702](https://github.com/nlohmann/json/issues/1702)\n- Forward header should't be amalgamated [\\#1700](https://github.com/nlohmann/json/issues/1700)\n- Json support for Cmake version 2.8.12 [\\#1699](https://github.com/nlohmann/json/issues/1699)\n- Intruisive scientific notation when using .dump\\(\\); [\\#1698](https://github.com/nlohmann/json/issues/1698)\n- Is there support for automatic serialization/deserialization? [\\#1696](https://github.com/nlohmann/json/issues/1696)\n- on MSVC dump\\(\\) will hard crash for larger json [\\#1693](https://github.com/nlohmann/json/issues/1693)\n- puzzled implicit conversions [\\#1692](https://github.com/nlohmann/json/issues/1692)\n- Information: My project uses this awesome library [\\#1691](https://github.com/nlohmann/json/issues/1691)\n- Consider listing files explicitly instead of using GLOB [\\#1686](https://github.com/nlohmann/json/issues/1686)\n- Failing tests on MSVC with VS2019 15.9.13 x64 [\\#1685](https://github.com/nlohmann/json/issues/1685)\n- Consider putting the user-defined literals in a namespace [\\#1682](https://github.com/nlohmann/json/issues/1682)\n- Change from v2 to v3. Encoding with cp1252 [\\#1680](https://github.com/nlohmann/json/issues/1680)\n- How to add Fifo\\_map into json using Cmake [\\#1679](https://github.com/nlohmann/json/issues/1679)\n- include.zip should contain meson.build [\\#1672](https://github.com/nlohmann/json/issues/1672)\n- \\[Question\\] How do I parse JSON into custom types? [\\#1669](https://github.com/nlohmann/json/issues/1669)\n- Binary \\(0x05\\) data type for BSON to JSON conversion [\\#1668](https://github.com/nlohmann/json/issues/1668)\n- Possible to call dump from lldb? [\\#1666](https://github.com/nlohmann/json/issues/1666)\n- Segmentation fault when linked with libunwind [\\#1665](https://github.com/nlohmann/json/issues/1665)\n- Should I include single-header after my to\\_json and from\\_json custom functions declaration? Why not? [\\#1663](https://github.com/nlohmann/json/issues/1663)\n- Errors/Warnings in VS 2019 when Including Header File [\\#1659](https://github.com/nlohmann/json/issues/1659)\n- Return null object from object's const operator\\[\\] as well. [\\#1658](https://github.com/nlohmann/json/issues/1658)\n- Can't stream json object in to std::basic\\_stringstream\\<wchar\\_t\\> [\\#1656](https://github.com/nlohmann/json/issues/1656)\n- C2440 in vs2015 cannot convert from 'initializer-list' to nlohmann::basic\\_json [\\#1655](https://github.com/nlohmann/json/issues/1655)\n- Issues around get and pointers [\\#1653](https://github.com/nlohmann/json/issues/1653)\n- Non-member operator== breaks enum \\(de\\)serialization [\\#1647](https://github.com/nlohmann/json/issues/1647)\n- Valgrind: bytes in 1 blocks are definitely lost [\\#1646](https://github.com/nlohmann/json/issues/1646)\n- Convenient way to make 'basic\\_json' accept 'QString' as an key type as well? [\\#1640](https://github.com/nlohmann/json/issues/1640)\n- mongodb: nan, inf [\\#1599](https://github.com/nlohmann/json/issues/1599)\n- Error in adl\\_serializer [\\#1590](https://github.com/nlohmann/json/issues/1590)\n- Injecting class during serialization [\\#1584](https://github.com/nlohmann/json/issues/1584)\n- output\\_adapter not user extensible [\\#1534](https://github.com/nlohmann/json/issues/1534)\n- Inclusion of nlohmann/json.hpp causes OS/ABI to change on Linux [\\#1410](https://github.com/nlohmann/json/issues/1410)\n- Add library versioning using inline namespaces [\\#1394](https://github.com/nlohmann/json/issues/1394)\n- CBOR byte string support [\\#1129](https://github.com/nlohmann/json/issues/1129)\n- How to deserialize array with derived objects [\\#716](https://github.com/nlohmann/json/issues/716)\n\n- Add restriction for tuple specialization of to\\_json [\\#1826](https://github.com/nlohmann/json/pull/1826) ([cbegue](https://github.com/cbegue))\n- Fix for \\#1647 [\\#1821](https://github.com/nlohmann/json/pull/1821) ([AnthonyVH](https://github.com/AnthonyVH))\n- Fix issue \\#1805 [\\#1806](https://github.com/nlohmann/json/pull/1806) ([cbegue](https://github.com/cbegue))\n- Fix some spelling errors - mostly in comments & documentation. [\\#1803](https://github.com/nlohmann/json/pull/1803) ([flopp](https://github.com/flopp))\n- Update Hedley to v11. [\\#1799](https://github.com/nlohmann/json/pull/1799) ([nemequ](https://github.com/nemequ))\n- iteration\\_proxy: Fix integer truncation from std::size\\_t to int [\\#1797](https://github.com/nlohmann/json/pull/1797) ([t-b](https://github.com/t-b))\n- appveyor.yml: Add MSVC 16 2019 support [\\#1780](https://github.com/nlohmann/json/pull/1780) ([t-b](https://github.com/t-b))\n- test/CMakeLists.txt: Use an explicit list instead of GLOB [\\#1779](https://github.com/nlohmann/json/pull/1779) ([t-b](https://github.com/t-b))\n- Make json\\_pointer::back const \\(resolves \\#1764\\) [\\#1769](https://github.com/nlohmann/json/pull/1769) ([chris0x44](https://github.com/chris0x44))\n- did you mean 'serialization'? [\\#1767](https://github.com/nlohmann/json/pull/1767) ([0xflotus](https://github.com/0xflotus))\n- Allow items\\(\\) to be used with custom string [\\#1765](https://github.com/nlohmann/json/pull/1765) ([crazyjul](https://github.com/crazyjul))\n- Cppcheck fixes [\\#1760](https://github.com/nlohmann/json/pull/1760) ([Xav83](https://github.com/Xav83))\n- Fix and add test's for SFINAE problem [\\#1741](https://github.com/nlohmann/json/pull/1741) ([tete17](https://github.com/tete17))\n- Fix clang sanitizer invocation [\\#1728](https://github.com/nlohmann/json/pull/1728) ([t-b](https://github.com/t-b))\n- Add gcc 9 and compile with experimental C++20 support [\\#1724](https://github.com/nlohmann/json/pull/1724) ([t-b](https://github.com/t-b))\n- Fix int64 min issue [\\#1722](https://github.com/nlohmann/json/pull/1722) ([t-b](https://github.com/t-b))\n- release: add singleinclude and meson.build to include.zip [\\#1694](https://github.com/nlohmann/json/pull/1694) ([eli-schwartz](https://github.com/eli-schwartz))\n\n## [v3.7.0](https://github.com/nlohmann/json/releases/tag/v3.7.0) (2019-07-28)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.1...v3.7.0)\n\n- How can I retrieve uknown strings from json file in my C++ program. [\\#1684](https://github.com/nlohmann/json/issues/1684)\n- contains\\(\\) is sometimes causing stack-based buffer overrun exceptions [\\#1683](https://github.com/nlohmann/json/issues/1683)\n- How to deserialize arrays  from json [\\#1681](https://github.com/nlohmann/json/issues/1681)\n- Compilation failed in VS2015 [\\#1678](https://github.com/nlohmann/json/issues/1678)\n- Why the compiled object file is so huge? [\\#1677](https://github.com/nlohmann/json/issues/1677)\n- From Version 2.1.1 to 3.6.1 serialize std::set [\\#1676](https://github.com/nlohmann/json/issues/1676)\n- Qt deprecation model halting compiltion [\\#1675](https://github.com/nlohmann/json/issues/1675)\n-  Build For Raspberry pi , Rapbery with new Compiler C++17 [\\#1671](https://github.com/nlohmann/json/issues/1671)\n- Build from Raspberry pi [\\#1667](https://github.com/nlohmann/json/issues/1667)\n- Can not translate map with integer key to dict string ?  [\\#1664](https://github.com/nlohmann/json/issues/1664)\n- Double type converts to scientific notation [\\#1661](https://github.com/nlohmann/json/issues/1661)\n- Missing v3.6.1 tag on master branch [\\#1657](https://github.com/nlohmann/json/issues/1657)\n- Support Fleese Binary Data Format [\\#1654](https://github.com/nlohmann/json/issues/1654)\n- Suggestion: replace alternative tokens for !, && and || with their symbols [\\#1652](https://github.com/nlohmann/json/issues/1652)\n- Build failure test-allocator.vcxproj [\\#1651](https://github.com/nlohmann/json/issues/1651)\n- How to provide function json& to\\_json\\(\\) which is similar as 'void to\\_json\\(json&j, const CObject& obj\\)'  ? [\\#1650](https://github.com/nlohmann/json/issues/1650)\n- Can't throw exception when starting file is a number [\\#1649](https://github.com/nlohmann/json/issues/1649)\n- to\\_json / from\\_json with nested type [\\#1648](https://github.com/nlohmann/json/issues/1648)\n- How to create a json object from a std::string, created by j.dump? [\\#1645](https://github.com/nlohmann/json/issues/1645)\n- Problem getting vector \\(array\\) of strings [\\#1644](https://github.com/nlohmann/json/issues/1644)\n- json.hpp compilation issue with other typedefs with same name [\\#1642](https://github.com/nlohmann/json/issues/1642)\n- nlohmann::adl\\_serializer\\<T,void\\>::to\\_json no matching overloaded function found [\\#1641](https://github.com/nlohmann/json/issues/1641)\n- overwrite adl\\_serializer\\<bool, void\\> to change behaviour [\\#1638](https://github.com/nlohmann/json/issues/1638)\n- json.SelectToken\\(\"Manufacturers.Products.Price\"\\); [\\#1637](https://github.com/nlohmann/json/issues/1637)\n- Add json type as value [\\#1636](https://github.com/nlohmann/json/issues/1636)\n- Unit conversion test error: conversion from 'nlohmann::json' to non-scalar type 'std::string\\_view' requested [\\#1634](https://github.com/nlohmann/json/issues/1634)\n- nlohmann VS JsonCpp by C++17 [\\#1633](https://github.com/nlohmann/json/issues/1633)\n- To integrate an inline helper function that return type name as string [\\#1632](https://github.com/nlohmann/json/issues/1632)\n- Return JSON as reference [\\#1631](https://github.com/nlohmann/json/issues/1631)\n- Updating from an older version causes problems with assing a json object to a struct [\\#1630](https://github.com/nlohmann/json/issues/1630)\n- Can without default constructor function for user defined classes when only to\\_json is needed? [\\#1629](https://github.com/nlohmann/json/issues/1629)\n- Compilation fails with clang 6.x-8.x in C++14 mode [\\#1628](https://github.com/nlohmann/json/issues/1628)\n- Treating floating point as string [\\#1627](https://github.com/nlohmann/json/issues/1627)\n- error parsing character å [\\#1626](https://github.com/nlohmann/json/issues/1626)\n- \\[Help\\] How to Improve Json Output Performance with Large Json Arrays [\\#1624](https://github.com/nlohmann/json/issues/1624)\n- Suggested link changes for reporting new issues \\[blob/develop/REAME.md and blob/develop/.github/CONTRIBUTING.md\\] [\\#1623](https://github.com/nlohmann/json/issues/1623)\n- Broken link to issue template in CONTRIBUTING.md [\\#1622](https://github.com/nlohmann/json/issues/1622)\n- Missing word in README.md file  [\\#1621](https://github.com/nlohmann/json/issues/1621)\n- Package manager instructions in README for brew is incorrect [\\#1620](https://github.com/nlohmann/json/issues/1620)\n- Building with Visual Studio 2019 [\\#1619](https://github.com/nlohmann/json/issues/1619)\n- Precedence of to\\_json and builtin harmful [\\#1617](https://github.com/nlohmann/json/issues/1617)\n- The type json is missing from the html documentation [\\#1616](https://github.com/nlohmann/json/issues/1616)\n- variant is not support in Release 3.6.1? [\\#1615](https://github.com/nlohmann/json/issues/1615)\n- Replace assert with throw for const operator\\[\\] [\\#1614](https://github.com/nlohmann/json/issues/1614)\n- Memory Overhead is Too High \\(10x or more\\) [\\#1613](https://github.com/nlohmann/json/issues/1613)\n- program crash everytime, when other data type incomming in json stream as expected [\\#1612](https://github.com/nlohmann/json/issues/1612)\n- Improved Enum Support [\\#1611](https://github.com/nlohmann/json/issues/1611)\n- is it possible convert json object back to stl container ? [\\#1610](https://github.com/nlohmann/json/issues/1610)\n- Add C++17-like emplace.back\\(\\) for arrays. [\\#1609](https://github.com/nlohmann/json/issues/1609)\n- is\\_nothrow\\_copy\\_constructible fails for json::const\\_iterator on MSVC2015 x86 Debug build [\\#1608](https://github.com/nlohmann/json/issues/1608)\n- Reading and writing array elements [\\#1607](https://github.com/nlohmann/json/issues/1607)\n- Converting json::value to int [\\#1605](https://github.com/nlohmann/json/issues/1605)\n- I have a vector of keys and and a string of value and i want to create nested json array [\\#1604](https://github.com/nlohmann/json/issues/1604)\n- In compatible JSON object from nlohmann::json to nohman::json - unexpected end of input; expected '\\[', '{', or a literal [\\#1603](https://github.com/nlohmann/json/issues/1603)\n- json parser crash if having a large number integer in message  [\\#1602](https://github.com/nlohmann/json/issues/1602)\n- Value method with undocumented throwing 302 exception [\\#1601](https://github.com/nlohmann/json/issues/1601)\n- Accessing value with json pointer adds key if not existing [\\#1600](https://github.com/nlohmann/json/issues/1600)\n- README.md broken link to project documentation [\\#1597](https://github.com/nlohmann/json/issues/1597)\n- Random Kudos: Thanks for your work on this! [\\#1596](https://github.com/nlohmann/json/issues/1596)\n- json::parse return value and errors [\\#1595](https://github.com/nlohmann/json/issues/1595)\n- initializer list constructor makes curly brace initialization fragile [\\#1594](https://github.com/nlohmann/json/issues/1594)\n- trying to log message for missing keyword, difference between \\[\"foo\"\\] and at\\(\"foo\"\\) [\\#1593](https://github.com/nlohmann/json/issues/1593)\n- std::string and std::wstring `to_json`  [\\#1592](https://github.com/nlohmann/json/issues/1592)\n- I have a C structure which I need to convert to a JSON. How do I do it? Haven't found proper examples so far. [\\#1591](https://github.com/nlohmann/json/issues/1591)\n- dump\\_escaped possible error ? [\\#1589](https://github.com/nlohmann/json/issues/1589)\n- json::parse\\(\\) into a vector\\<string\\> results in unhandled exception [\\#1587](https://github.com/nlohmann/json/issues/1587)\n- push\\_back\\(\\)/emplace\\_back\\(\\) on array invalidates pointers to existing array items [\\#1586](https://github.com/nlohmann/json/issues/1586)\n- Getting nlohmann::detail::parse\\_error on JSON generated by nlohmann::json not sure why [\\#1583](https://github.com/nlohmann/json/issues/1583)\n- getting error terminate called after throwing an instance of 'std::domain\\_error'   what\\(\\):  cannot use at\\(\\) with string [\\#1582](https://github.com/nlohmann/json/issues/1582)\n- how i create json file  [\\#1581](https://github.com/nlohmann/json/issues/1581)\n- prevent rounding of double datatype values [\\#1580](https://github.com/nlohmann/json/issues/1580)\n- Documentation Container Overview Doesn't Reference Const Methods [\\#1579](https://github.com/nlohmann/json/issues/1579)\n- Writing an array into a nlohmann::json object [\\#1578](https://github.com/nlohmann/json/issues/1578)\n- compilation error when using with another library [\\#1577](https://github.com/nlohmann/json/issues/1577)\n- Homebrew on OSX doesn't install cmake config file [\\#1576](https://github.com/nlohmann/json/issues/1576)\n- JSON Parse Out of Range Error [\\#1574](https://github.com/nlohmann/json/issues/1574)\n- Integrating into existing CMake Project [\\#1573](https://github.com/nlohmann/json/issues/1573)\n- conversion to std::string failed [\\#1571](https://github.com/nlohmann/json/issues/1571)\n- jPtr operation does not throw [\\#1569](https://github.com/nlohmann/json/issues/1569)\n- How to generate dll file for this project [\\#1568](https://github.com/nlohmann/json/issues/1568)\n- how to pass variable data to json in c [\\#1567](https://github.com/nlohmann/json/issues/1567)\n- I want to achieve an upgraded function. [\\#1566](https://github.com/nlohmann/json/issues/1566)\n- How to determine the type of elements read from a JSON array? [\\#1564](https://github.com/nlohmann/json/issues/1564)\n- try\\_get\\_to [\\#1563](https://github.com/nlohmann/json/issues/1563)\n- example code  compile error [\\#1562](https://github.com/nlohmann/json/issues/1562)\n- How to iterate over nested json object [\\#1561](https://github.com/nlohmann/json/issues/1561)\n- Build Option/Separate Function to Allow to Throw on Duplicate Keys [\\#1560](https://github.com/nlohmann/json/issues/1560)\n- Compiler Switches -Weffc++ & -Wshadow are throwing errors [\\#1558](https://github.com/nlohmann/json/issues/1558)\n- warning: use of the 'nodiscard' attribute is a C++17 extension [\\#1557](https://github.com/nlohmann/json/issues/1557)\n- Import/Export compressed JSON files [\\#1556](https://github.com/nlohmann/json/issues/1556)\n- GDB renderers for json library [\\#1554](https://github.com/nlohmann/json/issues/1554)\n- Is it possible to construct a json string object from a binary buffer? [\\#1553](https://github.com/nlohmann/json/issues/1553)\n- json objects in list [\\#1552](https://github.com/nlohmann/json/issues/1552)\n- Matrix output [\\#1550](https://github.com/nlohmann/json/issues/1550)\n- Using json merge\\_patch on ordered non-alphanumeric datasets [\\#1549](https://github.com/nlohmann/json/issues/1549)\n- Invalid parsed value for big integer [\\#1548](https://github.com/nlohmann/json/issues/1548)\n- Integrating with android ndk issues. [\\#1547](https://github.com/nlohmann/json/issues/1547)\n- add noexcept json::value\\(\"key\", default\\) method variant? [\\#1546](https://github.com/nlohmann/json/issues/1546)\n- Thank you! 🙌 [\\#1545](https://github.com/nlohmann/json/issues/1545)\n- Output and input matrix [\\#1544](https://github.com/nlohmann/json/issues/1544)\n- Add regression tests for MSVC [\\#1543](https://github.com/nlohmann/json/issues/1543)\n- \\[Help Needed!\\] Season of Docs [\\#1542](https://github.com/nlohmann/json/issues/1542)\n- program still abort\\(\\) or exit\\(\\) with try catch [\\#1541](https://github.com/nlohmann/json/issues/1541)\n- Have a json::type\\_error exception because of JSON object [\\#1540](https://github.com/nlohmann/json/issues/1540)\n- Using versioned namespaces [\\#1539](https://github.com/nlohmann/json/issues/1539)\n- Quoted numbers [\\#1538](https://github.com/nlohmann/json/issues/1538)\n- Reading a JSON file into an object [\\#1537](https://github.com/nlohmann/json/issues/1537)\n- Releases 3.6.0 and 3.6.1 don't build on conda / windows [\\#1536](https://github.com/nlohmann/json/issues/1536)\n- \\[Clang\\] warning: use of the 'nodiscard' attribute is a C++17 extension \\[-Wc++17-extensions\\] [\\#1535](https://github.com/nlohmann/json/issues/1535)\n- wchar\\_t/std::wstring json can be created but not accessed [\\#1533](https://github.com/nlohmann/json/issues/1533)\n- json stringify [\\#1532](https://github.com/nlohmann/json/issues/1532)\n- How can I use it from gcc on RPI [\\#1528](https://github.com/nlohmann/json/issues/1528)\n- std::pair treated as an array instead of key-value in `std::vector<std::pair<>>` [\\#1520](https://github.com/nlohmann/json/issues/1520)\n- Excessive Memory Usage for Large Json File [\\#1516](https://github.com/nlohmann/json/issues/1516)\n- SAX dumper [\\#1512](https://github.com/nlohmann/json/issues/1512)\n- Conversion to user type containing a std::vector not working with documented approach [\\#1511](https://github.com/nlohmann/json/issues/1511)\n- Inconsistent use of type alias. [\\#1507](https://github.com/nlohmann/json/issues/1507)\n- Is there a current way to represent strings as json int? [\\#1503](https://github.com/nlohmann/json/issues/1503)\n- Intermittent issues with loadJSON [\\#1484](https://github.com/nlohmann/json/issues/1484)\n- use json construct std::string [\\#1462](https://github.com/nlohmann/json/issues/1462)\n- JSON Creation [\\#1461](https://github.com/nlohmann/json/issues/1461)\n- Null bytes in files are treated like EOF [\\#1095](https://github.com/nlohmann/json/issues/1095)\n- Feature: to\\_string\\(const json& j\\); [\\#916](https://github.com/nlohmann/json/issues/916)\n\n- Use GNUInstallDirs instead of hard-coded path. [\\#1673](https://github.com/nlohmann/json/pull/1673) ([ghost](https://github.com/ghost))\n- Package Manager: MSYS2 \\(pacman\\) [\\#1670](https://github.com/nlohmann/json/pull/1670) ([podsvirov](https://github.com/podsvirov))\n- Fix json.hpp compilation issue with other typedefs with same name \\(Issue \\#1642\\) [\\#1643](https://github.com/nlohmann/json/pull/1643) ([kevinlul](https://github.com/kevinlul))\n- Add explicit conversion from json to std::string\\_view in conversion unit test [\\#1639](https://github.com/nlohmann/json/pull/1639) ([taylorhoward92](https://github.com/taylorhoward92))\n- Minor fixes in docs [\\#1625](https://github.com/nlohmann/json/pull/1625) ([nickaein](https://github.com/nickaein))\n- Fix broken links to documentation [\\#1598](https://github.com/nlohmann/json/pull/1598) ([nickaein](https://github.com/nickaein))\n- Added to\\_string and added basic tests [\\#1585](https://github.com/nlohmann/json/pull/1585) ([Macr0Nerd](https://github.com/Macr0Nerd))\n- Regression tests for MSVC [\\#1570](https://github.com/nlohmann/json/pull/1570) ([nickaein](https://github.com/nickaein))\n- Fix/1511 [\\#1555](https://github.com/nlohmann/json/pull/1555) ([theodelrieu](https://github.com/theodelrieu))\n- Remove C++17 extension warning from clang; \\#1535 [\\#1551](https://github.com/nlohmann/json/pull/1551) ([heavywatal](https://github.com/heavywatal))\n- moved from Catch to doctest for unit tests [\\#1439](https://github.com/nlohmann/json/pull/1439) ([onqtam](https://github.com/onqtam))\n\n## [v3.6.1](https://github.com/nlohmann/json/releases/tag/v3.6.1) (2019-03-20)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/3.6.1...v3.6.1)\n\n## [3.6.1](https://github.com/nlohmann/json/releases/tag/3.6.1) (2019-03-20)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.6.0...3.6.1)\n\n- Failed to build with \\<Windows.h\\> [\\#1531](https://github.com/nlohmann/json/issues/1531)\n- Compiling 3.6.0 with GCC \\> 7, array vs std::array \\#590 is back [\\#1530](https://github.com/nlohmann/json/issues/1530)\n- 3.6.0: warning: missing initializer for member 'std::array\\<char, 9ul\\>::\\_M\\_elems' \\[-Wmissing-field-initializers\\] [\\#1527](https://github.com/nlohmann/json/issues/1527)\n- unable to parse json  [\\#1525](https://github.com/nlohmann/json/issues/1525)\n\n## [v3.6.0](https://github.com/nlohmann/json/releases/tag/v3.6.0) (2019-03-19)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.5.0...v3.6.0)\n\n- How can I turn a string of a json array into a json array? [\\#1526](https://github.com/nlohmann/json/issues/1526)\n- Minor: missing a std:: namespace tag [\\#1521](https://github.com/nlohmann/json/issues/1521)\n- how to precision to four decimal for double when use to\\_json [\\#1519](https://github.com/nlohmann/json/issues/1519)\n- error parse [\\#1518](https://github.com/nlohmann/json/issues/1518)\n- Compile error: template argument deduction/substitution failed [\\#1515](https://github.com/nlohmann/json/issues/1515)\n- std::complex type [\\#1510](https://github.com/nlohmann/json/issues/1510)\n- CBOR byte string support [\\#1509](https://github.com/nlohmann/json/issues/1509)\n- Compilation error getting a std::pair\\<\\> on latest VS 2017 compiler [\\#1506](https://github.com/nlohmann/json/issues/1506)\n- \"Integration\" section of documentation needs update? [\\#1505](https://github.com/nlohmann/json/issues/1505)\n- Json object from string from a TCP socket [\\#1504](https://github.com/nlohmann/json/issues/1504)\n- MSVC warning C4946 \\(\"reinterpret\\_cast used between related classes\"\\) compiling json.hpp [\\#1502](https://github.com/nlohmann/json/issues/1502)\n- How to programmatically fill an n-th dimensional JSON object? [\\#1501](https://github.com/nlohmann/json/issues/1501)\n- Error compiling with clang and `JSON_NOEXCEPTION`: need to include `cstdlib` [\\#1500](https://github.com/nlohmann/json/issues/1500)\n- The code compiles unsuccessfully with android-ndk-r10e [\\#1499](https://github.com/nlohmann/json/issues/1499)\n- Cmake 3.1 in develop, when is it likely to make it into a stable release? [\\#1498](https://github.com/nlohmann/json/issues/1498)\n- Some Help please object inside array [\\#1494](https://github.com/nlohmann/json/issues/1494)\n- How to get data into vector of user-defined type from a Json object [\\#1493](https://github.com/nlohmann/json/issues/1493)\n- how to find subelement  without loop [\\#1490](https://github.com/nlohmann/json/issues/1490)\n- json to std::map [\\#1487](https://github.com/nlohmann/json/issues/1487)\n- Type in README.md [\\#1486](https://github.com/nlohmann/json/issues/1486)\n- Error in parsing and reading msgpack-lite  [\\#1485](https://github.com/nlohmann/json/issues/1485)\n- Compiling issues with libc 2.12 [\\#1483](https://github.com/nlohmann/json/issues/1483)\n- How do I use reference or pointer binding values? [\\#1482](https://github.com/nlohmann/json/issues/1482)\n- Compilation fails in MSVC with the Microsoft Language Extensions disabled [\\#1481](https://github.com/nlohmann/json/issues/1481)\n- Functional visit [\\#1480](https://github.com/nlohmann/json/issues/1480)\n- \\[Question\\] Unescaped dump [\\#1479](https://github.com/nlohmann/json/issues/1479)\n- Some Help please [\\#1478](https://github.com/nlohmann/json/issues/1478)\n- Global variables are stored within the JSON file, how do I declare them as global variables when I read them out in my C++ program?  [\\#1476](https://github.com/nlohmann/json/issues/1476)\n- Unable to modify one of the values within the JSON file, and save it  [\\#1475](https://github.com/nlohmann/json/issues/1475)\n- Documentation of parse function has two identical @pre causes [\\#1473](https://github.com/nlohmann/json/issues/1473)\n- GCC 9.0 build failure [\\#1472](https://github.com/nlohmann/json/issues/1472)\n- Can we have an `exists()` method? [\\#1471](https://github.com/nlohmann/json/issues/1471)\n- How to parse multi object json from file? [\\#1470](https://github.com/nlohmann/json/issues/1470)\n- How to returns the name of the upper object? [\\#1467](https://github.com/nlohmann/json/issues/1467)\n- Error: \"tuple\\_size\" has already been declared in the current scope [\\#1466](https://github.com/nlohmann/json/issues/1466)\n- Checking keys of two jsons against eachother [\\#1465](https://github.com/nlohmann/json/issues/1465)\n- Disable installation when used as meson subproject [\\#1463](https://github.com/nlohmann/json/issues/1463)\n- Unpack list of integers to a std::vector\\<int\\> [\\#1460](https://github.com/nlohmann/json/issues/1460)\n- Implement DRY definition of JSON representation of a c++ class  [\\#1459](https://github.com/nlohmann/json/issues/1459)\n- json.exception.type\\_error.305 with GCC 4.9 when using C++ {} initializer [\\#1458](https://github.com/nlohmann/json/issues/1458)\n- API to convert an \"uninitialized\" json into an empty object or empty array [\\#1456](https://github.com/nlohmann/json/issues/1456)\n- How to parse a vector of objects with const attributes [\\#1453](https://github.com/nlohmann/json/issues/1453)\n- NLOHMANN\\_JSON\\_SERIALIZE\\_ENUM potentially requires duplicate definitions [\\#1450](https://github.com/nlohmann/json/issues/1450)\n- Question about making json object from file directory [\\#1449](https://github.com/nlohmann/json/issues/1449)\n- .get\\(\\) throws error if used with userdefined structs in unordered\\_map [\\#1448](https://github.com/nlohmann/json/issues/1448)\n- Integer Overflow \\(OSS-Fuzz 12506\\) [\\#1447](https://github.com/nlohmann/json/issues/1447)\n- If a string has too many invalid UTF-8 characters, json::dump attempts to index an array out of bounds. [\\#1445](https://github.com/nlohmann/json/issues/1445)\n- Setting values of .JSON file [\\#1444](https://github.com/nlohmann/json/issues/1444)\n- alias object\\_t::key\\_type in basic\\_json [\\#1442](https://github.com/nlohmann/json/issues/1442)\n- Latest Ubuntu package is 2.1.1 [\\#1438](https://github.com/nlohmann/json/issues/1438)\n- lexer.hpp\\(1363\\)  '\\_snprintf': is not a  member | Visualstudio 2017 [\\#1437](https://github.com/nlohmann/json/issues/1437)\n- Static method invites inadvertent logic error. [\\#1433](https://github.com/nlohmann/json/issues/1433)\n- EOS compilation produces \"fatal error: 'nlohmann/json.hpp' file not found\" [\\#1432](https://github.com/nlohmann/json/issues/1432)\n- Support for bad commas [\\#1429](https://github.com/nlohmann/json/issues/1429)\n- Please have one base exception class for all json exceptions [\\#1427](https://github.com/nlohmann/json/issues/1427)\n- Compilation warning: 'tuple\\_size' defined as a class template here but previously declared as a struct template [\\#1426](https://github.com/nlohmann/json/issues/1426)\n- Which version can be used with GCC 4.8.2 ? [\\#1424](https://github.com/nlohmann/json/issues/1424)\n- Ignore nullptr values on constructing json object from a container [\\#1422](https://github.com/nlohmann/json/issues/1422)\n- Support for custom float precision via unquoted strings [\\#1421](https://github.com/nlohmann/json/issues/1421)\n- It is possible to call `json::find` with a json\\_pointer as argument. This causes runtime UB/crash. [\\#1418](https://github.com/nlohmann/json/issues/1418)\n- Dump throwing exception [\\#1416](https://github.com/nlohmann/json/issues/1416)\n- Build error  [\\#1415](https://github.com/nlohmann/json/issues/1415)\n- Append version to include.zip [\\#1412](https://github.com/nlohmann/json/issues/1412)\n- error C2039: '\\_snprintf': is not a member of 'std' - Windows [\\#1408](https://github.com/nlohmann/json/issues/1408)\n- Deserializing to vector [\\#1407](https://github.com/nlohmann/json/issues/1407)\n- Efficient way to set a `json` object as value into another `json` key [\\#1406](https://github.com/nlohmann/json/issues/1406)\n- Document return value of parse\\(\\) when allow\\_exceptions == false and parsing fails [\\#1405](https://github.com/nlohmann/json/issues/1405)\n- Unexpected behaviour with structured binding [\\#1404](https://github.com/nlohmann/json/issues/1404)\n- Which native types does get\\<type\\>\\(\\) allow? [\\#1403](https://github.com/nlohmann/json/issues/1403)\n- Add something like Json::StaticString [\\#1402](https://github.com/nlohmann/json/issues/1402)\n- -Wmismatched-tags in 3.5.0? [\\#1401](https://github.com/nlohmann/json/issues/1401)\n- Coverity Scan reports an UNCAUGHT\\_EXCEPT issue [\\#1400](https://github.com/nlohmann/json/issues/1400)\n- fff [\\#1399](https://github.com/nlohmann/json/issues/1399)\n- sorry this is not an issue, just a Question, How to change a key value in a file and save it ? [\\#1398](https://github.com/nlohmann/json/issues/1398)\n- appveyor x64 builds appear to be using Win32 toolset [\\#1374](https://github.com/nlohmann/json/issues/1374)\n- Serializing/Deserializing  a Class containing a vector of itself [\\#1373](https://github.com/nlohmann/json/issues/1373)\n- Retrieving array elements. [\\#1369](https://github.com/nlohmann/json/issues/1369)\n- Deserialize [\\#1366](https://github.com/nlohmann/json/issues/1366)\n- call of overloaded for push\\_back and operator+= is ambiguous [\\#1352](https://github.com/nlohmann/json/issues/1352)\n- got an error and cann't figure it out [\\#1351](https://github.com/nlohmann/json/issues/1351)\n- Improve number-to-string conversion [\\#1334](https://github.com/nlohmann/json/issues/1334)\n- Implicit type conversion error on MSVC [\\#1333](https://github.com/nlohmann/json/issues/1333)\n- NuGet Package [\\#1132](https://github.com/nlohmann/json/issues/1132)\n\n- Change macros to numeric\\_limits [\\#1514](https://github.com/nlohmann/json/pull/1514) ([naszta](https://github.com/naszta))\n- fix GCC 7.1.1 - 7.2.1 on CentOS [\\#1496](https://github.com/nlohmann/json/pull/1496) ([lieff](https://github.com/lieff))\n- Update Buckaroo instructions in README.md [\\#1495](https://github.com/nlohmann/json/pull/1495) ([njlr](https://github.com/njlr))\n- Fix gcc9 build error test/src/unit-allocator.cpp \\(Issue \\#1472\\) [\\#1492](https://github.com/nlohmann/json/pull/1492) ([stac47](https://github.com/stac47))\n- Fix typo in README.md [\\#1491](https://github.com/nlohmann/json/pull/1491) ([nickaein](https://github.com/nickaein))\n- Do proper endian conversions [\\#1489](https://github.com/nlohmann/json/pull/1489) ([andreas-schwab](https://github.com/andreas-schwab))\n- Fix documentation [\\#1477](https://github.com/nlohmann/json/pull/1477) ([nickaein](https://github.com/nickaein))\n- Implement contains\\(\\) member function [\\#1474](https://github.com/nlohmann/json/pull/1474) ([nickaein](https://github.com/nickaein))\n- Add operator/= and operator/ to construct a JSON pointer by appending two JSON pointers [\\#1469](https://github.com/nlohmann/json/pull/1469) ([garethsb](https://github.com/garethsb))\n- Disable Clang -Wmismatched-tags warning on tuple\\_size / tuple\\_element [\\#1468](https://github.com/nlohmann/json/pull/1468) ([past-due](https://github.com/past-due))\n- Disable installation when used as meson subproject. \\#1463 [\\#1464](https://github.com/nlohmann/json/pull/1464) ([elvisoric](https://github.com/elvisoric))\n- docs: README typo [\\#1455](https://github.com/nlohmann/json/pull/1455) ([wythe](https://github.com/wythe))\n- remove extra semicolon from readme [\\#1451](https://github.com/nlohmann/json/pull/1451) ([Afforix](https://github.com/Afforix))\n- attempt to fix \\#1445, flush buffer in serializer::dump\\_escaped in UTF8\\_REJECT case. [\\#1446](https://github.com/nlohmann/json/pull/1446) ([scinart](https://github.com/scinart))\n- Use C++11 features supported by CMake 3.1. [\\#1441](https://github.com/nlohmann/json/pull/1441) ([iwanders](https://github.com/iwanders))\n- :rotating\\_light: fixed unused variable warning [\\#1435](https://github.com/nlohmann/json/pull/1435) ([pboettch](https://github.com/pboettch))\n- allow push\\_back\\(\\) and pop\\_back\\(\\) calls on json\\_pointer [\\#1434](https://github.com/nlohmann/json/pull/1434) ([pboettch](https://github.com/pboettch))\n- Add instructions about using nlohmann/json with the conda package manager [\\#1430](https://github.com/nlohmann/json/pull/1430) ([nicoddemus](https://github.com/nicoddemus))\n- Updated year in README.md [\\#1425](https://github.com/nlohmann/json/pull/1425) ([jef](https://github.com/jef))\n- Fixed broken links in the README file [\\#1423](https://github.com/nlohmann/json/pull/1423) ([skypjack](https://github.com/skypjack))\n- Fixed broken links in the README file [\\#1420](https://github.com/nlohmann/json/pull/1420) ([skypjack](https://github.com/skypjack))\n- docs: typo in README [\\#1417](https://github.com/nlohmann/json/pull/1417) ([wythe](https://github.com/wythe))\n- Fix x64 target platform for appveyor [\\#1414](https://github.com/nlohmann/json/pull/1414) ([nickaein](https://github.com/nickaein))\n- Improve dump\\_integer performance [\\#1411](https://github.com/nlohmann/json/pull/1411) ([nickaein](https://github.com/nickaein))\n- buildsystem: relax requirement on cmake version [\\#1409](https://github.com/nlohmann/json/pull/1409) ([yann-morin-1998](https://github.com/yann-morin-1998))\n- CMake: Optional Install if Embedded [\\#1330](https://github.com/nlohmann/json/pull/1330) ([ax3l](https://github.com/ax3l))\n\n## [v3.5.0](https://github.com/nlohmann/json/releases/tag/v3.5.0) (2018-12-21)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.4.0...v3.5.0)\n\n- Copyconstructor inserts original into array with single element [\\#1397](https://github.com/nlohmann/json/issues/1397)\n- Get value without explicit typecasting [\\#1395](https://github.com/nlohmann/json/issues/1395)\n- Big file parsing [\\#1393](https://github.com/nlohmann/json/issues/1393)\n- Adding Structured Binding Support [\\#1388](https://github.com/nlohmann/json/issues/1388)\n- map\\<json::value\\_t, string\\> exhibits unexpected behavior [\\#1387](https://github.com/nlohmann/json/issues/1387)\n- Error Code Return [\\#1386](https://github.com/nlohmann/json/issues/1386)\n- using unordered\\_map as object type [\\#1385](https://github.com/nlohmann/json/issues/1385)\n- float precision [\\#1384](https://github.com/nlohmann/json/issues/1384)\n- \\[json.exception.type\\_error.316\\] invalid UTF-8 byte at index 1: 0xC3 [\\#1383](https://github.com/nlohmann/json/issues/1383)\n- Inconsistent Constructor \\(GCC vs. Clang\\) [\\#1381](https://github.com/nlohmann/json/issues/1381)\n- \\#define or || [\\#1379](https://github.com/nlohmann/json/issues/1379)\n- How to iterate inside the values ? [\\#1377](https://github.com/nlohmann/json/issues/1377)\n- items\\(\\) unable to get the elements [\\#1375](https://github.com/nlohmann/json/issues/1375)\n- conversion json to std::map doesn't work for types \\<int, double\\>  [\\#1372](https://github.com/nlohmann/json/issues/1372)\n- A minor issue in the build instructions [\\#1371](https://github.com/nlohmann/json/issues/1371)\n- Using this library without stream ? [\\#1370](https://github.com/nlohmann/json/issues/1370)\n- Writing and reading BSON data [\\#1368](https://github.com/nlohmann/json/issues/1368)\n- Retrieving array elements from object type iterator. [\\#1367](https://github.com/nlohmann/json/issues/1367)\n- json::dump\\(\\) silently crashes if items contain accented letters [\\#1365](https://github.com/nlohmann/json/issues/1365)\n- warnings in MSVC \\(2015\\) in 3.4.0 related to bool... [\\#1364](https://github.com/nlohmann/json/issues/1364)\n- Cant compile with -C++17 and beyond compiler options [\\#1362](https://github.com/nlohmann/json/issues/1362)\n- json to concrete type conversion through reference or pointer fails [\\#1361](https://github.com/nlohmann/json/issues/1361)\n- the first attributes of JSON string is misplaced  [\\#1360](https://github.com/nlohmann/json/issues/1360)\n- Copy-construct using initializer-list converts objects to arrays [\\#1359](https://github.com/nlohmann/json/issues/1359)\n- About value\\(key, default\\_value\\) and operator\\[\\]\\(key\\)  [\\#1358](https://github.com/nlohmann/json/issues/1358)\n- Problem with printing json response object [\\#1356](https://github.com/nlohmann/json/issues/1356)\n- Serializing pointer segfaults [\\#1355](https://github.com/nlohmann/json/issues/1355)\n- Read `long long int` data as a number. [\\#1354](https://github.com/nlohmann/json/issues/1354)\n- eclipse oxygen in ubuntu get\\<size\\_t\\> is ambiguous  [\\#1353](https://github.com/nlohmann/json/issues/1353)\n- Can't build on Visual Studio 2017 v15.8.9 [\\#1350](https://github.com/nlohmann/json/issues/1350)\n- cannot parse from string? [\\#1349](https://github.com/nlohmann/json/issues/1349)\n- Error: out\\_of\\_range [\\#1348](https://github.com/nlohmann/json/issues/1348)\n- expansion pattern 'CompatibleObjectType' contains no argument packs, with CUDA 10 [\\#1347](https://github.com/nlohmann/json/issues/1347)\n- Unable to update a value for a nested\\(multi-level\\) json file [\\#1344](https://github.com/nlohmann/json/issues/1344)\n- Fails to compile when std::iterator\\_traits is not SFINAE friendly. [\\#1341](https://github.com/nlohmann/json/issues/1341)\n- EOF flag not set on exhausted input streams. [\\#1340](https://github.com/nlohmann/json/issues/1340)\n- Shadowed Member in merge\\_patch [\\#1339](https://github.com/nlohmann/json/issues/1339)\n- Periods/literal dots in keys? [\\#1338](https://github.com/nlohmann/json/issues/1338)\n- Protect macro expansion of commonly defined macros [\\#1337](https://github.com/nlohmann/json/issues/1337)\n- How to validate an input before parsing? [\\#1336](https://github.com/nlohmann/json/issues/1336)\n- Non-verifying dump\\(\\) alternative for debugging/logging needed [\\#1335](https://github.com/nlohmann/json/issues/1335)\n- Json Libarary is not responding for me in c++ [\\#1332](https://github.com/nlohmann/json/issues/1332)\n- Question - how to find an object in an array [\\#1331](https://github.com/nlohmann/json/issues/1331)\n- Nesting additional data in json object [\\#1328](https://github.com/nlohmann/json/issues/1328)\n- can to\\_json\\(\\) be defined inside a class? [\\#1324](https://github.com/nlohmann/json/issues/1324)\n- CodeBlocks IDE can't find `json.hpp` header [\\#1318](https://github.com/nlohmann/json/issues/1318)\n- Change json\\_pointer to provide an iterator begin/end/etc, don't use vectors, and also enable string\\_view [\\#1312](https://github.com/nlohmann/json/issues/1312)\n- Xcode - adding it to library  [\\#1300](https://github.com/nlohmann/json/issues/1300)\n- unicode: accept char16\\_t, char32\\_t sequences [\\#1298](https://github.com/nlohmann/json/issues/1298)\n- unicode: char16\\_t\\* is compiler error, but char16\\_t\\[\\] is accepted [\\#1297](https://github.com/nlohmann/json/issues/1297)\n- Dockerfile Project Help Needed [\\#1296](https://github.com/nlohmann/json/issues/1296)\n- Comparisons between large unsigned and negative signed integers [\\#1295](https://github.com/nlohmann/json/issues/1295)\n- CMake alias to `nlohmann::json` [\\#1291](https://github.com/nlohmann/json/issues/1291)\n- Release zips without tests [\\#1285](https://github.com/nlohmann/json/issues/1285)\n- separate object\\_t::key\\_type from basic\\_json::key\\_type, and use an allocator which returns object\\_t::key\\_type [\\#1274](https://github.com/nlohmann/json/issues/1274)\n- Is there a nice way to associate external values with json elements? [\\#1256](https://github.com/nlohmann/json/issues/1256)\n- Delete by json\\_pointer [\\#1248](https://github.com/nlohmann/json/issues/1248)\n- Expose lexer, as a StAX parser [\\#1219](https://github.com/nlohmann/json/issues/1219)\n- Subclassing json\\(\\) & error on recursive load [\\#1201](https://github.com/nlohmann/json/issues/1201)\n- Check value for existence by json\\_pointer [\\#1194](https://github.com/nlohmann/json/issues/1194)\n\n- Feature/add file input adapter [\\#1392](https://github.com/nlohmann/json/pull/1392) ([dumarjo](https://github.com/dumarjo))\n-  Added Support for Structured Bindings  [\\#1391](https://github.com/nlohmann/json/pull/1391) ([pratikpc](https://github.com/pratikpc))\n- Link to issue \\#958 broken [\\#1382](https://github.com/nlohmann/json/pull/1382) ([kjpus](https://github.com/kjpus))\n- readme: fix typo [\\#1380](https://github.com/nlohmann/json/pull/1380) ([manu-chroma](https://github.com/manu-chroma))\n- recommend using explicit from JSON conversions [\\#1363](https://github.com/nlohmann/json/pull/1363) ([theodelrieu](https://github.com/theodelrieu))\n- Fix merge\\_patch shadow warning [\\#1346](https://github.com/nlohmann/json/pull/1346) ([ax3l](https://github.com/ax3l))\n- Allow installation via Meson [\\#1345](https://github.com/nlohmann/json/pull/1345) ([mpoquet](https://github.com/mpoquet))\n- Set eofbit on exhausted input stream. [\\#1343](https://github.com/nlohmann/json/pull/1343) ([mefyl](https://github.com/mefyl))\n- Add a SFINAE friendly iterator\\_traits and use that instead. [\\#1342](https://github.com/nlohmann/json/pull/1342) ([dgavedissian](https://github.com/dgavedissian))\n- Fix EOL Whitespaces & CMake Spelling [\\#1329](https://github.com/nlohmann/json/pull/1329) ([ax3l](https://github.com/ax3l))\n\n## [v3.4.0](https://github.com/nlohmann/json/releases/tag/v3.4.0) (2018-10-30)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0)\n\n- Big uint64\\_t values are serialized wrong [\\#1327](https://github.com/nlohmann/json/issues/1327)\n- \\[Question\\] Efficient check for equivalency? [\\#1325](https://github.com/nlohmann/json/issues/1325)\n- Can't use ifstream and .clear\\(\\) [\\#1321](https://github.com/nlohmann/json/issues/1321)\n- \\[Warning\\] -Wparentheses on line 555 on single\\_include [\\#1319](https://github.com/nlohmann/json/issues/1319)\n- Compilation error using at and find with enum struct [\\#1316](https://github.com/nlohmann/json/issues/1316)\n- Parsing JSON from a web address [\\#1311](https://github.com/nlohmann/json/issues/1311)\n- How to convert JSON to Struct with embeded subject [\\#1310](https://github.com/nlohmann/json/issues/1310)\n- Null safety/coalescing function? [\\#1309](https://github.com/nlohmann/json/issues/1309)\n- Building fails using single include file: json.hpp [\\#1308](https://github.com/nlohmann/json/issues/1308)\n- json::parse\\(std::string\\) Exception inside packaged Lib [\\#1306](https://github.com/nlohmann/json/issues/1306)\n- Problem in Dockerfile with installation of library [\\#1304](https://github.com/nlohmann/json/issues/1304)\n- compile error in from\\_json converting to container with std::pair [\\#1299](https://github.com/nlohmann/json/issues/1299)\n- Json that I am trying to parse, and I am lost Structure Array below top level [\\#1293](https://github.com/nlohmann/json/issues/1293)\n- Serializing std::variant causes stack overflow [\\#1292](https://github.com/nlohmann/json/issues/1292)\n- How do I go about customising from\\_json to support \\_\\_int128\\_t/\\_\\_uint128\\_t? [\\#1290](https://github.com/nlohmann/json/issues/1290)\n- merge\\_patch: inconsistent behaviour merging empty sub-object [\\#1289](https://github.com/nlohmann/json/issues/1289)\n- Buffer over/underrun using UBJson? [\\#1288](https://github.com/nlohmann/json/issues/1288)\n- Enable the latest C++ standard with Visual Studio [\\#1287](https://github.com/nlohmann/json/issues/1287)\n- truncation of constant value in to\\_cbor\\(\\) [\\#1286](https://github.com/nlohmann/json/issues/1286)\n- eosio.wasmsdk error [\\#1284](https://github.com/nlohmann/json/issues/1284)\n- use the same interface for writing arrays and non-arrays [\\#1283](https://github.com/nlohmann/json/issues/1283)\n- How to read json file with optional  entries and entries with different types [\\#1281](https://github.com/nlohmann/json/issues/1281)\n- merge result not as espected [\\#1279](https://github.com/nlohmann/json/issues/1279)\n- how to get only \"name\" from below json [\\#1278](https://github.com/nlohmann/json/issues/1278)\n- syntax error  on right json string [\\#1276](https://github.com/nlohmann/json/issues/1276)\n- Parsing JSON Array where members have no key, using custom types [\\#1267](https://github.com/nlohmann/json/issues/1267)\n- I get a json exception periodically from json::parse for the same json  [\\#1263](https://github.com/nlohmann/json/issues/1263)\n- serialize std::variant\\<...\\> [\\#1261](https://github.com/nlohmann/json/issues/1261)\n- GCC 8.2.1. Compilation error: invalid conversion from... [\\#1246](https://github.com/nlohmann/json/issues/1246)\n- BSON support [\\#1244](https://github.com/nlohmann/json/issues/1244)\n- enum to json mapping [\\#1208](https://github.com/nlohmann/json/issues/1208)\n- Soften the landing when dumping non-UTF8 strings \\(type\\_error.316 exception\\) [\\#1198](https://github.com/nlohmann/json/issues/1198)\n\n- Add macro to define enum/JSON mapping [\\#1323](https://github.com/nlohmann/json/pull/1323) ([nlohmann](https://github.com/nlohmann))\n- Add BSON support [\\#1320](https://github.com/nlohmann/json/pull/1320) ([nlohmann](https://github.com/nlohmann))\n- Properly convert constants to CharType [\\#1315](https://github.com/nlohmann/json/pull/1315) ([nlohmann](https://github.com/nlohmann))\n- Allow to set error handler for decoding errors [\\#1314](https://github.com/nlohmann/json/pull/1314) ([nlohmann](https://github.com/nlohmann))\n- Add Meson related info to README [\\#1305](https://github.com/nlohmann/json/pull/1305) ([koponomarenko](https://github.com/koponomarenko))\n- Improve diagnostic messages for binary formats [\\#1303](https://github.com/nlohmann/json/pull/1303) ([nlohmann](https://github.com/nlohmann))\n- add new is\\_constructible\\_\\* traits used in from\\_json [\\#1301](https://github.com/nlohmann/json/pull/1301) ([theodelrieu](https://github.com/theodelrieu))\n- add constraints for variadic json\\_ref constructors [\\#1294](https://github.com/nlohmann/json/pull/1294) ([theodelrieu](https://github.com/theodelrieu))\n- Improve diagnostic messages [\\#1282](https://github.com/nlohmann/json/pull/1282) ([nlohmann](https://github.com/nlohmann))\n- Removed linter warnings [\\#1280](https://github.com/nlohmann/json/pull/1280) ([nlohmann](https://github.com/nlohmann))\n- Thirdparty benchmark: Fix Clang detection. [\\#1277](https://github.com/nlohmann/json/pull/1277) ([Lord-Kamina](https://github.com/Lord-Kamina))\n\n## [v3.3.0](https://github.com/nlohmann/json/releases/tag/v3.3.0) (2018-10-05)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/3.3.0...v3.3.0)\n\n- Fix warning C4127: conditional expression is constant [\\#1272](https://github.com/nlohmann/json/pull/1272) ([antonioborondo](https://github.com/antonioborondo))\n- Turn off additional deprecation warnings for GCC. [\\#1271](https://github.com/nlohmann/json/pull/1271) ([chuckatkins](https://github.com/chuckatkins))\n- docs: Add additional CMake documentation [\\#1270](https://github.com/nlohmann/json/pull/1270) ([chuckatkins](https://github.com/chuckatkins))\n- unit-testsuites.cpp: fix hangup if file not found [\\#1262](https://github.com/nlohmann/json/pull/1262) ([knilch0r](https://github.com/knilch0r))\n- Fix broken cmake imported target alias [\\#1260](https://github.com/nlohmann/json/pull/1260) ([chuckatkins](https://github.com/chuckatkins))\n- GCC 48 [\\#1257](https://github.com/nlohmann/json/pull/1257) ([henryiii](https://github.com/henryiii))\n- Add version and license to meson.build [\\#1252](https://github.com/nlohmann/json/pull/1252) ([koponomarenko](https://github.com/koponomarenko))\n- \\#1179 Reordered the code. It seems to stop clang 3.4.2 in RHEL 7 from crash… [\\#1249](https://github.com/nlohmann/json/pull/1249) ([LEgregius](https://github.com/LEgregius))\n- Use a version check to provide backwards comatible CMake imported target names [\\#1245](https://github.com/nlohmann/json/pull/1245) ([chuckatkins](https://github.com/chuckatkins))\n- Fix issue \\#1237 [\\#1238](https://github.com/nlohmann/json/pull/1238) ([theodelrieu](https://github.com/theodelrieu))\n- Add a get overload taking a parameter. [\\#1231](https://github.com/nlohmann/json/pull/1231) ([theodelrieu](https://github.com/theodelrieu))\n- Move lambda out of unevaluated context [\\#1230](https://github.com/nlohmann/json/pull/1230) ([mandreyel](https://github.com/mandreyel))\n- Remove static asserts [\\#1228](https://github.com/nlohmann/json/pull/1228) ([theodelrieu](https://github.com/theodelrieu))\n- Better error 305 [\\#1221](https://github.com/nlohmann/json/pull/1221) ([rivertam](https://github.com/rivertam))\n- Fix \\#1213 [\\#1214](https://github.com/nlohmann/json/pull/1214) ([simnalamburt](https://github.com/simnalamburt))\n- Export package to allow builds without installing [\\#1202](https://github.com/nlohmann/json/pull/1202) ([dennisfischer](https://github.com/dennisfischer))\n\n## [3.3.0](https://github.com/nlohmann/json/releases/tag/3.3.0) (2018-10-05)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.2.0...3.3.0)\n\n- When key is not found print the key name into error too [\\#1273](https://github.com/nlohmann/json/issues/1273)\n- Visual Studio 2017 15.8.5 \"conditional expression is constant\" warning on Line 1851 in json.hpp [\\#1268](https://github.com/nlohmann/json/issues/1268)\n- how can we get this working on WSL? [\\#1264](https://github.com/nlohmann/json/issues/1264)\n- Help needed [\\#1259](https://github.com/nlohmann/json/issues/1259)\n- A way to get to a JSON values \"key\" [\\#1258](https://github.com/nlohmann/json/issues/1258)\n- While compiling got 76 errors [\\#1255](https://github.com/nlohmann/json/issues/1255)\n- Two blackslashes on json output file [\\#1253](https://github.com/nlohmann/json/issues/1253)\n- Including nlohmann the badwrong way. [\\#1250](https://github.com/nlohmann/json/issues/1250)\n- how to build with clang? [\\#1247](https://github.com/nlohmann/json/issues/1247)\n- Cmake target\\_link\\_libraries unable to find nlohmann\\_json since version 3.2.0 [\\#1243](https://github.com/nlohmann/json/issues/1243)\n- \\[Question\\] Access to end\\(\\) iterator reference [\\#1242](https://github.com/nlohmann/json/issues/1242)\n- Parsing different json format [\\#1241](https://github.com/nlohmann/json/issues/1241)\n- Parsing Multiple JSON Files [\\#1240](https://github.com/nlohmann/json/issues/1240)\n- Doesn't compile under C++17 [\\#1239](https://github.com/nlohmann/json/issues/1239)\n- Conversion operator for nlohmann::json is not SFINAE friendly [\\#1237](https://github.com/nlohmann/json/issues/1237)\n- Custom deserialization of number\\_float\\_t [\\#1236](https://github.com/nlohmann/json/issues/1236)\n- deprecated-declarations warnings when compiling tests with GCC 8.2.1. [\\#1233](https://github.com/nlohmann/json/issues/1233)\n- Incomplete type with json\\_fwd.hpp [\\#1232](https://github.com/nlohmann/json/issues/1232)\n- Parse Error [\\#1229](https://github.com/nlohmann/json/issues/1229)\n- json::get function with argument [\\#1227](https://github.com/nlohmann/json/issues/1227)\n- questions regarding from\\_json [\\#1226](https://github.com/nlohmann/json/issues/1226)\n- Lambda in unevaluated context [\\#1225](https://github.com/nlohmann/json/issues/1225)\n- NLohmann doesn't compile when enabling strict warning policies [\\#1224](https://github.com/nlohmann/json/issues/1224)\n- Creating array of objects [\\#1223](https://github.com/nlohmann/json/issues/1223)\n- Somewhat unhelpful error message \"cannot use operator\\[\\] with object\" [\\#1220](https://github.com/nlohmann/json/issues/1220)\n- single\\_include json.hpp [\\#1218](https://github.com/nlohmann/json/issues/1218)\n- Maps with enum class keys which are convertible to JSON strings should be converted to JSON dictionaries [\\#1217](https://github.com/nlohmann/json/issues/1217)\n- Adding JSON Array to the Array  [\\#1216](https://github.com/nlohmann/json/issues/1216)\n- Best way to output a vector of a given type to json [\\#1215](https://github.com/nlohmann/json/issues/1215)\n- compiler warning: double definition of macro JSON\\_INTERNAL\\_CATCH  [\\#1213](https://github.com/nlohmann/json/issues/1213)\n- Compilation error when using MOCK\\_METHOD1 from GMock and nlohmann::json [\\#1212](https://github.com/nlohmann/json/issues/1212)\n- Issues parsing a previously encoded binary \\(non-UTF8\\) string. [\\#1211](https://github.com/nlohmann/json/issues/1211)\n- Yet another ordering question: char \\* and parse\\(\\) [\\#1209](https://github.com/nlohmann/json/issues/1209)\n- Error using gcc 8.1.0 on Ubuntu 14.04 [\\#1207](https://github.com/nlohmann/json/issues/1207)\n- \"type must be string, but is \" std::string\\(j.type\\_name\\(\\)  [\\#1206](https://github.com/nlohmann/json/issues/1206)\n- Returning empty json object from a function of type const json& ? [\\#1205](https://github.com/nlohmann/json/issues/1205)\n- VS2017 compiler suggests using constexpr if [\\#1204](https://github.com/nlohmann/json/issues/1204)\n- Template instatiation error on compiling [\\#1203](https://github.com/nlohmann/json/issues/1203)\n- BUG - json dump field with unicode -\\> array of ints \\(instead of string\\) [\\#1197](https://github.com/nlohmann/json/issues/1197)\n- Compile error using Code::Blocks // mingw-w64 GCC 8.1.0 - \"Incomplete Type\" [\\#1193](https://github.com/nlohmann/json/issues/1193)\n- SEGFAULT on arm target  [\\#1190](https://github.com/nlohmann/json/issues/1190)\n- Compiler crash with old Clang [\\#1179](https://github.com/nlohmann/json/issues/1179)\n- Custom Precision on floating point numbers [\\#1170](https://github.com/nlohmann/json/issues/1170)\n- Can we have a json\\_view class like std::string\\_view? [\\#1158](https://github.com/nlohmann/json/issues/1158)\n- improve error handling [\\#1152](https://github.com/nlohmann/json/issues/1152)\n- We should remove static\\_asserts [\\#960](https://github.com/nlohmann/json/issues/960)\n\n## [v3.2.0](https://github.com/nlohmann/json/releases/tag/v3.2.0) (2018-08-20)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/3.2.0...v3.2.0)\n\n- Fix -Wno-sometimes-uninitialized by initializing \"result\" in parse\\_sax [\\#1200](https://github.com/nlohmann/json/pull/1200) ([thyu](https://github.com/thyu))\n- \\[RFC\\] Introduce a new macro function: JSON\\_INTERNAL\\_CATCH [\\#1187](https://github.com/nlohmann/json/pull/1187) ([simnalamburt](https://github.com/simnalamburt))\n- Fix unit tests that were silently skipped or crashed \\(depending on the compiler\\) [\\#1176](https://github.com/nlohmann/json/pull/1176) ([grembo](https://github.com/grembo))\n- Refactor/no virtual sax [\\#1153](https://github.com/nlohmann/json/pull/1153) ([theodelrieu](https://github.com/theodelrieu))\n- Fixed compiler error in VS 2015 for debug mode [\\#1151](https://github.com/nlohmann/json/pull/1151) ([sonulohani](https://github.com/sonulohani))\n- Fix links to cppreference named requirements \\(formerly concepts\\) [\\#1144](https://github.com/nlohmann/json/pull/1144) ([jrakow](https://github.com/jrakow))\n- meson: fix include directory [\\#1142](https://github.com/nlohmann/json/pull/1142) ([jrakow](https://github.com/jrakow))\n- Feature/unordered map conversion [\\#1138](https://github.com/nlohmann/json/pull/1138) ([theodelrieu](https://github.com/theodelrieu))\n- fixed compile error for \\#1045 [\\#1134](https://github.com/nlohmann/json/pull/1134) ([Daniel599](https://github.com/Daniel599))\n-  test \\(non\\)equality for alt\\_string implementation  [\\#1130](https://github.com/nlohmann/json/pull/1130) ([agrianius](https://github.com/agrianius))\n- remove stringstream dependency [\\#1117](https://github.com/nlohmann/json/pull/1117) ([TinyTinni](https://github.com/TinyTinni))\n- Provide a from\\_json overload for std::map [\\#1089](https://github.com/nlohmann/json/pull/1089) ([theodelrieu](https://github.com/theodelrieu))\n- fix typo in README [\\#1078](https://github.com/nlohmann/json/pull/1078) ([martin-mfg](https://github.com/martin-mfg))\n- Fix typo [\\#1058](https://github.com/nlohmann/json/pull/1058) ([dns13](https://github.com/dns13))\n- Misc cmake packaging enhancements [\\#1048](https://github.com/nlohmann/json/pull/1048) ([chuckatkins](https://github.com/chuckatkins))\n- Fixed incorrect LLVM version number in README [\\#1047](https://github.com/nlohmann/json/pull/1047) ([jammehcow](https://github.com/jammehcow))\n- Fix trivial typo in comment. [\\#1043](https://github.com/nlohmann/json/pull/1043) ([coryan](https://github.com/coryan))\n- Package Manager: Spack [\\#1041](https://github.com/nlohmann/json/pull/1041) ([ax3l](https://github.com/ax3l))\n- CMake: 3.8+ is Sufficient [\\#1040](https://github.com/nlohmann/json/pull/1040) ([ax3l](https://github.com/ax3l))\n- Added support for string\\_view in C++17 [\\#1028](https://github.com/nlohmann/json/pull/1028) ([gracicot](https://github.com/gracicot))\n- Added public target\\_compile\\_features for auto and constexpr [\\#1026](https://github.com/nlohmann/json/pull/1026) ([ktonon](https://github.com/ktonon))\n\n## [3.2.0](https://github.com/nlohmann/json/releases/tag/3.2.0) (2018-08-20)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.2...3.2.0)\n\n- Am I doing this wrong? Getting an empty string [\\#1199](https://github.com/nlohmann/json/issues/1199)\n- Incompatible Pointer Type [\\#1196](https://github.com/nlohmann/json/issues/1196)\n- json.exception.type\\_error.316 [\\#1195](https://github.com/nlohmann/json/issues/1195)\n- Strange warnings in Code::Blocks 17.12, GNU GCC [\\#1192](https://github.com/nlohmann/json/issues/1192)\n- \\[Question\\] Current place in code to change floating point resolution [\\#1191](https://github.com/nlohmann/json/issues/1191)\n- Add key name when throwing type error [\\#1189](https://github.com/nlohmann/json/issues/1189)\n- Not able to include in visual studio code? [\\#1188](https://github.com/nlohmann/json/issues/1188)\n- Get an Index or row number of an element [\\#1186](https://github.com/nlohmann/json/issues/1186)\n- Difference between `merge_patch` and `update` [\\#1183](https://github.com/nlohmann/json/issues/1183)\n- Is there a way to get an element from a JSON without throwing an exception on failure? [\\#1182](https://github.com/nlohmann/json/issues/1182)\n- to\\_string? [\\#1181](https://github.com/nlohmann/json/issues/1181)\n- How to cache a json object's pointer into a map? [\\#1180](https://github.com/nlohmann/json/issues/1180)\n- Can this library work within a Qt project for Android using Qt Creator? [\\#1178](https://github.com/nlohmann/json/issues/1178)\n- How to get all keys of one object? [\\#1177](https://github.com/nlohmann/json/issues/1177)\n- How can I only parse the first level and get the value as string? [\\#1175](https://github.com/nlohmann/json/issues/1175)\n- I have a query regarding nlohmann::basic\\_json::basic\\_json [\\#1174](https://github.com/nlohmann/json/issues/1174)\n- unordered\\_map with vectors won't convert to json? [\\#1173](https://github.com/nlohmann/json/issues/1173)\n- return json objects from functions [\\#1172](https://github.com/nlohmann/json/issues/1172)\n- Problem when exporting to CBOR [\\#1171](https://github.com/nlohmann/json/issues/1171)\n- Roundtripping null to nullptr does not work [\\#1169](https://github.com/nlohmann/json/issues/1169)\n- MSVC fails to compile std::swap specialization for nlohmann::json [\\#1168](https://github.com/nlohmann/json/issues/1168)\n- Unexpected behaviour of is\\_null - Part II [\\#1167](https://github.com/nlohmann/json/issues/1167)\n- Floating point imprecision [\\#1166](https://github.com/nlohmann/json/issues/1166)\n- Combine json objects into one? [\\#1165](https://github.com/nlohmann/json/issues/1165)\n- Is there any way to know if the object has changed? [\\#1164](https://github.com/nlohmann/json/issues/1164)\n- Value throws on null string [\\#1163](https://github.com/nlohmann/json/issues/1163)\n- Weird template issue in large project [\\#1162](https://github.com/nlohmann/json/issues/1162)\n- \\_json returns a different result vs ::parse [\\#1161](https://github.com/nlohmann/json/issues/1161)\n- Showing difference between two json objects [\\#1160](https://github.com/nlohmann/json/issues/1160)\n- no instance of overloaded function \"std::swap\" matches the specified type\t [\\#1159](https://github.com/nlohmann/json/issues/1159)\n- resize\\(...\\)? [\\#1157](https://github.com/nlohmann/json/issues/1157)\n- Issue with struct nested in class' to\\_json [\\#1155](https://github.com/nlohmann/json/issues/1155)\n- Deserialize std::map with std::nan [\\#1154](https://github.com/nlohmann/json/issues/1154)\n- Parse throwing errors [\\#1149](https://github.com/nlohmann/json/issues/1149)\n- cocoapod integration [\\#1148](https://github.com/nlohmann/json/issues/1148)\n- wstring parsing [\\#1147](https://github.com/nlohmann/json/issues/1147)\n- Is it possible to dump a two-dimensional array to \"\\[\\[null\\],\\[1,2,3\\]\\]\"? [\\#1146](https://github.com/nlohmann/json/issues/1146)\n- Want to write a class member variable and a struct variable \\( this structure is inside the class\\) to the json file [\\#1145](https://github.com/nlohmann/json/issues/1145)\n- Does json support converting an instance of a struct into json string? [\\#1143](https://github.com/nlohmann/json/issues/1143)\n- \\#Most efficient way to search for child parameters \\(recursive find?\\) [\\#1141](https://github.com/nlohmann/json/issues/1141)\n-  could not find to\\_json\\(\\) method in T's namespace [\\#1140](https://github.com/nlohmann/json/issues/1140)\n- chars get treated as JSON numbers not JSON strings [\\#1139](https://github.com/nlohmann/json/issues/1139)\n- How do I count number of objects in array? [\\#1137](https://github.com/nlohmann/json/issues/1137)\n- Serializing a vector of classes? [\\#1136](https://github.com/nlohmann/json/issues/1136)\n- Compile error. Unable convert form nullptr to nullptr&& [\\#1135](https://github.com/nlohmann/json/issues/1135)\n- std::unordered\\_map in struct, serialization [\\#1133](https://github.com/nlohmann/json/issues/1133)\n- dump\\(\\) can't handle umlauts [\\#1131](https://github.com/nlohmann/json/issues/1131)\n- Add a way to get a key reference from the iterator [\\#1127](https://github.com/nlohmann/json/issues/1127)\n- can't not parse \"\\\\“ string [\\#1123](https://github.com/nlohmann/json/issues/1123)\n-  if  json file  contain Internationalization   chars   ,  get  exception [\\#1122](https://github.com/nlohmann/json/issues/1122)\n- How to use a json::iterator dereferenced value in code? [\\#1120](https://github.com/nlohmann/json/issues/1120)\n- Disable implicit conversions from json to std::initializer\\_list\\<T\\> for any T [\\#1118](https://github.com/nlohmann/json/issues/1118)\n- Implicit conversions to complex types can lead to surprising and confusing errors [\\#1116](https://github.com/nlohmann/json/issues/1116)\n- How can I write from\\_json for a complex datatype that is not default constructible? [\\#1115](https://github.com/nlohmann/json/issues/1115)\n- Compile error in VS2015 when compiling unit-conversions.cpp [\\#1114](https://github.com/nlohmann/json/issues/1114)\n- ADL Serializer for std::any / boost::any [\\#1113](https://github.com/nlohmann/json/issues/1113)\n- Unexpected behaviour of is\\_null [\\#1112](https://github.com/nlohmann/json/issues/1112)\n- How to resolve  \" undefined reference to `std::\\_\\_throw\\_bad\\_cast\\(\\)'\" [\\#1111](https://github.com/nlohmann/json/issues/1111)\n- cannot compile on ubuntu 18.04 and 16.04 [\\#1110](https://github.com/nlohmann/json/issues/1110)\n- JSON representation for floating point values has too many digits [\\#1109](https://github.com/nlohmann/json/issues/1109)\n- Not working for classes containing \"\\_declspec\\(dllimport\\)\" in their declaration [\\#1108](https://github.com/nlohmann/json/issues/1108)\n- Get keys from json object [\\#1107](https://github.com/nlohmann/json/issues/1107)\n- Cannot deserialize types using std::ratio [\\#1105](https://github.com/nlohmann/json/issues/1105)\n-  i want to learn json [\\#1104](https://github.com/nlohmann/json/issues/1104)\n- Type checking during compile [\\#1103](https://github.com/nlohmann/json/issues/1103)\n- Iterate through sub items [\\#1102](https://github.com/nlohmann/json/issues/1102)\n- cppcheck failing for version 3.1.2 [\\#1101](https://github.com/nlohmann/json/issues/1101)\n- Deserializing std::map [\\#1100](https://github.com/nlohmann/json/issues/1100)\n- accessing key by reference [\\#1098](https://github.com/nlohmann/json/issues/1098)\n- clang 3.8.0 croaks while trying to compile with debug symbols [\\#1097](https://github.com/nlohmann/json/issues/1097)\n- Serialize a list of class objects with json [\\#1096](https://github.com/nlohmann/json/issues/1096)\n- Small question [\\#1094](https://github.com/nlohmann/json/issues/1094)\n- Upgrading to 3.x: to\\_/from\\_json with enum class [\\#1093](https://github.com/nlohmann/json/issues/1093)\n- Q: few questions about json construction [\\#1092](https://github.com/nlohmann/json/issues/1092)\n- general crayCC compilation failure [\\#1091](https://github.com/nlohmann/json/issues/1091)\n- Merge Patch clears original data [\\#1090](https://github.com/nlohmann/json/issues/1090)\n- \\[Question\\] how to use nlohmann/json in c++? [\\#1088](https://github.com/nlohmann/json/issues/1088)\n- C++17 decomposition declaration support [\\#1087](https://github.com/nlohmann/json/issues/1087)\n- \\[Question\\] Access multi-level json objects [\\#1086](https://github.com/nlohmann/json/issues/1086)\n- Serializing vector [\\#1085](https://github.com/nlohmann/json/issues/1085)\n- update nested value in multi hierarchy json object [\\#1084](https://github.com/nlohmann/json/issues/1084)\n- Overriding default values? [\\#1083](https://github.com/nlohmann/json/issues/1083)\n- detail namespace collision with Cereal? [\\#1082](https://github.com/nlohmann/json/issues/1082)\n- Error using json.dump\\(\\); [\\#1081](https://github.com/nlohmann/json/issues/1081)\n- Consuming TCP Stream [\\#1080](https://github.com/nlohmann/json/issues/1080)\n- Compilation error with strong typed enums in map in combination with namespaces [\\#1079](https://github.com/nlohmann/json/issues/1079)\n- cassert error [\\#1076](https://github.com/nlohmann/json/issues/1076)\n- Valid json data not being parsed [\\#1075](https://github.com/nlohmann/json/issues/1075)\n- Feature request :: Better testing for key existance without try/catch [\\#1074](https://github.com/nlohmann/json/issues/1074)\n- Hi, I have input like a.b.c and want to convert it to \\\"a\\\"{\\\"b\\\": \\\"c\\\"} form. Any suggestions how do I do this? Thanks. [\\#1073](https://github.com/nlohmann/json/issues/1073)\n- ADL deserializer not picked up for non default-constructible type [\\#1072](https://github.com/nlohmann/json/issues/1072)\n- Deserializing std::array doesn't compiler \\(no insert\\(\\)\\) [\\#1071](https://github.com/nlohmann/json/issues/1071)\n- Serializing OpenCV Mat problem [\\#1070](https://github.com/nlohmann/json/issues/1070)\n- Compilation error with ICPC compiler [\\#1068](https://github.com/nlohmann/json/issues/1068)\n- Not existing value, crash [\\#1065](https://github.com/nlohmann/json/issues/1065)\n- cyryllic symbols [\\#1064](https://github.com/nlohmann/json/issues/1064)\n- newbie usage question [\\#1063](https://github.com/nlohmann/json/issues/1063)\n- Trying j\\[\"strTest\"\\] = \"%A\" produces \"strTest\": \"-0X1.CCCCCCCCCCCCCP+205\" [\\#1062](https://github.com/nlohmann/json/issues/1062)\n- convert json value to std::string??? [\\#1061](https://github.com/nlohmann/json/issues/1061)\n- Commented out test cases, should they be removed? [\\#1060](https://github.com/nlohmann/json/issues/1060)\n- different behaviour between clang and gcc with braced initialization [\\#1059](https://github.com/nlohmann/json/issues/1059)\n- json array:  initialize with prescribed size and `resize` method. [\\#1057](https://github.com/nlohmann/json/issues/1057)\n- Is it possible to use exceptions istead of assertions? [\\#1056](https://github.com/nlohmann/json/issues/1056)\n- when using assign operator in with json object a static assertion fails.. [\\#1055](https://github.com/nlohmann/json/issues/1055)\n- Iterate over leafs of a JSON data structure: enrich the JSON pointer API [\\#1054](https://github.com/nlohmann/json/issues/1054)\n- \\[Feature request\\] Access by path [\\#1053](https://github.com/nlohmann/json/issues/1053)\n- document that implicit js -\\> primitive conversion does not work for std::string::value\\_type and why [\\#1052](https://github.com/nlohmann/json/issues/1052)\n- error: ‘BasicJsonType’ in namespace ‘::’ does not name a type [\\#1051](https://github.com/nlohmann/json/issues/1051)\n- Destructor is called when filling object through assignement [\\#1050](https://github.com/nlohmann/json/issues/1050)\n- Is this thing thread safe for reads? [\\#1049](https://github.com/nlohmann/json/issues/1049)\n- clang-tidy: Call to virtual function during construction  [\\#1046](https://github.com/nlohmann/json/issues/1046)\n- Using STL algorithms with JSON containers with expected results? [\\#1045](https://github.com/nlohmann/json/issues/1045)\n- Usage with gtest/gmock not working as expected [\\#1044](https://github.com/nlohmann/json/issues/1044)\n- Consequences of from\\_json / to\\_json being in namespace of data struct. [\\#1042](https://github.com/nlohmann/json/issues/1042)\n- const\\_reference operator\\[\\]\\(const typename object\\_t::key\\_type& key\\) const throw instead of assert [\\#1039](https://github.com/nlohmann/json/issues/1039)\n- Trying to retrieve data from nested objects [\\#1038](https://github.com/nlohmann/json/issues/1038)\n- Direct download link for json\\_fwd.hpp? [\\#1037](https://github.com/nlohmann/json/issues/1037)\n- I know the library supports UTF-8, but failed to dump the value [\\#1036](https://github.com/nlohmann/json/issues/1036)\n- Putting a Vec3-like vector into a json object [\\#1035](https://github.com/nlohmann/json/issues/1035)\n- Ternary operator crash [\\#1034](https://github.com/nlohmann/json/issues/1034)\n- Issued with Clion Inspection Resolution since 2018.1 [\\#1033](https://github.com/nlohmann/json/issues/1033)\n- Some testcases fail and one never finishes [\\#1032](https://github.com/nlohmann/json/issues/1032)\n- Can this class work with wchar\\_t / std::wstring? [\\#1031](https://github.com/nlohmann/json/issues/1031)\n- Makefile: Valgrind flags have no effect [\\#1030](https://github.com/nlohmann/json/issues/1030)\n- 「==」 Should be 「\\>」 [\\#1029](https://github.com/nlohmann/json/issues/1029)\n- HOCON reader? [\\#1027](https://github.com/nlohmann/json/issues/1027)\n- add json string in previous string?? [\\#1025](https://github.com/nlohmann/json/issues/1025)\n- RFC: fluent parsing interface [\\#1023](https://github.com/nlohmann/json/issues/1023)\n- Does it support chinese character? [\\#1022](https://github.com/nlohmann/json/issues/1022)\n- to/from\\_msgpack only works with standard typization [\\#1021](https://github.com/nlohmann/json/issues/1021)\n- Build failure using latest clang and GCC compilers [\\#1020](https://github.com/nlohmann/json/issues/1020)\n- can two json objects be concatenated? [\\#1019](https://github.com/nlohmann/json/issues/1019)\n- Erase by integer index [\\#1018](https://github.com/nlohmann/json/issues/1018)\n- Function find overload taking a json\\_pointer [\\#1017](https://github.com/nlohmann/json/issues/1017)\n- I think should implement an parser function [\\#1016](https://github.com/nlohmann/json/issues/1016)\n- Readme gif [\\#1015](https://github.com/nlohmann/json/issues/1015)\n- Python bindings [\\#1014](https://github.com/nlohmann/json/issues/1014)\n- how to add two json string in single object?? [\\#1012](https://github.com/nlohmann/json/issues/1012)\n- how to serialize class Object \\(convert data in object into json\\)?? [\\#1011](https://github.com/nlohmann/json/issues/1011)\n- Enable forward declaration of json by making json a class instead of a using declaration [\\#997](https://github.com/nlohmann/json/issues/997)\n- compilation error while using intel c++ compiler 2018 [\\#994](https://github.com/nlohmann/json/issues/994)\n- How to create a json variable? [\\#990](https://github.com/nlohmann/json/issues/990)\n- istream \\>\\> json  --- 1st character skipped in stream [\\#976](https://github.com/nlohmann/json/issues/976)\n- Add a SAX parser [\\#971](https://github.com/nlohmann/json/issues/971)\n- How to solve large json file? [\\#927](https://github.com/nlohmann/json/issues/927)\n- json\\_pointer public push\\_back, pop\\_back [\\#837](https://github.com/nlohmann/json/issues/837)\n- Using input\\_adapter in a slightly unexpected way [\\#834](https://github.com/nlohmann/json/issues/834)\n\n## [v3.1.2](https://github.com/nlohmann/json/releases/tag/v3.1.2) (2018-03-14)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/3.1.2...v3.1.2)\n\n- Allowing for user-defined string type in lexer/parser [\\#1009](https://github.com/nlohmann/json/pull/1009) ([nlohmann](https://github.com/nlohmann))\n- dump to alternative string type, as defined in basic\\_json template [\\#1006](https://github.com/nlohmann/json/pull/1006) ([agrianius](https://github.com/agrianius))\n- Fix memory leak during parser callback [\\#1001](https://github.com/nlohmann/json/pull/1001) ([nlohmann](https://github.com/nlohmann))\n- fixed misprinted condition detected by PVS Studio. [\\#992](https://github.com/nlohmann/json/pull/992) ([bogemic](https://github.com/bogemic))\n- Fix/basic json conversion [\\#986](https://github.com/nlohmann/json/pull/986) ([theodelrieu](https://github.com/theodelrieu))\n- Make integration section concise [\\#981](https://github.com/nlohmann/json/pull/981) ([wla80](https://github.com/wla80))\n\n## [3.1.2](https://github.com/nlohmann/json/releases/tag/3.1.2) (2018-03-14)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.1...3.1.2)\n\n- STL containers are always serialized to a nested array like \\[\\[1,2,3\\]\\] [\\#1013](https://github.com/nlohmann/json/issues/1013)\n- The library doesn't want to insert an unordered\\_map [\\#1010](https://github.com/nlohmann/json/issues/1010)\n- Convert Json to uint8\\_t [\\#1008](https://github.com/nlohmann/json/issues/1008)\n- How to compare two JSON objects? [\\#1007](https://github.com/nlohmann/json/issues/1007)\n- Syntax checking [\\#1003](https://github.com/nlohmann/json/issues/1003)\n- more than one operator '=' matches these operands [\\#1002](https://github.com/nlohmann/json/issues/1002)\n- How to check if key existed  [\\#1000](https://github.com/nlohmann/json/issues/1000)\n- nlohmann::json::parse exhaust memory in go binding [\\#999](https://github.com/nlohmann/json/issues/999)\n- Range-based iteration over a non-array object [\\#998](https://github.com/nlohmann/json/issues/998)\n- get\\<T\\> for types that are not default constructible [\\#996](https://github.com/nlohmann/json/issues/996)\n- Prevent Null values to appear in .dump\\(\\) [\\#995](https://github.com/nlohmann/json/issues/995)\n- number parsing [\\#993](https://github.com/nlohmann/json/issues/993)\n- C2664 \\(C++/CLR\\) cannot convert 'nullptr' to 'nullptr &&' [\\#987](https://github.com/nlohmann/json/issues/987)\n- Uniform initialization from another json object differs between gcc and clang. [\\#985](https://github.com/nlohmann/json/issues/985)\n- Problem with adding the lib as a submodule [\\#983](https://github.com/nlohmann/json/issues/983)\n- UTF-8/Unicode error [\\#982](https://github.com/nlohmann/json/issues/982)\n- \"forcing MSVC stacktrace to show which T we're talking about.\" error [\\#980](https://github.com/nlohmann/json/issues/980)\n- reverse order of serialization  [\\#979](https://github.com/nlohmann/json/issues/979)\n- Assigning between different json types [\\#977](https://github.com/nlohmann/json/issues/977)\n- Support serialisation of `unique_ptr<>` and `shared_ptr<>` [\\#975](https://github.com/nlohmann/json/issues/975)\n- Unexpected end of input \\(not same as one before\\) [\\#974](https://github.com/nlohmann/json/issues/974)\n- Segfault on direct initializing json object [\\#973](https://github.com/nlohmann/json/issues/973)\n- Segmentation fault on G++ when trying to assign json string literal to custom json type. [\\#972](https://github.com/nlohmann/json/issues/972)\n- os\\_defines.h:44:19: error: missing binary operator before token \"\\(\" [\\#970](https://github.com/nlohmann/json/issues/970)\n- Passing an iteration object by reference to a function [\\#967](https://github.com/nlohmann/json/issues/967)\n- Json and fmt::lib's format\\_arg\\(\\) [\\#964](https://github.com/nlohmann/json/issues/964)\n\n## [v3.1.1](https://github.com/nlohmann/json/releases/tag/v3.1.1) (2018-02-13)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.0...v3.1.1)\n\n- Updation of child object isn't reflected in parent Object [\\#968](https://github.com/nlohmann/json/issues/968)\n- How to add user defined C++ path to sublime text  [\\#966](https://github.com/nlohmann/json/issues/966)\n- fast number parsing [\\#965](https://github.com/nlohmann/json/issues/965)\n- With non-unique keys, later stored entries are not taken into account anymore [\\#963](https://github.com/nlohmann/json/issues/963)\n- Timeout \\(OSS-Fuzz 6034\\) [\\#962](https://github.com/nlohmann/json/issues/962)\n- Incorrect parsing of indefinite length CBOR strings. [\\#961](https://github.com/nlohmann/json/issues/961)\n- Reload a json file at runtime without emptying my std::ifstream [\\#959](https://github.com/nlohmann/json/issues/959)\n- Split headers should be part of the release [\\#956](https://github.com/nlohmann/json/issues/956)\n- Coveralls shows no coverage data [\\#953](https://github.com/nlohmann/json/issues/953)\n- Feature request: Implicit conversion to bool [\\#951](https://github.com/nlohmann/json/issues/951)\n- converting json to vector of type with templated constructor [\\#924](https://github.com/nlohmann/json/issues/924)\n- No structured bindings support? [\\#901](https://github.com/nlohmann/json/issues/901)\n- \\[Request\\] Macro generating from\\_json\\(\\) and to\\_json\\(\\) [\\#895](https://github.com/nlohmann/json/issues/895)\n- basic\\_json::value throws exception instead of returning default value [\\#871](https://github.com/nlohmann/json/issues/871)\n\n- Fix constraints on from\\_json\\(CompatibleArrayType\\) [\\#969](https://github.com/nlohmann/json/pull/969) ([theodelrieu](https://github.com/theodelrieu))\n- Make coveralls watch the include folder [\\#957](https://github.com/nlohmann/json/pull/957) ([theodelrieu](https://github.com/theodelrieu))\n- Fix links in README.md [\\#955](https://github.com/nlohmann/json/pull/955) ([patrikhuber](https://github.com/patrikhuber))\n- Add a note about installing the library with cget [\\#954](https://github.com/nlohmann/json/pull/954) ([pfultz2](https://github.com/pfultz2))\n\n## [v3.1.0](https://github.com/nlohmann/json/releases/tag/v3.1.0) (2018-02-01)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/3.1.0...v3.1.0)\n\n- Templatize std::string in binary\\_reader \\#941 [\\#950](https://github.com/nlohmann/json/pull/950) ([kaidokert](https://github.com/kaidokert))\n- fix cmake install directory \\(for real this time\\) [\\#944](https://github.com/nlohmann/json/pull/944) ([theodelrieu](https://github.com/theodelrieu))\n- Allow overriding THROW/CATCH/TRY macros with no-exceptions \\#938 [\\#940](https://github.com/nlohmann/json/pull/940) ([kaidokert](https://github.com/kaidokert))\n- Removed compiler warning about unused variable 'kMinExp' [\\#936](https://github.com/nlohmann/json/pull/936) ([zerodefect](https://github.com/zerodefect))\n- Fix a typo in README.md [\\#930](https://github.com/nlohmann/json/pull/930) ([Pipeliner](https://github.com/Pipeliner))\n- Howto installation of json\\_fwd.hpp \\(fixes \\#923\\) [\\#925](https://github.com/nlohmann/json/pull/925) ([zerodefect](https://github.com/zerodefect))\n- fix sfinae on basic\\_json UDT constructor [\\#919](https://github.com/nlohmann/json/pull/919) ([theodelrieu](https://github.com/theodelrieu))\n- Floating-point formatting [\\#915](https://github.com/nlohmann/json/pull/915) ([abolz](https://github.com/abolz))\n- Fix/cmake install [\\#911](https://github.com/nlohmann/json/pull/911) ([theodelrieu](https://github.com/theodelrieu))\n- fix link to the documentation of the emplace function [\\#900](https://github.com/nlohmann/json/pull/900) ([Dobiasd](https://github.com/Dobiasd))\n- JSON Merge Patch \\(RFC 7396\\) [\\#876](https://github.com/nlohmann/json/pull/876) ([nlohmann](https://github.com/nlohmann))\n- Refactor/split it [\\#700](https://github.com/nlohmann/json/pull/700) ([theodelrieu](https://github.com/theodelrieu))\n\n## [3.1.0](https://github.com/nlohmann/json/releases/tag/3.1.0) (2018-02-01)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.1...3.1.0)\n\n- I have a proposal [\\#949](https://github.com/nlohmann/json/issues/949)\n- VERSION define\\(s\\) [\\#948](https://github.com/nlohmann/json/issues/948)\n- v3.0.1 compile error in icc 16.0.4 [\\#947](https://github.com/nlohmann/json/issues/947)\n- Use in VS2017 15.5.5 [\\#946](https://github.com/nlohmann/json/issues/946)\n- Process for reporting Security Bugs? [\\#945](https://github.com/nlohmann/json/issues/945)\n- Please expose a NLOHMANN\\_JSON\\_VERSION macro [\\#943](https://github.com/nlohmann/json/issues/943)\n- Change header include directory to nlohmann/json [\\#942](https://github.com/nlohmann/json/issues/942)\n- string\\_type in binary\\_reader [\\#941](https://github.com/nlohmann/json/issues/941)\n- compile error with clang 5.0 -std=c++1z and no string\\_view [\\#939](https://github.com/nlohmann/json/issues/939)\n- Allow overriding JSON\\_THROW to something else than abort\\(\\) [\\#938](https://github.com/nlohmann/json/issues/938)\n- Handle invalid string in Json file [\\#937](https://github.com/nlohmann/json/issues/937)\n- Unused variable 'kMinExp' [\\#935](https://github.com/nlohmann/json/issues/935)\n- yytext is already defined [\\#933](https://github.com/nlohmann/json/issues/933)\n- Equality operator fails [\\#931](https://github.com/nlohmann/json/issues/931)\n- use in visual studio 2015 [\\#929](https://github.com/nlohmann/json/issues/929)\n- Relative includes of json\\_fwd.hpp in detail/meta.hpp. \\[Develop branch\\] [\\#928](https://github.com/nlohmann/json/issues/928)\n- GCC 7.x issue [\\#926](https://github.com/nlohmann/json/issues/926)\n- json\\_fwd.hpp not installed [\\#923](https://github.com/nlohmann/json/issues/923)\n- Use Google Benchmarks [\\#921](https://github.com/nlohmann/json/issues/921)\n- Move class json\\_pointer to separate file [\\#920](https://github.com/nlohmann/json/issues/920)\n- Unable to locate 'to\\_json\\(\\)' and 'from\\_json\\(\\)' methods in the same namespace [\\#917](https://github.com/nlohmann/json/issues/917)\n- \\[answered\\]Read key1 from .value example  [\\#914](https://github.com/nlohmann/json/issues/914)\n- Don't use `define private public` in test files [\\#913](https://github.com/nlohmann/json/issues/913)\n- value\\(\\) template argument type deduction [\\#912](https://github.com/nlohmann/json/issues/912)\n- Installation path is incorrect [\\#910](https://github.com/nlohmann/json/issues/910)\n- H [\\#909](https://github.com/nlohmann/json/issues/909)\n- Build failure using clang 5 [\\#908](https://github.com/nlohmann/json/issues/908)\n- Amalgate [\\#907](https://github.com/nlohmann/json/issues/907)\n- Update documentation and tests wrt. split headers [\\#906](https://github.com/nlohmann/json/issues/906)\n- Lib not working on ubuntu 16.04 [\\#905](https://github.com/nlohmann/json/issues/905)\n- Problem when writing to file. [\\#904](https://github.com/nlohmann/json/issues/904)\n- C2864 error when compiling with VS2015 and VS 2017 [\\#903](https://github.com/nlohmann/json/issues/903)\n- \\[json.exception.type\\_error.304\\] cannot use at\\(\\) with object [\\#902](https://github.com/nlohmann/json/issues/902)\n- How do I forward nlohmann::json declaration? [\\#899](https://github.com/nlohmann/json/issues/899)\n- How to effectively store binary data? [\\#898](https://github.com/nlohmann/json/issues/898)\n- How to get the length of a JSON string without retrieving its std::string? [\\#897](https://github.com/nlohmann/json/issues/897)\n- Regression Tests Failure using \"ctest\" [\\#887](https://github.com/nlohmann/json/issues/887)\n- Discuss: add JSON Merge Patch \\(RFC 7396\\)? [\\#877](https://github.com/nlohmann/json/issues/877)\n- Discuss: replace static \"iterator\\_wrapper\" function with \"items\" member function [\\#874](https://github.com/nlohmann/json/issues/874)\n- Make optional user-data available in from\\_json [\\#864](https://github.com/nlohmann/json/issues/864)\n- Casting to std::string not working in VS2015 [\\#861](https://github.com/nlohmann/json/issues/861)\n- Sequential reading of JSON arrays [\\#851](https://github.com/nlohmann/json/issues/851)\n- Idea: Handle Multimaps Better [\\#816](https://github.com/nlohmann/json/issues/816)\n- Floating point rounding [\\#777](https://github.com/nlohmann/json/issues/777)\n- Loss of precision when serializing \\<double\\> [\\#360](https://github.com/nlohmann/json/issues/360)\n\n## [v3.0.1](https://github.com/nlohmann/json/releases/tag/v3.0.1) (2017-12-29)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/3.0.1...v3.0.1)\n\n- Includes CTest module/adds BUILD\\_TESTING option [\\#885](https://github.com/nlohmann/json/pull/885) ([TinyTinni](https://github.com/TinyTinni))\n- Fix MSVC warning C4819 [\\#882](https://github.com/nlohmann/json/pull/882) ([erengy](https://github.com/erengy))\n- Merge branch 'develop' into coverity\\_scan [\\#880](https://github.com/nlohmann/json/pull/880) ([nlohmann](https://github.com/nlohmann))\n- :wrench: Fix up a few more effc++ items [\\#858](https://github.com/nlohmann/json/pull/858) ([mattismyname](https://github.com/mattismyname))\n\n## [3.0.1](https://github.com/nlohmann/json/releases/tag/3.0.1) (2017-12-29)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.0...3.0.1)\n\n- Problem parsing array to global vector [\\#896](https://github.com/nlohmann/json/issues/896)\n- Invalid RFC6902 copy operation succeeds [\\#894](https://github.com/nlohmann/json/issues/894)\n- How to rename a key during looping? [\\#893](https://github.com/nlohmann/json/issues/893)\n- clang++-6.0 \\(6.0.0-svn321357-1\\) warning [\\#892](https://github.com/nlohmann/json/issues/892)\n- Make json.hpp aware of the modules TS? [\\#891](https://github.com/nlohmann/json/issues/891)\n- All enum values not handled in switch cases. \\( -Wswitch-enum \\) [\\#889](https://github.com/nlohmann/json/issues/889)\n- JSON Pointer resolve failure resulting in incorrect exception code [\\#888](https://github.com/nlohmann/json/issues/888)\n- Unexpected nested arrays from std::vector [\\#886](https://github.com/nlohmann/json/issues/886)\n- erase multiple elements from a json object [\\#884](https://github.com/nlohmann/json/issues/884)\n- Container function overview in Doxygen is not updated [\\#883](https://github.com/nlohmann/json/issues/883)\n- How to use this for binary file uploads [\\#881](https://github.com/nlohmann/json/issues/881)\n- Allow setting JSON\\_BuildTests=OFF from parent CMakeLists.txt [\\#846](https://github.com/nlohmann/json/issues/846)\n- Unit test fails for local-independent str-to-num [\\#845](https://github.com/nlohmann/json/issues/845)\n- Another idea about type support [\\#774](https://github.com/nlohmann/json/issues/774)\n\n## [v3.0.0](https://github.com/nlohmann/json/releases/tag/v3.0.0) (2017-12-17)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/3.0.0...v3.0.0)\n\n- :white\\_check\\_mark: re-added tests for algorithms [\\#879](https://github.com/nlohmann/json/pull/879) ([nlohmann](https://github.com/nlohmann))\n- Overworked library toward 3.0.0 release [\\#875](https://github.com/nlohmann/json/pull/875) ([nlohmann](https://github.com/nlohmann))\n- :rotating\\_light: remove C4996 warnings \\#872 [\\#873](https://github.com/nlohmann/json/pull/873) ([nlohmann](https://github.com/nlohmann))\n- :boom: throwing an exception in case dump encounters a non-UTF-8 string \\#838 [\\#870](https://github.com/nlohmann/json/pull/870) ([nlohmann](https://github.com/nlohmann))\n- :memo: fixing documentation \\#867 [\\#868](https://github.com/nlohmann/json/pull/868) ([nlohmann](https://github.com/nlohmann))\n- iter\\_impl template conformance with C++17 [\\#860](https://github.com/nlohmann/json/pull/860) ([bogemic](https://github.com/bogemic))\n- Std allocator conformance cpp17 [\\#856](https://github.com/nlohmann/json/pull/856) ([bogemic](https://github.com/bogemic))\n- cmake: use BUILD\\_INTERFACE/INSTALL\\_INTERFACE [\\#855](https://github.com/nlohmann/json/pull/855) ([theodelrieu](https://github.com/theodelrieu))\n- to/from\\_json: add a MSVC-specific static\\_assert to force a stacktrace [\\#854](https://github.com/nlohmann/json/pull/854) ([theodelrieu](https://github.com/theodelrieu))\n- Add .natvis for MSVC debug view [\\#844](https://github.com/nlohmann/json/pull/844) ([TinyTinni](https://github.com/TinyTinni))\n- Updated hunter package links [\\#829](https://github.com/nlohmann/json/pull/829) ([jowr](https://github.com/jowr))\n- Typos README [\\#811](https://github.com/nlohmann/json/pull/811) ([Itja](https://github.com/Itja))\n- add forwarding references to json\\_ref constructor [\\#807](https://github.com/nlohmann/json/pull/807) ([theodelrieu](https://github.com/theodelrieu))\n- Add transparent comparator and perfect forwarding support to find\\(\\) and count\\(\\) [\\#795](https://github.com/nlohmann/json/pull/795) ([jseward](https://github.com/jseward))\n- Error : 'identifier \"size\\_t\" is undefined' in linux [\\#793](https://github.com/nlohmann/json/pull/793) ([sonulohani](https://github.com/sonulohani))\n- Fix Visual Studio 2017 warnings [\\#788](https://github.com/nlohmann/json/pull/788) ([jseward](https://github.com/jseward))\n- Fix warning C4706 on Visual Studio 2017 [\\#785](https://github.com/nlohmann/json/pull/785) ([jseward](https://github.com/jseward))\n- Set GENERATE\\_TAGFILE in Doxyfile [\\#783](https://github.com/nlohmann/json/pull/783) ([eld00d](https://github.com/eld00d))\n- using more CMake [\\#765](https://github.com/nlohmann/json/pull/765) ([nlohmann](https://github.com/nlohmann))\n- Simplified istream handing \\#367 [\\#764](https://github.com/nlohmann/json/pull/764) ([pjkundert](https://github.com/pjkundert))\n- Add info for the vcpkg package. [\\#753](https://github.com/nlohmann/json/pull/753) ([gregmarr](https://github.com/gregmarr))\n- fix from\\_json implementation for pair/tuple [\\#708](https://github.com/nlohmann/json/pull/708) ([theodelrieu](https://github.com/theodelrieu))\n- Update json.hpp [\\#686](https://github.com/nlohmann/json/pull/686) ([GoWebProd](https://github.com/GoWebProd))\n- Remove duplicate word [\\#685](https://github.com/nlohmann/json/pull/685) ([daixtrose](https://github.com/daixtrose))\n- To fix compilation issue for intel OSX compiler [\\#682](https://github.com/nlohmann/json/pull/682) ([kbthomp1](https://github.com/kbthomp1))\n- Digraph warning [\\#679](https://github.com/nlohmann/json/pull/679) ([traits](https://github.com/traits))\n- massage -\\> message [\\#678](https://github.com/nlohmann/json/pull/678) ([DmitryKuk](https://github.com/DmitryKuk))\n- Fix \"not constraint\" grammar in docs [\\#674](https://github.com/nlohmann/json/pull/674) ([wincent](https://github.com/wincent))\n- Add documentation for integration with CMake and hunter [\\#671](https://github.com/nlohmann/json/pull/671) ([dan-42](https://github.com/dan-42))\n- REFACTOR: rewrite CMakeLists.txt for better inlcude and reuse [\\#669](https://github.com/nlohmann/json/pull/669) ([dan-42](https://github.com/dan-42))\n- enable\\_testing only if the JSON\\_BuildTests is ON [\\#666](https://github.com/nlohmann/json/pull/666) ([effolkronium](https://github.com/effolkronium))\n- Support moving from rvalues in std::initializer\\_list [\\#663](https://github.com/nlohmann/json/pull/663) ([himikof](https://github.com/himikof))\n- add ensure\\_ascii parameter to dump. \\#330 [\\#654](https://github.com/nlohmann/json/pull/654) ([ryanjmulder](https://github.com/ryanjmulder))\n- Rename BuildTests to JSON\\_BuildTests [\\#652](https://github.com/nlohmann/json/pull/652) ([olegendo](https://github.com/olegendo))\n- Don't include \\<iostream\\>, use std::make\\_shared [\\#650](https://github.com/nlohmann/json/pull/650) ([olegendo](https://github.com/olegendo))\n- Refacto/split basic json [\\#643](https://github.com/nlohmann/json/pull/643) ([theodelrieu](https://github.com/theodelrieu))\n- fix typo in operator\\_\\_notequal example [\\#630](https://github.com/nlohmann/json/pull/630) ([Chocobo1](https://github.com/Chocobo1))\n- Fix MSVC warning C4819 [\\#629](https://github.com/nlohmann/json/pull/629) ([Chocobo1](https://github.com/Chocobo1))\n- \\[BugFix\\] Add parentheses around std::min [\\#626](https://github.com/nlohmann/json/pull/626) ([koemeet](https://github.com/koemeet))\n- add pair/tuple conversions [\\#624](https://github.com/nlohmann/json/pull/624) ([theodelrieu](https://github.com/theodelrieu))\n- remove std::pair support [\\#615](https://github.com/nlohmann/json/pull/615) ([theodelrieu](https://github.com/theodelrieu))\n- Add pair support, fix CompatibleObject conversions \\(fixes \\#600\\) [\\#609](https://github.com/nlohmann/json/pull/609) ([theodelrieu](https://github.com/theodelrieu))\n- \\#550 Fix iterator related compiling issues for Intel icc [\\#598](https://github.com/nlohmann/json/pull/598) ([HenryRLee](https://github.com/HenryRLee))\n- Issue \\#593 Fix the arithmetic operators in the iterator and reverse iterator [\\#595](https://github.com/nlohmann/json/pull/595) ([HenryRLee](https://github.com/HenryRLee))\n- fix doxygen error of basic\\_json::get\\(\\) [\\#583](https://github.com/nlohmann/json/pull/583) ([zhaohuaxishi](https://github.com/zhaohuaxishi))\n- Fixing assignement for iterator wrapper second, and adding unit test [\\#579](https://github.com/nlohmann/json/pull/579) ([Type1J](https://github.com/Type1J))\n- Adding first and second properties to iteration\\_proxy\\_internal [\\#578](https://github.com/nlohmann/json/pull/578) ([Type1J](https://github.com/Type1J))\n- Adding support for Meson. [\\#576](https://github.com/nlohmann/json/pull/576) ([Type1J](https://github.com/Type1J))\n- add enum class default conversions [\\#545](https://github.com/nlohmann/json/pull/545) ([theodelrieu](https://github.com/theodelrieu))\n- Properly pop diagnostics [\\#540](https://github.com/nlohmann/json/pull/540) ([tinloaf](https://github.com/tinloaf))\n- Add Visual Studio 17 image to appveyor build matrix [\\#536](https://github.com/nlohmann/json/pull/536) ([vpetrigo](https://github.com/vpetrigo))\n- UTF8 encoding enhancement [\\#534](https://github.com/nlohmann/json/pull/534) ([TedLyngmo](https://github.com/TedLyngmo))\n- Fix typo [\\#530](https://github.com/nlohmann/json/pull/530) ([berkus](https://github.com/berkus))\n- Make exception base class visible in basic\\_json [\\#526](https://github.com/nlohmann/json/pull/526) ([krzysztofwos](https://github.com/krzysztofwos))\n- :art: Namespace `uint8_t` from the C++ stdlib [\\#510](https://github.com/nlohmann/json/pull/510) ([alexweej](https://github.com/alexweej))\n- add to\\_json method for C arrays [\\#508](https://github.com/nlohmann/json/pull/508) ([theodelrieu](https://github.com/theodelrieu))\n- Fix -Weffc++ warnings \\(GNU 6.3.1\\) [\\#496](https://github.com/nlohmann/json/pull/496) ([TedLyngmo](https://github.com/TedLyngmo))\n\n## [3.0.0](https://github.com/nlohmann/json/releases/tag/3.0.0) (2017-12-17)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.1...3.0.0)\n\n- unicode strings [\\#878](https://github.com/nlohmann/json/issues/878)\n- Visual Studio 2017 15.5 C++17 std::allocator deprecations [\\#872](https://github.com/nlohmann/json/issues/872)\n- Typo \"excpetion\" [\\#869](https://github.com/nlohmann/json/issues/869)\n- Explicit array example in README.md incorrect [\\#867](https://github.com/nlohmann/json/issues/867)\n- why don't you release this from Feb. ? [\\#865](https://github.com/nlohmann/json/issues/865)\n- json::parse throws std::invalid\\_argument when processing string generated by json::dump\\(\\) [\\#863](https://github.com/nlohmann/json/issues/863)\n- code analysis: potential bug? [\\#859](https://github.com/nlohmann/json/issues/859)\n- MSVC2017, 15.5 new issues.   [\\#857](https://github.com/nlohmann/json/issues/857)\n- very basic: fetching string value/content without quotes [\\#853](https://github.com/nlohmann/json/issues/853)\n- Ambiguous function call to get with pointer type and constant json object in VS2015 \\(15.4.4\\) [\\#852](https://github.com/nlohmann/json/issues/852)\n- How to put  object in the array as a member? [\\#850](https://github.com/nlohmann/json/issues/850)\n- misclick, please ignore [\\#849](https://github.com/nlohmann/json/issues/849)\n- Make XML great again. [\\#847](https://github.com/nlohmann/json/issues/847)\n- Converting to array not working [\\#843](https://github.com/nlohmann/json/issues/843)\n- Iteration weirdness [\\#842](https://github.com/nlohmann/json/issues/842)\n- Use reference or pointer as Object value [\\#841](https://github.com/nlohmann/json/issues/841)\n- Ambiguity in parsing nested maps [\\#840](https://github.com/nlohmann/json/issues/840)\n- could not find from\\_json\\(\\) method in T's namespace [\\#839](https://github.com/nlohmann/json/issues/839)\n- Incorrect parse error with binary data in keys? [\\#838](https://github.com/nlohmann/json/issues/838)\n- using dump\\(\\) when std::wstring is StringType with VS2017 [\\#836](https://github.com/nlohmann/json/issues/836)\n- Show the path of the currently parsed value when an error occurs [\\#835](https://github.com/nlohmann/json/issues/835)\n- Repetitive data type while reading [\\#833](https://github.com/nlohmann/json/issues/833)\n- Storing multiple types inside map [\\#831](https://github.com/nlohmann/json/issues/831)\n- Application terminating [\\#830](https://github.com/nlohmann/json/issues/830)\n- Missing CMake hunter package? [\\#828](https://github.com/nlohmann/json/issues/828)\n- std::map\\<std::string, std::string\\> from json object yields C2665: 'std::pair\\<const \\_Kty,\\_Ty\\>::pair': none of the 2 overloads could convert all the argument types [\\#827](https://github.com/nlohmann/json/issues/827)\n- object.dump gives quoted string, want to use .dump\\(\\) to generate javascripts. [\\#826](https://github.com/nlohmann/json/issues/826)\n- Assertion failed on \\[\"NoExistKey\"\\] of an not existing key of const json& [\\#825](https://github.com/nlohmann/json/issues/825)\n- vs2015 error : static member will remain uninitialized at runtime but use in constant-expressions is supported [\\#824](https://github.com/nlohmann/json/issues/824)\n- Code Checking Warnings from json.hpp on VS2017 Community [\\#821](https://github.com/nlohmann/json/issues/821)\n- Missing iostream in try online [\\#820](https://github.com/nlohmann/json/issues/820)\n- Floating point value loses decimal point during dump [\\#818](https://github.com/nlohmann/json/issues/818)\n- Conan package for the library [\\#817](https://github.com/nlohmann/json/issues/817)\n- stream error  [\\#815](https://github.com/nlohmann/json/issues/815)\n- Link error when using find\\(\\) on the latest commit [\\#814](https://github.com/nlohmann/json/issues/814)\n- ABI issue with json object between 2 shared libraries [\\#813](https://github.com/nlohmann/json/issues/813)\n- scan\\_string\\(\\) return token\\_type::parse\\_error; when parse ansi file [\\#812](https://github.com/nlohmann/json/issues/812)\n- segfault when using fifo\\_map with json [\\#810](https://github.com/nlohmann/json/issues/810)\n- This shit is shit  [\\#809](https://github.com/nlohmann/json/issues/809)\n- \\_finite and \\_isnan are no members of \"std\" [\\#808](https://github.com/nlohmann/json/issues/808)\n- how to print out the line which causing exception? [\\#806](https://github.com/nlohmann/json/issues/806)\n- {} uses copy constructor, while = does not [\\#805](https://github.com/nlohmann/json/issues/805)\n- json.hpp:8955: multiple definition of function that is not defined twice or more. [\\#804](https://github.com/nlohmann/json/issues/804)\n- \\[question\\] to\\_json for base and derived class [\\#803](https://github.com/nlohmann/json/issues/803)\n- Misleading error message - unexpected '\"' - on incorrect utf-8 symbol [\\#802](https://github.com/nlohmann/json/issues/802)\n- json data = std::string\\_view\\(\"hi\"\\); doesn't work? [\\#801](https://github.com/nlohmann/json/issues/801)\n- Thread safety of parse\\(\\) [\\#800](https://github.com/nlohmann/json/issues/800)\n- Numbers as strings [\\#799](https://github.com/nlohmann/json/issues/799)\n- Tests failing on arm [\\#797](https://github.com/nlohmann/json/issues/797)\n- Using your library \\(without modification\\) in another library [\\#796](https://github.com/nlohmann/json/issues/796)\n- Iterating over sub-object [\\#794](https://github.com/nlohmann/json/issues/794)\n- how to get the json object again from which printed by the method of dump\\(\\) [\\#792](https://github.com/nlohmann/json/issues/792)\n- ppa to include source [\\#791](https://github.com/nlohmann/json/issues/791)\n- Different include paths in macOS and Ubuntu [\\#790](https://github.com/nlohmann/json/issues/790)\n- Missing break after line 12886 in switch/case [\\#789](https://github.com/nlohmann/json/issues/789)\n- All unit tests fail? [\\#787](https://github.com/nlohmann/json/issues/787)\n- More use of move semantics in deserialization [\\#786](https://github.com/nlohmann/json/issues/786)\n- warning C4706 - Visual Studio 2017 \\(/W4\\) [\\#784](https://github.com/nlohmann/json/issues/784)\n- Compile error in clang 5.0 [\\#782](https://github.com/nlohmann/json/issues/782)\n- Error Installing appium\\_lib with Ruby v2.4.2 Due to JSON [\\#781](https://github.com/nlohmann/json/issues/781)\n- ::get\\<int\\>\\(\\) fails in new\\(er\\) release \\[MSVC\\] [\\#780](https://github.com/nlohmann/json/issues/780)\n- Type Conversion [\\#779](https://github.com/nlohmann/json/issues/779)\n- Segfault on nested parsing [\\#778](https://github.com/nlohmann/json/issues/778)\n- Build warnings: shadowing exception id [\\#776](https://github.com/nlohmann/json/issues/776)\n- multi-level JSON support. [\\#775](https://github.com/nlohmann/json/issues/775)\n- SIGABRT on dump\\(\\) [\\#773](https://github.com/nlohmann/json/issues/773)\n- \\[Question\\] Custom StringType template parameter \\(possibility for a KeyType template parameter\\) [\\#772](https://github.com/nlohmann/json/issues/772)\n- constexpr ALL the Things! [\\#771](https://github.com/nlohmann/json/issues/771)\n- error: ‘BasicJsonType’ in namespace ‘::’ does not name a type [\\#770](https://github.com/nlohmann/json/issues/770)\n- Program calls abort function [\\#769](https://github.com/nlohmann/json/issues/769)\n- \\[Question\\] Floating point resolution config during dump\\(\\) ? [\\#768](https://github.com/nlohmann/json/issues/768)\n- make check - no test ran [\\#767](https://github.com/nlohmann/json/issues/767)\n- The library cannot work properly with custom allocator based containers [\\#766](https://github.com/nlohmann/json/issues/766)\n- Documentation or feature request. [\\#763](https://github.com/nlohmann/json/issues/763)\n- warnings in msvc about mix/max macro while windows.h is used in the project [\\#762](https://github.com/nlohmann/json/issues/762)\n- std::signbit ambiguous [\\#761](https://github.com/nlohmann/json/issues/761)\n- How to use value for std::experimental::optional type? [\\#760](https://github.com/nlohmann/json/issues/760)\n- Cannot load json file properly [\\#759](https://github.com/nlohmann/json/issues/759)\n- Compilation error with unordered\\_map\\< int, int \\> [\\#758](https://github.com/nlohmann/json/issues/758)\n- CBOR string [\\#757](https://github.com/nlohmann/json/issues/757)\n- Proposal: out\\_of\\_range should be a subclass of std::out\\_of\\_range [\\#756](https://github.com/nlohmann/json/issues/756)\n- Getter is setting the value to null if the key does not exist [\\#754](https://github.com/nlohmann/json/issues/754)\n- parsing works sometimes and crashes others [\\#752](https://github.com/nlohmann/json/issues/752)\n- Static\\_assert failed \"incompatible pointer type\" with Xcode [\\#751](https://github.com/nlohmann/json/issues/751)\n- user-defined literal operator not found [\\#750](https://github.com/nlohmann/json/issues/750)\n- getting clean string from it.key\\(\\) [\\#748](https://github.com/nlohmann/json/issues/748)\n- Best method for exploring and obtaining values of nested json objects when the names are not known beforehand? [\\#747](https://github.com/nlohmann/json/issues/747)\n- null char at the end of string [\\#746](https://github.com/nlohmann/json/issues/746)\n- Incorrect sample for operator \\>\\> in docs [\\#745](https://github.com/nlohmann/json/issues/745)\n- User-friendly documentation [\\#744](https://github.com/nlohmann/json/issues/744)\n- Retrieve all values that match a json path [\\#743](https://github.com/nlohmann/json/issues/743)\n- Compilation issue with gcc 7.2 [\\#742](https://github.com/nlohmann/json/issues/742)\n- CMake target nlohmann\\_json does not have src into its interface includes [\\#741](https://github.com/nlohmann/json/issues/741)\n- Error when serializing empty json: type must be string, but is object [\\#740](https://github.com/nlohmann/json/issues/740)\n- Conversion error for std::map\\<int, std::string\\>  [\\#739](https://github.com/nlohmann/json/issues/739)\n- Dumping Json to file as array [\\#738](https://github.com/nlohmann/json/issues/738)\n- nesting json objects [\\#737](https://github.com/nlohmann/json/issues/737)\n- where to find general help? [\\#736](https://github.com/nlohmann/json/issues/736)\n- Compilation Error on Clang 5.0 Upgrade [\\#735](https://github.com/nlohmann/json/issues/735)\n- Compilation error with std::map\\<std::string, std::string\\> on vs 2015 [\\#734](https://github.com/nlohmann/json/issues/734)\n- Benchmarks for Binary formats [\\#733](https://github.com/nlohmann/json/issues/733)\n- Support \\n symbols in json string. [\\#731](https://github.com/nlohmann/json/issues/731)\n- Project's name is too generic and hard to search for [\\#730](https://github.com/nlohmann/json/issues/730)\n- Visual Studio 2015 IntelliTrace problems [\\#729](https://github.com/nlohmann/json/issues/729)\n- How to erase nested objects inside other objects? [\\#728](https://github.com/nlohmann/json/issues/728)\n- Serialization for CBOR [\\#726](https://github.com/nlohmann/json/issues/726)\n- Using json Object as value in a map [\\#725](https://github.com/nlohmann/json/issues/725)\n- std::regex and nlohmann::json value [\\#724](https://github.com/nlohmann/json/issues/724)\n- Warnings when compiling with VisualStudio 2015 [\\#723](https://github.com/nlohmann/json/issues/723)\n- Has this lib the unicode \\(wstring\\) support? [\\#722](https://github.com/nlohmann/json/issues/722)\n- When will be 3.0 in master? [\\#721](https://github.com/nlohmann/json/issues/721)\n- Determine the type from error message. [\\#720](https://github.com/nlohmann/json/issues/720)\n- Compile-Error C2100 \\(MS VS2015\\) in line 887 json.hpp [\\#719](https://github.com/nlohmann/json/issues/719)\n- from\\_json not working for boost::optional example [\\#718](https://github.com/nlohmann/json/issues/718)\n- about from\\_json and to\\_json function [\\#717](https://github.com/nlohmann/json/issues/717)\n- How to detect parse failure? [\\#715](https://github.com/nlohmann/json/issues/715)\n- Parse throw std::ios\\_base::failure exception when failbit set to true [\\#714](https://github.com/nlohmann/json/issues/714)\n- Is there a way of format just making a pretty print without changing the key's orders ? [\\#713](https://github.com/nlohmann/json/issues/713)\n- Serialization of array of not same model items [\\#712](https://github.com/nlohmann/json/issues/712)\n- pointer to json parse vector [\\#711](https://github.com/nlohmann/json/issues/711)\n- Gtest SEH Exception [\\#709](https://github.com/nlohmann/json/issues/709)\n- broken from\\_json implementation for pair and tuple  [\\#707](https://github.com/nlohmann/json/issues/707)\n- Unevaluated lambda in assert breaks gcc 7 build [\\#705](https://github.com/nlohmann/json/issues/705)\n- Issues when adding values to firebase database [\\#704](https://github.com/nlohmann/json/issues/704)\n- Floating point equality - revisited [\\#703](https://github.com/nlohmann/json/issues/703)\n- Conversion from valarray\\<double\\> to json fails to build [\\#702](https://github.com/nlohmann/json/issues/702)\n- internal compiler error \\(gcc7\\)  [\\#701](https://github.com/nlohmann/json/issues/701)\n- One build system to rule them all [\\#698](https://github.com/nlohmann/json/issues/698)\n- Generated nlohmann\\_jsonConfig.cmake does not set JSON\\_INCLUDE\\_DIR [\\#695](https://github.com/nlohmann/json/issues/695)\n- support the Chinese language in json string [\\#694](https://github.com/nlohmann/json/issues/694)\n- NaN problem within develop branch [\\#693](https://github.com/nlohmann/json/issues/693)\n- Please post example of specialization for boost::filesystem [\\#692](https://github.com/nlohmann/json/issues/692)\n- Impossible to do an array of composite objects [\\#691](https://github.com/nlohmann/json/issues/691)\n- How to save json to file? [\\#690](https://github.com/nlohmann/json/issues/690)\n- my simple json parser [\\#689](https://github.com/nlohmann/json/issues/689)\n- problem with new struct parsing syntax [\\#688](https://github.com/nlohmann/json/issues/688)\n- Parse error while parse the json string contains  UTF 8 encoded document bytes string [\\#684](https://github.com/nlohmann/json/issues/684)\n- \\[question\\] how to get a string value by pointer [\\#683](https://github.com/nlohmann/json/issues/683)\n- create json object from string variable [\\#681](https://github.com/nlohmann/json/issues/681)\n- adl\\_serializer and CRTP [\\#680](https://github.com/nlohmann/json/issues/680)\n- Is there a way to control the precision of serialized floating point numbers? [\\#677](https://github.com/nlohmann/json/issues/677)\n- Is there a way to get the path of a value? [\\#676](https://github.com/nlohmann/json/issues/676)\n- Could the parser locate errors to line? [\\#675](https://github.com/nlohmann/json/issues/675)\n- There is performance inefficiency found by coverity tool json2.1.1/include/nlohmann/json.hpp [\\#673](https://github.com/nlohmann/json/issues/673)\n- include problem, when cmake on osx [\\#672](https://github.com/nlohmann/json/issues/672)\n- Operator= ambiguous in C++1z and GCC 7.1.1 [\\#670](https://github.com/nlohmann/json/issues/670)\n- should't the cmake install target be to nlohman/json.hpp [\\#668](https://github.com/nlohmann/json/issues/668)\n- deserialise from `std::vector` [\\#667](https://github.com/nlohmann/json/issues/667)\n- How to iterate? [\\#665](https://github.com/nlohmann/json/issues/665)\n- could this json lib work on windows? [\\#664](https://github.com/nlohmann/json/issues/664)\n- How does from\\_json work? [\\#662](https://github.com/nlohmann/json/issues/662)\n- insert\\(or merge\\) object should replace same key , not ignore [\\#661](https://github.com/nlohmann/json/issues/661)\n- Parse method doesn't handle newlines. [\\#659](https://github.com/nlohmann/json/issues/659)\n- Compilation \"note\" on GCC 6 ARM [\\#658](https://github.com/nlohmann/json/issues/658)\n- Adding additional push\\_back/operator+= rvalue overloads for JSON object [\\#657](https://github.com/nlohmann/json/issues/657)\n- dump's parameter \"ensure\\_ascii\" creates too long sequences [\\#656](https://github.com/nlohmann/json/issues/656)\n- Question: parsing `void *` [\\#655](https://github.com/nlohmann/json/issues/655)\n- how should I check a string is valid JSON string ? [\\#653](https://github.com/nlohmann/json/issues/653)\n- Question: thread safety of read only accesses [\\#651](https://github.com/nlohmann/json/issues/651)\n- Eclipse: Method 'size' could not be resolved [\\#649](https://github.com/nlohmann/json/issues/649)\n- Update/Add object fields [\\#648](https://github.com/nlohmann/json/issues/648)\n- No exception raised for Out Of Range input of numbers [\\#647](https://github.com/nlohmann/json/issues/647)\n- Package Name [\\#646](https://github.com/nlohmann/json/issues/646)\n- What is the meaning of operator\\[\\]\\(T\\* key\\) [\\#645](https://github.com/nlohmann/json/issues/645)\n- Which is the correct way to json objects as parameters to functions? [\\#644](https://github.com/nlohmann/json/issues/644)\n- Method to get string representations of values [\\#642](https://github.com/nlohmann/json/issues/642)\n-  CBOR serialization of a given JSON value does not serialize [\\#641](https://github.com/nlohmann/json/issues/641)\n- Are we forced to use \"-fexceptions\" flag in android ndk project [\\#640](https://github.com/nlohmann/json/issues/640)\n- Comparison of objects containing floats [\\#639](https://github.com/nlohmann/json/issues/639)\n- 'localeconv' is not supported by NDK for SDK  \\<=20 [\\#638](https://github.com/nlohmann/json/issues/638)\n- \\[Question\\] cLion integration [\\#637](https://github.com/nlohmann/json/issues/637)\n- How to construct an iteratable usage in nlohmann json? [\\#636](https://github.com/nlohmann/json/issues/636)\n- \\[Question\\] copy assign json-container to vector [\\#635](https://github.com/nlohmann/json/issues/635)\n- Get size without .dump\\(\\) [\\#634](https://github.com/nlohmann/json/issues/634)\n- Segmentation fault when parsing invalid json file [\\#633](https://github.com/nlohmann/json/issues/633)\n- How to serialize from json to vector\\<customType\\>? [\\#632](https://github.com/nlohmann/json/issues/632)\n- no member named 'thousands\\_sep' in 'lconv' [\\#631](https://github.com/nlohmann/json/issues/631)\n- \\[Question\\] Any fork for \\(the unsupported\\) Visual Studio 2012 version? [\\#628](https://github.com/nlohmann/json/issues/628)\n- Dependency injection in serializer [\\#627](https://github.com/nlohmann/json/issues/627)\n- from\\_json for std::array [\\#625](https://github.com/nlohmann/json/issues/625)\n- Discussion: How to structure the parsing function families [\\#623](https://github.com/nlohmann/json/issues/623)\n- Question: How to erase subtree [\\#622](https://github.com/nlohmann/json/issues/622)\n- Insertion into nested json field [\\#621](https://github.com/nlohmann/json/issues/621)\n- Question: return static json object from function [\\#618](https://github.com/nlohmann/json/issues/618)\n- icc16 error [\\#617](https://github.com/nlohmann/json/issues/617)\n- \\[-Wdeprecated-declarations\\] in row `j >> ss;` in file `json.hpp:7405:26` and FAILED unit tests with MinGWx64! [\\#616](https://github.com/nlohmann/json/issues/616)\n- to\\_json for pairs, tuples [\\#614](https://github.com/nlohmann/json/issues/614)\n- Using uninitialized memory 'buf' in line 11173 v2.1.1? [\\#613](https://github.com/nlohmann/json/issues/613)\n- How to parse multiple same Keys of JSON and save them? [\\#612](https://github.com/nlohmann/json/issues/612)\n- \"Multiple declarations\" error when using types defined with `typedef` [\\#611](https://github.com/nlohmann/json/issues/611)\n- 2.1.1+ breaks compilation of shared\\_ptr\\<json\\> == 0 [\\#610](https://github.com/nlohmann/json/issues/610)\n- a bug of inheritance ?  [\\#608](https://github.com/nlohmann/json/issues/608)\n- std::map key conversion with to\\_json [\\#607](https://github.com/nlohmann/json/issues/607)\n- json.hpp:6384:62: error: wrong number of template arguments \\(1, should be 2\\) [\\#606](https://github.com/nlohmann/json/issues/606)\n- Incremental parsing: Where's the push version? [\\#605](https://github.com/nlohmann/json/issues/605)\n- Is there a way to validate the structure of a json object ? [\\#604](https://github.com/nlohmann/json/issues/604)\n- \\[Question\\] Issue when using Appveyor when compiling library [\\#603](https://github.com/nlohmann/json/issues/603)\n- BOM not skipped when using json:parse\\(iterator\\) [\\#602](https://github.com/nlohmann/json/issues/602)\n- Use of the binary type in CBOR and Message Pack [\\#601](https://github.com/nlohmann/json/issues/601)\n- Newbie issue: how does one convert a map in Json back to std::map? [\\#600](https://github.com/nlohmann/json/issues/600)\n- Plugin system [\\#599](https://github.com/nlohmann/json/issues/599)\n- Using custom types for scalars? [\\#596](https://github.com/nlohmann/json/issues/596)\n- Issues with the arithmetic in iterator and reverse iterator [\\#593](https://github.com/nlohmann/json/issues/593)\n- not enough examples [\\#592](https://github.com/nlohmann/json/issues/592)\n- in-class initialization for type 'const T' is not yet implemented [\\#591](https://github.com/nlohmann/json/issues/591)\n- compiling with gcc 7 -\\> error on bool operator \\< [\\#590](https://github.com/nlohmann/json/issues/590)\n- Parsing from stream leads to an array [\\#589](https://github.com/nlohmann/json/issues/589)\n- Buggy support for binary string data [\\#587](https://github.com/nlohmann/json/issues/587)\n- C++17's ambiguous conversion [\\#586](https://github.com/nlohmann/json/issues/586)\n- How does the messagepack encoding/decoding compare to msgpack-cpp in terms of performance? [\\#585](https://github.com/nlohmann/json/issues/585)\n- is it possible to check existence of a value deep in hierarchy? [\\#584](https://github.com/nlohmann/json/issues/584)\n- loading from a stream and exceptions [\\#582](https://github.com/nlohmann/json/issues/582)\n- Visual Studio seems not to have all min\\(\\) function versions [\\#581](https://github.com/nlohmann/json/issues/581)\n- Supporting of the json schema [\\#580](https://github.com/nlohmann/json/issues/580)\n- Stack-overflow \\(OSS-Fuzz 1444\\) [\\#577](https://github.com/nlohmann/json/issues/577)\n- Heap-buffer-overflow \\(OSS-Fuzz 1400\\) [\\#575](https://github.com/nlohmann/json/issues/575)\n- JSON escape quotes [\\#574](https://github.com/nlohmann/json/issues/574)\n- error: static\\_assert failed [\\#573](https://github.com/nlohmann/json/issues/573)\n- Storing floats, and round trip serialisation/deserialisation diffs [\\#572](https://github.com/nlohmann/json/issues/572)\n- JSON.getLong produces inconsistent results [\\#571](https://github.com/nlohmann/json/issues/571)\n- Request: Object.at\\(\\) with default return value [\\#570](https://github.com/nlohmann/json/issues/570)\n- Internal structure gets corrupted while parsing [\\#569](https://github.com/nlohmann/json/issues/569)\n- create template \\<typename Iter\\> basic\\_json from\\_cbor\\(Iter begin, Iter end\\) [\\#568](https://github.com/nlohmann/json/issues/568)\n- Conan.io [\\#566](https://github.com/nlohmann/json/issues/566)\n- contradictory documentation regarding json::find [\\#565](https://github.com/nlohmann/json/issues/565)\n- Unexpected '\\\"' in middle of array [\\#564](https://github.com/nlohmann/json/issues/564)\n- Support parse std::pair to Json object [\\#563](https://github.com/nlohmann/json/issues/563)\n- json and Microsoft Visual c++ Compiler Nov 2012 CTP [\\#562](https://github.com/nlohmann/json/issues/562)\n- from\\_json declaration order and exceptions [\\#561](https://github.com/nlohmann/json/issues/561)\n- Tip: Don't upgrade to VS2017 if using json initializer list constructs [\\#559](https://github.com/nlohmann/json/issues/559)\n- parse error - unexpected end of input [\\#558](https://github.com/nlohmann/json/issues/558)\n- Cant modify existing numbers inside a json object [\\#557](https://github.com/nlohmann/json/issues/557)\n- Better support for SAX style serialize and deserialize in new version? [\\#554](https://github.com/nlohmann/json/issues/554)\n- Cannot convert from json array to std::array [\\#553](https://github.com/nlohmann/json/issues/553)\n- Do not define an unnamed namespace in a header file \\(DCL59-CPP\\) [\\#552](https://github.com/nlohmann/json/issues/552)\n- Parse error on known good json file [\\#551](https://github.com/nlohmann/json/issues/551)\n- Warning on Intel compiler \\(icc 17\\) [\\#550](https://github.com/nlohmann/json/issues/550)\n- multiple versions of 'vsnprintf' [\\#549](https://github.com/nlohmann/json/issues/549)\n- illegal indirection [\\#548](https://github.com/nlohmann/json/issues/548)\n- Ambiguous compare operators with clang-5.0 [\\#547](https://github.com/nlohmann/json/issues/547)\n- Using tsl::ordered\\_map [\\#546](https://github.com/nlohmann/json/issues/546)\n- Compiler support errors are inconvenient [\\#544](https://github.com/nlohmann/json/issues/544)\n- Duplicate symbols error happens while to\\_json/from\\_json method implemented inside entity definition header file [\\#542](https://github.com/nlohmann/json/issues/542)\n- consider adding a bool json::is\\_valid\\(std::string const&\\) non-member function [\\#541](https://github.com/nlohmann/json/issues/541)\n- Help request [\\#539](https://github.com/nlohmann/json/issues/539)\n- How to deal with missing keys in `from_json`? [\\#538](https://github.com/nlohmann/json/issues/538)\n- recursive from\\_msgpack implementation will stack overflow [\\#537](https://github.com/nlohmann/json/issues/537)\n- Exception objects must be nothrow copy constructible \\(ERR60-CPP\\) [\\#531](https://github.com/nlohmann/json/issues/531)\n- Support for multiple root elements [\\#529](https://github.com/nlohmann/json/issues/529)\n- Port has\\_shape from dropbox/json11 [\\#528](https://github.com/nlohmann/json/issues/528)\n- dump\\_float: truncation from ptrdiff\\_t to long [\\#527](https://github.com/nlohmann/json/issues/527)\n- Make exception base class visible in basic\\_json [\\#525](https://github.com/nlohmann/json/issues/525)\n- msgpack unit test failures on ppc64 arch [\\#524](https://github.com/nlohmann/json/issues/524)\n- How about split the implementation out, and only leave the interface? [\\#523](https://github.com/nlohmann/json/issues/523)\n- VC++2017 not enough actual parameters for macro 'max' [\\#522](https://github.com/nlohmann/json/issues/522)\n- crash on empty ifstream [\\#521](https://github.com/nlohmann/json/issues/521)\n- Suggestion: Support tabs for indentation when serializing to stream. [\\#520](https://github.com/nlohmann/json/issues/520)\n- Abrt in get\\_number \\(OSS-Fuzz 885\\) [\\#519](https://github.com/nlohmann/json/issues/519)\n- Abrt on unknown address \\(OSS-Fuzz 884\\) [\\#518](https://github.com/nlohmann/json/issues/518)\n- Stack-overflow \\(OSS-Fuzz 869\\) [\\#517](https://github.com/nlohmann/json/issues/517)\n- Assertion error \\(OSS-Fuzz 868\\) [\\#516](https://github.com/nlohmann/json/issues/516)\n- NaN to json and back [\\#515](https://github.com/nlohmann/json/issues/515)\n- Comparison of NaN [\\#514](https://github.com/nlohmann/json/issues/514)\n- why it's not possible to serialize c++11 enums directly [\\#513](https://github.com/nlohmann/json/issues/513)\n- clang compile error: use of overloaded operator '\\<=' is ambiguous   with \\(nlohmann::json{{\"a\", 5}}\\)\\[\"a\"\\] \\<= 10 [\\#512](https://github.com/nlohmann/json/issues/512)\n- Why not also look inside the type for \\(static\\) to\\_json and from\\_json funtions? [\\#511](https://github.com/nlohmann/json/issues/511)\n- Parser issues [\\#509](https://github.com/nlohmann/json/issues/509)\n- I may not understand [\\#507](https://github.com/nlohmann/json/issues/507)\n- VS2017 min / max problem for 2.1.1 [\\#506](https://github.com/nlohmann/json/issues/506)\n- CBOR/MessagePack is not read until the end [\\#505](https://github.com/nlohmann/json/issues/505)\n- Assertion error \\(OSS-Fuzz 856\\) [\\#504](https://github.com/nlohmann/json/issues/504)\n- Return position in parse error exceptions [\\#503](https://github.com/nlohmann/json/issues/503)\n- conversion from/to C array is not supported [\\#502](https://github.com/nlohmann/json/issues/502)\n- error C2338: could not find to\\_json\\(\\) method in T's namespace [\\#501](https://github.com/nlohmann/json/issues/501)\n- Test suite fails in en\\_GB.UTF-8 [\\#500](https://github.com/nlohmann/json/issues/500)\n- cannot use operator\\[\\] with number [\\#499](https://github.com/nlohmann/json/issues/499)\n- consider using \\_\\_cpp\\_exceptions and/or \\_\\_EXCEPTIONS to disable/enable exception support [\\#498](https://github.com/nlohmann/json/issues/498)\n- Stack-overflow \\(OSS-Fuzz issue 814\\) [\\#497](https://github.com/nlohmann/json/issues/497)\n- Using in Unreal Engine - handling custom types conversion [\\#495](https://github.com/nlohmann/json/issues/495)\n- Conversion from vector\\<bool\\> to json fails to build [\\#494](https://github.com/nlohmann/json/issues/494)\n- fill\\_line\\_buffer incorrectly tests m\\_stream for eof but not fail or bad bits [\\#493](https://github.com/nlohmann/json/issues/493)\n- Compiling with \\_GLIBCXX\\_DEBUG yields iterator-comparison warnings during tests [\\#492](https://github.com/nlohmann/json/issues/492)\n- crapy interface [\\#491](https://github.com/nlohmann/json/issues/491)\n- Fix Visual Studo 2013 builds. [\\#490](https://github.com/nlohmann/json/issues/490)\n- Failed to compile with -D\\_GLIBCXX\\_PARALLEL [\\#489](https://github.com/nlohmann/json/issues/489)\n- Input several field with the same name [\\#488](https://github.com/nlohmann/json/issues/488)\n- read in .json file yields strange sizes [\\#487](https://github.com/nlohmann/json/issues/487)\n- json::value\\_t can't be a map's key type in VC++ 2015 [\\#486](https://github.com/nlohmann/json/issues/486)\n- Using fifo\\_map [\\#485](https://github.com/nlohmann/json/issues/485)\n- Cannot get float pointer for value stored as `0` [\\#484](https://github.com/nlohmann/json/issues/484)\n- byte string support [\\#483](https://github.com/nlohmann/json/issues/483)\n- https://github.com/nlohmann/json\\#execute-unit-tests [\\#481](https://github.com/nlohmann/json/issues/481)\n- Remove deprecated constructor basic\\_json\\(std::istream&\\) [\\#480](https://github.com/nlohmann/json/issues/480)\n- writing the binary json file? [\\#479](https://github.com/nlohmann/json/issues/479)\n- CBOR/MessagePack from uint8\\_t \\* and size [\\#478](https://github.com/nlohmann/json/issues/478)\n- Streaming binary representations  [\\#477](https://github.com/nlohmann/json/issues/477)\n- Reuse memory in to\\_cbor and to\\_msgpack functions [\\#476](https://github.com/nlohmann/json/issues/476)\n- Error Using JSON Library with arrays C++ [\\#475](https://github.com/nlohmann/json/issues/475)\n- Moving forward to version 3.0.0 [\\#474](https://github.com/nlohmann/json/issues/474)\n- Inconsistent behavior in conversion to array type [\\#473](https://github.com/nlohmann/json/issues/473)\n- Create a \\[key:member\\_pointer\\] map to ease parsing custom types [\\#471](https://github.com/nlohmann/json/issues/471)\n- MSVC 2015 update 2 [\\#469](https://github.com/nlohmann/json/issues/469)\n- VS2017 implicit to std::string conversion fix. [\\#464](https://github.com/nlohmann/json/issues/464)\n- How to make sure a string or string literal is a valid JSON? [\\#458](https://github.com/nlohmann/json/issues/458)\n- basic\\_json templated on a \"policy\" class [\\#456](https://github.com/nlohmann/json/issues/456)\n- json::value\\(const json\\_pointer&, ValueType\\) requires exceptions to return the default value. [\\#440](https://github.com/nlohmann/json/issues/440)\n- is it possible merge two json object [\\#428](https://github.com/nlohmann/json/issues/428)\n- Is it possible to turn this into a shared library? [\\#420](https://github.com/nlohmann/json/issues/420)\n- Further thoughts on performance improvements [\\#418](https://github.com/nlohmann/json/issues/418)\n- nan number stored as null [\\#388](https://github.com/nlohmann/json/issues/388)\n- Behavior of operator\\>\\> should more closely resemble that of built-in overloads. [\\#367](https://github.com/nlohmann/json/issues/367)\n- Request: range-based-for over a json-object to expose .first/.second [\\#350](https://github.com/nlohmann/json/issues/350)\n- feature wish: JSONPath [\\#343](https://github.com/nlohmann/json/issues/343)\n- UTF-8/Unicode escape and dump [\\#330](https://github.com/nlohmann/json/issues/330)\n- Serialized value not always can be parsed. [\\#329](https://github.com/nlohmann/json/issues/329)\n- Is there a way to forward declare nlohmann::json? [\\#314](https://github.com/nlohmann/json/issues/314)\n- Exception line [\\#301](https://github.com/nlohmann/json/issues/301)\n- Do not throw exception when default\\_value's type does not match the actual type [\\#278](https://github.com/nlohmann/json/issues/278)\n- dump\\(\\) method doesn't work with a custom allocator [\\#268](https://github.com/nlohmann/json/issues/268)\n- Readme documentation enhancements [\\#248](https://github.com/nlohmann/json/issues/248)\n- Use user-defined exceptions [\\#244](https://github.com/nlohmann/json/issues/244)\n- Incorrect C++11 allocator model support [\\#161](https://github.com/nlohmann/json/issues/161)\n\n## [v2.1.1](https://github.com/nlohmann/json/releases/tag/v2.1.1) (2017-02-25)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/2.1.1...v2.1.1)\n\n- Speedup CI builds using cotire [\\#461](https://github.com/nlohmann/json/pull/461) ([tusharpm](https://github.com/tusharpm))\n- TurpentineDistillery feature/locale independent str to num [\\#450](https://github.com/nlohmann/json/pull/450) ([nlohmann](https://github.com/nlohmann))\n- README: adjust boost::optional example [\\#439](https://github.com/nlohmann/json/pull/439) ([jaredgrubb](https://github.com/jaredgrubb))\n- fix \\#414 - comparing to 0 literal [\\#415](https://github.com/nlohmann/json/pull/415) ([stanmihai4](https://github.com/stanmihai4))\n- locale-independent num-to-str [\\#378](https://github.com/nlohmann/json/pull/378) ([TurpentineDistillery](https://github.com/TurpentineDistillery))\n\n## [2.1.1](https://github.com/nlohmann/json/releases/tag/2.1.1) (2017-02-25)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.1.0...2.1.1)\n\n- warning in the library [\\#472](https://github.com/nlohmann/json/issues/472)\n- How to create an array of Objects? [\\#470](https://github.com/nlohmann/json/issues/470)\n- \\[Bug?\\] Cannot get int pointer, but int64\\_t works [\\#468](https://github.com/nlohmann/json/issues/468)\n- Illegal indirection [\\#467](https://github.com/nlohmann/json/issues/467)\n- in vs can't find linkageId   [\\#466](https://github.com/nlohmann/json/issues/466)\n- Roundtrip error while parsing \"1000000000000000010E5\" [\\#465](https://github.com/nlohmann/json/issues/465)\n- C4996 error and warning with Visual Studio [\\#463](https://github.com/nlohmann/json/issues/463)\n- Support startIndex for from\\_cbor/from\\_msgpack [\\#462](https://github.com/nlohmann/json/issues/462)\n- question: monospace font used in feature slideshow? [\\#460](https://github.com/nlohmann/json/issues/460)\n- Object.keys\\(\\) [\\#459](https://github.com/nlohmann/json/issues/459)\n- Use “, “ as delimiter for json-objects. [\\#457](https://github.com/nlohmann/json/issues/457)\n- Enum -\\> string during serialization and vice versa [\\#455](https://github.com/nlohmann/json/issues/455)\n- doubles are printed as integers [\\#454](https://github.com/nlohmann/json/issues/454)\n- Warnings with Visual Studio c++ \\(VS2015 Update 3\\) [\\#453](https://github.com/nlohmann/json/issues/453)\n- Heap-buffer-overflow \\(OSS-Fuzz issue 585\\) [\\#452](https://github.com/nlohmann/json/issues/452)\n- use of undeclared identifier 'UINT8\\_MAX' [\\#451](https://github.com/nlohmann/json/issues/451)\n- Question on the lifetime managment of objects at the lower levels [\\#449](https://github.com/nlohmann/json/issues/449)\n- Json should not be constructible with 'json\\*' [\\#448](https://github.com/nlohmann/json/issues/448)\n- Move value\\_t to namespace scope [\\#447](https://github.com/nlohmann/json/issues/447)\n- Typo in README.md [\\#446](https://github.com/nlohmann/json/issues/446)\n- make check compilation is unneccesarily slow [\\#445](https://github.com/nlohmann/json/issues/445)\n- Problem in dump\\(\\) in json.h caused by ss.imbue [\\#444](https://github.com/nlohmann/json/issues/444)\n- I want to create Windows Application in Visual Studio 2015 c++, and i have a problem [\\#443](https://github.com/nlohmann/json/issues/443)\n- Implicit conversion issues [\\#442](https://github.com/nlohmann/json/issues/442)\n- Parsing of floats locale dependent [\\#302](https://github.com/nlohmann/json/issues/302)\n\n## [v2.1.0](https://github.com/nlohmann/json/releases/tag/v2.1.0) (2017-01-28)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/2.1.0...v2.1.0)\n\n- conversion from/to user-defined types [\\#435](https://github.com/nlohmann/json/pull/435) ([nlohmann](https://github.com/nlohmann))\n- Fix documentation error [\\#430](https://github.com/nlohmann/json/pull/430) ([vjon](https://github.com/vjon))\n\n## [2.1.0](https://github.com/nlohmann/json/releases/tag/2.1.0) (2017-01-28)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.10...2.1.0)\n\n- Parsing multiple JSON objects from a string or stream [\\#438](https://github.com/nlohmann/json/issues/438)\n- Use-of-uninitialized-value \\(OSS-Fuzz issue 477\\) [\\#437](https://github.com/nlohmann/json/issues/437)\n- add `reserve` function for array to reserve memory before adding json values into it [\\#436](https://github.com/nlohmann/json/issues/436)\n- Typo in examples page [\\#434](https://github.com/nlohmann/json/issues/434)\n- avoid malformed json [\\#433](https://github.com/nlohmann/json/issues/433)\n- How to add json objects to a map? [\\#432](https://github.com/nlohmann/json/issues/432)\n- create json instance from raw json \\(unsigned char\\*\\) [\\#431](https://github.com/nlohmann/json/issues/431)\n- Getting std::invalid\\_argument: stream error when following example [\\#429](https://github.com/nlohmann/json/issues/429)\n- Forward declare-only header? [\\#427](https://github.com/nlohmann/json/issues/427)\n- Implicit conversion from array to object [\\#425](https://github.com/nlohmann/json/issues/425)\n- error C4996: 'strerror' when reading file [\\#422](https://github.com/nlohmann/json/issues/422)\n- Get an error - JSON pointer must be empty or begin with '/' [\\#421](https://github.com/nlohmann/json/issues/421)\n- size parameter for parse\\(\\) [\\#419](https://github.com/nlohmann/json/issues/419)\n- json.hpp forcibly defines GCC\\_VERSION [\\#417](https://github.com/nlohmann/json/issues/417)\n- Use-of-uninitialized-value \\(OSS-Fuzz issue 377\\) [\\#416](https://github.com/nlohmann/json/issues/416)\n- comparing to 0 literal [\\#414](https://github.com/nlohmann/json/issues/414)\n- Single char converted to ASCII code instead of string [\\#413](https://github.com/nlohmann/json/issues/413)\n- How to know if a string  was parsed as utf-8? [\\#406](https://github.com/nlohmann/json/issues/406)\n- Overloaded += to add objects to an array makes no sense? [\\#404](https://github.com/nlohmann/json/issues/404)\n- Finding a value in an array [\\#399](https://github.com/nlohmann/json/issues/399)\n- add release information in static function [\\#397](https://github.com/nlohmann/json/issues/397)\n- Optimize memory usage of json objects in combination with binary serialization [\\#373](https://github.com/nlohmann/json/issues/373)\n- Conversion operators not considered [\\#369](https://github.com/nlohmann/json/issues/369)\n- Append \".0\" to serialized floating\\_point values that are digits-only. [\\#362](https://github.com/nlohmann/json/issues/362)\n- Add a customization point for user-defined types [\\#328](https://github.com/nlohmann/json/issues/328)\n- Conformance report for reference [\\#307](https://github.com/nlohmann/json/issues/307)\n- Document the best way to serialize/deserialize user defined types to json [\\#298](https://github.com/nlohmann/json/issues/298)\n- Add StringView template typename to basic\\_json [\\#297](https://github.com/nlohmann/json/issues/297)\n- \\[Improvement\\] Add option to remove exceptions [\\#296](https://github.com/nlohmann/json/issues/296)\n- Performance in miloyip/nativejson-benchmark [\\#202](https://github.com/nlohmann/json/issues/202)\n\n## [v2.0.10](https://github.com/nlohmann/json/releases/tag/v2.0.10) (2017-01-02)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/2.0.10...v2.0.10)\n\n- Feature/clang sanitize [\\#410](https://github.com/nlohmann/json/pull/410) ([Daniel599](https://github.com/Daniel599))\n- Add Doozer build badge [\\#400](https://github.com/nlohmann/json/pull/400) ([andoma](https://github.com/andoma))\n\n## [2.0.10](https://github.com/nlohmann/json/releases/tag/2.0.10) (2017-01-02)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.9...2.0.10)\n\n- Heap-buffer-overflow \\(OSS-Fuzz issue 367\\) [\\#412](https://github.com/nlohmann/json/issues/412)\n- Heap-buffer-overflow \\(OSS-Fuzz issue 366\\) [\\#411](https://github.com/nlohmann/json/issues/411)\n- Use-of-uninitialized-value \\(OSS-Fuzz issue 347\\) [\\#409](https://github.com/nlohmann/json/issues/409)\n- Heap-buffer-overflow \\(OSS-Fuzz issue 344\\) [\\#408](https://github.com/nlohmann/json/issues/408)\n- Heap-buffer-overflow \\(OSS-Fuzz issue 343\\) [\\#407](https://github.com/nlohmann/json/issues/407)\n- Heap-buffer-overflow \\(OSS-Fuzz issue 342\\) [\\#405](https://github.com/nlohmann/json/issues/405)\n- strerror throwing error in compiler VS2015 [\\#403](https://github.com/nlohmann/json/issues/403)\n- json::parse of std::string being underlined by Visual Studio [\\#402](https://github.com/nlohmann/json/issues/402)\n- Explicitly getting string without .dump\\(\\)  [\\#401](https://github.com/nlohmann/json/issues/401)\n- Possible to speed up json::parse? [\\#398](https://github.com/nlohmann/json/issues/398)\n- the alphabetic order in the code influence console\\_output. [\\#396](https://github.com/nlohmann/json/issues/396)\n- Execute tests with clang sanitizers [\\#394](https://github.com/nlohmann/json/issues/394)\n- Check if library can be used with ETL [\\#361](https://github.com/nlohmann/json/issues/361)\n\n## [v2.0.9](https://github.com/nlohmann/json/releases/tag/v2.0.9) (2016-12-16)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/2.0.9...v2.0.9)\n\n- Replace class iterator and const\\_iterator by using a single template class to reduce code. [\\#395](https://github.com/nlohmann/json/pull/395) ([Bosswestfalen](https://github.com/Bosswestfalen))\n- Clang: quiet a warning [\\#391](https://github.com/nlohmann/json/pull/391) ([jaredgrubb](https://github.com/jaredgrubb))\n- Fix issue \\#380: Signed integer overflow check [\\#390](https://github.com/nlohmann/json/pull/390) ([qwename](https://github.com/qwename))\n\n## [2.0.9](https://github.com/nlohmann/json/releases/tag/2.0.9) (2016-12-16)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.8...2.0.9)\n\n- \\#pragma GCC diagnostic ignored \"-Wdocumentation\" [\\#393](https://github.com/nlohmann/json/issues/393)\n- How to parse this json file and write separate sub object as json files? [\\#392](https://github.com/nlohmann/json/issues/392)\n- Integer-overflow \\(OSS-Fuzz issue 267\\) [\\#389](https://github.com/nlohmann/json/issues/389)\n- Implement indefinite-length types from RFC 7049 [\\#387](https://github.com/nlohmann/json/issues/387)\n- template parameter \"T\" is not used in declaring the parameter types of function template [\\#386](https://github.com/nlohmann/json/issues/386)\n- Serializing json instances containing already serialized string values without escaping [\\#385](https://github.com/nlohmann/json/issues/385)\n- Add test cases from RFC 7049 [\\#384](https://github.com/nlohmann/json/issues/384)\n- Add a table of contents to the README file [\\#383](https://github.com/nlohmann/json/issues/383)\n- Update FAQ section in the guidelines for contributing [\\#382](https://github.com/nlohmann/json/issues/382)\n- Allow for forward declaring nlohmann::json [\\#381](https://github.com/nlohmann/json/issues/381)\n- Bug in overflow detection when parsing integers [\\#380](https://github.com/nlohmann/json/issues/380)\n- A unique name to mention the library? [\\#377](https://github.com/nlohmann/json/issues/377)\n- Non-unique keys in objects. [\\#375](https://github.com/nlohmann/json/issues/375)\n- Request: binary serialization/deserialization [\\#358](https://github.com/nlohmann/json/issues/358)\n\n## [v2.0.8](https://github.com/nlohmann/json/releases/tag/v2.0.8) (2016-12-02)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/2.0.8...v2.0.8)\n\n## [2.0.8](https://github.com/nlohmann/json/releases/tag/2.0.8) (2016-12-02)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.7...2.0.8)\n\n- Reading from file [\\#374](https://github.com/nlohmann/json/issues/374)\n- Compiler warnings? [\\#372](https://github.com/nlohmann/json/issues/372)\n- docs: how to release a json object in memory? [\\#371](https://github.com/nlohmann/json/issues/371)\n- crash in dump [\\#370](https://github.com/nlohmann/json/issues/370)\n- Coverity issue \\(FORWARD\\_NULL\\) in lexer\\(std::istream& s\\) [\\#368](https://github.com/nlohmann/json/issues/368)\n- json::parse on failed stream gets stuck [\\#366](https://github.com/nlohmann/json/issues/366)\n- Performance improvements [\\#365](https://github.com/nlohmann/json/issues/365)\n- 'to\\_string' is not a member of 'std'  [\\#364](https://github.com/nlohmann/json/issues/364)\n- Crash in dump\\(\\) from a static object [\\#359](https://github.com/nlohmann/json/issues/359)\n- json::parse\\(...\\) vs json j; j.parse\\(...\\) [\\#357](https://github.com/nlohmann/json/issues/357)\n- Hi, is there any method to dump  json to string with the insert order rather than alphabets [\\#356](https://github.com/nlohmann/json/issues/356)\n- Provide an example of reading from an json with only a key that has an array of strings. [\\#354](https://github.com/nlohmann/json/issues/354)\n- Request: access with default value. [\\#353](https://github.com/nlohmann/json/issues/353)\n- {} and \\[\\] causes parser error. [\\#352](https://github.com/nlohmann/json/issues/352)\n- Reading a JSON file into a JSON object [\\#351](https://github.com/nlohmann/json/issues/351)\n- Request: 'emplace\\_back' [\\#349](https://github.com/nlohmann/json/issues/349)\n- Is it possible to stream data through the json parser without storing everything in memory? [\\#347](https://github.com/nlohmann/json/issues/347)\n- pure virtual conversion operator [\\#346](https://github.com/nlohmann/json/issues/346)\n- Floating point precision lost [\\#345](https://github.com/nlohmann/json/issues/345)\n- unit-conversions SIGSEGV on armv7hl [\\#303](https://github.com/nlohmann/json/issues/303)\n- Coverity scan fails [\\#299](https://github.com/nlohmann/json/issues/299)\n- Using QString as string type [\\#274](https://github.com/nlohmann/json/issues/274)\n\n## [v2.0.7](https://github.com/nlohmann/json/releases/tag/v2.0.7) (2016-11-02)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.6...v2.0.7)\n\n- JSON5 [\\#348](https://github.com/nlohmann/json/issues/348)\n- Check \"Parsing JSON is a Minefield\" [\\#344](https://github.com/nlohmann/json/issues/344)\n- Allow hex numbers [\\#342](https://github.com/nlohmann/json/issues/342)\n- Convert strings to numbers [\\#341](https://github.com/nlohmann/json/issues/341)\n- \"\"-operators ignore the length parameter [\\#340](https://github.com/nlohmann/json/issues/340)\n- JSON into std::tuple [\\#339](https://github.com/nlohmann/json/issues/339)\n- JSON into vector [\\#335](https://github.com/nlohmann/json/issues/335)\n- Installing with Homebrew on Mac Errors \\(El Capitan\\) [\\#331](https://github.com/nlohmann/json/issues/331)\n- g++ make check results in error [\\#312](https://github.com/nlohmann/json/issues/312)\n- Cannot convert from 'json' to 'char' [\\#276](https://github.com/nlohmann/json/issues/276)\n- Please add a Pretty-Print option for arrays to stay always in one line [\\#229](https://github.com/nlohmann/json/issues/229)\n- Conversion to STL map\\<string, vector\\<int\\>\\> gives error [\\#220](https://github.com/nlohmann/json/issues/220)\n- std::unorderd\\_map cannot be used as ObjectType [\\#164](https://github.com/nlohmann/json/issues/164)\n\n- fix minor grammar/style issue in README.md [\\#336](https://github.com/nlohmann/json/pull/336) ([seeekr](https://github.com/seeekr))\n\n## [v2.0.6](https://github.com/nlohmann/json/releases/tag/v2.0.6) (2016-10-15)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.5...v2.0.6)\n\n- How to handle json files? [\\#333](https://github.com/nlohmann/json/issues/333)\n- This file requires compiler and library support .... [\\#332](https://github.com/nlohmann/json/issues/332)\n- Segmentation fault on saving json to file [\\#326](https://github.com/nlohmann/json/issues/326)\n- parse error - unexpected \\<uninitialized\\> with 2.0.5 [\\#325](https://github.com/nlohmann/json/issues/325)\n- Add nested object capability to pointers [\\#323](https://github.com/nlohmann/json/issues/323)\n- Fix usage examples' comments for std::multiset [\\#322](https://github.com/nlohmann/json/issues/322)\n- json\\_unit runs forever when executed in build directory [\\#319](https://github.com/nlohmann/json/issues/319)\n- Visual studio 2015 update3 true != TRUE [\\#317](https://github.com/nlohmann/json/issues/317)\n- releasing single header file in compressed format [\\#316](https://github.com/nlohmann/json/issues/316)\n- json object from std::ifstream [\\#315](https://github.com/nlohmann/json/issues/315)\n\n- make has\\_mapped\\_type struct friendly [\\#324](https://github.com/nlohmann/json/pull/324) ([vpetrigo](https://github.com/vpetrigo))\n- Fix usage examples' comments for std::multiset [\\#321](https://github.com/nlohmann/json/pull/321) ([vasild](https://github.com/vasild))\n- Include dir relocation [\\#318](https://github.com/nlohmann/json/pull/318) ([ChristophJud](https://github.com/ChristophJud))\n- trivial documentation fix [\\#313](https://github.com/nlohmann/json/pull/313) ([5tefan](https://github.com/5tefan))\n\n## [v2.0.5](https://github.com/nlohmann/json/releases/tag/v2.0.5) (2016-09-14)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.4...v2.0.5)\n\n- \\[feature request\\]: schema validator and comments [\\#311](https://github.com/nlohmann/json/issues/311)\n- make json\\_benchmarks no longer working in 2.0.4 [\\#310](https://github.com/nlohmann/json/issues/310)\n- Segmentation fault \\(core dumped\\) [\\#309](https://github.com/nlohmann/json/issues/309)\n- No matching member function for call to 'get\\_impl' [\\#308](https://github.com/nlohmann/json/issues/308)\n\n## [v2.0.4](https://github.com/nlohmann/json/releases/tag/v2.0.4) (2016-09-11)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.3...v2.0.4)\n\n- Parsing fails without space at end of file [\\#306](https://github.com/nlohmann/json/issues/306)\n- json schema validator [\\#305](https://github.com/nlohmann/json/issues/305)\n- Unused variable warning [\\#304](https://github.com/nlohmann/json/issues/304)\n\n## [v2.0.3](https://github.com/nlohmann/json/releases/tag/v2.0.3) (2016-08-31)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.2...v2.0.3)\n\n- warning C4706: assignment within conditional expression [\\#295](https://github.com/nlohmann/json/issues/295)\n- Q: Is it possible to build json tree from already UTF8 encoded values? [\\#293](https://github.com/nlohmann/json/issues/293)\n- Equality operator results in array when assigned object [\\#292](https://github.com/nlohmann/json/issues/292)\n- Support for integers not from the range \\[-\\(2\\*\\*53\\)+1, \\(2\\*\\*53\\)-1\\] in parser [\\#291](https://github.com/nlohmann/json/issues/291)\n- Support for iterator-range parsing [\\#290](https://github.com/nlohmann/json/issues/290)\n- Horribly inconsistent behavior between const/non-const reference in operator \\[\\] \\(\\) [\\#289](https://github.com/nlohmann/json/issues/289)\n- Silently get numbers into smaller types [\\#288](https://github.com/nlohmann/json/issues/288)\n- Incorrect parsing of large int64\\_t numbers [\\#287](https://github.com/nlohmann/json/issues/287)\n- \\[question\\]: macro to disable floating point support [\\#284](https://github.com/nlohmann/json/issues/284)\n\n- unit-constructor1.cpp: Fix floating point truncation warning [\\#300](https://github.com/nlohmann/json/pull/300) ([t-b](https://github.com/t-b))\n\n## [v2.0.2](https://github.com/nlohmann/json/releases/tag/v2.0.2) (2016-07-31)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.1...v2.0.2)\n\n- can function dump\\(\\)  return string in the order I push in the json object ? [\\#286](https://github.com/nlohmann/json/issues/286)\n- Error on the Mac: Undefined symbols for architecture x86\\_64 [\\#285](https://github.com/nlohmann/json/issues/285)\n- value\\(\\) does not work with \\_json\\_pointer types [\\#283](https://github.com/nlohmann/json/issues/283)\n- Build error for std::int64 [\\#282](https://github.com/nlohmann/json/issues/282)\n- strings can't be accessed after dump\\(\\)-\\>parse\\(\\) - type is lost [\\#281](https://github.com/nlohmann/json/issues/281)\n- Easy serialization of classes [\\#280](https://github.com/nlohmann/json/issues/280)\n- recursive data structures [\\#277](https://github.com/nlohmann/json/issues/277)\n- hexify\\(\\) function emits conversion warning [\\#270](https://github.com/nlohmann/json/issues/270)\n\n- let the makefile choose the correct sed [\\#279](https://github.com/nlohmann/json/pull/279) ([murinicanor](https://github.com/murinicanor))\n- Update hexify to use array lookup instead of ternary \\(\\#270\\) [\\#275](https://github.com/nlohmann/json/pull/275) ([dtoma](https://github.com/dtoma))\n\n## [v2.0.1](https://github.com/nlohmann/json/releases/tag/v2.0.1) (2016-06-28)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...v2.0.1)\n\n- Compilation error. [\\#273](https://github.com/nlohmann/json/issues/273)\n- dump\\(\\) performance degradation in v2 [\\#272](https://github.com/nlohmann/json/issues/272)\n\n- fixed a tiny typo [\\#271](https://github.com/nlohmann/json/pull/271) ([feroldi](https://github.com/feroldi))\n\n## [v2.0.0](https://github.com/nlohmann/json/releases/tag/v2.0.0) (2016-06-23)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...v2.0.0)\n\n- json::diff generates incorrect patch when removing multiple array elements. [\\#269](https://github.com/nlohmann/json/issues/269)\n- Docs - What does Json\\[key\\] return? [\\#267](https://github.com/nlohmann/json/issues/267)\n- Compiler Errors With JSON.hpp [\\#265](https://github.com/nlohmann/json/issues/265)\n- Ambiguous push\\_back and operator+= overloads [\\#263](https://github.com/nlohmann/json/issues/263)\n- Preseving order of items in json [\\#262](https://github.com/nlohmann/json/issues/262)\n- '\\' char problem in strings [\\#261](https://github.com/nlohmann/json/issues/261)\n- VS2015 compile fail [\\#260](https://github.com/nlohmann/json/issues/260)\n- -Wconversion warning [\\#259](https://github.com/nlohmann/json/issues/259)\n- Maybe a bug [\\#258](https://github.com/nlohmann/json/issues/258)\n- Few tests failed on Visual C++ 2015 [\\#257](https://github.com/nlohmann/json/issues/257)\n- Access keys when iteration with new for loop C++11 [\\#256](https://github.com/nlohmann/json/issues/256)\n- multiline text values [\\#255](https://github.com/nlohmann/json/issues/255)\n- Error when using json in g++ [\\#254](https://github.com/nlohmann/json/issues/254)\n- is the release 2.0? [\\#253](https://github.com/nlohmann/json/issues/253)\n- concatenate objects [\\#252](https://github.com/nlohmann/json/issues/252)\n- Encoding [\\#251](https://github.com/nlohmann/json/issues/251)\n- Unable to build example for constructing json object with stringstreams [\\#250](https://github.com/nlohmann/json/issues/250)\n- Hexadecimal support [\\#249](https://github.com/nlohmann/json/issues/249)\n- Update long-term goals [\\#246](https://github.com/nlohmann/json/issues/246)\n- Contribution To This Json Project [\\#245](https://github.com/nlohmann/json/issues/245)\n- Trouble using parser with initial dictionary [\\#243](https://github.com/nlohmann/json/issues/243)\n- Unit test fails when doing a CMake out-of-tree build [\\#241](https://github.com/nlohmann/json/issues/241)\n- -Wconversion warnings [\\#239](https://github.com/nlohmann/json/issues/239)\n- Additional integration options [\\#237](https://github.com/nlohmann/json/issues/237)\n- .get\\<std::string\\>\\(\\) works for non spaced string but returns as array for spaced/longer strings [\\#236](https://github.com/nlohmann/json/issues/236)\n- ambiguous overload for 'push\\_back' and 'operator+=' [\\#235](https://github.com/nlohmann/json/issues/235)\n- Can't use basic\\_json::iterator as a base iterator for std::move\\_iterator [\\#233](https://github.com/nlohmann/json/issues/233)\n- json object's creation can freezes execution [\\#231](https://github.com/nlohmann/json/issues/231)\n- Incorrect dumping of parsed numbers with exponents, but without decimal places [\\#230](https://github.com/nlohmann/json/issues/230)\n- double values are serialized with commas as decimal points [\\#228](https://github.com/nlohmann/json/issues/228)\n- Move semantics with std::initializer\\_list [\\#225](https://github.com/nlohmann/json/issues/225)\n- replace emplace [\\#224](https://github.com/nlohmann/json/issues/224)\n- abort during getline in yyfill [\\#223](https://github.com/nlohmann/json/issues/223)\n- free\\(\\): invalid pointer error in GCC 5.2.1 [\\#221](https://github.com/nlohmann/json/issues/221)\n- Error compile Android NDK  error: 'strtof' is not a member of 'std' [\\#219](https://github.com/nlohmann/json/issues/219)\n- Wrong link in the README.md [\\#217](https://github.com/nlohmann/json/issues/217)\n- Wide character strings not supported [\\#216](https://github.com/nlohmann/json/issues/216)\n- Memory allocations using range-based for loops [\\#214](https://github.com/nlohmann/json/issues/214)\n- would you like to support gcc 4.8.1?  [\\#211](https://github.com/nlohmann/json/issues/211)\n- Reading concatenated json's from an istream [\\#210](https://github.com/nlohmann/json/issues/210)\n- Conflicting typedef of ssize\\_t on Windows 32 bit when using Boost.Python [\\#204](https://github.com/nlohmann/json/issues/204)\n- Inconsistency between operator\\[\\] and push\\_back [\\#203](https://github.com/nlohmann/json/issues/203)\n- Small bugs in json.hpp \\(get\\_number\\) and unit.cpp \\(non-standard integer type test\\) [\\#199](https://github.com/nlohmann/json/issues/199)\n- GCC/clang floating point parsing bug in strtod\\(\\) [\\#195](https://github.com/nlohmann/json/issues/195)\n- What is within scope? [\\#192](https://github.com/nlohmann/json/issues/192)\n- Bugs in miloyip/nativejson-benchmark: roundtrips [\\#187](https://github.com/nlohmann/json/issues/187)\n- Floating point exceptions [\\#181](https://github.com/nlohmann/json/issues/181)\n- Integer conversion to unsigned [\\#178](https://github.com/nlohmann/json/issues/178)\n- map string string fails to compile [\\#176](https://github.com/nlohmann/json/issues/176)\n- In basic\\_json::basic\\_json\\(const CompatibleArrayType& val\\), the requirement of CompatibleArrayType is not strict enough. [\\#174](https://github.com/nlohmann/json/issues/174)\n- Provide a FAQ [\\#163](https://github.com/nlohmann/json/issues/163)\n- Implicit assignment to std::string fails [\\#144](https://github.com/nlohmann/json/issues/144)\n\n- Fix Issue \\#265 [\\#266](https://github.com/nlohmann/json/pull/266) ([06needhamt](https://github.com/06needhamt))\n- Define CMake/CTest tests [\\#247](https://github.com/nlohmann/json/pull/247) ([robertmrk](https://github.com/robertmrk))\n- Out of tree builds and a few other miscellaneous CMake cleanups. [\\#242](https://github.com/nlohmann/json/pull/242) ([ChrisKitching](https://github.com/ChrisKitching))\n- Implement additional integration options [\\#238](https://github.com/nlohmann/json/pull/238) ([robertmrk](https://github.com/robertmrk))\n- make serialization locale-independent [\\#232](https://github.com/nlohmann/json/pull/232) ([nlohmann](https://github.com/nlohmann))\n- fixes \\#223 by updating README.md [\\#227](https://github.com/nlohmann/json/pull/227) ([kevin--](https://github.com/kevin--))\n- Use namespace std for int64\\_t and uint64\\_t [\\#226](https://github.com/nlohmann/json/pull/226) ([lv-zheng](https://github.com/lv-zheng))\n- Added missing cerrno header to fix ERANGE compile error on android [\\#222](https://github.com/nlohmann/json/pull/222) ([Teemperor](https://github.com/Teemperor))\n- Corrected readme [\\#218](https://github.com/nlohmann/json/pull/218) ([Annihil](https://github.com/Annihil))\n- Create PULL\\_REQUEST\\_TEMPLATE.md [\\#213](https://github.com/nlohmann/json/pull/213) ([whackashoe](https://github.com/whackashoe))\n- fixed noexcept; added constexpr [\\#208](https://github.com/nlohmann/json/pull/208) ([nlohmann](https://github.com/nlohmann))\n- Add support for afl-fuzz testing [\\#207](https://github.com/nlohmann/json/pull/207) ([mykter](https://github.com/mykter))\n- replaced ssize\\_t occurrences with auto \\(addresses \\#204\\) [\\#205](https://github.com/nlohmann/json/pull/205) ([nlohmann](https://github.com/nlohmann))\n- Fixed issue \\#199 - Small bugs in json.hpp \\(get\\_number\\) and unit.cpp \\(non-standard integer type test\\) [\\#200](https://github.com/nlohmann/json/pull/200) ([twelsby](https://github.com/twelsby))\n- Fix broken link [\\#197](https://github.com/nlohmann/json/pull/197) ([vog](https://github.com/vog))\n- Issue \\#195 - update Travis to Trusty due to gcc/clang strtod\\(\\) bug [\\#196](https://github.com/nlohmann/json/pull/196) ([twelsby](https://github.com/twelsby))\n- Issue \\#178 - Extending support to full uint64\\_t/int64\\_t range and unsigned type \\(updated\\) [\\#193](https://github.com/nlohmann/json/pull/193) ([twelsby](https://github.com/twelsby))\n\n## [v1.1.0](https://github.com/nlohmann/json/releases/tag/v1.1.0) (2016-01-24)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0...v1.1.0)\n\n- Small error in pull \\#185 [\\#194](https://github.com/nlohmann/json/issues/194)\n- Bugs in miloyip/nativejson-benchmark: floating-point parsing [\\#186](https://github.com/nlohmann/json/issues/186)\n- Floating point equality [\\#185](https://github.com/nlohmann/json/issues/185)\n- Unused variables in catch [\\#180](https://github.com/nlohmann/json/issues/180)\n- Typo in documentation [\\#179](https://github.com/nlohmann/json/issues/179)\n- JSON performance benchmark comparision [\\#177](https://github.com/nlohmann/json/issues/177)\n- Since re2c is often ignored in pull requests, it may make sense to make a contributing.md file [\\#175](https://github.com/nlohmann/json/issues/175)\n- Question about exceptions [\\#173](https://github.com/nlohmann/json/issues/173)\n- Android? [\\#172](https://github.com/nlohmann/json/issues/172)\n- Cannot index by key of type static constexpr const char\\* [\\#171](https://github.com/nlohmann/json/issues/171)\n- Add assertions [\\#168](https://github.com/nlohmann/json/issues/168)\n- MSVC 2015 build fails when attempting to compare object\\_t [\\#167](https://github.com/nlohmann/json/issues/167)\n- Member detector is not portable [\\#166](https://github.com/nlohmann/json/issues/166)\n- Unnecessary const\\_cast [\\#162](https://github.com/nlohmann/json/issues/162)\n- Question about get\\_ref\\(\\) [\\#128](https://github.com/nlohmann/json/issues/128)\n- range based for loop for objects [\\#83](https://github.com/nlohmann/json/issues/83)\n- Consider submitting this to the Boost Library Incubator [\\#66](https://github.com/nlohmann/json/issues/66)\n\n- Fixed Issue \\#186 - add strto\\(f|d|ld\\) overload wrappers, \"-0.0\" special case and FP trailing zero [\\#191](https://github.com/nlohmann/json/pull/191) ([twelsby](https://github.com/twelsby))\n- Issue \\#185 - remove approx\\(\\) and use \\#pragma to kill warnings [\\#190](https://github.com/nlohmann/json/pull/190) ([twelsby](https://github.com/twelsby))\n- Fixed Issue \\#171 - added two extra template overloads of operator\\[\\] for T\\* arguments [\\#189](https://github.com/nlohmann/json/pull/189) ([twelsby](https://github.com/twelsby))\n- Fixed issue \\#167 - removed operator ValueType\\(\\) condition for VS2015 [\\#188](https://github.com/nlohmann/json/pull/188) ([twelsby](https://github.com/twelsby))\n- Implementation of get\\_ref\\(\\) [\\#184](https://github.com/nlohmann/json/pull/184) ([dariomt](https://github.com/dariomt))\n- Fixed some typos in CONTRIBUTING.md [\\#182](https://github.com/nlohmann/json/pull/182) ([nibroc](https://github.com/nibroc))\n\n## [v1.0.0](https://github.com/nlohmann/json/releases/tag/v1.0.0) (2015-12-27)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0-rc1...v1.0.0)\n\n- add key name to exception [\\#160](https://github.com/nlohmann/json/issues/160)\n- Getting member discarding qualifyer [\\#159](https://github.com/nlohmann/json/issues/159)\n- basic\\_json::iterator::value\\(\\) output includes quotes while basic\\_json::iterator::key\\(\\) doesn't [\\#158](https://github.com/nlohmann/json/issues/158)\n- Indexing `const basic_json<>` with `const basic_string<char>` [\\#157](https://github.com/nlohmann/json/issues/157)\n- token\\_type\\_name\\(token\\_type t\\): not all control paths return a value [\\#156](https://github.com/nlohmann/json/issues/156)\n- prevent json.hpp from emitting compiler warnings [\\#154](https://github.com/nlohmann/json/issues/154)\n- json::parse\\(string\\) does not check utf8 bom [\\#152](https://github.com/nlohmann/json/issues/152)\n- unsigned 64bit values output as signed [\\#151](https://github.com/nlohmann/json/issues/151)\n- Wish feature: json5 [\\#150](https://github.com/nlohmann/json/issues/150)\n- Unable to compile on MSVC 2015 with SDL checking enabled: This function or variable may be unsafe. [\\#149](https://github.com/nlohmann/json/issues/149)\n- \"Json Object\" type does not keep object order [\\#148](https://github.com/nlohmann/json/issues/148)\n- dump\\(\\)  convert strings encoded by utf-8 to shift-jis on windows 10.  [\\#147](https://github.com/nlohmann/json/issues/147)\n- Unable to get field names in a json object [\\#145](https://github.com/nlohmann/json/issues/145)\n- Question: Is the use of incomplete type correct? [\\#138](https://github.com/nlohmann/json/issues/138)\n- json.hpp:5746:32: error: 'to\\_string' is not a member of 'std' [\\#136](https://github.com/nlohmann/json/issues/136)\n- Bug in basic\\_json::operator\\[\\] const overload [\\#135](https://github.com/nlohmann/json/issues/135)\n- wrong enable\\_if for const pointer \\(instead of pointer-to-const\\) [\\#134](https://github.com/nlohmann/json/issues/134)\n- overload of at\\(\\) with default value [\\#133](https://github.com/nlohmann/json/issues/133)\n- Splitting source [\\#132](https://github.com/nlohmann/json/issues/132)\n- Question about get\\_ptr\\(\\) [\\#127](https://github.com/nlohmann/json/issues/127)\n- Visual Studio 14 Debug assertion failed [\\#125](https://github.com/nlohmann/json/issues/125)\n- Memory leak in face of exceptions [\\#118](https://github.com/nlohmann/json/issues/118)\n- Find and Count for arrays [\\#117](https://github.com/nlohmann/json/issues/117)\n- dynamically constructing an arbitrarily nested object [\\#114](https://github.com/nlohmann/json/issues/114)\n- Returning any data type [\\#113](https://github.com/nlohmann/json/issues/113)\n- Compile error with g++ 4.9.3 cygwin 64-bit [\\#112](https://github.com/nlohmann/json/issues/112)\n- insert json array issue with gcc4.8.2 [\\#110](https://github.com/nlohmann/json/issues/110)\n- error: unterminated raw string [\\#109](https://github.com/nlohmann/json/issues/109)\n- vector\\<json\\> copy constructor really weird [\\#108](https://github.com/nlohmann/json/issues/108)\n- \\[clang-3.6.2\\] string/sstream with number to json issue [\\#107](https://github.com/nlohmann/json/issues/107)\n- object field accessors [\\#103](https://github.com/nlohmann/json/issues/103)\n- v8pp and json [\\#95](https://github.com/nlohmann/json/issues/95)\n- Wishlist [\\#65](https://github.com/nlohmann/json/issues/65)\n- Windows/Visual Studio \\(through 2013\\) is unsupported [\\#62](https://github.com/nlohmann/json/issues/62)\n\n- Replace sprintf with hex function, this fixes \\#149 [\\#153](https://github.com/nlohmann/json/pull/153) ([whackashoe](https://github.com/whackashoe))\n- Fix character skipping after a surrogate pair [\\#146](https://github.com/nlohmann/json/pull/146) ([robertmrk](https://github.com/robertmrk))\n- Detect correctly pointer-to-const [\\#137](https://github.com/nlohmann/json/pull/137) ([dariomt](https://github.com/dariomt))\n- disabled \"CopyAssignable\" test for MSVC in Debug mode, see \\#125 [\\#131](https://github.com/nlohmann/json/pull/131) ([dariomt](https://github.com/dariomt))\n- removed stream operator for iterator, resolution for \\#125 [\\#130](https://github.com/nlohmann/json/pull/130) ([dariomt](https://github.com/dariomt))\n- fixed typos in comments for examples [\\#129](https://github.com/nlohmann/json/pull/129) ([dariomt](https://github.com/dariomt))\n- Remove superfluous inefficiency [\\#126](https://github.com/nlohmann/json/pull/126) ([d-frey](https://github.com/d-frey))\n- remove invalid parameter '-stdlib=libc++' in CMakeLists.txt [\\#124](https://github.com/nlohmann/json/pull/124) ([emvivre](https://github.com/emvivre))\n- exception-safe object creation, fixes \\#118 [\\#122](https://github.com/nlohmann/json/pull/122) ([d-frey](https://github.com/d-frey))\n- Fix small oversight. [\\#121](https://github.com/nlohmann/json/pull/121) ([ColinH](https://github.com/ColinH))\n- Overload parse\\(\\) to accept an rvalue reference [\\#120](https://github.com/nlohmann/json/pull/120) ([silverweed](https://github.com/silverweed))\n- Use the right variable name in doc string [\\#115](https://github.com/nlohmann/json/pull/115) ([whoshuu](https://github.com/whoshuu))\n\n## [v1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1) (2015-07-26)\n\n[Full Changelog](https://github.com/nlohmann/json/compare/4502e7e51c0569419c26e75fbdd5748170603e54...v1.0.0-rc1)\n\n- Finish documenting the public interface in Doxygen [\\#102](https://github.com/nlohmann/json/issues/102)\n- Binary string causes numbers to be dumped as hex [\\#101](https://github.com/nlohmann/json/issues/101)\n- failed to iterator json object with reverse\\_iterator [\\#100](https://github.com/nlohmann/json/issues/100)\n- 'noexcept' : unknown override specifier [\\#99](https://github.com/nlohmann/json/issues/99)\n- json float parsing problem [\\#98](https://github.com/nlohmann/json/issues/98)\n- Adjust wording to JSON RFC [\\#97](https://github.com/nlohmann/json/issues/97)\n- static analysis warnings [\\#94](https://github.com/nlohmann/json/issues/94)\n- reverse\\_iterator operator inheritance problem [\\#93](https://github.com/nlohmann/json/issues/93)\n- init error [\\#92](https://github.com/nlohmann/json/issues/92)\n- access by \\(const\\) reference [\\#91](https://github.com/nlohmann/json/issues/91)\n- is\\_integer and is\\_float tests [\\#90](https://github.com/nlohmann/json/issues/90)\n- Nonstandard integer type [\\#89](https://github.com/nlohmann/json/issues/89)\n- static library build [\\#84](https://github.com/nlohmann/json/issues/84)\n- lexer::get\\_number return NAN [\\#82](https://github.com/nlohmann/json/issues/82)\n- MinGW have no std::to\\_string [\\#80](https://github.com/nlohmann/json/issues/80)\n- Incorrect behaviour of basic\\_json::count method [\\#78](https://github.com/nlohmann/json/issues/78)\n- Invoking is\\_array\\(\\) function creates \"null\" value [\\#77](https://github.com/nlohmann/json/issues/77)\n- dump\\(\\) / parse\\(\\) not idempotent [\\#76](https://github.com/nlohmann/json/issues/76)\n- Handle infinity and NaN cases [\\#70](https://github.com/nlohmann/json/issues/70)\n- errors in g++-4.8.1 [\\#68](https://github.com/nlohmann/json/issues/68)\n- Keys when iterating over objects [\\#67](https://github.com/nlohmann/json/issues/67)\n- Compilation results in tons of warnings [\\#64](https://github.com/nlohmann/json/issues/64)\n- Complete brief documentation [\\#61](https://github.com/nlohmann/json/issues/61)\n- Double quotation mark is not parsed correctly [\\#60](https://github.com/nlohmann/json/issues/60)\n- Get coverage back to 100% [\\#58](https://github.com/nlohmann/json/issues/58)\n- erase elements using iterators [\\#57](https://github.com/nlohmann/json/issues/57)\n- Removing item from array [\\#56](https://github.com/nlohmann/json/issues/56)\n- Serialize/Deserialize like PHP? [\\#55](https://github.com/nlohmann/json/issues/55)\n- Numbers as keys [\\#54](https://github.com/nlohmann/json/issues/54)\n- Why are elements alphabetized on key while iterating? [\\#53](https://github.com/nlohmann/json/issues/53)\n- Document erase, count, and iterators key and value [\\#52](https://github.com/nlohmann/json/issues/52)\n- Do not use std::to\\_string [\\#51](https://github.com/nlohmann/json/issues/51)\n- Supported compilers [\\#50](https://github.com/nlohmann/json/issues/50)\n- Confused about iterating through json objects [\\#49](https://github.com/nlohmann/json/issues/49)\n- Use non-member begin/end [\\#48](https://github.com/nlohmann/json/issues/48)\n- Erase key [\\#47](https://github.com/nlohmann/json/issues/47)\n- Key iterator [\\#46](https://github.com/nlohmann/json/issues/46)\n- Add count member function [\\#45](https://github.com/nlohmann/json/issues/45)\n- Problem getting vector \\(array\\) of strings [\\#44](https://github.com/nlohmann/json/issues/44)\n- Compilation error due to assuming that private=public [\\#43](https://github.com/nlohmann/json/issues/43)\n- Use of deprecated implicit copy constructor [\\#42](https://github.com/nlohmann/json/issues/42)\n- Printing attribute names [\\#39](https://github.com/nlohmann/json/issues/39)\n- dumping a small number\\_float just outputs 0.000000 [\\#37](https://github.com/nlohmann/json/issues/37)\n- find is error [\\#32](https://github.com/nlohmann/json/issues/32)\n- Avoid using spaces when encoding without pretty print [\\#31](https://github.com/nlohmann/json/issues/31)\n- Cannot encode long numbers [\\#30](https://github.com/nlohmann/json/issues/30)\n- segmentation fault when iterating over empty arrays/objects [\\#28](https://github.com/nlohmann/json/issues/28)\n- Creating an empty array [\\#27](https://github.com/nlohmann/json/issues/27)\n- Custom allocator support [\\#25](https://github.com/nlohmann/json/issues/25)\n- make the type of the used string container customizable [\\#20](https://github.com/nlohmann/json/issues/20)\n- Improper parsing of JSON string \"\\\\\" [\\#17](https://github.com/nlohmann/json/issues/17)\n- create a header-only version [\\#16](https://github.com/nlohmann/json/issues/16)\n- Don't return \"const values\" [\\#15](https://github.com/nlohmann/json/issues/15)\n- Add to\\_string overload for indentation [\\#13](https://github.com/nlohmann/json/issues/13)\n- string parser does not recognize uncompliant strings [\\#12](https://github.com/nlohmann/json/issues/12)\n- possible double-free in find function [\\#11](https://github.com/nlohmann/json/issues/11)\n- UTF-8 encoding/deconding/testing [\\#10](https://github.com/nlohmann/json/issues/10)\n- move code into namespace [\\#9](https://github.com/nlohmann/json/issues/9)\n- free functions for explicit objects and arrays in initializer lists [\\#8](https://github.com/nlohmann/json/issues/8)\n- unique\\_ptr for ownership [\\#7](https://github.com/nlohmann/json/issues/7)\n- Add unit tests [\\#4](https://github.com/nlohmann/json/issues/4)\n- Drop C++98 support [\\#3](https://github.com/nlohmann/json/issues/3)\n- Test case coverage [\\#2](https://github.com/nlohmann/json/issues/2)\n- Runtime error in Travis job [\\#1](https://github.com/nlohmann/json/issues/1)\n\n- Keyword 'inline' is useless when member functions are defined in headers [\\#87](https://github.com/nlohmann/json/pull/87) ([ahamez](https://github.com/ahamez))\n- Remove useless typename [\\#86](https://github.com/nlohmann/json/pull/86) ([ahamez](https://github.com/ahamez))\n- Avoid warning with Xcode's clang [\\#85](https://github.com/nlohmann/json/pull/85) ([ahamez](https://github.com/ahamez))\n-  Fix typos [\\#73](https://github.com/nlohmann/json/pull/73) ([aqnouch](https://github.com/aqnouch))\n- Replace `default_callback` function with `nullptr` and check for null… [\\#72](https://github.com/nlohmann/json/pull/72) ([aburgh](https://github.com/aburgh))\n- support enum [\\#71](https://github.com/nlohmann/json/pull/71) ([likebeta](https://github.com/likebeta))\n- Fix performance regression introduced with the parsing callback feature. [\\#69](https://github.com/nlohmann/json/pull/69) ([aburgh](https://github.com/aburgh))\n- Improve the implementations of the comparission-operators [\\#63](https://github.com/nlohmann/json/pull/63) ([Florianjw](https://github.com/Florianjw))\n- Fix compilation of json\\_unit with GCC 5 [\\#59](https://github.com/nlohmann/json/pull/59) ([dkopecek](https://github.com/dkopecek))\n- Parse streams incrementally. [\\#40](https://github.com/nlohmann/json/pull/40) ([aburgh](https://github.com/aburgh))\n- Feature/small float serialization [\\#38](https://github.com/nlohmann/json/pull/38) ([jrandall](https://github.com/jrandall))\n- template version with re2c scanner [\\#36](https://github.com/nlohmann/json/pull/36) ([nlohmann](https://github.com/nlohmann))\n- more descriptive documentation in example [\\#33](https://github.com/nlohmann/json/pull/33) ([luxe](https://github.com/luxe))\n- Fix string conversion under Clang [\\#26](https://github.com/nlohmann/json/pull/26) ([wancw](https://github.com/wancw))\n- Fixed dumping of strings [\\#24](https://github.com/nlohmann/json/pull/24) ([Teemperor](https://github.com/Teemperor))\n- Added a remark to the readme that coverage is GCC only for now [\\#23](https://github.com/nlohmann/json/pull/23) ([Teemperor](https://github.com/Teemperor))\n- Unicode escaping [\\#22](https://github.com/nlohmann/json/pull/22) ([Teemperor](https://github.com/Teemperor))\n- Implemented the JSON spec for string parsing for everything but the \\uXXXX escaping [\\#21](https://github.com/nlohmann/json/pull/21) ([Teemperor](https://github.com/Teemperor))\n- add the std iterator typedefs to iterator and const\\_iterator [\\#19](https://github.com/nlohmann/json/pull/19) ([kirkshoop](https://github.com/kirkshoop))\n- Fixed escaped quotes [\\#18](https://github.com/nlohmann/json/pull/18) ([Teemperor](https://github.com/Teemperor))\n- Fix double delete on std::bad\\_alloc exception [\\#14](https://github.com/nlohmann/json/pull/14) ([elliotgoodrich](https://github.com/elliotgoodrich))\n- Added CMake and lcov [\\#6](https://github.com/nlohmann/json/pull/6) ([Teemperor](https://github.com/Teemperor))\n- Version 2.0 [\\#5](https://github.com/nlohmann/json/pull/5) ([nlohmann](https://github.com/nlohmann))\n\n\n\n\\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*\n"
  },
  {
    "path": "subprojects/nlohmann_json/LICENSE.MIT",
    "content": "MIT License \n\nCopyright (c) 2013-2022 Niels Lohmann\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "subprojects/nlohmann_json/Makefile",
    "content": ".PHONY: pretty clean ChangeLog.md release\n\n##########################################################################\n# configuration\n##########################################################################\n\n# directory to recent compiler binaries\nCOMPILER_DIR=/usr/local/opt/llvm/bin\n\n# find GNU sed to use `-i` parameter\nSED:=$(shell command -v gsed || which sed)\n\n\n##########################################################################\n# source files\n##########################################################################\n\n# the list of sources in the include folder\nSRCS=$(shell find include -type f | sort)\n\n# the single header (amalgamated from the source files)\nAMALGAMATED_FILE=single_include/nlohmann/json.hpp\n\n\n##########################################################################\n# documentation of the Makefile's targets\n##########################################################################\n\n# main target\nall:\n\t@echo \"amalgamate - amalgamate file single_include/nlohmann/json.hpp from the include/nlohmann sources\"\n\t@echo \"ChangeLog.md - generate ChangeLog file\"\n\t@echo \"check-amalgamation - check whether sources have been amalgamated\"\n\t@echo \"clean - remove built files\"\n\t@echo \"doctest - compile example files and check their output\"\n\t@echo \"fuzz_testing - prepare fuzz testing of the JSON parser\"\n\t@echo \"fuzz_testing_bson - prepare fuzz testing of the BSON parser\"\n\t@echo \"fuzz_testing_cbor - prepare fuzz testing of the CBOR parser\"\n\t@echo \"fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser\"\n\t@echo \"fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser\"\n\t@echo \"pretty - beautify code with Artistic Style\"\n\t@echo \"run_benchmarks - build and run benchmarks\"\n\n\n##########################################################################\n# documentation tests\n##########################################################################\n\n# compile example files and check output\ndoctest:\n\t$(MAKE) check_output -C doc\n\n\n##########################################################################\n# benchmarks\n##########################################################################\n\nrun_benchmarks:\n\trm -fr cmake-build-benchmarks\n\tmkdir cmake-build-benchmarks\n\tcd cmake-build-benchmarks ; cmake ../benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release -DJSON_BuildTests=On\n\tcd cmake-build-benchmarks ; ninja\n\tcd cmake-build-benchmarks ; ./json_benchmarks\n\n##########################################################################\n# fuzzing\n##########################################################################\n\n# the overall fuzz testing target\nfuzz_testing:\n\trm -fr fuzz-testing\n\tmkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out\n\t$(MAKE) parse_afl_fuzzer -C test CXX=afl-clang++\n\tmv test/parse_afl_fuzzer fuzz-testing/fuzzer\n\tfind test/data/json_tests -size -5k -name *json | xargs -I{} cp \"{}\" fuzz-testing/testcases\n\t@echo \"Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer\"\n\nfuzz_testing_bson:\n\trm -fr fuzz-testing\n\tmkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out\n\t$(MAKE) parse_bson_fuzzer -C test CXX=afl-clang++\n\tmv test/parse_bson_fuzzer fuzz-testing/fuzzer\n\tfind test/data -size -5k -name *.bson | xargs -I{} cp \"{}\" fuzz-testing/testcases\n\t@echo \"Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer\"\n\nfuzz_testing_cbor:\n\trm -fr fuzz-testing\n\tmkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out\n\t$(MAKE) parse_cbor_fuzzer -C test CXX=afl-clang++\n\tmv test/parse_cbor_fuzzer fuzz-testing/fuzzer\n\tfind test/data -size -5k -name *.cbor | xargs -I{} cp \"{}\" fuzz-testing/testcases\n\t@echo \"Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer\"\n\nfuzz_testing_msgpack:\n\trm -fr fuzz-testing\n\tmkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out\n\t$(MAKE) parse_msgpack_fuzzer -C test CXX=afl-clang++\n\tmv test/parse_msgpack_fuzzer fuzz-testing/fuzzer\n\tfind test/data -size -5k -name *.msgpack | xargs -I{} cp \"{}\" fuzz-testing/testcases\n\t@echo \"Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer\"\n\nfuzz_testing_ubjson:\n\trm -fr fuzz-testing\n\tmkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out\n\t$(MAKE) parse_ubjson_fuzzer -C test CXX=afl-clang++\n\tmv test/parse_ubjson_fuzzer fuzz-testing/fuzzer\n\tfind test/data -size -5k -name *.ubjson | xargs -I{} cp \"{}\" fuzz-testing/testcases\n\t@echo \"Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer\"\n\nfuzzing-start:\n\tafl-fuzz -S fuzzer1 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &\n\tafl-fuzz -S fuzzer2 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &\n\tafl-fuzz -S fuzzer3 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &\n\tafl-fuzz -S fuzzer4 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &\n\tafl-fuzz -S fuzzer5 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &\n\tafl-fuzz -S fuzzer6 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &\n\tafl-fuzz -S fuzzer7 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &\n\tafl-fuzz -M fuzzer0 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer\n\nfuzzing-stop:\n\t-killall fuzzer\n\t-killall afl-fuzz\n\n\n##########################################################################\n# Static analysis\n##########################################################################\n\n# call PVS-Studio Analyzer <https://www.viva64.com/en/pvs-studio/>\npvs_studio:\n\trm -fr cmake-build-pvs-studio\n\tmkdir cmake-build-pvs-studio\n\tcd cmake-build-pvs-studio ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DJSON_MultipleHeaders=ON\n\tcd cmake-build-pvs-studio ; pvs-studio-analyzer analyze -j 10\n\tcd cmake-build-pvs-studio ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs\n\topen cmake-build-pvs-studio/pvs/index.html\n\n##########################################################################\n# Code format and source amalgamation\n##########################################################################\n\n# call the Artistic Style pretty printer on all source files\npretty:\n\tastyle \\\n\t\t--style=allman \\\n\t\t--indent=spaces=4 \\\n\t\t--indent-modifiers \\\n\t    --indent-switches \\\n\t    --indent-preproc-block \\\n\t    --indent-preproc-define \\\n\t    --indent-col1-comments \\\n\t    --pad-oper \\\n\t    --pad-header \\\n\t    --align-pointer=type \\\n\t    --align-reference=type \\\n\t    --add-brackets \\\n\t    --convert-tabs \\\n\t    --close-templates \\\n\t    --lineend=linux \\\n\t    --preserve-date \\\n\t    --suffix=none \\\n\t    --formatted \\\n\t   $(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp test/src/*.hpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp\n\n# call the Clang-Format on all source files\npretty_format:\n\tfor FILE in $(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp test/src/*.hpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done\n\n# create single header file\namalgamate: $(AMALGAMATED_FILE)\n\n# call the amalgamation tool and pretty print\n$(AMALGAMATED_FILE): $(SRCS)\n\tthird_party/amalgamate/amalgamate.py -c third_party/amalgamate/config.json -s . --verbose=yes\n\t$(MAKE) pretty\n\n# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources\n# Note: this target is called by Travis\ncheck-amalgamation:\n\t@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~\n\t@$(MAKE) amalgamate\n\t@diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo \"===================================================================\\n  Amalgamation required! Please read the contribution guidelines\\n  in file .github/CONTRIBUTING.md.\\n===================================================================\" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false)\n\t@mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE)\n\n\n##########################################################################\n# ChangeLog\n##########################################################################\n\n# Create a ChangeLog based on the git log using the GitHub Changelog Generator\n# (<https://github.com/github-changelog-generator/github-changelog-generator>).\n\n# variable to control the diffs between the last released version and the current repository state\nNEXT_VERSION ?= \"unreleased\"\n\nChangeLog.md:\n\tgithub_changelog_generator -o ChangeLog.md --user nlohmann --project json --simple-list --release-url https://github.com/nlohmann/json/releases/tag/%s --future-release $(NEXT_VERSION)\n\t$(SED) -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md\n\t$(SED) -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md\n\n\n##########################################################################\n# Release files\n##########################################################################\n\n# Create the files for a release and add signatures and hashes. We use `-X` to make the resulting ZIP file\n# reproducible, see <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.\n\nrelease:\n\trm -fr release_files\n\tmkdir release_files\n\tzip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) meson.build LICENSE.MIT\n\tgpg --armor --detach-sig include.zip\n\tmv include.zip include.zip.asc release_files\n\tgpg --armor --detach-sig $(AMALGAMATED_FILE)\n\tcp $(AMALGAMATED_FILE) release_files\n\tmv $(AMALGAMATED_FILE).asc release_files\n\tcd release_files ; shasum -a 256 json.hpp > hashes.txt\n\tcd release_files ; shasum -a 256 include.zip >> hashes.txt\n\n\n##########################################################################\n# Maintenance\n##########################################################################\n\n# clean up\nclean:\n\trm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html\n\trm -fr benchmarks/files/numbers/*.json\n\trm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64\n\trm -fr cmake-build-benchmarks cmake-build-pedantic fuzz-testing cmake-build-clang-analyze cmake-build-pvs-studio cmake-build-infer cmake_build\n\t$(MAKE) clean -Cdoc\n\n##########################################################################\n# Thirdparty code\n##########################################################################\n\nupdate_hedley:\n\trm -f include/nlohmann/thirdparty/hedley/hedley.hpp include/nlohmann/thirdparty/hedley/hedley_undef.hpp\n\tcurl https://raw.githubusercontent.com/nemequ/hedley/master/hedley.h -o include/nlohmann/thirdparty/hedley/hedley.hpp\n\t$(SED) -i 's/HEDLEY_/JSON_HEDLEY_/g' include/nlohmann/thirdparty/hedley/hedley.hpp\n\tgrep \"[[:blank:]]*#[[:blank:]]*undef\" include/nlohmann/thirdparty/hedley/hedley.hpp | grep -v \"__\" | sort | uniq | $(SED) 's/ //g' | $(SED) 's/undef/undef /g' > include/nlohmann/thirdparty/hedley/hedley_undef.hpp\n\t$(SED) -i '1s/^/#pragma once\\n\\n/' include/nlohmann/thirdparty/hedley/hedley.hpp\n\t$(SED) -i '1s/^/#pragma once\\n\\n/' include/nlohmann/thirdparty/hedley/hedley_undef.hpp\n\t$(MAKE) amalgamate\n"
  },
  {
    "path": "subprojects/nlohmann_json/README.md",
    "content": "[![JSON for Modern C++](https://raw.githubusercontent.com/nlohmann/json/master/doc/json.gif)](https://github.com/nlohmann/json/releases)\n\n[![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json)\n[![Ubuntu](https://github.com/nlohmann/json/workflows/Ubuntu/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AUbuntu)\n[![macOS](https://github.com/nlohmann/json/workflows/macOS/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AmacOS)\n[![Windows](https://github.com/nlohmann/json/workflows/Windows/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AWindows)\n[![Coverage Status](https://coveralls.io/repos/github/nlohmann/json/badge.svg?branch=develop)](https://coveralls.io/github/nlohmann/json?branch=develop)\n[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/e0d1a9d5d6fd46fcb655c4cb930bb3e8)](https://www.codacy.com/gh/nlohmann/json/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=nlohmann/json&amp;utm_campaign=Badge_Grade)\n[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/nlohmann/json.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/nlohmann/json/context:cpp)\n[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/json.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json)\n[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/1mp10JbaANo6FUc7)\n[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](https://nlohmann.github.io/json/doxygen/index.html)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)\n[![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases)\n[![GitHub Downloads](https://img.shields.io/github/downloads/nlohmann/json/total)](https://github.com/nlohmann/json/releases)\n[![GitHub Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](https://github.com/nlohmann/json/issues)\n[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/nlohmann/json.svg)](https://isitmaintained.com/project/nlohmann/json \"Average time to resolve an issue\")\n[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/289/badge)](https://bestpractices.coreinfrastructure.org/projects/289)\n[![GitHub Sponsors](https://img.shields.io/badge/GitHub-Sponsors-ff69b4)](https://github.com/sponsors/nlohmann)\n\n- [Design goals](#design-goals)\n- [Sponsors](#sponsors)\n- [Support](#support) ([documentation](https://json.nlohmann.me), [FAQ](https://json.nlohmann.me/home/faq/), [discussions](https://github.com/nlohmann/json/discussions), [API](https://json.nlohmann.me/api/basic_json/), [bug issues](https://github.com/nlohmann/json/issues))\n- [Examples](#examples)\n  - [JSON as first-class data type](#json-as-first-class-data-type)\n  - [Serialization / Deserialization](#serialization--deserialization)\n  - [STL-like access](#stl-like-access)\n  - [Conversion from STL containers](#conversion-from-stl-containers)\n  - [JSON Pointer and JSON Patch](#json-pointer-and-json-patch)\n  - [JSON Merge Patch](#json-merge-patch)\n  - [Implicit conversions](#implicit-conversions)\n  - [Conversions to/from arbitrary types](#arbitrary-types-conversions)\n  - [Specializing enum conversion](#specializing-enum-conversion)\n  - [Binary formats (BSON, CBOR, MessagePack, and UBJSON)](#binary-formats-bson-cbor-messagepack-and-ubjson)\n- [Supported compilers](#supported-compilers)\n- [Integration](#integration)\n  - [CMake](#cmake)\n  - [Package Managers](#package-managers)\n  - [Pkg-config](#pkg-config)\n- [License](#license)\n- [Contact](#contact)\n- [Thanks](#thanks)\n- [Used third-party tools](#used-third-party-tools)\n- [Projects using JSON for Modern C++](#projects-using-json-for-modern-c)\n- [Notes](#notes)\n- [Execute unit tests](#execute-unit-tests)\n\n## Design goals\n\nThere are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals:\n\n- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you'll know what I mean.\n\n- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.\n\n- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](https://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).\n\nOther aspects were not so important to us:\n\n- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs.\n\n- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set.\n\nSee the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information.\n\n\n## Sponsors\n\nYou can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann).\n\n### :label: Named Sponsors\n\n- [Michael Hartmann](https://github.com/reFX-Mike)\n- [Stefan Hagen](https://github.com/sthagen)\n- [Steve Sperandeo](https://github.com/homer6)\n- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe)\n- [Steve Wagner](https://github.com/ciroque)\n\nThanks everyone!\n\n## Support\n\n:question: If you have a **question**, please check if it is already answered in the [**FAQ**](https://json.nlohmann.me/home/faq/) or the [**Q&A**](https://github.com/nlohmann/json/discussions/categories/q-a) section. If not, please [**ask a new question**](https://github.com/nlohmann/json/discussions/new) there.\n\n:books: If you want to **learn more** about how to use the library, check out the rest of the [**README**](#examples), have a look at [**code examples**](https://github.com/nlohmann/json/tree/develop/doc/examples), or browse through the [**help pages**](https://json.nlohmann.me).\n\n:construction: If you want to understand the **API** better, check out the [**API Reference**](https://json.nlohmann.me/api/basic_json/) or the [**Doxygen documentation**](https://json.nlohmann.me/doxygen/index.html).\n\n:bug: If you found a **bug**, please check the [**FAQ**](https://json.nlohmann.me/home/faq/) if it is a known issue or the result of a design decision. Please also have a look at the [**issue list**](https://github.com/nlohmann/json/issues) before you [**create a new issue**](https://github.com/nlohmann/json/issues/new/choose). Please provide as much information as possible to help us understand and reproduce your issue.\n\nThere is also a [**docset**](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B) for the documentation browsers [Dash](https://kapeli.com/dash), [Velocity](https://velocity.silverlakesoftware.com), and [Zeal](https://zealdocs.org) that contains the full [documentation](https://json.nlohmann.me) as offline resource.\n\n## Examples\n\nBeside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/api/basic_json/emplace/)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)).\n\n### JSON as first-class data type\n\nHere are some examples to give you an idea how to use the class.\n\nAssume you want to create the JSON object\n\n```json\n{\n  \"pi\": 3.141,\n  \"happy\": true,\n  \"name\": \"Niels\",\n  \"nothing\": null,\n  \"answer\": {\n    \"everything\": 42\n  },\n  \"list\": [1, 0, 2],\n  \"object\": {\n    \"currency\": \"USD\",\n    \"value\": 42.99\n  }\n}\n```\n\nWith this library, you could write:\n\n```cpp\n// create an empty structure (null)\njson j;\n\n// add a number that is stored as double (note the implicit conversion of j to an object)\nj[\"pi\"] = 3.141;\n\n// add a Boolean that is stored as bool\nj[\"happy\"] = true;\n\n// add a string that is stored as std::string\nj[\"name\"] = \"Niels\";\n\n// add another null object by passing nullptr\nj[\"nothing\"] = nullptr;\n\n// add an object inside the object\nj[\"answer\"][\"everything\"] = 42;\n\n// add an array that is stored as std::vector (using an initializer list)\nj[\"list\"] = { 1, 0, 2 };\n\n// add another object (using an initializer list of pairs)\nj[\"object\"] = { {\"currency\", \"USD\"}, {\"value\", 42.99} };\n\n// instead, you could also write (which looks very similar to the JSON above)\njson j2 = {\n  {\"pi\", 3.141},\n  {\"happy\", true},\n  {\"name\", \"Niels\"},\n  {\"nothing\", nullptr},\n  {\"answer\", {\n    {\"everything\", 42}\n  }},\n  {\"list\", {1, 0, 2}},\n  {\"object\", {\n    {\"currency\", \"USD\"},\n    {\"value\", 42.99}\n  }}\n};\n```\n\nNote that in all these cases, you never need to \"tell\" the compiler which JSON value type you want to use. If you want to be explicit or express some edge cases, the functions [`json::array()`](https://nlohmann.github.io/json/api/basic_json/array/) and [`json::object()`](https://nlohmann.github.io/json/api/basic_json/object/) will help:\n\n```cpp\n// a way to express the empty array []\njson empty_array_explicit = json::array();\n\n// ways to express the empty object {}\njson empty_object_implicit = json({});\njson empty_object_explicit = json::object();\n\n// a way to express an _array_ of key/value pairs [[\"currency\", \"USD\"], [\"value\", 42.99]]\njson array_not_object = json::array({ {\"currency\", \"USD\"}, {\"value\", 42.99} });\n```\n\n### Serialization / Deserialization\n\n#### To/from strings\n\nYou can create a JSON value (deserialization) by appending `_json` to a string literal:\n\n```cpp\n// create object from string literal\njson j = \"{ \\\"happy\\\": true, \\\"pi\\\": 3.141 }\"_json;\n\n// or even nicer with a raw string literal\nauto j2 = R\"(\n  {\n    \"happy\": true,\n    \"pi\": 3.141\n  }\n)\"_json;\n```\n\nNote that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string value. That is, `json j = \"{ \\\"happy\\\": true, \\\"pi\\\": 3.141 }\"` would just store the string `\"{ \"happy\": true, \"pi\": 3.141 }\"` rather than parsing the actual object.\n\nThe above example can also be expressed explicitly using [`json::parse()`](https://nlohmann.github.io/json/api/basic_json/parse/):\n\n```cpp\n// parse explicitly\nauto j3 = json::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\n```\n\nYou can also get a string representation of a JSON value (serialize):\n\n```cpp\n// explicit conversion to string\nstd::string s = j.dump();    // {\"happy\":true,\"pi\":3.141}\n\n// serialization with pretty printing\n// pass in the amount of spaces to indent\nstd::cout << j.dump(4) << std::endl;\n// {\n//     \"happy\": true,\n//     \"pi\": 3.141\n// }\n```\n\nNote the difference between serialization and assignment:\n\n```cpp\n// store a string in a JSON value\njson j_string = \"this is a string\";\n\n// retrieve the string value\nauto cpp_string = j_string.get<std::string>();\n// retrieve the string value (alternative when a variable already exists)\nstd::string cpp_string2;\nj_string.get_to(cpp_string2);\n\n// retrieve the serialized value (explicit JSON serialization)\nstd::string serialized_string = j_string.dump();\n\n// output of original string\nstd::cout << cpp_string << \" == \" << cpp_string2 << \" == \" << j_string.get<std::string>() << '\\n';\n// output of serialized value\nstd::cout << j_string << \" == \" << serialized_string << std::endl;\n```\n\n[`.dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) returns the originally stored string value.\n\nNote the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.\n\n#### To/from streams (e.g. files, string streams)\n\nYou can also use streams to serialize and deserialize:\n\n```cpp\n// deserialize from standard input\njson j;\nstd::cin >> j;\n\n// serialize to standard output\nstd::cout << j;\n\n// the setw manipulator was overloaded to set the indentation for pretty printing\nstd::cout << std::setw(4) << j << std::endl;\n```\n\nThese operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files:\n\n```cpp\n// read a JSON file\nstd::ifstream i(\"file.json\");\njson j;\ni >> j;\n\n// write prettified JSON to another file\nstd::ofstream o(\"pretty.json\");\no << std::setw(4) << j << std::endl;\n```\n\nPlease note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use.\n\n#### Read from iterator range\n\nYou can also parse JSON from an iterator range; that is, from any container accessible by iterators whose `value_type` is an integral type of 1, 2 or 4 bytes, which will be interpreted as UTF-8, UTF-16 and UTF-32 respectively. For instance, a `std::vector<std::uint8_t>`, or a `std::list<std::uint16_t>`:\n\n```cpp\nstd::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};\njson j = json::parse(v.begin(), v.end());\n```\n\nYou may leave the iterators for the range [begin, end):\n\n```cpp\nstd::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};\njson j = json::parse(v);\n```\n\n#### Custom data source\n\nSince the parse function accepts arbitrary iterator ranges, you can provide your own data sources by implementing the `LegacyInputIterator` concept.\n\n```cpp\nstruct MyContainer {\n  void advance();\n  const char& get_current();\n};\n\nstruct MyIterator {\n    using difference_type = std::ptrdiff_t;\n    using value_type = char;\n    using pointer = const char*;\n    using reference = const char&;\n    using iterator_category = std::input_iterator_tag;\n\n    MyIterator& operator++() {\n        MyContainer.advance();\n        return *this;\n    }\n\n    bool operator!=(const MyIterator& rhs) const {\n        return rhs.target != target;\n    }\n\n    reference operator*() const {\n        return target.get_current();\n    }\n\n    MyContainer* target = nullptr;\n};\n\nMyIterator begin(MyContainer& tgt) {\n    return MyIterator{&tgt};\n}\n\nMyIterator end(const MyContainer&) {\n    return {};\n}\n\nvoid foo() {\n    MyContainer c;\n    json j = json::parse(c);\n}\n```\n\n#### SAX interface\n\nThe library uses a SAX-like interface with the following functions:\n\n```cpp\n// called when null is parsed\nbool null();\n\n// called when a boolean is parsed; value is passed\nbool boolean(bool val);\n\n// called when a signed or unsigned integer number is parsed; value is passed\nbool number_integer(number_integer_t val);\nbool number_unsigned(number_unsigned_t val);\n\n// called when a floating-point number is parsed; value and original string is passed\nbool number_float(number_float_t val, const string_t& s);\n\n// called when a string is parsed; value is passed and can be safely moved away\nbool string(string_t& val);\n// called when a binary value is parsed; value is passed and can be safely moved away\nbool binary(binary_t& val);\n\n// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)\nbool start_object(std::size_t elements);\nbool end_object();\nbool start_array(std::size_t elements);\nbool end_array();\n// called when an object key is parsed; value is passed and can be safely moved away\nbool key(string_t& val);\n\n// called when a parse error occurs; byte position, the last token, and an exception is passed\nbool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex);\n```\n\nThe return value of each function determines whether parsing should proceed.\n\nTo implement your own SAX handler, proceed as follows:\n\n1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax<json>` as base class, but you can also use any class where the functions described above are implemented and public.\n2. Create an object of your SAX interface class, e.g. `my_sax`.\n3. Call `bool json::sax_parse(input, &my_sax)`; where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.\n\nNote the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a  `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp).\n\n### STL-like access\n\nWe designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement.\n\n```cpp\n// create an array using push_back\njson j;\nj.push_back(\"foo\");\nj.push_back(1);\nj.push_back(true);\n\n// also use emplace_back\nj.emplace_back(1.78);\n\n// iterate the array\nfor (json::iterator it = j.begin(); it != j.end(); ++it) {\n  std::cout << *it << '\\n';\n}\n\n// range-based for\nfor (auto& element : j) {\n  std::cout << element << '\\n';\n}\n\n// getter/setter\nconst auto tmp = j[0].get<std::string>();\nj[1] = 42;\nbool foo = j.at(2);\n\n// comparison\nj == R\"([\"foo\", 1, true, 1.78])\"_json;  // true\n\n// other stuff\nj.size();     // 4 entries\nj.empty();    // false\nj.type();     // json::value_t::array\nj.clear();    // the array is empty again\n\n// convenience type checkers\nj.is_null();\nj.is_boolean();\nj.is_number();\nj.is_object();\nj.is_array();\nj.is_string();\n\n// create an object\njson o;\no[\"foo\"] = 23;\no[\"bar\"] = false;\no[\"baz\"] = 3.141;\n\n// also use emplace\no.emplace(\"weather\", \"sunny\");\n\n// special iterator member functions for objects\nfor (json::iterator it = o.begin(); it != o.end(); ++it) {\n  std::cout << it.key() << \" : \" << it.value() << \"\\n\";\n}\n\n// the same code as range for\nfor (auto& el : o.items()) {\n  std::cout << el.key() << \" : \" << el.value() << \"\\n\";\n}\n\n// even easier with structured bindings (C++17)\nfor (auto& [key, value] : o.items()) {\n  std::cout << key << \" : \" << value << \"\\n\";\n}\n\n// find an entry\nif (o.contains(\"foo\")) {\n  // there is an entry with key \"foo\"\n}\n\n// or via find and an iterator\nif (o.find(\"foo\") != o.end()) {\n  // there is an entry with key \"foo\"\n}\n\n// or simpler using count()\nint foo_present = o.count(\"foo\"); // 1\nint fob_present = o.count(\"fob\"); // 0\n\n// delete an entry\no.erase(\"foo\");\n```\n\n\n### Conversion from STL containers\n\nAny sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON values (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends on how the elements are ordered in the respective STL container.\n\n```cpp\nstd::vector<int> c_vector {1, 2, 3, 4};\njson j_vec(c_vector);\n// [1, 2, 3, 4]\n\nstd::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};\njson j_deque(c_deque);\n// [1.2, 2.3, 3.4, 5.6]\n\nstd::list<bool> c_list {true, true, false, true};\njson j_list(c_list);\n// [true, true, false, true]\n\nstd::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};\njson j_flist(c_flist);\n// [12345678909876, 23456789098765, 34567890987654, 45678909876543]\n\nstd::array<unsigned long, 4> c_array {{1, 2, 3, 4}};\njson j_array(c_array);\n// [1, 2, 3, 4]\n\nstd::set<std::string> c_set {\"one\", \"two\", \"three\", \"four\", \"one\"};\njson j_set(c_set); // only one entry for \"one\" is used\n// [\"four\", \"one\", \"three\", \"two\"]\n\nstd::unordered_set<std::string> c_uset {\"one\", \"two\", \"three\", \"four\", \"one\"};\njson j_uset(c_uset); // only one entry for \"one\" is used\n// maybe [\"two\", \"three\", \"four\", \"one\"]\n\nstd::multiset<std::string> c_mset {\"one\", \"two\", \"one\", \"four\"};\njson j_mset(c_mset); // both entries for \"one\" are used\n// maybe [\"one\", \"two\", \"one\", \"four\"]\n\nstd::unordered_multiset<std::string> c_umset {\"one\", \"two\", \"one\", \"four\"};\njson j_umset(c_umset); // both entries for \"one\" are used\n// maybe [\"one\", \"two\", \"one\", \"four\"]\n```\n\nLikewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON values (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container.\n\n```cpp\nstd::map<std::string, int> c_map { {\"one\", 1}, {\"two\", 2}, {\"three\", 3} };\njson j_map(c_map);\n// {\"one\": 1, \"three\": 3, \"two\": 2 }\n\nstd::unordered_map<const char*, double> c_umap { {\"one\", 1.2}, {\"two\", 2.3}, {\"three\", 3.4} };\njson j_umap(c_umap);\n// {\"one\": 1.2, \"two\": 2.3, \"three\": 3.4}\n\nstd::multimap<std::string, bool> c_mmap { {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true} };\njson j_mmap(c_mmap); // only one entry for key \"three\" is used\n// maybe {\"one\": true, \"two\": true, \"three\": true}\n\nstd::unordered_multimap<std::string, bool> c_ummap { {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true} };\njson j_ummap(c_ummap); // only one entry for key \"three\" is used\n// maybe {\"one\": true, \"two\": true, \"three\": true}\n```\n\n### JSON Pointer and JSON Patch\n\nThe library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values. On top of this, **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) allows describing differences between two JSON values - effectively allowing patch and diff operations known from Unix.\n\n```cpp\n// a JSON value\njson j_original = R\"({\n  \"baz\": [\"one\", \"two\", \"three\"],\n  \"foo\": \"bar\"\n})\"_json;\n\n// access members with a JSON pointer (RFC 6901)\nj_original[\"/baz/1\"_json_pointer];\n// \"two\"\n\n// a JSON patch (RFC 6902)\njson j_patch = R\"([\n  { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n  { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n  { \"op\": \"remove\", \"path\": \"/foo\"}\n])\"_json;\n\n// apply the patch\njson j_result = j_original.patch(j_patch);\n// {\n//    \"baz\": \"boo\",\n//    \"hello\": [\"world\"]\n// }\n\n// calculate a JSON patch from two JSON values\njson::diff(j_result, j_original);\n// [\n//   { \"op\":\" replace\", \"path\": \"/baz\", \"value\": [\"one\", \"two\", \"three\"] },\n//   { \"op\": \"remove\",\"path\": \"/hello\" },\n//   { \"op\": \"add\", \"path\": \"/foo\", \"value\": \"bar\" }\n// ]\n```\n\n### JSON Merge Patch\n\nThe library supports **JSON Merge Patch** ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. Instead of using JSON Pointer (see above) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified.\n\n```cpp\n// a JSON value\njson j_document = R\"({\n  \"a\": \"b\",\n  \"c\": {\n    \"d\": \"e\",\n    \"f\": \"g\"\n  }\n})\"_json;\n\n// a patch\njson j_patch = R\"({\n  \"a\":\"z\",\n  \"c\": {\n    \"f\": null\n  }\n})\"_json;\n\n// apply the patch\nj_document.merge_patch(j_patch);\n// {\n//  \"a\": \"z\",\n//  \"c\": {\n//    \"d\": \"e\"\n//  }\n// }\n```\n\n### Implicit conversions\n\nSupported types can be implicitly converted to JSON values.\n\nIt is recommended to **NOT USE** implicit conversions **FROM** a JSON value.\nYou can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958).\nYou can switch off implicit conversions by defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` before including the `json.hpp` header. When using CMake, you can also achieve this by setting the option `JSON_ImplicitConversions` to `OFF`.\n\n```cpp\n// strings\nstd::string s1 = \"Hello, world!\";\njson js = s1;\nauto s2 = js.get<std::string>();\n// NOT RECOMMENDED\nstd::string s3 = js;\nstd::string s4;\ns4 = js;\n\n// Booleans\nbool b1 = true;\njson jb = b1;\nauto b2 = jb.get<bool>();\n// NOT RECOMMENDED\nbool b3 = jb;\nbool b4;\nb4 = jb;\n\n// numbers\nint i = 42;\njson jn = i;\nauto f = jn.get<double>();\n// NOT RECOMMENDED\ndouble f2 = jb;\ndouble f3;\nf3 = jb;\n\n// etc.\n```\n\nNote that `char` types are not automatically converted to JSON strings, but to integer numbers. A conversion to a string must be specified explicitly:\n\n```cpp\nchar ch = 'A';                       // ASCII value 65\njson j_default = ch;                 // stores integer number 65\njson j_string = std::string(1, ch);  // stores string \"A\"\n```\n\n### Arbitrary types conversions\n\nEvery type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:\n\n```cpp\nnamespace ns {\n    // a simple struct to model a person\n    struct person {\n        std::string name;\n        std::string address;\n        int age;\n    };\n}\n\nns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// convert to JSON: copy each value into the JSON object\njson j;\nj[\"name\"] = p.name;\nj[\"address\"] = p.address;\nj[\"age\"] = p.age;\n\n// ...\n\n// convert from JSON: copy each value from the JSON object\nns::person p {\n    j[\"name\"].get<std::string>(),\n    j[\"address\"].get<std::string>(),\n    j[\"age\"].get<int>()\n};\n```\n\nIt works, but that's quite a lot of boilerplate... Fortunately, there's a better way:\n\n```cpp\n// create a person\nns::person p {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// conversion: person -> json\njson j = p;\n\nstd::cout << j << std::endl;\n// {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n\n// conversion: json -> person\nauto p2 = j.get<ns::person>();\n\n// that's it\nassert(p == p2);\n```\n\n#### Basic usage\n\nTo make this work with one of your types, you only need to provide two functions:\n\n```cpp\nusing json = nlohmann::json;\n\nnamespace ns {\n    void to_json(json& j, const person& p) {\n        j = json{{\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age}};\n    }\n\n    void from_json(const json& j, person& p) {\n        j.at(\"name\").get_to(p.name);\n        j.at(\"address\").get_to(p.address);\n        j.at(\"age\").get_to(p.age);\n    }\n} // namespace ns\n```\n\nThat's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.\nLikewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.\n\nSome important things:\n\n* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).\n* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.\n* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)\n* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/api/basic_json/at/) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.\n* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.\n\n#### Simplify your life with macros\n\nIf you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate.\n\nThere are two macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object:\n\n- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the namespace of the class/struct to create code for.\n- `NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the class/struct to create code for. This macro can also access private members.\n\nIn both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members.\n\n##### Examples\n\nThe `to_json`/`from_json` functions for the `person` struct above can be created with:\n\n```cpp\nnamespace ns {\n    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n}\n```\n\nHere is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed:\n\n```cpp\nnamespace ns {\n    class address {\n      private:\n        std::string street;\n        int housenumber;\n        int postcode;\n\n      public:\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)\n    };\n}\n```\n\n#### How do I convert third-party types?\n\nThis requires a bit more advanced technique. But first, let's see how this conversion mechanism works:\n\nThe library uses **JSON Serializers** to convert types to json.\nThe default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)).\n\nIt is implemented like this (simplified):\n\n```cpp\ntemplate <typename T>\nstruct adl_serializer {\n    static void to_json(json& j, const T& value) {\n        // calls the \"to_json\" method in T's namespace\n    }\n\n    static void from_json(const json& j, T& value) {\n        // same thing, but with the \"from_json\" method\n    }\n};\n```\n\nThis serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`...\n\nTo solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example:\n\n```cpp\n// partial specialization (full specialization works too)\nnamespace nlohmann {\n    template <typename T>\n    struct adl_serializer<boost::optional<T>> {\n        static void to_json(json& j, const boost::optional<T>& opt) {\n            if (opt == boost::none) {\n                j = nullptr;\n            } else {\n              j = *opt; // this will call adl_serializer<T>::to_json which will\n                        // find the free function to_json in T's namespace!\n            }\n        }\n\n        static void from_json(const json& j, boost::optional<T>& opt) {\n            if (j.is_null()) {\n                opt = boost::none;\n            } else {\n                opt = j.get<T>(); // same as above, but with\n                                  // adl_serializer<T>::from_json\n            }\n        }\n    };\n}\n```\n\n#### How can I use `get()` for non-default constructible/non-copyable types?\n\nThere is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:\n\n```cpp\nstruct move_only_type {\n    move_only_type() = delete;\n    move_only_type(int ii): i(ii) {}\n    move_only_type(const move_only_type&) = delete;\n    move_only_type(move_only_type&&) = default;\n\n    int i;\n};\n\nnamespace nlohmann {\n    template <>\n    struct adl_serializer<move_only_type> {\n        // note: the return type is no longer 'void', and the method only takes\n        // one argument\n        static move_only_type from_json(const json& j) {\n            return {j.get<int>()};\n        }\n\n        // Here's the catch! You must provide a to_json method! Otherwise, you\n        // will not be able to convert move_only_type to json, since you fully\n        // specialized adl_serializer on that type\n        static void to_json(json& j, move_only_type t) {\n            j = t.i;\n        }\n    };\n}\n```\n\n#### Can I write my own serializer? (Advanced use)\n\nYes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/test/src/unit-udt.cpp) in the test suite, to see a few examples.\n\nIf you write your own serializer, you'll need to do a few things:\n\n- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`)\n- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods\n- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL\n\nHere is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.\n\n```cpp\n// You should use void as a second template argument\n// if you don't need compile-time checks on T\ntemplate<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>\nstruct less_than_32_serializer {\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, T value) {\n        // we want to use ADL, and call the correct to_json overload\n        using nlohmann::to_json; // this method is called by adl_serializer,\n                                 // this is where the magic happens\n        to_json(j, value);\n    }\n\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n        // same thing here\n        using nlohmann::from_json;\n        from_json(j, value);\n    }\n};\n```\n\nBe **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention:\n\n```cpp\ntemplate <typename T, void>\nstruct bad_serializer\n{\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) {\n      // this calls BasicJsonType::json_serializer<T>::to_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      j = value;\n    }\n\n    template <typename BasicJsonType>\n    static void to_json(const BasicJsonType& j, T& value) {\n      // this calls BasicJsonType::json_serializer<T>::from_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      value = j.template get<T>(); // oops!\n    }\n};\n```\n\n### Specializing enum conversion\n\nBy default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be undefined or a different enum value than was originally intended.\n\nIt is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:\n\n```cpp\n// example enum type declaration\nenum TaskState {\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID=-1,\n};\n\n// map TaskState values to JSON as strings\nNLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {\n    {TS_INVALID, nullptr},\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n```\n\nThe `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code.\n\n**Usage:**\n\n```cpp\n// enum to JSON as string\njson j = TS_STOPPED;\nassert(j == \"stopped\");\n\n// json string to enum\njson j3 = \"running\";\nassert(j3.get<TaskState>() == TS_RUNNING);\n\n// undefined json value to enum (where the first map entry above is the default)\njson jPi = 3.14;\nassert(jPi.get<TaskState>() == TS_INVALID );\n```\n\nJust as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,\n- `NLOHMANN_JSON_SERIALIZE_ENUM()` MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to integer serialization.\n- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.\n\nOther Important points:\n- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.\n- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.\n\n### Binary formats (BSON, CBOR, MessagePack, and UBJSON)\n\nThough JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [BSON](https://bsonspec.org) (Binary JSON), [CBOR](https://cbor.io) (Concise Binary Object Representation), [MessagePack](https://msgpack.org), and [UBJSON](https://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.\n\n```cpp\n// create a JSON value\njson j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n// serialize to BSON\nstd::vector<std::uint8_t> v_bson = json::to_bson(j);\n\n// 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n\n// roundtrip\njson j_from_bson = json::from_bson(v_bson);\n\n// serialize to CBOR\nstd::vector<std::uint8_t> v_cbor = json::to_cbor(j);\n\n// 0xA2, 0x67, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xF5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00\n\n// roundtrip\njson j_from_cbor = json::from_cbor(v_cbor);\n\n// serialize to MessagePack\nstd::vector<std::uint8_t> v_msgpack = json::to_msgpack(j);\n\n// 0x82, 0xA7, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xC3, 0xA6, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00\n\n// roundtrip\njson j_from_msgpack = json::from_msgpack(v_msgpack);\n\n// serialize to UBJSON\nstd::vector<std::uint8_t> v_ubjson = json::to_ubjson(j);\n\n// 0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n\n// roundtrip\njson j_from_ubjson = json::from_ubjson(v_ubjson);\n```\n\nThe library also supports binary types from BSON, CBOR (byte strings), and MessagePack (bin, ext, fixext). They are stored by default as `std::vector<std::uint8_t>` to be processed outside the library.\n\n```cpp\n// CBOR byte string with payload 0xCAFE\nstd::vector<std::uint8_t> v = {0x42, 0xCA, 0xFE};\n\n// read value\njson j = json::from_cbor(v);\n\n// the JSON value has type binary\nj.is_binary(); // true\n\n// get reference to stored binary value\nauto& binary = j.get_binary();\n\n// the binary value has no subtype (CBOR has no binary subtypes)\nbinary.has_subtype(); // false\n\n// access std::vector<std::uint8_t> member functions\nbinary.size(); // 2\nbinary[0]; // 0xCA\nbinary[1]; // 0xFE\n\n// set subtype to 0x10\nbinary.set_subtype(0x10);\n\n// serialize to MessagePack\nauto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE\n```\n\n\n## Supported compilers\n\nThough it's 2022 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:\n\n- GCC 4.8 - 11.0 (and possibly later)\n- Clang 3.4 - 13.0 (and possibly later)\n- Apple Clang 9.1 - 13.0 (and possibly later)\n- Intel C++ Compiler 17.0.2 (and possibly later)\n- Nvidia CUDA Compiler 11.0.221 (and possibly later)\n- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)\n- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)\n- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)\n\nI would be happy to learn about other compilers/versions.\n\nPlease note:\n\n- GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler.\n- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.\n\n    ```\n    APP_STL := c++_shared\n    NDK_TOOLCHAIN_VERSION := clang3.6\n    APP_CPPFLAGS += -frtti -fexceptions\n    ```\n\n    The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10.\n\n- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`) may occur. Note this is not an issue with the code,  but rather with the compiler itself. On Android, see above to build with a newer environment.  For MinGW, please refer to [this site](https://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).\n\n- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case.\n\nThe following compilers are currently used in continuous integration at [AppVeyor](https://ci.appveyor.com/project/nlohmann/json), [Drone CI](https://cloud.drone.io/nlohmann/json), and [GitHub Actions](https://github.com/nlohmann/json/actions):\n\n| Compiler                                                                                               | Operating System   | CI Provider    |\n|--------------------------------------------------------------------------------------------------------|--------------------|----------------|\n| Apple Clang 10.0.1 (clang-1001.0.46.4); Xcode 10.3                                                     | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 11.0.0 (clang-1100.0.33.12); Xcode 11.2.1                                                  | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 11.0.0 (clang-1100.0.33.17); Xcode 11.3.1                                                  | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 11.0.3 (clang-1103.0.32.59); Xcode 11.4.1                                                  | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 11.0.3 (clang-1103.0.32.62); Xcode 11.5                                                    | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 11.0.3 (clang-1103.0.32.62); Xcode 11.6                                                    | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 11.0.3 (clang-1103.0.32.62); Xcode 11.7                                                    | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 12.0.0 (clang-1200.0.32.2); Xcode 12                                                       | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 12.0.0 (clang-1200.0.32.21); Xcode 12.1                                                    | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 12.0.0 (clang-1200.0.32.21); Xcode 12.1.1                                                  | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 12.0.0 (clang-1200.0.32.27); Xcode 12.2                                                    | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 12.0.0 (clang-1200.0.32.28); Xcode 12.3                                                    | macOS 10.15.7      | GitHub Actions |\n| Apple Clang 12.0.0 (clang-1200.0.32.29); Xcode 12.4                                                    | macOS 10.15.7      | GitHub Actions |\n| GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu2)                                                                      | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 4.9.3 (Ubuntu 4.9.3-13ubuntu2)                                                                     | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.12)                                                             | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 6.4.0 (Ubuntu 6.4.0-17ubuntu1)                                                                     | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 7.5.0 (Ubuntu 7.5.0-6ubuntu2)                                                                      | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)                                          | Windows-10.0.17763 | GitHub Actions |\n| GCC 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)                                          | Windows-10.0.17763 | GitHub Actions |\n| GCC 8.4.0 (Ubuntu 8.4.0-3ubuntu2)                                                                      | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)                                                               | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 10.2.0 (Ubuntu 10.2.0-5ubuntu1~20.04)                                                              | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 11.0.1 20210321 (experimental)                                                                     | Ubuntu 20.04.3 LTS | GitHub Actions |\n| GCC 11.1.0                                                                                             | Ubuntu (aarch64)   | Drone CI       |\n| Clang 3.5.2 (3.5.2-3ubuntu1)                                                                           | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 3.6.2 (3.6.2-3ubuntu2)                                                                           | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 3.7.1 (3.7.1-2ubuntu2)                                                                           | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 3.8.0 (3.8.0-2ubuntu4)                                                                           | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 3.9.1 (3.9.1-4ubuntu3\\~16.04.2)                                                                  | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 4.0.0 (4.0.0-1ubuntu1\\~16.04.2)                                                                  | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 5.0.0 (5.0.0-3\\~16.04.1)                                                                         | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 6.0.1 (6.0.1-14)                                                                                 | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 7.0.1 (7.0.1-12)                                                                                 | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 8.0.1 (8.0.1-9)                                                                                  | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 9.0.1 (9.0.1-12)                                                                                 | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 10.0.0 (10.0.0-4ubuntu1)                                                                         | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 10.0.0 with GNU-like command-line                                                                | Windows-10.0.17763 | GitHub Actions |\n| Clang 11.0.0 with GNU-like command-line                                                                | Windows-10.0.17763 | GitHub Actions |\n| Clang 11.0.0 with MSVC-like command-line                                                               | Windows-10.0.17763 | GitHub Actions |\n| Clang 11.0.0 (11.0.0-2~ubuntu20.04.1)                                                                  | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 12.0.0 (12.0.0-3ubuntu1~20.04.3)                                                                 | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 13.0.1 (13.0.1-++20211015123032+cf15ccdeb6d5-1exp120211015003613.5)                              | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Clang 14.0.0 (14.0.0-++20211221052852+55c71c9eac9b-1exp120211221172954.95)                             | Ubuntu 20.04.3 LTS | GitHub Actions |\n| NVCC 11.0.221                                                                                          | Ubuntu 20.04.3 LTS | GitHub Actions |\n| Visual Studio 14 2015 MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1)                            | Windows-6.3.9600   | AppVeyor       |\n| Visual Studio 15 2017 MSVC 19.16.27035.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor       |\n| Visual Studio 15 2017 MSVC 19.16.27045.0 (Build Engine version 15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | GitHub Actions |\n| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework)    | Windows-10.0.17763 | GitHub Actions |\n| Visual Studio 16 2019 MSVC 19.28.29912.0 (Build Engine version 16.9.0+57a23d249 for .NET Framework)    | Windows-10.0.17763 | AppVeyor       |\n\n\n## Integration\n\n[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add\n\n```cpp\n#include <nlohmann/json.hpp>\n\n// for convenience\nusing json = nlohmann::json;\n```\n\nto the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).\n\nYou can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.\n\n### CMake\n\nYou can also use the `nlohmann_json::nlohmann_json` interface target in CMake.  This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.\n\n#### External\n\nTo use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:\n\n```cmake\n# CMakeLists.txt\nfind_package(nlohmann_json 3.2.0 REQUIRED)\n...\nadd_library(foo ...)\n...\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n\nThe package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.\n\n#### Embedded\n\nTo embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:\n\n```cmake\n# Typically you don't care so much for a third party library's tests to be\n# run from your own project's code.\nset(JSON_BuildTests OFF CACHE INTERNAL \"\")\n\n# If you only include this third party in PRIVATE source files, you do not\n# need to install it when your main project gets installed.\n# set(JSON_Install OFF CACHE INTERNAL \"\")\n\n# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it\n# unintended consequences that will break the build.  It's generally\n# discouraged (although not necessarily well documented as such) to use\n# include(...) for pulling in other CMake projects anyways.\nadd_subdirectory(nlohmann_json)\n...\nadd_library(foo ...)\n...\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n\n##### Embedded (FetchContent)\n\nSince CMake v3.11,\n[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can\nbe used to automatically download the repository as a dependency at configure time.\n\nExample:\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(json\n  GIT_REPOSITORY https://github.com/nlohmann/json.git\n  GIT_TAG v3.7.3)\n\nFetchContent_GetProperties(json)\nif(NOT json_POPULATED)\n  FetchContent_Populate(json)\n  add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)\nendif()\n\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n\n**Note**: The repository https://github.com/nlohmann/json download size is huge.\nIt contains all the dataset used for the benchmarks. You might want to depend on\na smaller repository. For instance, you might want to replace the URL above by\nhttps://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent\n\n#### Supporting Both\n\nTo allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:\n\n``` cmake\n# Top level CMakeLists.txt\nproject(FOO)\n...\noption(FOO_USE_EXTERNAL_JSON \"Use an external JSON library\" OFF)\n...\nadd_subdirectory(thirdparty)\n...\nadd_library(foo ...)\n...\n# Note that the namespaced target will always be available regardless of the\n# import method\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n```cmake\n# thirdparty/CMakeLists.txt\n...\nif(FOO_USE_EXTERNAL_JSON)\n  find_package(nlohmann_json 3.2.0 REQUIRED)\nelse()\n  set(JSON_BuildTests OFF CACHE INTERNAL \"\")\n  add_subdirectory(nlohmann_json)\nendif()\n...\n```\n\n`thirdparty/nlohmann_json` is then a complete copy of this source tree.\n\n### Package Managers\n\n:beer: If you are using OS X and [Homebrew](https://brew.sh), just type `brew install nlohmann-json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann-json --HEAD`. See [nlohmann-json](https://formulae.brew.sh/formula/nlohmann-json) for more information.\n\nIf you are using the [Meson Build System](https://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging.\n\nThe provided `meson.build` can also be used as an alternative to cmake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, simply have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly.\n\nIf you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add [`nlohmann_json/x.y.z`](https://conan.io/center/nlohmann_json) to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/conan-io/conan-center-index/issues) if you experience problems with the packages.\n\nIf you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.\n\nIf you are using [hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging.\n\nIf you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example).\n\nIf you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can install the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) with `vcpkg install nlohmann-json` and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging.\n\nIf you are using [cget](https://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).\n\nIf you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `\"nlohmann_json\", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).\n\nIf you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please file issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).\n\nIf you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues).\n\nIf you are using [MSYS2](https://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages.\n\nIf you are using [MacPorts](https://ports.macports.org), execute `sudo port install nlohmann-json` to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package.\n\nIf you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository https://cppget.org or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml).\nPlease file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages.\n\nIf you are using [`wsjcpp`](https://wsjcpp.org), you can use the command `wsjcpp install \"https://github.com/nlohmann/json:develop\"` to get the latest version. Note you can change the branch \":develop\" to an existing tag or another branch.\n\nIf you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake:\n\n```cmake\nCPMAddPackage(\n    NAME nlohmann_json\n    GITHUB_REPOSITORY nlohmann/json\n    VERSION 3.9.1)\n```\n\n### Pkg-config\n\nIf you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed:\n\n```sh\npkg-config nlohmann_json --cflags\n```\n\nUsers of the Meson build system will also be able to use a system-wide library, which will be found by `pkg-config`:\n\n```meson\njson = dependency('nlohmann_json', required: true)\n```\n\n\n## License\n\n<img align=\"right\" src=\"https://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png\">\n\nThe class is licensed under the [MIT License](https://opensource.org/licenses/MIT):\n\nCopyright &copy; 2013-2022 [Niels Lohmann](https://nlohmann.me)\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.\n\n* * *\n\nThe class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2008-2009 [Björn Hoehrmann](https://bjoern.hoehrmann.de/) <bjoern@hoehrmann.de>\n\nThe class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2009 [Florian Loitsch](https://florian.loitsch.com/)\n\nThe class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).\n\nThe class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).\n\n## Contact\n\nIf you have questions regarding the library, I would like to invite you to [open an issue at GitHub](https://github.com/nlohmann/json/issues/new/choose). Please describe your request, problem, or question as detailed as possible, and also mention the version of the library you are using as well as the version of your compiler and operating system. Opening an issue at GitHub allows other users and contributors to this library to collaborate. For instance, I have little experience with MSVC, and most issues in this regard have been solved by a growing community. If you have a look at the [closed issues](https://github.com/nlohmann/json/issues?q=is%3Aissue+is%3Aclosed), you will see that we react quite timely in most cases.\n\nOnly if your request would contain confidential information, please [send me an email](mailto:mail@nlohmann.me). For encrypted messages, please use [this key](https://keybase.io/nlohmann/pgp_keys.asc).\n\n## Security\n\n[Commits by Niels Lohmann](https://github.com/nlohmann/json/commits) and [releases](https://github.com/nlohmann/json/releases) are signed with this [PGP Key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69).\n\n## Thanks\n\nI deeply appreciate the help of the following people.\n\n<img src=\"https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png\" align=\"right\">\n\n- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization.\n- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes.\n- [kirkshoop](https://github.com/kirkshoop) made the iterators of the class composable to other libraries.\n- [wancw](https://github.com/wanwc) fixed a bug that hindered the class to compile with Clang.\n- Tomas Åblad found a bug in the iterator implementation.\n- [Joshua C. Randall](https://github.com/jrandall) fixed a bug in the floating-point serialization.\n- [Aaron Burghardt](https://github.com/aburgh) implemented code to parse streams incrementally. Furthermore, he greatly improved the parser class by allowing the definition of a filter function to discard undesired elements while parsing.\n- [Daniel Kopeček](https://github.com/dkopecek) fixed a bug in the compilation with GCC 5.0.\n- [Florian Weber](https://github.com/Florianjw) fixed a bug in and improved the performance of the comparison operators.\n- [Eric Cornelius](https://github.com/EricMCornelius) pointed out a bug in the handling with NaN and infinity values. He also improved the performance of the string escaping.\n- [易思龙](https://github.com/likebeta) implemented a conversion from anonymous enums.\n- [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual studio.\n- [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types.\n- [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling.\n- [dariomt](https://github.com/dariomt) fixed some typos in the examples.\n- [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation.\n- [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue.\n- [Huu Nguyen](https://github.com/whoshuu) correct a variable name in the documentation.\n- [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference.\n- [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values.\n- [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK.\n- [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio.\n- [406345](https://github.com/406345) fixed two small warnings.\n- [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function.\n- [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines.\n- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers.\n- [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file.\n- [msm-](https://github.com/msm-) added support for American Fuzzy Lop.\n- [Annihil](https://github.com/Annihil) fixed an example in the README file.\n- [Themercee](https://github.com/Themercee) noted a wrong URL in the README file.\n- [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`.\n- [abc100m](https://github.com/abc100m) analyzed the issues with GCC 4.8 and proposed a [partial solution](https://github.com/nlohmann/json/pull/212).\n- [zewt](https://github.com/zewt) added useful notes to the README file about Android.\n- [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake.\n- [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files.\n- [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal).\n- [Mário Feroldi](https://github.com/thelostt) fixed a small typo.\n- [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release.\n- [Damien](https://github.com/dtoma) fixed one of the last conversion warnings.\n- [Thomas Braun](https://github.com/t-b) fixed a warning in a test case and adjusted MSVC calls in the CI.\n- [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks.\n- [Stefan](https://github.com/5tefan) fixed a minor issue in the documentation.\n- [Vasil Dimov](https://github.com/vasild) fixed the documentation regarding conversions from `std::multiset`.\n- [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion.\n- [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix.\n- [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file.\n- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function.\n- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing.\n- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan.\n- [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning.\n- [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check.\n- [Bosswestfalen](https://github.com/Bosswestfalen) merged two iterator classes into a smaller one.\n- [Daniel599](https://github.com/Daniel599) helped to get Travis execute the tests with Clang's sanitizers.\n- [Jonathan Lee](https://github.com/vjon) fixed an example in the README file.\n- [gnzlbg](https://github.com/gnzlbg) supported the implementation of user-defined types.\n- [Alexej Harm](https://github.com/qis) helped to get the user-defined types working with Visual Studio.\n- [Jared Grubb](https://github.com/jaredgrubb) supported the implementation of user-defined types.\n- [EnricoBilla](https://github.com/EnricoBilla) noted a typo in an example.\n- [Martin Hořeňovský](https://github.com/horenmar) found a way for a 2x speedup for the compilation time of the test suite.\n- [ukhegg](https://github.com/ukhegg) found proposed an improvement for the examples section.\n- [rswanson-ihi](https://github.com/rswanson-ihi) noted a typo in the README.\n- [Mihai Stan](https://github.com/stanmihai4) fixed a bug in the comparison with `nullptr`s.\n- [Tushar Maheshwari](https://github.com/tusharpm) added [cotire](https://github.com/sakra/cotire) support to speed up the compilation.\n- [TedLyngmo](https://github.com/TedLyngmo) noted a typo in the README, removed unnecessary bit arithmetic, and fixed some `-Weffc++` warnings.\n- [Krzysztof Woś](https://github.com/krzysztofwos) made exceptions more visible.\n- [ftillier](https://github.com/ftillier) fixed a compiler warning.\n- [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped.\n- [Fytch](https://github.com/Fytch) found a bug in the documentation.\n- [Jay Sistar](https://github.com/Type1J) implemented a Meson build description.\n- [Henry Lee](https://github.com/HenryRLee) fixed a warning in ICC and improved the iterator implementation.\n- [Vincent Thiery](https://github.com/vthiery) maintains a package for the Conan package manager.\n- [Steffen](https://github.com/koemeet) fixed a potential issue with MSVC and `std::min`.\n- [Mike Tzou](https://github.com/Chocobo1) fixed some typos.\n- [amrcode](https://github.com/amrcode) noted a misleading documentation about comparison of floats.\n- [Oleg Endo](https://github.com/olegendo) reduced the memory consumption by replacing `<iostream>` with `<iosfwd>`.\n- [dan-42](https://github.com/dan-42) cleaned up the CMake files to simplify including/reusing of the library.\n- [Nikita Ofitserov](https://github.com/himikof) allowed for moving values from initializer lists.\n- [Greg Hurrell](https://github.com/wincent) fixed a typo.\n- [Dmitry Kukovinets](https://github.com/DmitryKuk) fixed a typo.\n- [kbthomp1](https://github.com/kbthomp1) fixed an issue related to the Intel OSX compiler.\n- [Markus Werle](https://github.com/daixtrose) fixed a typo.\n- [WebProdPP](https://github.com/WebProdPP) fixed a subtle error in a precondition check.\n- [Alex](https://github.com/leha-bot) noted an error in a code sample.\n- [Tom de Geus](https://github.com/tdegeus) reported some warnings with ICC and helped to fix them.\n- [Perry Kundert](https://github.com/pjkundert) simplified reading from input streams.\n- [Sonu Lohani](https://github.com/sonulohani) fixed a small compilation error.\n- [Jamie Seward](https://github.com/jseward) fixed all MSVC warnings.\n- [Nate Vargas](https://github.com/eld00d) added a Doxygen tag file.\n- [pvleuven](https://github.com/pvleuven) helped to fix a warning in ICC.\n- [Pavel](https://github.com/crea7or) helped to fix some warnings in MSVC.\n- [Jamie Seward](https://github.com/jseward) avoided unnecessary string copies in `find()` and `count()`.\n- [Mitja](https://github.com/Itja) fixed some typos.\n- [Jorrit Wronski](https://github.com/jowr) updated the Hunter package links.\n- [Matthias Möller](https://github.com/TinyTinni) added a `.natvis` for the MSVC debug view.\n- [bogemic](https://github.com/bogemic) fixed some C++17 deprecation warnings.\n- [Eren Okka](https://github.com/erengy) fixed some MSVC warnings.\n- [abolz](https://github.com/abolz) integrated the Grisu2 algorithm for proper floating-point formatting, allowing more roundtrip checks to succeed.\n- [Vadim Evard](https://github.com/Pipeliner) fixed a Markdown issue in the README.\n- [zerodefect](https://github.com/zerodefect) fixed a compiler warning.\n- [Kert](https://github.com/kaidokert) allowed to template the string type in the serialization and added the possibility to override the exceptional behavior.\n- [mark-99](https://github.com/mark-99) helped fixing an ICC error.\n- [Patrik Huber](https://github.com/patrikhuber) fixed links in the README file.\n- [johnfb](https://github.com/johnfb) found a bug in the implementation of CBOR's indefinite length strings.\n- [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager.\n- [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise.\n- [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback.\n- [agrianius](https://github.com/agrianius) allowed to dump JSON to an alternative string type.\n- [Kevin Tonon](https://github.com/ktonon) overworked the C++11 compiler checks in CMake.\n- [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io).\n- [Carlos O'Ryan](https://github.com/coryan) fixed a typo.\n- [James Upjohn](https://github.com/jammehcow) fixed a version number in the compilers section.\n- [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration.\n- [Jan Schöppach](https://github.com/dns13) fixed a typo.\n- [martin-mfg](https://github.com/martin-mfg) fixed a typo.\n- [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`.\n- [agrianius](https://github.com/agrianius) added code to use alternative string implementations.\n- [Daniel599](https://github.com/Daniel599) allowed to use more algorithms with the `items()` function.\n- [Julius Rakow](https://github.com/jrakow) fixed the Meson include directory and fixed the links to [cppreference.com](cppreference.com).\n- [Sonu Lohani](https://github.com/sonulohani) fixed the compilation with MSVC 2015 in debug mode.\n- [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases.\n- [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library.\n- [thyu](https://github.com/thyu) fixed a compiler warning.\n- [David Guthrie](https://github.com/LEgregius) fixed a subtle compilation error with Clang 3.4.2.\n- [Dennis Fischer](https://github.com/dennisfischer) allowed to call `find_package` without installing the library.\n- [Hyeon Kim](https://github.com/simnalamburt) fixed an issue with a double macro definition.\n- [Ben Berman](https://github.com/rivertam) made some error messages more understandable.\n- [zakalibit](https://github.com/zakalibit) fixed a compilation problem with the Intel C++ compiler.\n- [mandreyel](https://github.com/mandreyel) fixed a compilation problem.\n- [Kostiantyn Ponomarenko](https://github.com/koponomarenko) added version and license information to the Meson build file.\n- [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8.\n- [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory.\n- [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning.\n- [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define an enum/JSON mapping.\n- [efp](https://github.com/efp) added line and column information to parse errors.\n- [julian-becker](https://github.com/julian-becker) added BSON support.\n- [Pratik Chowdhury](https://github.com/pratikpc) added support for structured bindings.\n- [David Avedissian](https://github.com/davedissian) added support for Clang 5.0.1 (PS4 version).\n- [Jonathan Dumaresq](https://github.com/dumarjo) implemented an input adapter to read from `FILE*`.\n- [kjpus](https://github.com/kjpus) fixed a link in the documentation.\n- [Manvendra Singh](https://github.com/manu-chroma) fixed a typo in the documentation.\n- [ziggurat29](https://github.com/ziggurat29) fixed an MSVC warning.\n- [Sylvain Corlay](https://github.com/SylvainCorlay) added code to avoid an issue with MSVC.\n- [mefyl](https://github.com/mefyl) fixed a bug when JSON was parsed from an input stream.\n- [Millian Poquet](https://github.com/mpoquet) allowed to install the library via Meson.\n- [Michael Behrns-Miller](https://github.com/moodboom) found an issue with a missing namespace.\n- [Nasztanovics Ferenc](https://github.com/naszta) fixed a compilation issue with libc 2.12.\n- [Andreas Schwab](https://github.com/andreas-schwab) fixed the endian conversion.\n- [Mark-Dunning](https://github.com/Mark-Dunning) fixed a warning in MSVC.\n- [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) added `operator/` for JSON Pointers.\n- [John-Mark](https://github.com/johnmarkwayve) noted a missing header.\n- [Vitaly Zaitsev](https://github.com/xvitaly) fixed compilation with GCC 9.0.\n- [Laurent Stacul](https://github.com/stac47) fixed compilation with GCC 9.0.\n- [Ivor Wanders](https://github.com/iwanders) helped to reduce the CMake requirement to version 3.1.\n- [njlr](https://github.com/njlr) updated the Buckaroo instructions.\n- [Lion](https://github.com/lieff) fixed a compilation issue with GCC 7 on CentOS.\n- [Isaac Nickaein](https://github.com/nickaein) improved the integer serialization performance and  implemented the `contains()` function.\n- [past-due](https://github.com/past-due) suppressed an unfixable warning.\n- [Elvis Oric](https://github.com/elvisoric) improved Meson support.\n- [Matěj Plch](https://github.com/Afforix) fixed an example in the README.\n- [Mark Beckwith](https://github.com/wythe) fixed a typo.\n- [scinart](https://github.com/scinart) fixed bug in the serializer.\n- [Patrick Boettcher](https://github.com/pboettch) implemented `push_back()` and `pop_back()` for JSON Pointers.\n- [Bruno Oliveira](https://github.com/nicoddemus) added support for Conda.\n- [Michele Caini](https://github.com/skypjack) fixed links in the README.\n- [Hani](https://github.com/hnkb) documented how to install the library with NuGet.\n- [Mark Beckwith](https://github.com/wythe) fixed a typo.\n- [yann-morin-1998](https://github.com/yann-morin-1998) helped to reduce the CMake requirement to version 3.1.\n- [Konstantin Podsvirov](https://github.com/podsvirov) maintains a package for the MSYS2 software distro.\n- [remyabel](https://github.com/remyabel) added GNUInstallDirs to the CMake files.\n- [Taylor Howard](https://github.com/taylorhoward92) fixed a unit test.\n- [Gabe Ron](https://github.com/Macr0Nerd) implemented the `to_string` method.\n- [Watal M. Iwasaki](https://github.com/heavywatal) fixed a Clang warning.\n- [Viktor Kirilov](https://github.com/onqtam) switched the unit tests from [Catch](https://github.com/philsquared/Catch) to [doctest](https://github.com/onqtam/doctest)\n- [Juncheng E](https://github.com/ejcjason) fixed a typo.\n- [tete17](https://github.com/tete17) fixed a bug in the `contains` function.\n- [Xav83](https://github.com/Xav83) fixed some cppcheck warnings.\n- [0xflotus](https://github.com/0xflotus) fixed some typos.\n- [Christian Deneke](https://github.com/chris0x44) added a const version of `json_pointer::back`.\n- [Julien Hamaide](https://github.com/crazyjul) made the `items()` function work with custom string types.\n- [Evan Nemerson](https://github.com/nemequ) updated fixed a bug in Hedley and updated this library accordingly.\n- [Florian Pigorsch](https://github.com/flopp) fixed a lot of typos.\n- [Camille Bégué](https://github.com/cbegue) fixed an issue in the conversion from  `std::pair` and `std::tuple` to `json`.\n- [Anthony VH](https://github.com/AnthonyVH) fixed a compile error in an enum deserialization.\n- [Yuriy Vountesmery](https://github.com/ua-code-dragon) noted a subtle bug in a preprocessor check.\n- [Chen](https://github.com/dota17) fixed numerous issues in the library.\n- [Antony Kellermann](https://github.com/aokellermann) added a CI step for GCC 10.1.\n- [Alex](https://github.com/gistrec) fixed an MSVC warning.\n- [Rainer](https://github.com/rvjr) proposed an improvement in the floating-point serialization in CBOR.\n- [Francois Chabot](https://github.com/FrancoisChabot) made performance improvements in the input adapters.\n- [Arthur Sonzogni](https://github.com/ArthurSonzogni) documented how the library can be included via `FetchContent`.\n- [Rimas Misevičius](https://github.com/rmisev) fixed an error message.\n- [Alexander Myasnikov](https://github.com/alexandermyasnikov) fixed some examples and a link in the README.\n- [Hubert Chathi](https://github.com/uhoreg) made CMake's version config file architecture-independent.\n- [OmnipotentEntity](https://github.com/OmnipotentEntity) implemented the binary values for CBOR, MessagePack, BSON, and UBJSON.\n- [ArtemSarmini](https://github.com/ArtemSarmini) fixed a compilation issue with GCC 10 and fixed a leak.\n- [Evgenii Sopov](https://github.com/sea-kg) integrated the library to the wsjcpp package manager.\n- [Sergey Linev](https://github.com/linev) fixed a compiler warning.\n- [Miguel Magalhães](https://github.com/magamig) fixed the year in the copyright.\n- [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) fixed a compilation issue with MSVC.\n- [Alexander “weej” Jones](https://github.com/alex-weej) fixed an example in the README.\n- [Antoine Cœur](https://github.com/Coeur) fixed some typos in the documentation.\n- [jothepro](https://github.com/jothepro) updated links to the Hunter package.\n- [Dave Lee](https://github.com/kastiglione) fixed link in the README.\n- [Joël Lamotte](https://github.com/Klaim) added instruction for using Build2's package manager.\n- [Paul Jurczak](https://github.com/pauljurczak) fixed an example in the README.\n- [Sonu Lohani](https://github.com/sonulohani) fixed a warning.\n- [Carlos Gomes Martinho](https://github.com/gocarlos) updated the Conan package source.\n- [Konstantin Podsvirov](https://github.com/podsvirov) fixed the MSYS2 package documentation.\n- [Tridacnid](https://github.com/Tridacnid) improved the CMake tests.\n- [Michael](https://github.com/MBalszun) fixed MSVC warnings.\n- [Quentin Barbarat](https://github.com/quentin-dev) fixed an example in the documentation.\n- [XyFreak](https://github.com/XyFreak) fixed a compiler warning.\n- [TotalCaesar659](https://github.com/TotalCaesar659) fixed links in the README.\n- [Tanuj Garg](https://github.com/tanuj208) improved the fuzzer coverage for UBSAN input.\n- [AODQ](https://github.com/AODQ) fixed a compiler warning.\n- [jwittbrodt](https://github.com/jwittbrodt) made `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` inline.\n- [pfeatherstone](https://github.com/pfeatherstone) improved the upper bound of arguments of the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.\n- [Jan Procházka](https://github.com/jprochazk) fixed a bug in the CBOR parser for binary and string values.\n- [T0b1-iOS](https://github.com/T0b1-iOS) fixed a bug in the new hash implementation.\n- [Matthew Bauer](https://github.com/matthewbauer) adjusted the CBOR writer to create tags for binary subtypes.\n- [gatopeich](https://github.com/gatopeich) implemented an ordered map container for `nlohmann::ordered_json`.\n- [Érico Nogueira Rolim](https://github.com/ericonr) added support for pkg-config.\n- [KonanM](https://github.com/KonanM) proposed an implementation for the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.\n- [Guillaume Racicot](https://github.com/gracicot) implemented `string_view` support and allowed C++20 support.\n- [Alex Reinking](https://github.com/alexreinking) improved CMake support for `FetchContent`.\n- [Hannes Domani](https://github.com/ssbssa) provided a GDB pretty printer.\n- Lars Wirzenius reviewed the README file.\n- [Jun Jie](https://github.com/ongjunjie) fixed a compiler path in the CMake scripts.\n- [Ronak Buch](https://github.com/rbuch) fixed typos in the documentation.\n- [Alexander Karzhenkov](https://github.com/karzhenkov) fixed a move constructor and the Travis builds.\n- [Leonardo Lima](https://github.com/leozz37) added CPM.Cmake support.\n- [Joseph Blackman](https://github.com/jbzdarkid) fixed a warning.\n- [Yaroslav](https://github.com/YarikTH) updated doctest and implemented unit tests.\n- [Martin Stump](https://github.com/globberwops) fixed a bug in the CMake files.\n- [Jaakko Moisio](https://github.com/jasujm) fixed a bug in the input adapters.\n- [bl-ue](https://github.com/bl-ue) fixed some Markdown issues in the README file.\n- [William A. Wieselquist](https://github.com/wawiesel) fixed an example from the README.\n- [abbaswasim](https://github.com/abbaswasim) fixed an example from the README.\n- [Remy Jette](https://github.com/remyjette) fixed a warning.\n- [Fraser](https://github.com/frasermarlow) fixed the documentation.\n- [Ben Beasley](https://github.com/musicinmybrain) updated doctest.\n- [Doron Behar](https://github.com/doronbehar) fixed pkg-config.pc.\n- [raduteo](https://github.com/raduteo) fixed a warning.\n- [David Pfahler](https://github.com/theShmoo) added the possibility to compile the library without I/O support.\n- [Morten Fyhn Amundsen](https://github.com/mortenfyhn) fixed a typo.\n- [jpl-mac](https://github.com/jpl-mac) allowed to treat the library as a system header in CMake.\n- [Jason Dsouza](https://github.com/jasmcaus) fixed the indentation of the CMake file.\n- [offa](https://github.com/offa) added a link to Conan Center to the documentation.\n- [TotalCaesar659](https://github.com/TotalCaesar659) updated the links in the documentation to use HTTPS.\n- [Rafail Giavrimis](https://github.com/grafail) fixed the Google Benchmark default branch.\n- [Louis Dionne](https://github.com/ldionne) fixed a conversion operator.\n- [justanotheranonymoususer](https://github.com/justanotheranonymoususer) made the examples in the README more consistent.\n- [Finkman](https://github.com/Finkman) suppressed some `-Wfloat-equal` warnings.\n- [Ferry Huberts](https://github.com/fhuberts) fixed `-Wswitch-enum` warnings.\n- [Arseniy Terekhin](https://github.com/senyai) made the GDB pretty-printer robust against unset variable names.\n- [Amir Masoud Abdol](https://github.com/amirmasoudabdol) updated the Homebrew command as nlohmann/json is now in homebrew-core.\n- [Hallot](https://github.com/Hallot) fixed some `-Wextra-semi-stmt warnings`.\n- [Giovanni Cerretani](https://github.com/gcerretani) fixed `-Wunused` warnings on `JSON_DIAGNOSTICS`.\n- [Bogdan Popescu](https://github.com/Kapeli) hosts the [docset](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B) for offline documentation viewers.\n- [Carl Smedstad](https://github.com/carlsmedstad) fixed an assertion error when using `JSON_DIAGNOSTICS`.\n- [miikka75](https://github.com/miikka75) provided an important fix to compile C++17 code with Clang 9.\n- [Maarten Becker](https://github.com/kernie) fixed a warning for shadowed variables.\n- [Cristi Vîjdea](https://github.com/axnsan12) fixed typos in the `operator[]` documentation.\n- [Alex Beregszaszi](https://github.com/axic) fixed spelling mistakes in comments.\n- [Dirk Stolle](https://github.com/striezel) fixed typos in documentation.\n- [Daniel Albuschat](https://github.com/daniel-kun) corrected the parameter name in the `parse` documentation.\n- [Prince Mendiratta](https://github.com/Prince-Mendiratta) fixed a link to the FAQ.\n\nThanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.\n\n\n## Used third-party tools\n\nThe library itself consists of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot!\n\n- [**amalgamate.py - Amalgamate C source and header files**](https://github.com/edlund/amalgamate) to create a single header file\n- [**American fuzzy lop**](https://lcamtuf.coredump.cx/afl/) for fuzz testing\n- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows\n- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code indentation\n- [**Clang**](https://clang.llvm.org) for compilation with code sanitizers\n- [**CMake**](https://cmake.org) for build automation\n- [**Codacity**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json)\n- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)\n- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)\n- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis\n- [**doctest**](https://github.com/onqtam/doctest) for the unit tests\n- [**Doxygen**](https://www.doxygen.nl/index.html) to generate [documentation](https://nlohmann.github.io/json/doxygen/index.html)\n- [**git-update-ghpages**](https://github.com/rstacruz/git-update-ghpages) to upload the documentation to gh-pages\n- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md)\n- [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks\n- [**Hedley**](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros\n- [**lcov**](http://ltp.sourceforge.net/coverage/lcov.php) to process coverage information and create an HTML view\n- [**libFuzzer**](https://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz\n- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json))\n- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments.\n- [**Valgrind**](https://valgrind.org) to check for correct memory management\n\n\n## Projects using JSON for Modern C++\n\nThe library is currently used in Apple macOS Sierra and iOS 10. I am not sure what they are using the library for, but I am happy that it runs on so many devices.\n\n\n## Notes\n\n### Character encoding\n\nThe library supports **Unicode input** as follows:\n\n- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1).\n- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers.\n- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors.\n- [Unicode noncharacters](https://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library.\n- Invalid surrogates (e.g., incomplete pairs such as `\\uDEAD`) will yield parse errors.\n- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.\n- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.\n- To store wide strings (e.g., `std::wstring`), you need to convert them to a UTF-8 encoded `std::string` before, see [an example](https://json.nlohmann.me/home/faq/#wide-string-handling).\n\n### Comments in JSON\n\nThis library does not support comments by default. It does so for three reasons:\n\n1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript.\n2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012:\n\n\t> I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability.  I know that the lack of comments makes some people sad, but it shouldn't.\n\n\t> Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.\n\n3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this.\n\nHowever, you can pass set parameter `ignore_comments` to true in the `parse` function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace.\n\n### Order of object keys\n\nBy default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as \"an unordered collection of zero or more name/value pairs\".\n\nIf you do want to preserve the insertion order, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179). Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).\n\n### Memory Release\n\nWe checked with Valgrind and the Address Sanitizer (ASAN) that there are no memory leaks.\n\nIf you find that a parsing program with this library does not release memory, please consider the following case, and it may be unrelated to this library.\n\n**Your program is compiled with glibc.** There is a tunable threshold that glibc uses to decide whether to actually return memory to the system or whether to cache it for later reuse. If in your program you make lots of small allocations and those small allocations are not a contiguous block and are presumably below the threshold, then they will not get returned to the OS.\nHere is a related issue [#1924](https://github.com/nlohmann/json/issues/1924).\n\n### Further notes\n\n- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/api/basic_json/operator%5B%5D/) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/api/basic_json/at/). Furthermore, you can define `JSON_ASSERT(x)` to replace calls to `assert(x)`.\n- As the exact number type is not defined in the [JSON specification](https://tools.ietf.org/html/rfc8259.html), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.\n- The code can be compiled without C++ **runtime type identification** features; that is, you can use the `-fno-rtti` compiler flag.\n- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior. Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824).\n\n## Execute unit tests\n\nTo compile and run the tests, you need to execute\n\n```sh\n$ mkdir build\n$ cd build\n$ cmake .. -DJSON_BuildTests=On\n$ cmake --build .\n$ ctest --output-on-failure\n```\n\nNote that during the `ctest` stage, several JSON test files are downloaded from an [external repository](https://github.com/nlohmann/json_test_data). If policies forbid downloading artifacts during testing, you can download the files yourself and pass the directory with the test files via `-DJSON_TestDataDirectory=path` to CMake. Then, no Internet connectivity is required. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.\n\nIn case you have downloaded the library rather than checked out the code via Git, test `cmake_fetch_content_configure` will fail. Please execute `ctest -LE git_required` to skip these tests. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.\n\nSome tests change the installed files and hence make the whole process not reproducible. Please execute `ctest -LE not_reproducible` to skip these tests. See [issue #2324](https://github.com/nlohmann/json/issues/2324) for more information.\n\nNote you need to call `cmake -LE \"not_reproducible|git_required\"` to exclude both labels. See [issue #2596](https://github.com/nlohmann/json/issues/2596) for more information.\n\nAs Intel compilers use unsafe floating point optimization by default, the unit tests may fail. Use flag [`/fp:precise`](https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/floating-point-options/fp-model-fp.html) then.\n"
  },
  {
    "path": "subprojects/nlohmann_json/appveyor.yml",
    "content": "version: '{build}'\n\nenvironment:\n  matrix:\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015\n      configuration: Debug\n      platform: x86\n      CXX_FLAGS: \"/W4 /WX\"\n      CMAKE_OPTIONS: \"\"\n      GENERATOR: Visual Studio 14 2015\n\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015\n      configuration: Release\n      platform: x86\n      CXX_FLAGS: \"/W4 /WX\"\n      CMAKE_OPTIONS: \"\"\n      GENERATOR: Visual Studio 14 2015\n\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015\n      configuration: Release\n      platform: x86\n      name: with_win_header\n      CXX_FLAGS: \"/W4 /WX\"\n      CMAKE_OPTIONS: \"\"\n      GENERATOR: Visual Studio 14 2015\n\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017\n      configuration: Release\n      platform: x86\n      CXX_FLAGS: \"/permissive- /std:c++latest /utf-8 /W4 /WX\"\n      CMAKE_OPTIONS: \"\"\n      GENERATOR: Visual Studio 15 2017\n\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019\n      configuration: Release\n      platform: x86\n      CXX_FLAGS: \"/W4 /WX\"\n      CMAKE_OPTIONS: \"-DJSON_ImplicitConversions=OFF\"\n      GENERATOR: Visual Studio 16 2019\n\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015\n      configuration: Release\n      platform: x64\n      CXX_FLAGS: \"/W4 /WX\"\n      CMAKE_OPTIONS: \"\"\n      GENERATOR: Visual Studio 14 2015\n\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017\n      configuration: Release\n      platform: x64\n      CXX_FLAGS: \"/permissive- /std:c++latest /Zc:__cplusplus /utf-8 /W4 /WX\"\n      CMAKE_OPTIONS: \"\"\n      GENERATOR: Visual Studio 15 2017\n\ninit:\n  - cmake --version\n  - msbuild /version\n\ninstall:\n  - if \"%platform%\"==\"x86\"    set GENERATOR_PLATFORM=Win32\n\nbefore_build:\n  # for with_win_header build, inject the inclusion of Windows.h to the single-header library\n  - ps: if ($env:name -Eq \"with_win_header\") { $header_path = \"single_include\\nlohmann\\json.hpp\" }\n  - ps: if ($env:name -Eq \"with_win_header\") { \"#include <Windows.h>`n\" + (Get-Content $header_path | Out-String) | Set-Content $header_path }\n  - cmake . -G \"%GENERATOR%\" -A \"%GENERATOR_PLATFORM%\" -DCMAKE_CXX_FLAGS=\"%CXX_FLAGS%\" -DCMAKE_IGNORE_PATH=\"C:/Program Files/Git/usr/bin\" -DJSON_BuildTests=On \"%CMAKE_OPTIONS%\"\n\nbuild_script:\n  - cmake --build . --config \"%configuration%\"\n\ntest_script:\n  - if \"%configuration%\"==\"Release\" ctest -C \"%configuration%\" -V -j\n  # On Debug builds, skip test-unicode_all\n  # as it is extremely slow to run and cause\n  # occasional timeouts on AppVeyor.\n  # More info: https://github.com/nlohmann/json/pull/1570\n  - if \"%configuration%\"==\"Debug\" ctest --exclude-regex \"test-unicode\" -C \"%configuration%\" -V -j\n\n# only build PRs and commits to develop branch\n# (see https://help.appveyor.com/discussions/questions/55079-two-builds-per-commit-to-pull-request)\nbranches:\n  only:\n    - develop\n"
  },
  {
    "path": "subprojects/nlohmann_json/benchmarks/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.11)\nproject(JSON_Benchmarks LANGUAGES CXX)\n\n# set compiler flags\nif((CMAKE_CXX_COMPILER_ID MATCHES GNU) OR (CMAKE_CXX_COMPILER_ID MATCHES Clang))\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -flto -DNDEBUG -O3\")\nendif()\n\n# configure Google Benchmarks\ninclude(FetchContent)\nFetchContent_Declare(\n    benchmark\n    GIT_REPOSITORY https://github.com/google/benchmark.git\n    GIT_TAG origin/main\n    GIT_SHALLOW TRUE\n)\n\nFetchContent_GetProperties(benchmark)\nif(NOT benchmark_POPULATED)\n    FetchContent_Populate(benchmark)\n    set(BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL \"\" FORCE)\n    add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR})\nendif()\n\n# download test data\ninclude(${CMAKE_SOURCE_DIR}/../cmake/download_test_data.cmake)\n\n# benchmark binary\nadd_executable(json_benchmarks src/benchmarks.cpp)\ntarget_compile_features(json_benchmarks PRIVATE cxx_std_11)\ntarget_link_libraries(json_benchmarks benchmark ${CMAKE_THREAD_LIBS_INIT})\nadd_dependencies(json_benchmarks download_test_data)\ntarget_include_directories(json_benchmarks PRIVATE ${CMAKE_SOURCE_DIR}/../single_include ${CMAKE_BINARY_DIR}/include)\n"
  },
  {
    "path": "subprojects/nlohmann_json/benchmarks/src/benchmarks.cpp",
    "content": "#include \"benchmark/benchmark.h\"\n#include <nlohmann/json.hpp>\n#include <fstream>\n#include <test_data.hpp>\n\nusing json = nlohmann::json;\n\n//////////////////////////////////////////////////////////////////////////////\n// parse JSON from file\n//////////////////////////////////////////////////////////////////////////////\n\nstatic void ParseFile(benchmark::State& state, const char* filename)\n{\n    while (state.KeepRunning())\n    {\n        state.PauseTiming();\n        auto* f = new std::ifstream(filename);\n        auto* j = new json();\n        state.ResumeTiming();\n\n        *j = json::parse(*f);\n\n        state.PauseTiming();\n        delete f;\n        delete j;\n        state.ResumeTiming();\n    }\n\n    std::ifstream file(filename, std::ios::binary | std::ios::ate);\n    state.SetBytesProcessed(state.iterations() * file.tellg());\n}\nBENCHMARK_CAPTURE(ParseFile, jeopardy,          TEST_DATA_DIRECTORY \"/jeopardy/jeopardy.json\");\nBENCHMARK_CAPTURE(ParseFile, canada,            TEST_DATA_DIRECTORY \"/nativejson-benchmark/canada.json\");\nBENCHMARK_CAPTURE(ParseFile, citm_catalog,      TEST_DATA_DIRECTORY \"/nativejson-benchmark/citm_catalog.json\");\nBENCHMARK_CAPTURE(ParseFile, twitter,           TEST_DATA_DIRECTORY \"/nativejson-benchmark/twitter.json\");\nBENCHMARK_CAPTURE(ParseFile, floats,            TEST_DATA_DIRECTORY \"/regression/floats.json\");\nBENCHMARK_CAPTURE(ParseFile, signed_ints,       TEST_DATA_DIRECTORY \"/regression/signed_ints.json\");\nBENCHMARK_CAPTURE(ParseFile, unsigned_ints,     TEST_DATA_DIRECTORY \"/regression/unsigned_ints.json\");\nBENCHMARK_CAPTURE(ParseFile, small_signed_ints, TEST_DATA_DIRECTORY \"/regression/small_signed_ints.json\");\n\n//////////////////////////////////////////////////////////////////////////////\n// parse JSON from string\n//////////////////////////////////////////////////////////////////////////////\n\nstatic void ParseString(benchmark::State& state, const char* filename)\n{\n    std::ifstream f(filename);\n    std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());\n\n    while (state.KeepRunning())\n    {\n        state.PauseTiming();\n        auto* j = new json();\n        state.ResumeTiming();\n\n        *j = json::parse(str);\n\n        state.PauseTiming();\n        delete j;\n        state.ResumeTiming();\n    }\n\n    state.SetBytesProcessed(state.iterations() * str.size());\n}\nBENCHMARK_CAPTURE(ParseString, jeopardy,          TEST_DATA_DIRECTORY \"/jeopardy/jeopardy.json\");\nBENCHMARK_CAPTURE(ParseString, canada,            TEST_DATA_DIRECTORY \"/nativejson-benchmark/canada.json\");\nBENCHMARK_CAPTURE(ParseString, citm_catalog,      TEST_DATA_DIRECTORY \"/nativejson-benchmark/citm_catalog.json\");\nBENCHMARK_CAPTURE(ParseString, twitter,           TEST_DATA_DIRECTORY \"/nativejson-benchmark/twitter.json\");\nBENCHMARK_CAPTURE(ParseString, floats,            TEST_DATA_DIRECTORY \"/regression/floats.json\");\nBENCHMARK_CAPTURE(ParseString, signed_ints,       TEST_DATA_DIRECTORY \"/regression/signed_ints.json\");\nBENCHMARK_CAPTURE(ParseString, unsigned_ints,     TEST_DATA_DIRECTORY \"/regression/unsigned_ints.json\");\nBENCHMARK_CAPTURE(ParseString, small_signed_ints, TEST_DATA_DIRECTORY \"/regression/small_signed_ints.json\");\n\n\n//////////////////////////////////////////////////////////////////////////////\n// serialize JSON\n//////////////////////////////////////////////////////////////////////////////\n\nstatic void Dump(benchmark::State& state, const char* filename, int indent)\n{\n    std::ifstream f(filename);\n    std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());\n    json j = json::parse(str);\n\n    while (state.KeepRunning())\n    {\n        j.dump(indent);\n    }\n\n    state.SetBytesProcessed(state.iterations() * j.dump(indent).size());\n}\nBENCHMARK_CAPTURE(Dump, jeopardy / -,          TEST_DATA_DIRECTORY \"/jeopardy/jeopardy.json\",                 -1);\nBENCHMARK_CAPTURE(Dump, jeopardy / 4,          TEST_DATA_DIRECTORY \"/jeopardy/jeopardy.json\",                 4);\nBENCHMARK_CAPTURE(Dump, canada / -,            TEST_DATA_DIRECTORY \"/nativejson-benchmark/canada.json\",       -1);\nBENCHMARK_CAPTURE(Dump, canada / 4,            TEST_DATA_DIRECTORY \"/nativejson-benchmark/canada.json\",       4);\nBENCHMARK_CAPTURE(Dump, citm_catalog / -,      TEST_DATA_DIRECTORY \"/nativejson-benchmark/citm_catalog.json\", -1);\nBENCHMARK_CAPTURE(Dump, citm_catalog / 4,      TEST_DATA_DIRECTORY \"/nativejson-benchmark/citm_catalog.json\", 4);\nBENCHMARK_CAPTURE(Dump, twitter / -,           TEST_DATA_DIRECTORY \"/nativejson-benchmark/twitter.json\",      -1);\nBENCHMARK_CAPTURE(Dump, twitter / 4,           TEST_DATA_DIRECTORY \"/nativejson-benchmark/twitter.json\",      4);\nBENCHMARK_CAPTURE(Dump, floats / -,            TEST_DATA_DIRECTORY \"/regression/floats.json\",                 -1);\nBENCHMARK_CAPTURE(Dump, floats / 4,            TEST_DATA_DIRECTORY \"/regression/floats.json\",                 4);\nBENCHMARK_CAPTURE(Dump, signed_ints / -,       TEST_DATA_DIRECTORY \"/regression/signed_ints.json\",            -1);\nBENCHMARK_CAPTURE(Dump, signed_ints / 4,       TEST_DATA_DIRECTORY \"/regression/signed_ints.json\",            4);\nBENCHMARK_CAPTURE(Dump, unsigned_ints / -,     TEST_DATA_DIRECTORY \"/regression/unsigned_ints.json\",          -1);\nBENCHMARK_CAPTURE(Dump, unsigned_ints / 4,     TEST_DATA_DIRECTORY \"/regression/unsigned_ints.json\",          4);\nBENCHMARK_CAPTURE(Dump, small_signed_ints / -, TEST_DATA_DIRECTORY \"/regression/small_signed_ints.json\",      -1);\nBENCHMARK_CAPTURE(Dump, small_signed_ints / 4, TEST_DATA_DIRECTORY \"/regression/small_signed_ints.json\",      4);\n\n\nBENCHMARK_MAIN();\n"
  },
  {
    "path": "subprojects/nlohmann_json/cmake/ci.cmake",
    "content": "# number of parallel jobs for CTest\nset(N 10)\n\n###############################################################################\n# Needed tools.\n###############################################################################\n\ninclude(FindPython3)\nfind_package(Python3 COMPONENTS Interpreter)\n\nfind_program(ASTYLE_TOOL NAMES astyle)\nexecute_process(COMMAND ${ASTYLE_TOOL} --version OUTPUT_VARIABLE ASTYLE_TOOL_VERSION ERROR_VARIABLE ASTYLE_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" ASTYLE_TOOL_VERSION \"${ASTYLE_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Artistic Style ${ASTYLE_TOOL_VERSION} (${ASTYLE_TOOL})\")\n\nfind_program(CLANG_TOOL NAMES clang++-HEAD clang++-14 clang++-13 clang++-12 clang++-11 clang++)\nexecute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" CLANG_TOOL_VERSION \"${CLANG_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})\")\n\nfind_program(CLANG_TIDY_TOOL NAMES clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy)\nexecute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" CLANG_TIDY_TOOL_VERSION \"${CLANG_TIDY_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})\")\n\nmessage(STATUS \"🔖 CMake ${CMAKE_VERSION} (${CMAKE_COMMAND})\")\n\nfind_program(CPPCHECK_TOOL NAMES cppcheck)\nexecute_process(COMMAND ${CPPCHECK_TOOL} --version OUTPUT_VARIABLE CPPCHECK_TOOL_VERSION ERROR_VARIABLE CPPCHECK_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" CPPCHECK_TOOL_VERSION \"${CPPCHECK_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Cppcheck ${CPPCHECK_TOOL_VERSION} (${CPPCHECK_TOOL})\")\n\nfind_program(GCC_TOOL NAMES g++-HEAD g++-11 g++-latest)\nexecute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" GCC_TOOL_VERSION \"${GCC_TOOL_VERSION}\")\nmessage(STATUS \"🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})\")\n\nfind_program(GCOV_TOOL NAMES gcov-HEAD gcov-11 gcov-10 gcov)\nexecute_process(COMMAND ${GCOV_TOOL} --version OUTPUT_VARIABLE GCOV_TOOL_VERSION ERROR_VARIABLE GCOV_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" GCOV_TOOL_VERSION \"${GCOV_TOOL_VERSION}\")\nmessage(STATUS \"🔖 GCOV ${GCOV_TOOL_VERSION} (${GCOV_TOOL})\")\n\nfind_program(GIT_TOOL NAMES git)\nexecute_process(COMMAND ${GIT_TOOL} --version OUTPUT_VARIABLE GIT_TOOL_VERSION ERROR_VARIABLE GIT_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" GIT_TOOL_VERSION \"${GIT_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Git ${GIT_TOOL_VERSION} (${GIT_TOOL})\")\n\nfind_program(IWYU_TOOL NAMES include-what-you-use iwyu)\nexecute_process(COMMAND ${IWYU_TOOL} --version OUTPUT_VARIABLE IWYU_TOOL_VERSION ERROR_VARIABLE IWYU_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" IWYU_TOOL_VERSION \"${IWYU_TOOL_VERSION}\")\nmessage(STATUS \"🔖 include-what-you-use ${IWYU_TOOL_VERSION} (${IWYU_TOOL})\")\n\nfind_program(INFER_TOOL NAMES infer)\nexecute_process(COMMAND ${INFER_TOOL} --version OUTPUT_VARIABLE INFER_TOOL_VERSION ERROR_VARIABLE INFER_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" INFER_TOOL_VERSION \"${INFER_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Infer ${INFER_TOOL_VERSION} (${INFER_TOOL})\")\n\nfind_program(LCOV_TOOL NAMES lcov)\nexecute_process(COMMAND ${LCOV_TOOL} --version OUTPUT_VARIABLE LCOV_TOOL_VERSION ERROR_VARIABLE LCOV_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" LCOV_TOOL_VERSION \"${LCOV_TOOL_VERSION}\")\nmessage(STATUS \"🔖 LCOV ${LCOV_TOOL_VERSION} (${LCOV_TOOL})\")\n\nfind_program(NINJA_TOOL NAMES ninja)\nexecute_process(COMMAND ${NINJA_TOOL} --version OUTPUT_VARIABLE NINJA_TOOL_VERSION ERROR_VARIABLE NINJA_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" NINJA_TOOL_VERSION \"${NINJA_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Ninja ${NINJA_TOOL_VERSION} (${NINJA_TOOL})\")\n\nfind_program(OCLINT_TOOL NAMES oclint-json-compilation-database)\nfind_program(OCLINT_VERSION_TOOL NAMES oclint)\nexecute_process(COMMAND ${OCLINT_VERSION_TOOL} --version OUTPUT_VARIABLE OCLINT_TOOL_VERSION ERROR_VARIABLE OCLINT_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" OCLINT_TOOL_VERSION \"${OCLINT_TOOL_VERSION}\")\nmessage(STATUS \"🔖 OCLint ${OCLINT_TOOL_VERSION} (${OCLINT_TOOL})\")\n\nfind_program(VALGRIND_TOOL NAMES valgrind)\nexecute_process(COMMAND ${VALGRIND_TOOL} --version OUTPUT_VARIABLE VALGRIND_TOOL_VERSION ERROR_VARIABLE VALGRIND_TOOL_VERSION)\nstring(REGEX MATCH \"[0-9]+(\\\\.[0-9]+)+\" VALGRIND_TOOL_VERSION \"${VALGRIND_TOOL_VERSION}\")\nmessage(STATUS \"🔖 Valgrind ${VALGRIND_TOOL_VERSION} (${VALGRIND_TOOL})\")\n\nfind_program(GENHTML_TOOL NAMES genhtml)\nfind_program(PLOG_CONVERTER_TOOL NAMES plog-converter)\nfind_program(PVS_STUDIO_ANALYZER_TOOL NAMES pvs-studio-analyzer)\nfind_program(SCAN_BUILD_TOOL NAMES scan-build-14 scan-build-13 scan-build-12 scan-build-11 scan-build)\n\n# the individual source files\nfile(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp)\n\n###############################################################################\n# Thorough check with recent compilers\n###############################################################################\n\n# Ignored Clang warnings:\n# -Wno-c++98-compat               The library targets C++11.\n# -Wno-c++98-compat-pedantic      The library targets C++11.\n# -Wno-deprecated-declarations    The library contains annotations for deprecated functions.\n# -Wno-extra-semi-stmt            The library uses std::assert which triggers this warning.\n# -Wno-padded                     We do not care about padding warnings.\n# -Wno-covered-switch-default     All switches list all cases and a default case.\n# -Wno-weak-vtables               The library is header-only.\n# -Wreserved-identifier           See https://github.com/onqtam/doctest/issues/536.\n\nset(CLANG_CXXFLAGS \"-std=c++11                        \\\n    -Werror                                           \\\n    -Weverything                                      \\\n    -Wno-c++98-compat                                    \\\n    -Wno-c++98-compat-pedantic                           \\\n    -Wno-deprecated-declarations                         \\\n    -Wno-extra-semi-stmt                                 \\\n    -Wno-padded                                          \\\n    -Wno-covered-switch-default                          \\\n    -Wno-weak-vtables                                    \\\n    -Wno-reserved-identifier                             \\\n\")\n\n# Ignored GCC warnings:\n# -Wno-abi-tag                    We do not care about ABI tags.\n# -Wno-aggregate-return           The library uses aggregate returns.\n# -Wno-long-long                  The library uses the long long type to interface with system functions.\n# -Wno-namespaces                 The library uses namespaces.\n# -Wno-padded                     We do not care about padding warnings.\n# -Wno-system-headers             We do not care about warnings in system headers.\n# -Wno-templates                  The library uses templates.\n\nset(GCC_CXXFLAGS \"-std=c++11                          \\\n    -pedantic                                         \\\n    -Werror                                           \\\n    --all-warnings                                    \\\n    --extra-warnings                                  \\\n    -W                                                \\\n    -WNSObject-attribute                              \\\n    -Wno-abi-tag                                         \\\n    -Waddress                                         \\\n    -Waddress-of-packed-member                        \\\n    -Wno-aggregate-return                                \\\n    -Waggressive-loop-optimizations                   \\\n    -Waligned-new=all                                 \\\n    -Wall                                             \\\n    -Walloc-zero                                      \\\n    -Walloca                                          \\\n    -Wanalyzer-double-fclose                          \\\n    -Wanalyzer-double-free                            \\\n    -Wanalyzer-exposure-through-output-file           \\\n    -Wanalyzer-file-leak                              \\\n    -Wanalyzer-free-of-non-heap                       \\\n    -Wanalyzer-malloc-leak                            \\\n    -Wanalyzer-mismatching-deallocation               \\\n    -Wanalyzer-null-argument                          \\\n    -Wanalyzer-null-dereference                       \\\n    -Wanalyzer-possible-null-argument                 \\\n    -Wanalyzer-possible-null-dereference              \\\n    -Wanalyzer-shift-count-negative                   \\\n    -Wanalyzer-shift-count-overflow                   \\\n    -Wanalyzer-stale-setjmp-buffer                    \\\n    -Wanalyzer-tainted-array-index                    \\\n    -Wanalyzer-too-complex                            \\\n    -Wanalyzer-unsafe-call-within-signal-handler      \\\n    -Wanalyzer-use-after-free                         \\\n    -Wanalyzer-use-of-pointer-in-stale-stack-frame    \\\n    -Wanalyzer-write-to-const                         \\\n    -Wanalyzer-write-to-string-literal                \\\n    -Warith-conversion                                \\\n    -Warray-bounds                                    \\\n    -Warray-bounds=2                                  \\\n    -Warray-parameter=2                               \\\n    -Wattribute-alias=2                               \\\n    -Wattribute-warning                               \\\n    -Wattributes                                      \\\n    -Wbool-compare                                    \\\n    -Wbool-operation                                  \\\n    -Wbuiltin-declaration-mismatch                    \\\n    -Wbuiltin-macro-redefined                         \\\n    -Wc++0x-compat                                    \\\n    -Wc++11-compat                                    \\\n    -Wc++14-compat                                    \\\n    -Wc++17-compat                                    \\\n    -Wc++1z-compat                                    \\\n    -Wc++20-compat                                    \\\n    -Wc++2a-compat                                    \\\n    -Wcannot-profile                                  \\\n    -Wcast-align                                      \\\n    -Wcast-align=strict                               \\\n    -Wcast-function-type                              \\\n    -Wcast-qual                                       \\\n    -Wcatch-value=3                                   \\\n    -Wchar-subscripts                                 \\\n    -Wclass-conversion                                \\\n    -Wclass-memaccess                                 \\\n    -Wclobbered                                       \\\n    -Wcomma-subscript                                 \\\n    -Wcomment                                         \\\n    -Wcomments                                        \\\n    -Wconditionally-supported                         \\\n    -Wconversion                                      \\\n    -Wconversion-null                                 \\\n    -Wcoverage-mismatch                               \\\n    -Wcpp                                             \\\n    -Wctad-maybe-unsupported                          \\\n    -Wctor-dtor-privacy                               \\\n    -Wdangling-else                                   \\\n    -Wdate-time                                       \\\n    -Wdelete-incomplete                               \\\n    -Wdelete-non-virtual-dtor                         \\\n    -Wdeprecated                                      \\\n    -Wdeprecated-copy                                 \\\n    -Wdeprecated-copy-dtor                            \\\n    -Wdeprecated-declarations                         \\\n    -Wdeprecated-enum-enum-conversion                 \\\n    -Wdeprecated-enum-float-conversion                \\\n    -Wdisabled-optimization                           \\\n    -Wdiv-by-zero                                     \\\n    -Wdouble-promotion                                \\\n    -Wduplicated-branches                             \\\n    -Wduplicated-cond                                 \\\n    -Weffc++                                          \\\n    -Wempty-body                                      \\\n    -Wendif-labels                                    \\\n    -Wenum-compare                                    \\\n    -Wenum-conversion                                 \\\n    -Wexpansion-to-defined                            \\\n    -Wextra                                           \\\n    -Wextra-semi                                      \\\n    -Wfloat-conversion                                \\\n    -Wfloat-equal                                     \\\n    -Wformat-contains-nul                             \\\n    -Wformat-diag                                     \\\n    -Wformat-extra-args                               \\\n    -Wformat-nonliteral                               \\\n    -Wformat-overflow=2                               \\\n    -Wformat-security                                 \\\n    -Wformat-signedness                               \\\n    -Wformat-truncation=2                             \\\n    -Wformat-y2k                                      \\\n    -Wformat-zero-length                              \\\n    -Wformat=2                                        \\\n    -Wframe-address                                   \\\n    -Wfree-nonheap-object                             \\\n    -Whsa                                             \\\n    -Wif-not-aligned                                  \\\n    -Wignored-attributes                              \\\n    -Wignored-qualifiers                              \\\n    -Wimplicit-fallthrough=5                          \\\n    -Winaccessible-base                               \\\n    -Winherited-variadic-ctor                         \\\n    -Winit-list-lifetime                              \\\n    -Winit-self                                       \\\n    -Winline                                          \\\n    -Wint-in-bool-context                             \\\n    -Wint-to-pointer-cast                             \\\n    -Winvalid-memory-model                            \\\n    -Winvalid-offsetof                                \\\n    -Winvalid-pch                                     \\\n    -Wliteral-suffix                                  \\\n    -Wlogical-not-parentheses                         \\\n    -Wlogical-op                                      \\\n    -Wno-long-long                                       \\\n    -Wlto-type-mismatch                               \\\n    -Wmain                                            \\\n    -Wmaybe-uninitialized                             \\\n    -Wmemset-elt-size                                 \\\n    -Wmemset-transposed-args                          \\\n    -Wmisleading-indentation                          \\\n    -Wmismatched-dealloc                              \\\n    -Wmismatched-new-delete                           \\\n    -Wmismatched-tags                                 \\\n    -Wmissing-attributes                              \\\n    -Wmissing-braces                                  \\\n    -Wmissing-declarations                            \\\n    -Wmissing-field-initializers                      \\\n    -Wmissing-include-dirs                            \\\n    -Wmissing-profile                                 \\\n    -Wmultichar                                       \\\n    -Wmultiple-inheritance                            \\\n    -Wmultistatement-macros                           \\\n    -Wno-namespaces                                      \\\n    -Wnarrowing                                       \\\n    -Wnoexcept                                        \\\n    -Wnoexcept-type                                   \\\n    -Wnon-template-friend                             \\\n    -Wnon-virtual-dtor                                \\\n    -Wnonnull                                         \\\n    -Wnonnull-compare                                 \\\n    -Wnormalized=nfkc                                 \\\n    -Wnull-dereference                                \\\n    -Wodr                                             \\\n    -Wold-style-cast                                  \\\n    -Wopenmp-simd                                     \\\n    -Woverflow                                        \\\n    -Woverlength-strings                              \\\n    -Woverloaded-virtual                              \\\n    -Wpacked                                          \\\n    -Wpacked-bitfield-compat                          \\\n    -Wpacked-not-aligned                              \\\n    -Wno-padded                                          \\\n    -Wparentheses                                     \\\n    -Wpedantic                                        \\\n    -Wpessimizing-move                                \\\n    -Wplacement-new=2                                 \\\n    -Wpmf-conversions                                 \\\n    -Wpointer-arith                                   \\\n    -Wpointer-compare                                 \\\n    -Wpragmas                                         \\\n    -Wprio-ctor-dtor                                  \\\n    -Wpsabi                                           \\\n    -Wrange-loop-construct                            \\\n    -Wredundant-decls                                 \\\n    -Wredundant-move                                  \\\n    -Wredundant-tags                                  \\\n    -Wregister                                        \\\n    -Wreorder                                         \\\n    -Wrestrict                                        \\\n    -Wreturn-local-addr                               \\\n    -Wreturn-type                                     \\\n    -Wscalar-storage-order                            \\\n    -Wsequence-point                                  \\\n    -Wshadow=compatible-local                         \\\n    -Wshadow=global                                   \\\n    -Wshadow=local                                    \\\n    -Wshift-count-negative                            \\\n    -Wshift-count-overflow                            \\\n    -Wshift-negative-value                            \\\n    -Wshift-overflow=2                                \\\n    -Wsign-compare                                    \\\n    -Wsign-conversion                                 \\\n    -Wsign-promo                                      \\\n    -Wsized-deallocation                              \\\n    -Wsizeof-array-argument                           \\\n    -Wsizeof-array-div                                \\\n    -Wsizeof-pointer-div                              \\\n    -Wsizeof-pointer-memaccess                        \\\n    -Wstack-protector                                 \\\n    -Wstrict-aliasing                                 \\\n    -Wstrict-aliasing=3                               \\\n    -Wstrict-null-sentinel                            \\\n    -Wstrict-overflow                                 \\\n    -Wstrict-overflow=5                               \\\n    -Wstring-compare                                  \\\n    -Wstringop-overflow=4                             \\\n    -Wstringop-overread                               \\\n    -Wstringop-truncation                             \\\n    -Wsubobject-linkage                               \\\n    -Wsuggest-attribute=cold                          \\\n    -Wsuggest-attribute=const                         \\\n    -Wsuggest-attribute=format                        \\\n    -Wsuggest-attribute=malloc                        \\\n    -Wsuggest-attribute=noreturn                      \\\n    -Wsuggest-attribute=pure                          \\\n    -Wsuggest-final-methods                           \\\n    -Wsuggest-final-types                             \\\n    -Wsuggest-override                                \\\n    -Wswitch                                          \\\n    -Wswitch-bool                                     \\\n    -Wswitch-default                                  \\\n    -Wswitch-enum                                     \\\n    -Wswitch-outside-range                            \\\n    -Wswitch-unreachable                              \\\n    -Wsync-nand                                       \\\n    -Wsynth                                           \\\n    -Wno-system-headers                                  \\\n    -Wtautological-compare                            \\\n    -Wno-templates                                       \\\n    -Wterminate                                       \\\n    -Wtrampolines                                     \\\n    -Wtrigraphs                                       \\\n    -Wtsan                                            \\\n    -Wtype-limits                                     \\\n    -Wundef                                           \\\n    -Wuninitialized                                   \\\n    -Wunknown-pragmas                                 \\\n    -Wunreachable-code                                \\\n    -Wunsafe-loop-optimizations                       \\\n    -Wunused                                          \\\n    -Wunused-but-set-parameter                        \\\n    -Wunused-but-set-variable                         \\\n    -Wunused-const-variable=2                         \\\n    -Wunused-function                                 \\\n    -Wunused-label                                    \\\n    -Wunused-local-typedefs                           \\\n    -Wunused-macros                                   \\\n    -Wunused-parameter                                \\\n    -Wunused-result                                   \\\n    -Wunused-value                                    \\\n    -Wunused-variable                                 \\\n    -Wuseless-cast                                    \\\n    -Wvarargs                                         \\\n    -Wvariadic-macros                                 \\\n    -Wvector-operation-performance                    \\\n    -Wvexing-parse                                    \\\n    -Wvirtual-inheritance                             \\\n    -Wvirtual-move-assign                             \\\n    -Wvla                                             \\\n    -Wvla-parameter                                   \\\n    -Wvolatile                                        \\\n    -Wvolatile-register-var                           \\\n    -Wwrite-strings                                   \\\n    -Wzero-as-null-pointer-constant                   \\\n    -Wzero-length-bounds                              \\\n\")\n\nadd_custom_target(ci_test_gcc\n    COMMAND CXX=${GCC_TOOL} CXXFLAGS=${GCC_CXXFLAGS} ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n    COMMENT \"Compile and test with GCC using maximal warning flags\"\n)\n\nadd_custom_target(ci_test_clang\n    COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXXFLAGS} ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_clang && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n    COMMENT \"Compile and test with Clang using maximal warning flags\"\n)\n\n###############################################################################\n# Different C++ Standards.\n###############################################################################\n\nforeach(CXX_STANDARD 11 14 17 20)\n    add_custom_target(ci_test_gcc_cxx${CXX_STANDARD}\n        COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND}\n            -DCMAKE_BUILD_TYPE=Debug -GNinja\n            -DCMAKE_CXX_STANDARD=${CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON\n            -DJSON_BuildTests=ON -DJSON_FastTests=ON\n            -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD}\n        COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD}\n        COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n        COMMENT \"Compile and test with GCC for C++${CXX_STANDARD}\"\n    )\n\n    add_custom_target(ci_test_clang_cxx${CXX_STANDARD}\n        COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}\n            -DCMAKE_BUILD_TYPE=Debug -GNinja\n            -DCMAKE_CXX_STANDARD=${CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON\n            -DJSON_BuildTests=ON\n            -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD}\n        COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD}\n        COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n        COMMENT \"Compile and test with Clang for C++${CXX_STANDARD}\"\n    )\nendforeach()\n\n###############################################################################\n# Disable exceptions.\n###############################################################################\n\nadd_custom_target(ci_test_noexceptions\n    COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}\n    -DCMAKE_BUILD_TYPE=Debug -GNinja\n    -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON -DCMAKE_CXX_FLAGS=-DJSON_NOEXCEPTION -DDOCTEST_TEST_FILTER=--no-throw\n    -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noexceptions\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noexceptions\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_noexceptions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n    COMMENT \"Compile and test with exceptions switched off\"\n)\n\n###############################################################################\n# Disable implicit conversions.\n###############################################################################\n\nadd_custom_target(ci_test_noimplicitconversions\n    COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}\n    -DCMAKE_BUILD_TYPE=Debug -GNinja\n    -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON -DJSON_ImplicitConversions=OFF\n    -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noimplicitconversions\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noimplicitconversions\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_noimplicitconversions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n    COMMENT \"Compile and test with implicit conversions switched off\"\n)\n\n###############################################################################\n# Enable improved diagnostics.\n###############################################################################\n\nadd_custom_target(ci_test_diagnostics\n    COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}\n    -DCMAKE_BUILD_TYPE=Debug -GNinja\n    -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON -DJSON_Diagnostics=ON\n    -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_diagnostics\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_diagnostics\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_diagnostics && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n    COMMENT \"Compile and test with improved diagnostics enabled\"\n)\n\n###############################################################################\n# Coverage.\n###############################################################################\n\nadd_custom_target(ci_test_coverage\n    COMMAND CXX=g++ ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS=\"--coverage;-fprofile-arcs;-ftest-coverage\"\n        -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n\n    COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc lcov_branch_coverage=1\n    COMMAND ${LCOV_TOOL} -e json.info ${SRC_FILES} --output-file json.info.filtered --rc lcov_branch_coverage=1\n    COMMAND ${CMAKE_SOURCE_DIR}/test/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept\n    COMMAND genhtml --title \"JSON for Modern C++\" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.filtered.noexcept\n\n    COMMENT \"Compile and test with coverage\"\n)\n\n###############################################################################\n# Sanitizers.\n###############################################################################\n\nset(CLANG_CXX_FLAGS_SANITIZER \"-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base\")\n\nadd_custom_target(ci_test_clang_sanitizer\n    COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_sanitizer\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_sanitizer\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_sanitizer && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n    COMMENT \"Compile and test with sanitizers\"\n)\n\n###############################################################################\n# Check if header is amalgamated and sources are properly indented.\n###############################################################################\n\nset(ASTYLE_FLAGS --style=allman --indent=spaces=4 --indent-modifiers --indent-switches --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-oper --pad-header --align-pointer=type --align-reference=type --add-brackets --convert-tabs --close-templates --lineend=linux --preserve-date --formatted)\n\nfile(GLOB_RECURSE INDENT_FILES\n    ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp\n    ${PROJECT_SOURCE_DIR}/test/src/*.cpp\n    ${PROJECT_SOURCE_DIR}/test/src/*.hpp\n    ${PROJECT_SOURCE_DIR}/benchmarks/src/benchmarks.cpp\n    ${PROJECT_SOURCE_DIR}/doc/examples/*.cpp\n)\n\nadd_custom_target(ci_test_amalgamation\n    COMMAND rm -fr ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp~\n    COMMAND cp ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp~\n    COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/third_party/amalgamate/amalgamate.py -c ${PROJECT_SOURCE_DIR}/third_party/amalgamate/config.json -s .\n    COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} --suffix=none --quiet ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp\n    COMMAND diff ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp~ ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp\n\n    COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} ${INDENT_FILES}\n    COMMAND cd ${PROJECT_SOURCE_DIR} && for FILE in `find . -name '*.orig'`\\; do false \\; done\n\n    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}\n    COMMENT \"Check amalagamation and indentation\"\n)\n\n###############################################################################\n# Valgrind.\n###############################################################################\n\nadd_custom_target(ci_test_valgrind\n    COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON -DJSON_Valgrind=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_valgrind\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_valgrind\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_valgrind && ${CMAKE_CTEST_COMMAND} -L valgrind --parallel ${N} --output-on-failure\n    COMMENT \"Compile and test with Valgrind\"\n)\n\n###############################################################################\n# Check code with Clang Static Analyzer.\n###############################################################################\n\nset(CLANG_ANALYZER_CHECKS \"fuchsia.HandleChecker,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,optin.cplusplus.UninitializedObject,optin.cplusplus.VirtualCall,optin.mpi.MPI-Checker,optin.osx.OSObjectCStyleCast,optin.osx.cocoa.localizability.EmptyLocalizationContextChecker,optin.osx.cocoa.localizability.NonLocalizedStringChecker,optin.performance.GCDAntipattern,optin.performance.Padding,optin.portability.UnixAPI,security.FloatLoopCounter,security.insecureAPI.DeprecatedOrUnsafeBufferHandling,security.insecureAPI.bcmp,security.insecureAPI.bcopy,security.insecureAPI.bzero,security.insecureAPI.rand,security.insecureAPI.strcpy,valist.CopyToSelf,valist.Uninitialized,valist.Unterminated,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,core.CallAndMessage,core.DivideZero,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.VLASize,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.PlacementNew,cplusplus.PureVirtualCall,deadcode.DeadStores,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,osx.API,osx.MIG,osx.NumberObjectConversion,osx.OSObjectRetainCount,osx.ObjCProperty,osx.SecKeychainAPI,osx.cocoa.AtSync,osx.cocoa.AutoreleaseWrite,osx.cocoa.ClassRelease,osx.cocoa.Dealloc,osx.cocoa.IncompatibleMethodTypes,osx.cocoa.Loops,osx.cocoa.MissingSuperCall,osx.cocoa.NSAutoreleasePool,osx.cocoa.NSError,osx.cocoa.NilArg,osx.cocoa.NonNilReturnValue,osx.cocoa.ObjCGenerics,osx.cocoa.RetainCount,osx.cocoa.RunLoopAutoreleaseLeak,osx.cocoa.SelfInit,osx.cocoa.SuperDealloc,osx.cocoa.UnusedIvars,osx.cocoa.VariadicMethodTypes,osx.coreFoundation.CFError,osx.coreFoundation.CFNumber,osx.coreFoundation.CFRetainRelease,osx.coreFoundation.containers.OutOfBounds,osx.coreFoundation.containers.PointerSizedValues,security.insecureAPI.UncheckedReturn,security.insecureAPI.decodeValueOfObjCType,security.insecureAPI.getpw,security.insecureAPI.gets,security.insecureAPI.mkstemp,security.insecureAPI.mktemp,security.insecureAPI.vfork,unix.API,unix.Malloc,unix.MallocSizeof,unix.MismatchedDeallocator,unix.Vfork,unix.cstring.BadSizeArg,unix.cstring.NullArg\")\n\nadd_custom_target(ci_clang_analyze\n    COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_analyze\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_analyze && ${SCAN_BUILD_TOOL} -enable-checker ${CLANG_ANALYZER_CHECKS} --use-c++=${CLANG_TOOL} -analyze-headers -o ${PROJECT_BINARY_DIR}/report ninja\n    COMMENT \"Check code with Clang Analyzer\"\n)\n\n###############################################################################\n# Check code with Cppcheck.\n###############################################################################\n\nadd_custom_target(ci_cppcheck\n    COMMAND ${CPPCHECK_TOOL} --enable=warning --suppress=missingReturn --inline-suppr --inconclusive --force --std=c++11 ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp --error-exitcode=1\n    COMMENT \"Check code with Cppcheck\"\n)\n\n###############################################################################\n# Check code with cpplint.\n###############################################################################\n\nadd_custom_target(ci_cpplint\n    COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/third_party/cpplint/cpplint.py --filter=-whitespace,-legal,-runtime/references,-runtime/explicit,-runtime/indentation_namespace,-readability/casting,-readability/nolint --quiet --recursive ${SRC_FILES}\n    COMMENT \"Check code with cpplint\"\n)\n\n###############################################################################\n# Check code with OCLint.\n###############################################################################\n\nfile(COPY ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp DESTINATION ${PROJECT_BINARY_DIR}/src_single)\nfile(RENAME ${PROJECT_BINARY_DIR}/src_single/json.hpp ${PROJECT_BINARY_DIR}/src_single/all.cpp)\nfile(APPEND \"${PROJECT_BINARY_DIR}/src_single/all.cpp\" \"\\n\\nint main()\\n{}\\n\")\n\nadd_executable(single_all ${PROJECT_BINARY_DIR}/src_single/all.cpp)\ntarget_compile_features(single_all PRIVATE cxx_std_11)\n\nadd_custom_target(ci_oclint\n    COMMAND ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug\n        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n        -DJSON_BuildTests=OFF -DJSON_CI=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_oclint\n    COMMAND ${OCLINT_TOOL} -i ${PROJECT_BINARY_DIR}/build_oclint/src_single/all.cpp -p ${PROJECT_BINARY_DIR}/build_oclint --\n        -report-type html -enable-global-analysis --max-priority-1=0 --max-priority-2=1000 --max-priority-3=2000\n        --disable-rule=MultipleUnaryOperator\n        --disable-rule=DoubleNegative\n        --disable-rule=ShortVariableName\n        --disable-rule=GotoStatement\n        --disable-rule=LongLine\n        -o ${PROJECT_BINARY_DIR}/build_oclint/oclint_report.html\n    COMMENT \"Check code with OCLint\"\n)\n\n###############################################################################\n# Check code with Clang-Tidy.\n###############################################################################\n\nadd_custom_target(ci_clang_tidy\n    COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_CLANG_TIDY=${CLANG_TIDY_TOOL}\n        -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_tidy\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_tidy\n    COMMENT \"Check code with Clang-Tidy\"\n)\n\n###############################################################################\n# Check code with PVS-Studio Analyzer <https://www.viva64.com/en/pvs-studio/>.\n###############################################################################\n\nadd_custom_target(ci_pvs_studio\n    COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug\n        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n        -DJSON_BuildTests=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_pvs_studio\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PVS_STUDIO_ANALYZER_TOOL} analyze -j 10\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PLOG_CONVERTER_TOOL} -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs\n    COMMENT \"Check code with PVS Studio\"\n)\n\n###############################################################################\n# Check code with Infer <https://fbinfer.com> static analyzer.\n###############################################################################\n\nadd_custom_target(ci_infer\n    COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_infer\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run -- make\n    COMMENT \"Check code with Infer\"\n)\n\n###############################################################################\n# Run test suite with previously downloaded test data.\n###############################################################################\n\nadd_custom_target(ci_offline_testdata\n    COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_offline_testdata/test_data\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_offline_testdata/test_data && ${GIT_TOOL} clone -c advice.detachedHead=false --branch v3.0.0 https://github.com/nlohmann/json_test_data.git --quiet --depth 1\n    COMMAND ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_TestDataDirectory=${PROJECT_BINARY_DIR}/build_offline_testdata/test_data/json_test_data\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_offline_testdata\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_offline_testdata\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_offline_testdata && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure\n    COMMENT \"Check code with previously downloaded test data\"\n)\n\n###############################################################################\n# Run test suite when project was not checked out from Git\n###############################################################################\n\nadd_custom_target(ci_non_git_tests\n    COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_non_git_tests/sources\n    COMMAND cd ${PROJECT_SOURCE_DIR} && for FILE in `${GIT_TOOL} ls-tree --name-only HEAD`\\; do cp -r $$FILE ${PROJECT_BINARY_DIR}/build_non_git_tests/sources \\; done\n    COMMAND ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON -DJSON_FastTests=ON\n        -S${PROJECT_BINARY_DIR}/build_non_git_tests/sources -B${PROJECT_BINARY_DIR}/build_non_git_tests\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_non_git_tests\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_non_git_tests && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE git_required --output-on-failure\n    COMMENT \"Check code when project was not checked out from Git\"\n)\n\n###############################################################################\n# Run test suite and exclude tests that change installed files\n###############################################################################\n\nadd_custom_target(ci_reproducible_tests\n    COMMAND ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DJSON_BuildTests=ON -DJSON_FastTests=ON\n        -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_reproducible_tests\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_reproducible_tests\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_reproducible_tests && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE not_reproducible --output-on-failure\n    COMMENT \"Check code and exclude tests that change installed files\"\n)\n\n###############################################################################\n# Check if every header in the include folder includes sufficient headers to\n# be compiled individually.\n###############################################################################\n\nset(iwyu_path_and_options ${IWYU_TOOL} -Xiwyu --max_line_length=300)\n\nforeach(SRC_FILE ${SRC_FILES})\n    # get relative path of the header file\n    file(RELATIVE_PATH RELATIVE_SRC_FILE \"${PROJECT_SOURCE_DIR}/include/nlohmann\" \"${SRC_FILE}\")\n    # replace slashes and strip suffix\n    string(REPLACE \"/\" \"_\" RELATIVE_SRC_FILE \"${RELATIVE_SRC_FILE}\")\n    string(REPLACE \".hpp\" \"\" RELATIVE_SRC_FILE \"${RELATIVE_SRC_FILE}\")\n    # create code file\n    file(WRITE \"${PROJECT_BINARY_DIR}/src_single/${RELATIVE_SRC_FILE}.cpp\" \"#include \\\"${SRC_FILE}\\\" // IWYU pragma: keep\\n\\nint main()\\n{}\\n\")\n    # create executable\n    add_executable(single_${RELATIVE_SRC_FILE} EXCLUDE_FROM_ALL ${PROJECT_BINARY_DIR}/src_single/${RELATIVE_SRC_FILE}.cpp)\n    target_include_directories(single_${RELATIVE_SRC_FILE} PRIVATE ${PROJECT_SOURCE_DIR}/include)\n    target_compile_features(single_${RELATIVE_SRC_FILE} PRIVATE cxx_std_11)\n    set_property(TARGET single_${RELATIVE_SRC_FILE} PROPERTY CXX_INCLUDE_WHAT_YOU_USE \"${iwyu_path_and_options}\")\n    # remember binary for ci_single_binaries target\n    list(APPEND single_binaries single_${RELATIVE_SRC_FILE})\nendforeach()\n\nadd_custom_target(ci_single_binaries\n    DEPENDS ${single_binaries}\n    COMMENT \"Check if headers are self-contained\"\n)\n\n###############################################################################\n# Benchmarks\n###############################################################################\n\nadd_custom_target(ci_benchmarks\n    COMMAND ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Release -GNinja\n        -S${PROJECT_SOURCE_DIR}/benchmarks -B${PROJECT_BINARY_DIR}/build_benchmarks\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_benchmarks --target json_benchmarks\n    COMMAND cd ${PROJECT_BINARY_DIR}/build_benchmarks && ./json_benchmarks\n    COMMENT \"Run benchmarks\"\n)\n\n###############################################################################\n# CMake flags\n###############################################################################\n\nif (APPLE)\n    set(CMAKE_310_BINARY ${PROJECT_BINARY_DIR}/cmake-3.1.0-Darwin64/CMake.app/Contents/bin/cmake)\n    add_custom_command(\n        OUTPUT ${CMAKE_310_BINARY}\n        COMMAND wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Darwin64.tar.gz\n        COMMAND tar xfz cmake-3.1.0-Darwin64.tar.gz\n        COMMAND rm cmake-3.1.0-Darwin64.tar.gz\n        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}\n        COMMENT \"Download CMake 3.1.0\"\n    )\nelse()\n    set(CMAKE_310_BINARY ${PROJECT_BINARY_DIR}/cmake-3.1.0-Linux-x86_64/bin/cmake)\n    add_custom_command(\n        OUTPUT ${CMAKE_310_BINARY}\n        COMMAND wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Linux-x86_64.tar.gz\n        COMMAND tar xfz cmake-3.1.0-Linux-x86_64.tar.gz\n        COMMAND rm cmake-3.1.0-Linux-x86_64.tar.gz\n        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}\n        COMMENT \"Download CMake 3.1.0\"\n    )\nendif()\n\nset(JSON_CMAKE_FLAGS \"JSON_BuildTests;JSON_Install;JSON_MultipleHeaders;JSON_ImplicitConversions;JSON_Valgrind;JSON_Diagnostics;JSON_SystemInclude\")\n\nforeach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS})\n    string(TOLOWER \"ci_cmake_flag_${JSON_CMAKE_FLAG}\" JSON_CMAKE_FLAG_TARGET)\n    add_custom_target(\"${JSON_CMAKE_FLAG_TARGET}\"\n        COMMENT \"Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${CMAKE_VERSION})\"\n        COMMAND ${CMAKE_COMMAND}\n            -Werror=dev\n            -D${JSON_CMAKE_FLAG}=ON\n            -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}\n    )\n    add_custom_target(\"${JSON_CMAKE_FLAG_TARGET}_31\"\n        COMMENT \"Check CMake flag ${JSON_CMAKE_FLAG} (CMake 3.1)\"\n        COMMAND mkdir ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31\n        COMMAND cd ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31 && ${CMAKE_310_BINARY}\n            -Werror=dev ${PROJECT_SOURCE_DIR}\n            -D${JSON_CMAKE_FLAG}=ON\n            -DCMAKE_CXX_COMPILE_FEATURES=\"cxx_range_for\" -DCMAKE_CXX_FLAGS=\"-std=gnu++11\"\n        DEPENDS ${CMAKE_310_BINARY}\n    )\n    list(APPEND JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${JSON_CMAKE_FLAG_TARGET}_31)\n    list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET} ${PROJECT_BINARY_DIR}/build_${JSON_CMAKE_FLAG_TARGET}_31)\nendforeach()\n\nadd_custom_target(ci_cmake_flags\n    DEPENDS ${JSON_CMAKE_FLAG_TARGETS}\n    COMMENT \"Check CMake flags\"\n)\n\n###############################################################################\n# Use more installed compilers.\n###############################################################################\n\nforeach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6 g++-7 g++-8 g++-9 g++-10 clang++-3.5 clang++-3.6 clang++-3.7 clang++-3.8 clang++-3.9 clang++-4.0 clang++-5.0 clang++-6.0 clang++-7 clang++-8 clang++-9 clang++-10 clang++-11 clang++-12 clang++-13)\n    find_program(COMPILER_TOOL NAMES ${COMPILER})\n    if (COMPILER_TOOL)\n        if (\"${COMPILER}\" STREQUAL \"clang++-9\")\n            # fix for https://github.com/nlohmann/json/pull/3101#issuecomment-998788786 / https://stackoverflow.com/a/64051725/266378\n            set(ADDITIONAL_FLAGS \"-DCMAKE_CXX_FLAGS=--gcc-toolchain=/root/gcc/9\")\n        else()\n            unset(ADDITIONAL_FLAGS)\n        endif()\n\n        add_custom_target(ci_test_compiler_${COMPILER}\n            COMMAND CXX=${COMPILER} ${CMAKE_COMMAND}\n                -DCMAKE_BUILD_TYPE=Debug -GNinja\n                -DJSON_BuildTests=ON -DJSON_FastTests=ON\n                -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}\n                ${ADDITIONAL_FLAGS}\n            COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}\n            COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex \"test-unicode\" --output-on-failure\n            COMMENT \"Compile and test with ${COMPILER}\"\n        )\n    endif()\n    unset(COMPILER_TOOL CACHE)\nendforeach()\n\n###############################################################################\n# CUDA example\n###############################################################################\n\nadd_custom_target(ci_cuda_example\n    COMMAND ${CMAKE_COMMAND}\n        -DCMAKE_BUILD_TYPE=Debug -GNinja\n        -DCMAKE_CUDA_HOST_COMPILER=g++-8\n        -S${PROJECT_SOURCE_DIR}/test/cuda_example -B${PROJECT_BINARY_DIR}/build_cuda_example\n    COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example\n)\n\n###############################################################################\n# Clean up all generated files.\n###############################################################################\n\nadd_custom_target(ci_clean\n    COMMAND rm -fr ${PROJECT_BINARY_DIR}/build_* cmake-3.1.0-Darwin64 ${JSON_CMAKE_FLAG_BUILD_DIRS} ${single_binaries}\n    COMMENT \"Clean generated directories\"\n)\n"
  },
  {
    "path": "subprojects/nlohmann_json/cmake/config.cmake.in",
    "content": "include(FindPackageHandleStandardArgs)\nset(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE})\nfind_package_handle_standard_args(@PROJECT_NAME@ CONFIG_MODE)\n\nif(NOT TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_TARGETS_EXPORT_NAME@.cmake\")\n    if((NOT TARGET @NLOHMANN_JSON_TARGET_NAME@) AND\n       (NOT @PROJECT_NAME@_FIND_VERSION OR\n        @PROJECT_NAME@_FIND_VERSION VERSION_LESS 3.2.0))\n        add_library(@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED)\n        set_target_properties(@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES\n            INTERFACE_LINK_LIBRARIES @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@\n        )\n    endif()\nendif()\n"
  },
  {
    "path": "subprojects/nlohmann_json/cmake/download_test_data.cmake",
    "content": "set(JSON_TEST_DATA_URL     https://github.com/nlohmann/json_test_data)\nset(JSON_TEST_DATA_VERSION 3.0.0)\n\n# if variable is set, use test data from given directory rather than downloading them\nif(JSON_TestDataDirectory)\n    message(STATUS \"Using test data in ${JSON_TestDataDirectory}.\")\n    add_custom_target(download_test_data)\n    file(WRITE ${CMAKE_BINARY_DIR}/include/test_data.hpp \"#define TEST_DATA_DIRECTORY \\\"${JSON_TestDataDirectory}\\\"\\n\")\nelse()\n    find_package(Git)\n    # target to download test data\n    add_custom_target(download_test_data\n        COMMAND test -d json_test_data || ${GIT_EXECUTABLE} clone -c advice.detachedHead=false --branch v${JSON_TEST_DATA_VERSION} ${JSON_TEST_DATA_URL}.git --quiet --depth 1\n        COMMENT \"Downloading test data from ${JSON_TEST_DATA_URL} (v${JSON_TEST_DATA_VERSION})\"\n        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}\n    )\n    # create a header with the path to the downloaded test data\n    file(WRITE ${CMAKE_BINARY_DIR}/include/test_data.hpp \"#define TEST_DATA_DIRECTORY \\\"${CMAKE_BINARY_DIR}/json_test_data\\\"\\n\")\nendif()\n\n# determine the operating system (for debug and support purposes)\nfind_program(UNAME_COMMAND uname)\nfind_program(VER_COMMAND ver)\nfind_program(LSB_RELEASE_COMMAND lsb_release)\nfind_program(SW_VERS_COMMAND sw_vers)\nset(OS_VERSION_STRINGS \"${CMAKE_SYSTEM}\")\nif (VER_COMMAND)\n    execute_process(COMMAND ${VER_COMMAND} OUTPUT_VARIABLE VER_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)\n    set(OS_VERSION_STRINGS \"${OS_VERSION_STRINGS}; ${VER_COMMAND_RESULT}\")\nendif()\nif (SW_VERS_COMMAND)\n    execute_process(COMMAND ${SW_VERS_COMMAND} OUTPUT_VARIABLE SW_VERS_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)\n    string(REGEX REPLACE \"[ ]*\\n\" \"; \" SW_VERS_COMMAND_RESULT \"${SW_VERS_COMMAND_RESULT}\")\n    set(OS_VERSION_STRINGS \"${OS_VERSION_STRINGS}; ${SW_VERS_COMMAND_RESULT}\")\nendif()\nif (LSB_RELEASE_COMMAND)\n    execute_process(COMMAND ${LSB_RELEASE_COMMAND} -a OUTPUT_VARIABLE LSB_RELEASE_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)\n    string(REGEX REPLACE \"[ ]*\\n\" \"; \" LSB_RELEASE_COMMAND_RESULT \"${LSB_RELEASE_COMMAND_RESULT}\")\n    set(OS_VERSION_STRINGS \"${OS_VERSION_STRINGS}; ${LSB_RELEASE_COMMAND_RESULT}\")\nendif()\nif (UNAME_COMMAND)\n    execute_process(COMMAND ${UNAME_COMMAND} -a OUTPUT_VARIABLE UNAME_COMMAND_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)\n    set(OS_VERSION_STRINGS \"${OS_VERSION_STRINGS}; ${UNAME_COMMAND_RESULT}\")\nendif()\n\nmessage(STATUS \"Operating system: ${OS_VERSION_STRINGS}\")\n\n# determine the compiler (for debug and support purposes)\nif (MSVC)\n    execute_process(COMMAND ${CMAKE_CXX_COMPILER} OUTPUT_VARIABLE CXX_VERSION_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_VARIABLE CXX_VERSION_RESULT ERROR_STRIP_TRAILING_WHITESPACE)\n    set(CXX_VERSION_RESULT \"${CXX_VERSION_RESULT}; MSVC_VERSION=${MSVC_VERSION}; MSVC_TOOLSET_VERSION=${MSVC_TOOLSET_VERSION}\")\nelse()\n    execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE CXX_VERSION_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)\nendif()\nstring(REGEX REPLACE \"[ ]*\\n\" \"; \" CXX_VERSION_RESULT \"${CXX_VERSION_RESULT}\")\nmessage(STATUS \"Compiler: ${CXX_VERSION_RESULT}\")\n"
  },
  {
    "path": "subprojects/nlohmann_json/cmake/nlohmann_jsonConfigVersion.cmake.in",
    "content": "# This is essentially cmake's BasicConfigVersion-SameMajorVersion.cmake.in but\n# without the 32/64-bit check.  Since json is a header-only library, it doesn't\n# matter if it was built on a different platform than what it is used on (see\n# https://github.com/nlohmann/json/issues/1697).\nset(PACKAGE_VERSION \"@PROJECT_VERSION@\")\n\nif(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)\n  set(PACKAGE_VERSION_COMPATIBLE FALSE)\nelse()\n\n  if(PACKAGE_FIND_VERSION_MAJOR STREQUAL \"@PROJECT_VERSION_MAJOR@\")\n    set(PACKAGE_VERSION_COMPATIBLE TRUE)\n  else()\n    set(PACKAGE_VERSION_COMPATIBLE FALSE)\n  endif()\n\n  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)\n      set(PACKAGE_VERSION_EXACT TRUE)\n  endif()\nendif()\n"
  },
  {
    "path": "subprojects/nlohmann_json/cmake/pkg-config.pc.in",
    "content": "Name: ${PROJECT_NAME}\nDescription: JSON for Modern C++\nVersion: ${PROJECT_VERSION}\nCflags: -I${CMAKE_INSTALL_FULL_INCLUDEDIR}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/Makefile",
    "content": "SRCDIR = ../single_include\n\nall: create_output\n\n##########################################################################\n# example files\n##########################################################################\n\n# where are the example cpp files\nEXAMPLES = $(wildcard examples/*.cpp)\n\n# create output from a stand-alone example file\n%.output: %.cpp\n\tmake $(<:.cpp=) CPPFLAGS=\"-I $(SRCDIR)\" CXXFLAGS=\"-std=c++11\"\n\t./$(<:.cpp=) > $@\n\trm $(<:.cpp=)\n\n# compare created output with current output of the example files\n%.test: %.cpp\n\tmake $(<:.cpp=) CPPFLAGS=\"-I $(SRCDIR)\" CXXFLAGS=\"-std=c++11\"\n\t./$(<:.cpp=) > $@\n\tdiff $@ $(<:.cpp=.output)\n\trm $(<:.cpp=) $@\n\n# create output from all stand-alone example files\ncreate_output: $(EXAMPLES:.cpp=.output)\n\n# check output of all stand-alone example files\ncheck_output: $(EXAMPLES:.cpp=.test)\n\nclean:\n\trm -fr $(EXAMPLES:.cpp=)\n\t$(MAKE) clean -C docset\n\t$(MAKE) clean -C mkdocs\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/README.md",
    "content": "# Documentation\n\n## Generate documentation\n\nNote on documentation: The source files contain links to the online documentation at https://json.nlohmann.me. This URL\ncontains the most recent documentation and should also be applicable to previous versions; documentation for deprecated\nfunctions is not removed, but marked deprecated.\n\nIf you want to see the documentation for a specific tag or commit hash, you can generate it as follows (here for tag\n`v3.10.2`):\n\n```shell\ngit clone https://github.com/nlohmann/json.git\ncd json\ngit checkout v3.10.2\nmake install_venv serve -C doc/mkdocs\n```\n\nOpen URL <http://127.0.0.1:8000/> in your browser. Replace from any URL from the source code `https://json.nlohmann.me`\nwith `http://127.0.0.1:8000` to see the documentation for your tag or commit hash.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/docset/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleIdentifier</key>\n\t<string>nlohmann_json</string>\n\t<key>CFBundleName</key>\n\t<string>JSON for Modern C++</string>\n\t<key>DocSetPlatformFamily</key>\n\t<string>json</string>\n\t<key>isDashDocset</key>\n\t<true/>\n    <key>dashIndexFilePath</key>\n    <string>index.html</string>\n    <key>DashDocSetFallbackURL</key>\n    <string>https://nlohmann.github.io/json/</string>\n    <key>isJavaScriptEnabled</key>\n    <true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/docset/Makefile",
    "content": "JSON_for_Modern_C++.docset: Info.plist docSet.sql\n\t$(MAKE) clean\n\tmkdir -p JSON_for_Modern_C++.docset/Contents/Resources/Documents/\n\tcp icon*.png JSON_for_Modern_C++.docset\n\tcp Info.plist JSON_for_Modern_C++.docset/Contents\n\t# build and copy documentation\n\t$(MAKE) build -C ../mkdocs\n\tcp -r ../mkdocs/site/* JSON_for_Modern_C++.docset/Contents/Resources/Documents\n\t# patch CSS to hide navigation items\n\techo \"\\n\\nheader, footer, navi, div.md-sidebar--primary, nav.md-tabs--active, a.md-content__button { display: none; }\" >> \"$$(ls JSON_for_Modern_C++.docset/Contents/Resources/Documents/assets/stylesheets/main.*.min.css)\"\n\t# fix spacing\n\techo \"\\n\\ndiv.md-sidebar div.md-sidebar--secondary, div.md-main__inner { top: 0; margin-top: 0 }\" >> \"$$(ls JSON_for_Modern_C++.docset/Contents/Resources/Documents/assets/stylesheets/main.*.min.css)\"\n\t# remove \"JSON for Modern C++\" from page titles\n\tfind JSON_for_Modern_C++.docset/Contents/Resources/Documents -type f -exec gsed -i 's| - JSON for Modern C++</title>|</title>|' {} +\n\t# clean up\n\trm JSON_for_Modern_C++.docset/Contents/Resources/Documents/hooks.py\n\trm JSON_for_Modern_C++.docset/Contents/Resources/Documents/sitemap.*\n\t# generate index\n\tsqlite3 JSON_for_Modern_C++.docset/Contents/Resources/docSet.dsidx < docSet.sql\n\nJSON_for_Modern_C++.tgz: JSON_for_Modern_C++.docset\n\ttar --exclude='.DS_Store' -cvzf JSON_for_Modern_C++.tgz JSON_for_Modern_C++.docset\n\nclean:\n\trm -fr JSON_for_Modern_C++.docset JSON_for_Modern_C++.tgz\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/docset/README.md",
    "content": "# docset\n\nThe folder contains the required files to create a [docset](https://kapeli.com/docsets) which can be used in\ndocumentation browsers like [Dash](https://kapeli.com/dash), [Velocity](https://velocity.silverlakesoftware.com), or\n[Zeal](https://zealdocs.org).\n\nThe docset can be created with\n\n```sh\nmake nlohmann_json.docset\n```\n\nThe generated folder `nlohmann_json.docset` can then be opened in the documentation browser.\n\nA recent version is also part of the [Dash user contributions](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B).\n\n## Licenses\n\nThe [JSON logo](https://commons.wikimedia.org/wiki/File:JSON_vector_logo.svg) is public domain.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/docset/docSet.sql",
    "content": "DROP TABLE IF EXISTS searchIndex;\nCREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);\nCREATE UNIQUE INDEX anchor ON searchIndex (name, type, path);\n\n-- API\nINSERT INTO searchIndex(name, type, path) VALUES ('accept', 'Function', 'api/basic_json/accept/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('adl_serializer', 'Class', 'api/adl_serializer/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('array', 'Function', 'api/basic_json/array/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('array_t', 'Type', 'api/basic_json/array_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('at', 'Method', 'api/basic_json/at/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('back', 'Method', 'api/basic_json/back/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('basic_json', 'Class', 'api/basic_json/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('basic_json', 'Constructor', 'api/basic_json/basic_json/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('begin', 'Method', 'api/basic_json/begin/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('binary', 'Function', 'api/basic_json/binary/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('binary_t', 'Type', 'api/basic_json/binary_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('boolean_t', 'Type', 'api/basic_json/boolean_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('cbegin', 'Method', 'api/basic_json/cbegin/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('cbor_tag_handler_t', 'Enum', 'api/basic_json/cbor_tag_handler_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('cend', 'Method', 'api/basic_json/cend/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('clear', 'Method', 'api/basic_json/clear/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('contains', 'Method', 'api/basic_json/contains/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('count', 'Method', 'api/basic_json/count/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('crbegin', 'Method', 'api/basic_json/crbegin/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('crend', 'Method', 'api/basic_json/crend/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('diff', 'Function', 'api/basic_json/diff/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('dump', 'Method', 'api/basic_json/dump/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('emplace', 'Method', 'api/basic_json/emplace/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('emplace_back', 'Method', 'api/basic_json/emplace_back/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('empty', 'Method', 'api/basic_json/empty/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('end', 'Method', 'api/basic_json/end/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('erase', 'Method', 'api/basic_json/erase/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('error_handler_t', 'Enum', 'api/basic_json/error_handler_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('exception', 'Class', 'api/basic_json/exception/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('find', 'Method', 'api/basic_json/find/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('flatten', 'Method', 'api/basic_json/flatten/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('from_bson', 'Function', 'api/basic_json/from_bson/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('from_cbor', 'Function', 'api/basic_json/from_cbor/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('from_msgpack', 'Function', 'api/basic_json/from_msgpack/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('from_ubjson', 'Function', 'api/basic_json/from_ubjson/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('front', 'Method', 'api/basic_json/front/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('get', 'Method', 'api/basic_json/get/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('get_allocator', 'Function', 'api/basic_json/get_allocator/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('get_binary', 'Method', 'api/basic_json/get_binary/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('get_ptr', 'Method', 'api/basic_json/get_ptr/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('get_ref', 'Method', 'api/basic_json/get_ref/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('get_to', 'Method', 'api/basic_json/get_to/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('input_format_t', 'Enum', 'api/basic_json/input_format_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('insert', 'Method', 'api/basic_json/insert/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('invalid_iterator', 'Class', 'api/basic_json/invalid_iterator/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_array', 'Method', 'api/basic_json/is_array/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_binary', 'Method', 'api/basic_json/is_binary/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_boolean', 'Method', 'api/basic_json/is_boolean/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_discarded', 'Method', 'api/basic_json/is_discarded/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_null', 'Method', 'api/basic_json/is_null/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_number', 'Method', 'api/basic_json/is_number/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_number_float', 'Method', 'api/basic_json/is_number_float/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_number_integer', 'Method', 'api/basic_json/is_number_integer/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_number_unsigned', 'Method', 'api/basic_json/is_number_unsigned/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_object', 'Method', 'api/basic_json/is_object/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_primitive', 'Method', 'api/basic_json/is_primitive/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_string', 'Method', 'api/basic_json/is_string/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('is_structured', 'Method', 'api/basic_json/is_structured/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('items', 'Method', 'api/basic_json/items/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('json_pointer', 'Class', 'api/json_pointer/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('json_serializer', 'Type', 'api/basic_json/json_serializer/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('max_size', 'Method', 'api/basic_json/max_size/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('merge_patch', 'Method', 'api/basic_json/merge_patch/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('meta', 'Function', 'api/basic_json/meta/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('number_float_t', 'Type', 'api/basic_json/number_float_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('number_integer_t', 'Type', 'api/basic_json/number_integer_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('number_unsigned_t', 'Type', 'api/basic_json/number_unsigned_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('object', 'Function', 'api/basic_json/object/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('object_comparator_t', 'Type', 'api/basic_json/object_comparator_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('object_t', 'Type', 'api/basic_json/object_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator!=', 'Operator', 'api/basic_json/operator_ne/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator+=', 'Operator', 'api/basic_json/operator+=/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator=', 'Operator', 'api/basic_json/operator=/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator==', 'Operator', 'api/basic_json/operator_eq/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator<', 'Operator', 'api/basic_json/operator_lt/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator<=', 'Operator', 'api/basic_json/operator_le/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator>', 'Operator', 'api/basic_json/operator_gt/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator>=', 'Operator', 'api/basic_json/operator_ge/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator[]', 'Operator', 'api/basic_json/operator[]/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator\"\"_json', 'Literal', 'api/basic_json/operator_literal_json/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator\"\"_json_pointer', 'Literal', 'api/basic_json/operator_literal_json_pointer/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator ValueType', 'Operator', 'api/basic_json/operator_ValueType/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('operator value_t', 'Operator', 'api/basic_json/operator_value_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('ordered_json', 'Class', 'api/ordered_json/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('ordered_map', 'Class', 'api/ordered_map/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('out_of_range', 'Class', 'api/basic_json/out_of_range/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('other_error', 'Class', 'api/basic_json/other_error/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('parse', 'Function', 'api/basic_json/parse/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('parse_error', 'Class', 'api/basic_json/parse_error/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('parse_event_t', 'Enum', 'api/basic_json/parse_event_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('parser_callback_t', 'Type', 'api/basic_json/parser_callback_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('patch', 'Method', 'api/basic_json/patch/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('push_back', 'Method', 'api/basic_json/push_back/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('rbegin', 'Method', 'api/basic_json/rbegin/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('rend', 'Method', 'api/basic_json/rend/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('sax_parse', 'Function', 'api/basic_json/sax_parse/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('size', 'Method', 'api/basic_json/size/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('string_t', 'Type', 'api/basic_json/string_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('type', 'Method', 'api/basic_json/type/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('type_error', 'Class', 'api/basic_json/type_error/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('type_name', 'Method', 'api/basic_json/type_name/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('unflatten', 'Method', 'api/basic_json/unflatten/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('update', 'Method', 'api/basic_json/update/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('to_bson', 'Function', 'api/basic_json/to_bson/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('to_cbor', 'Function', 'api/basic_json/to_cbor/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('to_msgpack', 'Function', 'api/basic_json/to_msgpack/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('to_ubjson', 'Function', 'api/basic_json/to_ubjson/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('value', 'Method', 'api/basic_json/value/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('value_t', 'Enum', 'api/basic_json/value_t/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('~basic_json', 'Method', 'api/basic_json/~basic_json/index.html');\n\n-- Features\nINSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats', 'Guide', 'features/binary_formats/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('BSON', 'Guide', 'features/binary_formats/bson/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('CBOR', 'Guide', 'features/binary_formats/cbor/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('MessagePack', 'Guide', 'features/binary_formats/messagepack/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('UBJSON', 'Guide', 'features/binary_formats/ubjson/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Supported Macros', 'Guide', 'features/macros/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Binary Values', 'Guide', 'features/binary_values/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Comments', 'Guide', 'features/comments/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Iterators', 'Guide', 'features/iterators/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Types', 'Guide', 'features/types/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Number Handling', 'Guide', 'features/types/number_handling/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Element Access', 'Guide', 'features/element_access/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON Pointer', 'Guide', 'features/json_pointer/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON Patch and Diff', 'Guide', 'features/json_patch/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON Merge Patch', 'Guide', 'features/merge_patch/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Object Order', 'Guide', 'features/object_order/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Parsing and Exceptions', 'Guide', 'features/parsing/parse_exceptions/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('Parser Callbacks', 'Guide', 'features/parsing/parser_callbacks/index.html');\nINSERT INTO searchIndex(name, type, path) VALUES ('SAX Interface', 'Guide', 'features/parsing/sax_interface/index.html');\n\n-- Macros\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'features/macros/index.html#json_assertx');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'features/macros/index.html#json_catch_userexception');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'features/macros/index.html#json_diagnostics');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_11', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_14', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_17', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_20', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_NOEXCEPTION', 'Macro', 'features/macros/index.html#json_noexception');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_NO_IO', 'Macro', 'features/macros/index.html#json_no_io');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_SKIP_UNSUPPORTED_COMPILER_CHECK', 'Macro', 'features/macros/index.html#json_skip_unsupported_compiler_check');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_THROW_USER', 'Macro', 'features/macros/index.html#json_throw_userexception');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_TRY_USER', 'Macro', 'features/macros/index.html#json_try_user');\nINSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'features/macros/index.html#json_use_implicit_conversions');\nINSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE', 'Macro', 'features/macros/index.html#nlohmann_define_type_intrusivetype-member');\nINSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE', 'Macro', 'features/macros/index.html#nlohmann_define_type_non_intrusivetype-member');\nINSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM', 'Macro', 'features/macros/index.html#nlohmann_json_serialize_enumtype');\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/docset/docset.json",
    "content": "{\n  \"name\": \"JSON for Modern C++\",\n  \"version\": \"3.10.0\",\n  \"archive\": \"JSON_for_Modern_C++.tgz\",\n  \"author\": {\n    \"name\": \"Niels Lohmann\",\n    \"link\": \"https://twitter.com/nlohmann\"\n  },\n  \"aliases\": [\"nlohmann/json\"]\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/README.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // add new values\n    j[\"new\"][\"key\"][\"value\"] = {\"another\", \"list\"};\n\n    // count elements\n    auto s = j.size();\n    j[\"size\"] = s;\n\n    // pretty print with indent of 4 spaces\n    std::cout << std::setw(4) << j << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/README.output",
    "content": "{\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"new\": {\n        \"key\": {\n            \"value\": [\n                \"another\",\n                \"list\"\n            ]\n        }\n    },\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141,\n    \"size\": 8\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/accept__string.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a valid JSON text\n    auto valid_text = R\"(\n    {\n        \"numbers\": [1, 2, 3]\n    }\n    )\";\n\n    // an invalid JSON text\n    auto invalid_text = R\"(\n    {\n        \"strings\": [\"extra\", \"comma\", ]\n    }\n    )\";\n\n    std::cout << std::boolalpha\n              << json::accept(valid_text) << ' '\n              << json::accept(invalid_text) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/accept__string.output",
    "content": "true false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/array.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON arrays\n    json j_no_init_list = json::array();\n    json j_empty_init_list = json::array({});\n    json j_nonempty_init_list = json::array({1, 2, 3, 4});\n    json j_list_of_pairs = json::array({ {\"one\", 1}, {\"two\", 2} });\n\n    // serialize the JSON arrays\n    std::cout << j_no_init_list << '\\n';\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_nonempty_init_list << '\\n';\n    std::cout << j_list_of_pairs << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/array.output",
    "content": "[]\n[]\n[1,2,3,4]\n[[\"one\",1],[\"two\",2]]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/array_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::vector<json>, json::array_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/array_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__object_t_key_type.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\"\n    std::cout << object.at(\"the ugly\") << '\\n';\n\n    // change element with key \"the bad\"\n    object.at(\"the bad\") = \"il cattivo\";\n\n    // output changed array\n    std::cout << object << '\\n';\n\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-object type\n        json str = \"I am a string\";\n        str.at(\"the good\") = \"Another string\";\n    }\n    catch (json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write at a nonexisting key\n        object.at(\"the fast\") = \"il rapido\";\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__object_t_key_type.output",
    "content": "\"il brutto\"\n{\"the bad\":\"il cattivo\",\"the good\":\"il buono\",\"the ugly\":\"il brutto\"}\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.403] key 'the fast' not found\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__object_t_key_type_const.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    const json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\"\n    std::cout << object.at(\"the ugly\") << '\\n';\n\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-object type\n        const json str = \"I am a string\";\n        std::cout << str.at(\"the good\") << '\\n';\n    }\n    catch (json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read from a nonexisting key\n        std::cout << object.at(\"the fast\") << '\\n';\n    }\n    catch (json::out_of_range)\n    {\n        std::cout << \"out of range\" << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__object_t_key_type_const.output",
    "content": "\"il brutto\"\n[json.exception.type_error.304] cannot use at() with string\nout of range\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__size_type.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n\n    // change element at index 1 (second element) to \"second\"\n    array.at(1) = \"second\";\n\n    // output changed array\n    std::cout << array << '\\n';\n\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-array type\n        json str = \"I am a string\";\n        str.at(0) = \"Another string\";\n    }\n    catch (json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write beyond the array limit\n        array.at(5) = \"sixth\";\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__size_type.output",
    "content": "\"third\"\n[\"first\",\"second\",\"third\",\"fourth\"]\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.401] array index 5 is out of range\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__size_type_const.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    const json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-array type\n        const json str = \"I am a string\";\n        std::cout << str.at(0) << '\\n';\n    }\n    catch (json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read beyond the array limit\n        std::cout << array.at(5) << '\\n';\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at__size_type_const.output",
    "content": "\"third\"\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.401] array index 5 is out of range\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at_json_pointer.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j.at(\"/number\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j.at(\"/string\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j.at(\"/array\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j.at(\"/array/1\"_json_pointer) << '\\n';\n\n    // writing access\n\n    // change the string\n    j.at(\"/string\"_json_pointer) = \"bar\";\n    // output the changed string\n    std::cout << j[\"string\"] << '\\n';\n\n    // change an array element\n    j.at(\"/array/1\"_json_pointer) = 21;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n\n\n    // out_of_range.106\n    try\n    {\n        // try to use an array index with leading '0'\n        json::reference ref = j.at(\"/array/01\"_json_pointer);\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.109\n    try\n    {\n        // try to use an array index that is not a number\n        json::reference ref = j.at(\"/array/one\"_json_pointer);\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.401\n    try\n    {\n        // try to use an invalid array index\n        json::reference ref = j.at(\"/array/4\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.402\n    try\n    {\n        // try to use the array index '-'\n        json::reference ref = j.at(\"/array/-\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.403\n    try\n    {\n        // try to use a JSON pointer to a nonexistent object key\n        json::const_reference ref = j.at(\"/foo\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.404\n    try\n    {\n        // try to use a JSON pointer that cannot be resolved\n        json::reference ref = j.at(\"/number/foo\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at_json_pointer.output",
    "content": "1\n\"foo\"\n[1,2]\n2\n\"bar\"\n[1,21]\n[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\n[json.exception.parse_error.109] parse error: array index 'one' is not a number\n[json.exception.out_of_range.401] array index 4 is out of range\n[json.exception.out_of_range.402] array index '-' (2) is out of range\n[json.exception.out_of_range.403] key 'foo' not found\n[json.exception.out_of_range.404] unresolved reference token 'foo'\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at_json_pointer_const.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    const json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j.at(\"/number\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j.at(\"/string\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j.at(\"/array\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j.at(\"/array/1\"_json_pointer) << '\\n';\n\n    // out_of_range.109\n    try\n    {\n        // try to use an array index that is not a number\n        json::const_reference ref = j.at(\"/array/one\"_json_pointer);\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.401\n    try\n    {\n        // try to use an invalid array index\n        json::const_reference ref = j.at(\"/array/4\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.402\n    try\n    {\n        // try to use the array index '-'\n        json::const_reference ref = j.at(\"/array/-\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.403\n    try\n    {\n        // try to use a JSON pointer to a nonexistent object key\n        json::const_reference ref = j.at(\"/foo\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.404\n    try\n    {\n        // try to use a JSON pointer that cannot be resolved\n        json::const_reference ref = j.at(\"/number/foo\"_json_pointer);\n    }\n    catch (json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/at_json_pointer_const.output",
    "content": "1\n\"foo\"\n[1,2]\n2\n[json.exception.parse_error.109] parse error: array index 'one' is not a number\n[json.exception.out_of_range.401] array index 4 is out of range\n[json.exception.out_of_range.402] array index '-' (2) is out of range\n[json.exception.out_of_range.403] key 'foo' not found\n[json.exception.out_of_range.404] unresolved reference token 'foo'\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/back.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call back()\n    std::cout << j_boolean.back() << '\\n';\n    std::cout << j_number_integer.back() << '\\n';\n    std::cout << j_number_float.back() << '\\n';\n    std::cout << j_object.back() << '\\n';\n    //std::cout << j_object_empty.back() << '\\n';  // undefined behavior\n    std::cout << j_array.back() << '\\n';\n    //std::cout << j_array_empty.back() << '\\n';   // undefined behavior\n    std::cout << j_string.back() << '\\n';\n\n    // back() called on a null value\n    try\n    {\n        json j_null;\n        j_null.back();\n    }\n    catch (json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/back.output",
    "content": "true\n17\n23.42\n2\n16\n\"Hello, world\"\n[json.exception.invalid_iterator.214] cannot get value\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__CompatibleType.cpp",
    "content": "#include <iostream>\n#include <deque>\n#include <list>\n#include <forward_list>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <valarray>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // ============\n    // object types\n    // ============\n\n    // create an object from an object_t value\n    json::object_t object_value = { {\"one\", 1}, {\"two\", 2} };\n    json j_object_t(object_value);\n\n    // create an object from std::map\n    std::map<std::string, int> c_map\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 3}\n    };\n    json j_map(c_map);\n\n    // create an object from std::unordered_map\n    std::unordered_map<const char*, double> c_umap\n    {\n        {\"one\", 1.2}, {\"two\", 2.3}, {\"three\", 3.4}\n    };\n    json j_umap(c_umap);\n\n    // create an object from std::multimap\n    std::multimap<std::string, bool> c_mmap\n    {\n        {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true}\n    };\n    json j_mmap(c_mmap); // only one entry for key \"three\" is used\n\n    // create an object from std::unordered_multimap\n    std::unordered_multimap<std::string, bool> c_ummap\n    {\n        {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true}\n    };\n    json j_ummap(c_ummap); // only one entry for key \"three\" is used\n\n    // serialize the JSON objects\n    std::cout << j_object_t << '\\n';\n    std::cout << j_map << '\\n';\n    std::cout << j_umap << '\\n';\n    std::cout << j_mmap << '\\n';\n    std::cout << j_ummap << \"\\n\\n\";\n\n\n    // ===========\n    // array types\n    // ===========\n\n    // create an array from an array_t value\n    json::array_t array_value = {\"one\", \"two\", 3, 4.5, false};\n    json j_array_t(array_value);\n\n    // create an array from std::vector\n    std::vector<int> c_vector {1, 2, 3, 4};\n    json j_vec(c_vector);\n\n    // create an array from std::valarray\n    std::valarray<short> c_valarray {10, 9, 8, 7};\n    json j_valarray(c_valarray);\n\n    // create an array from std::deque\n    std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};\n    json j_deque(c_deque);\n\n    // create an array from std::list\n    std::list<bool> c_list {true, true, false, true};\n    json j_list(c_list);\n\n    // create an array from std::forward_list\n    std::forward_list<std::int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};\n    json j_flist(c_flist);\n\n    // create an array from std::array\n    std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};\n    json j_array(c_array);\n\n    // create an array from std::set\n    std::set<std::string> c_set {\"one\", \"two\", \"three\", \"four\", \"one\"};\n    json j_set(c_set); // only one entry for \"one\" is used\n\n    // create an array from std::unordered_set\n    std::unordered_set<std::string> c_uset {\"one\", \"two\", \"three\", \"four\", \"one\"};\n    json j_uset(c_uset); // only one entry for \"one\" is used\n\n    // create an array from std::multiset\n    std::multiset<std::string> c_mset {\"one\", \"two\", \"one\", \"four\"};\n    json j_mset(c_mset); // both entries for \"one\" are used\n\n    // create an array from std::unordered_multiset\n    std::unordered_multiset<std::string> c_umset {\"one\", \"two\", \"one\", \"four\"};\n    json j_umset(c_umset); // both entries for \"one\" are used\n\n    // serialize the JSON arrays\n    std::cout << j_array_t << '\\n';\n    std::cout << j_vec << '\\n';\n    std::cout << j_valarray << '\\n';\n    std::cout << j_deque << '\\n';\n    std::cout << j_list << '\\n';\n    std::cout << j_flist << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_set << '\\n';\n    std::cout << j_uset << '\\n';\n    std::cout << j_mset << '\\n';\n    std::cout << j_umset << \"\\n\\n\";\n\n\n    // ============\n    // string types\n    // ============\n\n    // create string from a string_t value\n    json::string_t string_value = \"The quick brown fox jumps over the lazy dog.\";\n    json j_string_t(string_value);\n\n    // create a JSON string directly from a string literal\n    json j_string_literal(\"The quick brown fox jumps over the lazy dog.\");\n\n    // create string from std::string\n    std::string s_stdstring = \"The quick brown fox jumps over the lazy dog.\";\n    json j_stdstring(s_stdstring);\n\n    // serialize the JSON strings\n    std::cout << j_string_t << '\\n';\n    std::cout << j_string_literal << '\\n';\n    std::cout << j_stdstring << \"\\n\\n\";\n\n\n    // ============\n    // number types\n    // ============\n\n    // create a JSON number from number_integer_t\n    json::number_integer_t value_integer_t = -42;\n    json j_integer_t(value_integer_t);\n\n    // create a JSON number from number_unsigned_t\n    json::number_integer_t value_unsigned_t = 17;\n    json j_unsigned_t(value_unsigned_t);\n\n    // create a JSON number from an anonymous enum\n    enum { enum_value = 17 };\n    json j_enum(enum_value);\n\n    // create values of different integer types\n    short n_short = 42;\n    int n_int = -23;\n    long n_long = 1024;\n    int_least32_t n_int_least32_t = -17;\n    uint8_t n_uint8_t = 8;\n\n    // create (integer) JSON numbers\n    json j_short(n_short);\n    json j_int(n_int);\n    json j_long(n_long);\n    json j_int_least32_t(n_int_least32_t);\n    json j_uint8_t(n_uint8_t);\n\n    // create values of different floating-point types\n    json::number_float_t v_ok = 3.141592653589793;\n    json::number_float_t v_nan = NAN;\n    json::number_float_t v_infinity = INFINITY;\n\n    // create values of different floating-point types\n    float n_float = 42.23;\n    float n_float_nan = 1.0f / 0.0f;\n    double n_double = 23.42;\n\n    // create (floating point) JSON numbers\n    json j_ok(v_ok);\n    json j_nan(v_nan);\n    json j_infinity(v_infinity);\n    json j_float(n_float);\n    json j_float_nan(n_float_nan);\n    json j_double(n_double);\n\n    // serialize the JSON numbers\n    std::cout << j_integer_t << '\\n';\n    std::cout << j_unsigned_t << '\\n';\n    std::cout << j_enum << '\\n';\n    std::cout << j_short << '\\n';\n    std::cout << j_int << '\\n';\n    std::cout << j_long << '\\n';\n    std::cout << j_int_least32_t << '\\n';\n    std::cout << j_uint8_t << '\\n';\n    std::cout << j_ok << '\\n';\n    std::cout << j_nan << '\\n';\n    std::cout << j_infinity << '\\n';\n    std::cout << j_float << '\\n';\n    std::cout << j_float_nan << '\\n';\n    std::cout << j_double << \"\\n\\n\";\n\n\n    // =============\n    // boolean types\n    // =============\n\n    // create boolean values\n    json j_truth = true;\n    json j_falsity = false;\n\n    // serialize the JSON booleans\n    std::cout << j_truth << '\\n';\n    std::cout << j_falsity << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__CompatibleType.output",
    "content": "{\"one\":1,\"two\":2}\n{\"one\":1,\"three\":3,\"two\":2}\n{\"one\":1.2,\"three\":3.4,\"two\":2.3}\n{\"one\":true,\"three\":false,\"two\":true}\n{\"one\":true,\"three\":false,\"two\":true}\n\n[\"one\",\"two\",3,4.5,false]\n[1,2,3,4]\n[10,9,8,7]\n[1.2,2.3,3.4,5.6]\n[true,true,false,true]\n[12345678909876,23456789098765,34567890987654,45678909876543]\n[1,2,3,4]\n[\"four\",\"one\",\"three\",\"two\"]\n[\"four\",\"three\",\"two\",\"one\"]\n[\"four\",\"one\",\"one\",\"two\"]\n[\"four\",\"two\",\"one\",\"one\"]\n\n\"The quick brown fox jumps over the lazy dog.\"\n\"The quick brown fox jumps over the lazy dog.\"\n\"The quick brown fox jumps over the lazy dog.\"\n\n-42\n17\n17\n42\n-23\n1024\n-17\n8\n3.141592653589793\nnull\nnull\n42.22999954223633\nnull\n23.42\n\ntrue\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__InputIt_InputIt.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_array = {\"alpha\", \"bravo\", \"charly\", \"delta\", \"easy\"};\n    json j_number = 42;\n    json j_object = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n\n    // create copies using iterators\n    json j_array_range(j_array.begin() + 1, j_array.end() - 2);\n    json j_number_range(j_number.begin(), j_number.end());\n    json j_object_range(j_object.begin(), j_object.find(\"two\"));\n\n    // serialize the values\n    std::cout << j_array_range << '\\n';\n    std::cout << j_number_range << '\\n';\n    std::cout << j_object_range << '\\n';\n\n    // example for an exception\n    try\n    {\n        json j_invalid(j_number.begin() + 1, j_number.end());\n    }\n    catch (json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__InputIt_InputIt.output",
    "content": "[\"bravo\",\"charly\"]\n42\n{\"one\":\"eins\"}\n[json.exception.invalid_iterator.204] iterators out of range\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__basic_json.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json j1 = {\"one\", \"two\", 3, 4.5, false};\n\n    // create a copy\n    json j2(j1);\n\n    // serialize the JSON array\n    std::cout << j1 << \" = \" << j2 << '\\n';\n    std::cout << std::boolalpha << (j1 == j2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__basic_json.output",
    "content": "[\"one\",\"two\",3,4.5,false] = [\"one\",\"two\",3,4.5,false]\ntrue\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__copyassignment.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json a = 23;\n    json b = 42;\n\n    // copy-assign a to b\n    b = a;\n\n    // serialize the JSON arrays\n    std::cout << a << '\\n';\n    std::cout << b << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__copyassignment.output",
    "content": "23\n23\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__list_init_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_empty_init_list = json({});\n    json j_object = { {\"one\", 1}, {\"two\", 2} };\n    json j_array = {1, 2, 3, 4};\n    json j_nested_object = { {\"one\", {1}}, {\"two\", {1, 2}} };\n    json j_nested_array = { {{1}, \"one\"}, {{1, 2}, \"two\"} };\n\n    // serialize the JSON value\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_nested_object << '\\n';\n    std::cout << j_nested_array << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__list_init_t.output",
    "content": "{}\n{\"one\":1,\"two\":2}\n[1,2,3,4]\n{\"one\":[1],\"two\":[1,2]}\n[[[1],\"one\"],[[1,2],\"two\"]]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__moveconstructor.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json a = 23;\n\n    // move contents of a to b\n    json b(std::move(a));\n\n    // serialize the JSON arrays\n    std::cout << a << '\\n';\n    std::cout << b << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__moveconstructor.output",
    "content": "null\n23\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__nullptr_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // implicitly create a JSON null value\n    json j1;\n\n    // explicitly create a JSON null value\n    json j2(nullptr);\n\n    // serialize the JSON null value\n    std::cout << j1 << '\\n' << j2 << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__nullptr_t.output",
    "content": "null\nnull\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__size_type_basic_json.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array by creating copies of a JSON value\n    json value = \"Hello\";\n    json array_0 = json(0, value);\n    json array_1 = json(1, value);\n    json array_5 = json(5, value);\n\n    // serialize the JSON arrays\n    std::cout << array_0 << '\\n';\n    std::cout << array_1 << '\\n';\n    std::cout << array_5 << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__size_type_basic_json.output",
    "content": "[]\n[\"Hello\"]\n[\"Hello\",\"Hello\",\"Hello\",\"Hello\",\"Hello\"]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__value.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"integer\", 0);\n    double v_floating = j.value(\"floating\", 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"nonexisting\", \"oops\");\n    bool v_boolean = j.value(\"nonexisting\", false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__value.output",
    "content": "1 42.23 oops false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__value_ptr.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"/integer\"_json_pointer, 0);\n    double v_floating = j.value(\"/floating\"_json_pointer, 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"/nonexisting\"_json_pointer, \"oops\");\n    bool v_boolean = j.value(\"/nonexisting\"_json_pointer, false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__value_ptr.output",
    "content": "1 42.23 oops false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__value_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create the different JSON values with default values\n    json j_null(json::value_t::null);\n    json j_boolean(json::value_t::boolean);\n    json j_number_integer(json::value_t::number_integer);\n    json j_number_float(json::value_t::number_float);\n    json j_object(json::value_t::object);\n    json j_array(json::value_t::array);\n    json j_string(json::value_t::string);\n\n    // serialize the JSON values\n    std::cout << j_null << '\\n';\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/basic_json__value_t.output",
    "content": "null\nfalse\n0\n0.0\n{}\n[]\n\"\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/begin.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the first element\n    json::iterator it = array.begin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/begin.output",
    "content": "1\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/binary.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a binary vector\n    std::vector<std::uint8_t> vec = {0xCA, 0xFE, 0xBA, 0xBE};\n\n    // create a binary JSON value with subtype 42\n    json j = json::binary(vec, 42);\n\n    // output type and subtype\n    std::cout << \"type: \" << j.type_name() << \", subtype: \" << j.get_binary().subtype() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/binary.output",
    "content": "type: binary, subtype: 42\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/binary_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>, json::binary_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/binary_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/boolean_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<bool, json::boolean_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/boolean_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/cbegin.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    const json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the first element\n    json::const_iterator it = array.cbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/cbegin.output",
    "content": "1\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/cend.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to one past the last element\n    json::const_iterator it = array.cend();\n\n    // decrement the iterator to point to the last element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/cend.output",
    "content": "5\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/clear.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call clear()\n    j_null.clear();\n    j_boolean.clear();\n    j_number_integer.clear();\n    j_number_float.clear();\n    j_object.clear();\n    j_array.clear();\n    j_string.clear();\n\n    // serialize the cleared values()\n    std::cout << j_null << '\\n';\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/clear.output",
    "content": "null\nfalse\n0\n0.0\n{}\n[]\n\"\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/contains.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create some JSON values\n    json j_object = R\"( {\"key\": \"value\"} )\"_json;\n    json j_array = R\"( [1, 2, 3] )\"_json;\n\n    // call contains\n    std::cout << std::boolalpha <<\n              \"j_object contains 'key': \" << j_object.contains(\"key\") << '\\n' <<\n              \"j_object contains 'another': \" << j_object.contains(\"another\") << '\\n' <<\n              \"j_array contains 'key': \" << j_array.contains(\"key\") << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/contains.output",
    "content": "j_object contains 'key': true\nj_object contains 'another': false\nj_array contains 'key': false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/contains_json_pointer.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    std::cout << std::boolalpha\n              << j.contains(\"/number\"_json_pointer) << '\\n'\n              << j.contains(\"/string\"_json_pointer) << '\\n'\n              << j.contains(\"/array\"_json_pointer) << '\\n'\n              << j.contains(\"/array/1\"_json_pointer) << '\\n'\n              << j.contains(\"/array/-\"_json_pointer) << '\\n'\n              << j.contains(\"/array/4\"_json_pointer) << '\\n'\n              << j.contains(\"/baz\"_json_pointer) << std::endl;\n\n    try\n    {\n        // try to use an array index with leading '0'\n        j.contains(\"/array/01\"_json_pointer);\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    try\n    {\n        // try to use an array index that is not a number\n        j.contains(\"/array/one\"_json_pointer);\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/contains_json_pointer.output",
    "content": "true\ntrue\ntrue\ntrue\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/count.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call count()\n    auto count_two = j_object.count(\"two\");\n    auto count_three = j_object.count(\"three\");\n\n    // print values\n    std::cout << \"number of elements with key \\\"two\\\": \" << count_two << '\\n';\n    std::cout << \"number of elements with key \\\"three\\\": \" << count_three << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/count.output",
    "content": "number of elements with key \"two\": 1\nnumber of elements with key \"three\": 0\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/crbegin.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-beginning\n    json::const_reverse_iterator it = array.crbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/crbegin.output",
    "content": "5\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/crend.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-end\n    json::const_reverse_iterator it = array.crend();\n\n    // increment the iterator to point to the first element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/crend.output",
    "content": "1\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/diagnostics_extended.cpp",
    "content": "#include <iostream>\n\n# define JSON_DIAGNOSTICS 1\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/diagnostics_extended.output",
    "content": "[json.exception.type_error.302] (/address/housenumber) type must be number, but is string\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/diagnostics_standard.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/diagnostics_standard.output",
    "content": "[json.exception.type_error.302] type must be number, but is string\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/diff.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // the source document\n    json source = R\"(\n        {\n            \"baz\": \"qux\",\n            \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the target document\n    json target = R\"(\n        {\n            \"baz\": \"boo\",\n            \"hello\": [\n                \"world\"\n            ]\n        }\n    )\"_json;\n\n    // create the patch\n    json patch = json::diff(source, target);\n\n    // roundtrip\n    json patched_source = source.patch(patch);\n\n    // output patch and roundtrip result\n    std::cout << std::setw(4) << patch << \"\\n\\n\"\n              << std::setw(4) << patched_source << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/diff.output",
    "content": "[\n    {\n        \"op\": \"replace\",\n        \"path\": \"/baz\",\n        \"value\": \"boo\"\n    },\n    {\n        \"op\": \"remove\",\n        \"path\": \"/foo\"\n    },\n    {\n        \"op\": \"add\",\n        \"path\": \"/hello\",\n        \"value\": [\n            \"world\"\n        ]\n    }\n]\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/dump.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hellö 😀!\";\n\n    // call dump()\n    std::cout << \"objects:\" << '\\n'\n              << j_object.dump() << \"\\n\\n\"\n              << j_object.dump(-1) << \"\\n\\n\"\n              << j_object.dump(0) << \"\\n\\n\"\n              << j_object.dump(4) << \"\\n\\n\"\n              << j_object.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"arrays:\" << '\\n'\n              << j_array.dump() << \"\\n\\n\"\n              << j_array.dump(-1) << \"\\n\\n\"\n              << j_array.dump(0) << \"\\n\\n\"\n              << j_array.dump(4) << \"\\n\\n\"\n              << j_array.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"strings:\" << '\\n'\n              << j_string.dump() << '\\n'\n              << j_string.dump(-1, ' ', true) << '\\n';\n\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"ä\\xA9ü\";\n    try\n    {\n        std::cout << j_invalid.dump() << std::endl;\n    }\n    catch (json::type_error& e)\n    {\n        std::cout << e.what() << std::endl;\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/dump.output",
    "content": "objects:\n{\"one\":1,\"two\":2}\n\n{\"one\":1,\"two\":2}\n\n{\n\"one\": 1,\n\"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n{\n\t\"one\": 1,\n\t\"two\": 2\n}\n\narrays:\n[1,2,4,8,16]\n\n[1,2,4,8,16]\n\n[\n1,\n2,\n4,\n8,\n16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\n[\n\t1,\n\t2,\n\t4,\n\t8,\n\t16\n]\n\nstrings:\n\"Hellö 😀!\"\n\"Hell\\u00f6 \\ud83d\\ude00!\"\n[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"ä�ü\"\nstring with ignored invalid characters: \"äü\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/emplace.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    auto res1 = object.emplace(\"three\", 3);\n    null.emplace(\"A\", \"a\");\n    null.emplace(\"B\", \"b\");\n\n    // the following call will not add an object, because there is already\n    // a value stored at key \"B\"\n    auto res2 = null.emplace(\"B\", \"c\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << *res1.first << \" \" << std::boolalpha << res1.second << '\\n';\n\n    std::cout << null << '\\n';\n    std::cout << *res2.first << \" \" << std::boolalpha << res2.second << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/emplace.output",
    "content": "{\"one\":1,\"two\":2}\nnull\n{\"one\":1,\"three\":3,\"two\":2}\n3 true\n{\"A\":\"a\",\"B\":\"b\"}\n\"b\" false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/emplace_back.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.emplace_back(6);\n    null.emplace_back(\"first\");\n    null.emplace_back(3, \"second\");\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/emplace_back.output",
    "content": "[1,2,3,4,5]\nnull\n[1,2,3,4,5,6]\n[\"first\",[\"second\",\"second\",\"second\"]]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/empty.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call empty()\n    std::cout << std::boolalpha;\n    std::cout << j_null.empty() << '\\n';\n    std::cout << j_boolean.empty() << '\\n';\n    std::cout << j_number_integer.empty() << '\\n';\n    std::cout << j_number_float.empty() << '\\n';\n    std::cout << j_object.empty() << '\\n';\n    std::cout << j_object_empty.empty() << '\\n';\n    std::cout << j_array.empty() << '\\n';\n    std::cout << j_array_empty.empty() << '\\n';\n    std::cout << j_string.empty() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/empty.output",
    "content": "true\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\ntrue\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/end.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to one past the last element\n    json::iterator it = array.end();\n\n    // decrement the iterator to point to the last element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/end.output",
    "content": "5\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__IteratorType.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call erase()\n    j_boolean.erase(j_boolean.begin());\n    j_number_integer.erase(j_number_integer.begin());\n    j_number_float.erase(j_number_float.begin());\n    j_object.erase(j_object.find(\"two\"));\n    j_array.erase(j_array.begin() + 2);\n    j_string.erase(j_string.begin());\n\n    // print values\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__IteratorType.output",
    "content": "null\nnull\nnull\n{\"one\":1}\n[1,2,8,16]\nnull\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__IteratorType_IteratorType.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call erase()\n    j_boolean.erase(j_boolean.begin(), j_boolean.end());\n    j_number_integer.erase(j_number_integer.begin(), j_number_integer.end());\n    j_number_float.erase(j_number_float.begin(), j_number_float.end());\n    j_object.erase(j_object.find(\"two\"), j_object.end());\n    j_array.erase(j_array.begin() + 1, j_array.begin() + 3);\n    j_string.erase(j_string.begin(), j_string.end());\n\n    // print values\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__IteratorType_IteratorType.output",
    "content": "null\nnull\nnull\n{\"one\":1}\n[1,8,16]\nnull\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__key_type.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call erase()\n    auto count_one = j_object.erase(\"one\");\n    auto count_three = j_object.erase(\"three\");\n\n    // print values\n    std::cout << j_object << '\\n';\n    std::cout << count_one << \" \" << count_three << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__key_type.output",
    "content": "{\"two\":2}\n1 0\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__size_type.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json j_array = {0, 1, 2, 3, 4, 5};\n\n    // call erase()\n    j_array.erase(2);\n\n    // print values\n    std::cout << j_array << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/erase__size_type.output",
    "content": "[0,1,3,4,5]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/exception.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for a non-existing key\n        json j = {{\"foo\", \"bar\"}};\n        json k = j.at(\"non-existing\");\n    }\n    catch (json::exception& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << std::endl;\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/exception.output",
    "content": "message: [json.exception.out_of_range.403] key 'non-existing' not found\nexception id: 403\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/find__key_type.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call find\n    auto it_two = j_object.find(\"two\");\n    auto it_three = j_object.find(\"three\");\n\n    // print values\n    std::cout << std::boolalpha;\n    std::cout << \"\\\"two\\\" was found: \" << (it_two != j_object.end()) << '\\n';\n    std::cout << \"value at key \\\"two\\\": \" << *it_two << '\\n';\n    std::cout << \"\\\"three\\\" was found: \" << (it_three != j_object.end()) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/find__key_type.output",
    "content": "\"two\" was found: true\nvalue at key \"two\": 2\n\"three\" was found: false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/flatten.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON value\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // call flatten()\n    std::cout << std::setw(4) << j.flatten() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/flatten.output",
    "content": "{\n    \"/answer/everything\": 42,\n    \"/happy\": true,\n    \"/list/0\": 1,\n    \"/list/1\": 0,\n    \"/list/2\": 2,\n    \"/name\": \"Niels\",\n    \"/nothing\": null,\n    \"/object/currency\": \"USD\",\n    \"/object/value\": 42.99,\n    \"/pi\": 3.141\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_bson.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d,\n                                   0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73,\n                                   0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00,\n                                   0x00, 0x00, 0x00\n                                  };\n\n    // deserialize it with BSON\n    json j = json::from_bson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_bson.output",
    "content": "{\n  \"compact\": true,\n  \"schema\": 0\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_cbor.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with CBOR\n    json j = json::from_cbor(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_cbor.output",
    "content": "{\n  \"compact\": true,\n  \"schema\": 0\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_msgpack.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with MessagePack\n    json j = json::from_msgpack(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_msgpack.output",
    "content": "{\n  \"compact\": true,\n  \"schema\": 0\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_ubjson.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with UBJSON\n    json j = json::from_ubjson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/from_ubjson.output",
    "content": "{\n  \"compact\": true,\n  \"schema\": 0\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/front.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call front()\n    //std::cout << j_null.front() << '\\n';          // would throw\n    std::cout << j_boolean.front() << '\\n';\n    std::cout << j_number_integer.front() << '\\n';\n    std::cout << j_number_float.front() << '\\n';\n    std::cout << j_object.front() << '\\n';\n    //std::cout << j_object_empty.front() << '\\n';  // undefined behavior\n    std::cout << j_array.front() << '\\n';\n    //std::cout << j_array_empty.front() << '\\n';   // undefined behavior\n    std::cout << j_string.front() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/front.output",
    "content": "true\n17\n23.42\n1\n1\n\"Hello, world\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get__PointerType.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting pointers\n    auto p1 = value.get<const json::number_integer_t*>();\n    auto p2 = value.get<json::number_integer_t*>();\n    auto p3 = value.get<json::number_integer_t* const>();\n    auto p4 = value.get<const json::number_integer_t* const>();\n    auto p5 = value.get<json::number_float_t*>();\n\n    // print the pointees\n    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\\n';\n    std::cout << std::boolalpha << (p5 == nullptr) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get__PointerType.output",
    "content": "17 17 17 17\ntrue\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get__ValueType_const.cpp",
    "content": "#include <iostream>\n#include <unordered_map>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    // use explicit conversions\n    auto v1 = json_types[\"boolean\"].get<bool>();\n    auto v2 = json_types[\"number\"][\"integer\"].get<int>();\n    auto v3 = json_types[\"number\"][\"integer\"].get<short>();\n    auto v4 = json_types[\"number\"][\"floating-point\"].get<float>();\n    auto v5 = json_types[\"number\"][\"floating-point\"].get<int>();\n    auto v6 = json_types[\"string\"].get<std::string>();\n    auto v7 = json_types[\"array\"].get<std::vector<short>>();\n    auto v8 = json_types.get<std::unordered_map<std::string, json>>();\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (auto i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get__ValueType_const.output",
    "content": "1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\nstring: \"Hello, world!\"\nnumber: {\"floating-point\":17.23,\"integer\":42}\nnull: null\nboolean: true\narray: [1,2,3,4,5]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_binary.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a binary vector\n    std::vector<std::uint8_t> vec = {0xCA, 0xFE, 0xBA, 0xBE};\n\n    // create a binary JSON value with subtype 42\n    json j = json::binary(vec, 42);\n\n    // output type and subtype\n    std::cout << \"type: \" << j.type_name() << \", subtype: \" << j.get_binary().subtype() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_binary.output",
    "content": "type: binary, subtype: 42\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_ptr.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting pointers\n    auto p1 = value.get_ptr<const json::number_integer_t*>();\n    auto p2 = value.get_ptr<json::number_integer_t*>();\n    auto p3 = value.get_ptr<json::number_integer_t* const>();\n    auto p4 = value.get_ptr<const json::number_integer_t* const>();\n    auto p5 = value.get_ptr<json::number_float_t*>();\n\n    // print the pointees\n    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\\n';\n    std::cout << std::boolalpha << (p5 == nullptr) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_ptr.output",
    "content": "17 17 17 17\ntrue\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_ref.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting references\n    auto r1 = value.get_ref<const json::number_integer_t&>();\n    auto r2 = value.get_ref<json::number_integer_t&>();\n\n    // print the values\n    std::cout << r1 << ' ' << r2 << '\\n';\n\n    // incompatible type throws exception\n    try\n    {\n        auto r3 = value.get_ref<json::number_float_t&>();\n    }\n    catch (json::type_error& ex)\n    {\n        std::cout << ex.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_ref.output",
    "content": "17 17\n[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_to.cpp",
    "content": "#include <iostream>\n#include <unordered_map>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    bool v1;\n    int v2;\n    short v3;\n    float v4;\n    int v5;\n    std::string v6;\n    std::vector<short> v7;\n    std::unordered_map<std::string, json> v8;\n\n\n    // use explicit conversions\n    json_types[\"boolean\"].get_to(v1);\n    json_types[\"number\"][\"integer\"].get_to(v2);\n    json_types[\"number\"][\"integer\"].get_to(v3);\n    json_types[\"number\"][\"floating-point\"].get_to(v4);\n    json_types[\"number\"][\"floating-point\"].get_to(v5);\n    json_types[\"string\"].get_to(v6);\n    json_types[\"array\"].get_to(v7);\n    json_types.get_to(v8);\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (auto i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/get_to.output",
    "content": "1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\nstring: \"Hello, world!\"\nnumber: {\"floating-point\":17.23,\"integer\":42}\nnull: null\nboolean: true\narray: [1,2,3,4,5]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert number 10 before number 3\n    auto new_pos = v.insert(v.begin() + 2, 10);\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert.output",
    "content": "10\n[1,2,10,3,4]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__count.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert number 7 copies of number 7 before number 3\n    auto new_pos = v.insert(v.begin() + 2, 7, 7);\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__count.output",
    "content": "7\n[1,2,7,7,7,7,7,7,7,3,4]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__ilist.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert range from v2 before the end of array v\n    auto new_pos = v.insert(v.end(), {7, 8, 9});\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__ilist.output",
    "content": "7\n[1,2,3,4,7,8,9]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__range.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // create a JSON array to copy values from\n    json v2 = {\"one\", \"two\", \"three\", \"four\"};\n\n    // insert range from v2 before the end of array v\n    auto new_pos = v.insert(v.end(), v2.begin(), v2.end());\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__range.output",
    "content": "\"one\"\n[1,2,3,4,\"one\",\"two\",\"three\",\"four\"]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__range_object.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create two JSON objects\n    json j1 = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n    json j2 = {{\"eleven\", \"elf\"}, {\"seventeen\", \"siebzehn\"}};\n\n    // output objects\n    std::cout << j1 << '\\n';\n    std::cout << j2 << '\\n';\n\n    // insert range from j2 to j1\n    j1.insert(j2.begin(), j2.end());\n\n    // output result of insert call\n    std::cout << j1 << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/insert__range_object.output",
    "content": "{\"one\":\"eins\",\"two\":\"zwei\"}\n{\"eleven\":\"elf\",\"seventeen\":\"siebzehn\"}\n{\"eleven\":\"elf\",\"one\":\"eins\",\"seventeen\":\"siebzehn\",\"two\":\"zwei\"}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/invalid_iterator.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling iterator::key() on non-object iterator\n        json j = \"string\";\n        json::iterator it = j.begin();\n        auto k = it.key();\n    }\n    catch (json::invalid_iterator& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << std::endl;\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/invalid_iterator.output",
    "content": "message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators\nexception id: 207\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_array.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_array()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_array() << '\\n';\n    std::cout << j_boolean.is_array() << '\\n';\n    std::cout << j_number_integer.is_array() << '\\n';\n    std::cout << j_number_unsigned_integer.is_array() << '\\n';\n    std::cout << j_number_float.is_array() << '\\n';\n    std::cout << j_object.is_array() << '\\n';\n    std::cout << j_array.is_array() << '\\n';\n    std::cout << j_string.is_array() << '\\n';\n    std::cout << j_binary.is_array() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_array.output",
    "content": "false\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_binary.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_binary()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_binary() << '\\n';\n    std::cout << j_boolean.is_binary() << '\\n';\n    std::cout << j_number_integer.is_binary() << '\\n';\n    std::cout << j_number_unsigned_integer.is_binary() << '\\n';\n    std::cout << j_number_float.is_binary() << '\\n';\n    std::cout << j_object.is_binary() << '\\n';\n    std::cout << j_array.is_binary() << '\\n';\n    std::cout << j_string.is_binary() << '\\n';\n    std::cout << j_binary.is_binary() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_binary.output",
    "content": "false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_boolean.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_boolean()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_boolean() << '\\n';\n    std::cout << j_boolean.is_boolean() << '\\n';\n    std::cout << j_number_integer.is_boolean() << '\\n';\n    std::cout << j_number_unsigned_integer.is_boolean() << '\\n';\n    std::cout << j_number_float.is_boolean() << '\\n';\n    std::cout << j_object.is_boolean() << '\\n';\n    std::cout << j_array.is_boolean() << '\\n';\n    std::cout << j_string.is_boolean() << '\\n';\n    std::cout << j_binary.is_boolean() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_boolean.output",
    "content": "false\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_discarded.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_discarded()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_discarded() << '\\n';\n    std::cout << j_boolean.is_discarded() << '\\n';\n    std::cout << j_number_integer.is_discarded() << '\\n';\n    std::cout << j_number_unsigned_integer.is_discarded() << '\\n';\n    std::cout << j_number_float.is_discarded() << '\\n';\n    std::cout << j_object.is_discarded() << '\\n';\n    std::cout << j_array.is_discarded() << '\\n';\n    std::cout << j_string.is_discarded() << '\\n';\n    std::cout << j_binary.is_discarded() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_discarded.output",
    "content": "false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_null.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_null()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_null() << '\\n';\n    std::cout << j_boolean.is_null() << '\\n';\n    std::cout << j_number_integer.is_null() << '\\n';\n    std::cout << j_number_unsigned_integer.is_null() << '\\n';\n    std::cout << j_number_float.is_null() << '\\n';\n    std::cout << j_object.is_null() << '\\n';\n    std::cout << j_array.is_null() << '\\n';\n    std::cout << j_string.is_null() << '\\n';\n    std::cout << j_binary.is_null() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_null.output",
    "content": "true\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number() << '\\n';\n    std::cout << j_boolean.is_number() << '\\n';\n    std::cout << j_number_integer.is_number() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number() << '\\n';\n    std::cout << j_number_float.is_number() << '\\n';\n    std::cout << j_object.is_number() << '\\n';\n    std::cout << j_array.is_number() << '\\n';\n    std::cout << j_string.is_number() << '\\n';\n    std::cout << j_binary.is_number() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number.output",
    "content": "false\nfalse\ntrue\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number_float.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_float()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_float() << '\\n';\n    std::cout << j_boolean.is_number_float() << '\\n';\n    std::cout << j_number_integer.is_number_float() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_float() << '\\n';\n    std::cout << j_number_float.is_number_float() << '\\n';\n    std::cout << j_object.is_number_float() << '\\n';\n    std::cout << j_array.is_number_float() << '\\n';\n    std::cout << j_string.is_number_float() << '\\n';\n    std::cout << j_binary.is_number_float() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number_float.output",
    "content": "false\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number_integer.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_integer()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_integer() << '\\n';\n    std::cout << j_boolean.is_number_integer() << '\\n';\n    std::cout << j_number_integer.is_number_integer() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_integer() << '\\n';\n    std::cout << j_number_float.is_number_integer() << '\\n';\n    std::cout << j_object.is_number_integer() << '\\n';\n    std::cout << j_array.is_number_integer() << '\\n';\n    std::cout << j_string.is_number_integer() << '\\n';\n    std::cout << j_binary.is_number_integer() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number_integer.output",
    "content": "false\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number_unsigned.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_unsigned()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_unsigned() << '\\n';\n    std::cout << j_boolean.is_number_unsigned() << '\\n';\n    std::cout << j_number_integer.is_number_unsigned() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_unsigned() << '\\n';\n    std::cout << j_number_float.is_number_unsigned() << '\\n';\n    std::cout << j_object.is_number_unsigned() << '\\n';\n    std::cout << j_array.is_number_unsigned() << '\\n';\n    std::cout << j_string.is_number_unsigned() << '\\n';\n    std::cout << j_binary.is_number_unsigned() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_number_unsigned.output",
    "content": "false\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_object.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_object()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_object() << '\\n';\n    std::cout << j_boolean.is_object() << '\\n';\n    std::cout << j_number_integer.is_object() << '\\n';\n    std::cout << j_number_unsigned_integer.is_object() << '\\n';\n    std::cout << j_number_float.is_object() << '\\n';\n    std::cout << j_object.is_object() << '\\n';\n    std::cout << j_array.is_object() << '\\n';\n    std::cout << j_string.is_object() << '\\n';\n    std::cout << j_binary.is_object() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_object.output",
    "content": "false\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_primitive.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_primitive()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_primitive() << '\\n';\n    std::cout << j_boolean.is_primitive() << '\\n';\n    std::cout << j_number_integer.is_primitive() << '\\n';\n    std::cout << j_number_unsigned_integer.is_primitive() << '\\n';\n    std::cout << j_number_float.is_primitive() << '\\n';\n    std::cout << j_object.is_primitive() << '\\n';\n    std::cout << j_array.is_primitive() << '\\n';\n    std::cout << j_string.is_primitive() << '\\n';\n    std::cout << j_binary.is_primitive() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_primitive.output",
    "content": "true\ntrue\ntrue\ntrue\ntrue\nfalse\nfalse\ntrue\ntrue\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_string.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_string()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_string() << '\\n';\n    std::cout << j_boolean.is_string() << '\\n';\n    std::cout << j_number_integer.is_string() << '\\n';\n    std::cout << j_number_unsigned_integer.is_string() << '\\n';\n    std::cout << j_number_float.is_string() << '\\n';\n    std::cout << j_object.is_string() << '\\n';\n    std::cout << j_array.is_string() << '\\n';\n    std::cout << j_string.is_string() << '\\n';\n    std::cout << j_binary.is_string() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_string.output",
    "content": "false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_structured.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_structured()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_structured() << '\\n';\n    std::cout << j_boolean.is_structured() << '\\n';\n    std::cout << j_number_integer.is_structured() << '\\n';\n    std::cout << j_number_unsigned_integer.is_structured() << '\\n';\n    std::cout << j_number_float.is_structured() << '\\n';\n    std::cout << j_object.is_structured() << '\\n';\n    std::cout << j_array.is_structured() << '\\n';\n    std::cout << j_string.is_structured() << '\\n';\n    std::cout << j_binary.is_structured() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/is_structured.output",
    "content": "false\nfalse\nfalse\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/items.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n\n    // example for an object\n    for (auto& x : j_object.items())\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n\n    // example for an array\n    for (auto& x : j_array.items())\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/items.output",
    "content": "key: one, value: 1\nkey: two, value: 2\nkey: 0, value: 1\nkey: 1, value: 2\nkey: 2, value: 4\nkey: 3, value: 8\nkey: 4, value: 16\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/iterator_wrapper.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n\n    //////////////////////////////////////////////////////////////////////////\n    // The static function iterator_wrapper was deprecated in version 3.1.0\n    // and will be removed in version 4.0.0. Please replace all occurrences\n    // of iterator_wrapper(j) with j.items().\n    //////////////////////////////////////////////////////////////////////////\n\n    // example for an object\n    for (auto& x : json::iterator_wrapper(j_object))\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n\n    // example for an array\n    for (auto& x : json::iterator_wrapper(j_array))\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/iterator_wrapper.output",
    "content": "key: one, value: 1\nkey: two, value: 2\nkey: 0, value: 1\nkey: 1, value: 2\nkey: 2, value: 4\nkey: 3, value: 8\nkey: 4, value: 16\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // correct JSON pointers\n    json::json_pointer p1;\n    json::json_pointer p2(\"\");\n    json::json_pointer p3(\"/\");\n    json::json_pointer p4(\"//\");\n    json::json_pointer p5(\"/foo/bar\");\n    json::json_pointer p6(\"/foo/bar/-\");\n    json::json_pointer p7(\"/foo/~0\");\n    json::json_pointer p8(\"/foo/~1\");\n\n    // error: JSON pointer does not begin with a slash\n    try\n    {\n        json::json_pointer p9(\"foo\");\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // error: JSON pointer uses escape symbol ~ not followed by 0 or 1\n    try\n    {\n        json::json_pointer p10(\"/foo/~\");\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // error: JSON pointer uses escape symbol ~ not followed by 0 or 1\n    try\n    {\n        json::json_pointer p11(\"/foo/~3\");\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer.output",
    "content": "[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'\n[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__back.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"/foo\");\n    json::json_pointer ptr2(\"/foo/0\");\n\n    // call empty()\n    std::cout << \"last reference token of \" << ptr1 << \" is \" << ptr1.back() << '\\n'\n              << \"last reference token of \" << ptr2 << \" is \" << ptr2.back() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__back.output",
    "content": "last reference token of \"/foo\" is foo\nlast reference token of \"/foo/0\" is 0\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__empty.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n\n    // call empty()\n    std::cout << std::boolalpha\n              << ptr0 << \": \" << ptr0.empty() << '\\n'\n              << ptr1 << \": \" << ptr1.empty() << '\\n'\n              << ptr2 << \": \" << ptr2.empty() << '\\n'\n              << ptr3 << \": \" << ptr3.empty() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__empty.output",
    "content": "\"\": true\n\"\": true\n\"/foo\": false\n\"/foo/0\": false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__operator_add.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON pointer\n    json::json_pointer ptr(\"/foo\");\n    std::cout << ptr << '\\n';\n\n    // append a JSON Pointer\n    ptr /= json::json_pointer(\"/bar/baz\");\n    std::cout << ptr << '\\n';\n\n    // append a string\n    ptr /= \"fob\";\n    std::cout << ptr << '\\n';\n\n    // append an array index\n    ptr /= 42;\n    std::cout << ptr << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__operator_add.output",
    "content": "\"/foo\"\n\"/foo/bar/baz\"\n\"/foo/bar/baz/fob\"\n\"/foo/bar/baz/fob/42\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__operator_add_binary.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON pointer\n    json::json_pointer ptr(\"/foo\");\n\n    // append a JSON Pointer\n    std::cout << ptr / json::json_pointer(\"/bar/baz\") << '\\n';\n\n    // append a string\n    std::cout << ptr / \"fob\" << '\\n';\n\n    // append an array index\n    std::cout << ptr / 42 << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__operator_add_binary.output",
    "content": "\"/foo/bar/baz\"\n\"/foo/fob\"\n\"/foo/42\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__parent_pointer.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n\n    // call parent_pointer()\n    std::cout << std::boolalpha\n              << \"parent of \" << ptr1 << \" is \" << ptr1.parent_pointer() << '\\n'\n              << \"parent of \" << ptr2 << \" is \" << ptr2.parent_pointer() << '\\n'\n              << \"parent of \" << ptr3 << \" is \" << ptr3.parent_pointer() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__parent_pointer.output",
    "content": "parent of \"\" is \"\"\nparent of \"/foo\" is \"\"\nparent of \"/foo/0\" is \"/foo\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__pop_back.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr(\"/foo/bar/baz\");\n    std::cout << ptr << '\\n';\n\n    // call pop_back()\n    ptr.pop_back();\n    std::cout << ptr << '\\n';\n\n    ptr.pop_back();\n    std::cout << ptr << '\\n';\n\n    ptr.pop_back();\n    std::cout << ptr << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__pop_back.output",
    "content": "\"/foo/bar/baz\"\n\"/foo/bar\"\n\"/foo\"\n\"\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__push_back.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr;\n    std::cout << ptr << '\\n';\n\n    // call push_back()\n    ptr.push_back(\"foo\");\n    std::cout << ptr << '\\n';\n\n    ptr.push_back(\"0\");\n    std::cout << ptr << '\\n';\n\n    ptr.push_back(\"bar\");\n    std::cout << ptr << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__push_back.output",
    "content": "\"\"\n\"/foo\"\n\"/foo/0\"\n\"/foo/0/bar\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__to_string.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n    json::json_pointer ptr4(\"/\");\n    json::json_pointer ptr5(\"/a~1b\");\n    json::json_pointer ptr6(\"/c%d\");\n    json::json_pointer ptr7(\"/e^f\");\n    json::json_pointer ptr8(\"/g|h\");\n    json::json_pointer ptr9(\"/i\\\\j\");\n    json::json_pointer ptr10(\"/k\\\"l\");\n    json::json_pointer ptr11(\"/ \");\n    json::json_pointer ptr12(\"/m~0n\");\n\n\n    std::cout << ptr1.to_string() << '\\n'\n              << ptr2.to_string() << '\\n'\n              << ptr3.to_string() << '\\n'\n              << ptr4.to_string() << '\\n'\n              << ptr5.to_string() << '\\n'\n              << ptr6.to_string() << '\\n'\n              << ptr7.to_string() << '\\n'\n              << ptr8.to_string() << '\\n'\n              << ptr9.to_string() << '\\n'\n              << ptr10.to_string() << '\\n'\n              << ptr11.to_string() << '\\n'\n              << ptr12.to_string() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/json_pointer__to_string.output",
    "content": "\n/foo\n/foo/0\n/\n/a~1b\n/c%d\n/e^f\n/g|h\n/i\\j\n/k\"l\n/ \n/m~0n\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/max_size.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call max_size()\n    std::cout << j_null.max_size() << '\\n';\n    std::cout << j_boolean.max_size() << '\\n';\n    std::cout << j_number_integer.max_size() << '\\n';\n    std::cout << j_number_float.max_size() << '\\n';\n    std::cout << j_object.max_size() << '\\n';\n    std::cout << j_array.max_size() << '\\n';\n    std::cout << j_string.max_size() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/max_size.output",
    "content": "0\n1\n1\n1\n256204778801521550\n1152921504606846975\n1\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/merge_patch.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n#include <iomanip> // for std::setw\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // the original document\n    json document = R\"({\n                \"title\": \"Goodbye!\",\n                \"author\": {\n                    \"givenName\": \"John\",\n                    \"familyName\": \"Doe\"\n                },\n                \"tags\": [\n                    \"example\",\n                    \"sample\"\n                ],\n                \"content\": \"This will be unchanged\"\n            })\"_json;\n\n    // the patch\n    json patch = R\"({\n                \"title\": \"Hello!\",\n                \"phoneNumber\": \"+01-123-456-7890\",\n                \"author\": {\n                    \"familyName\": null\n                },\n                \"tags\": [\n                    \"example\"\n                ]\n            })\"_json;\n\n    // apply the patch\n    document.merge_patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << document << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/merge_patch.output",
    "content": "{\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/meta.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // call meta()\n    std::cout << std::setw(4) << json::meta() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/meta.output",
    "content": "{\n    \"compiler\": {\n        \"c++\": \"201103\",\n        \"family\": \"clang\",\n        \"version\": \"13.0.0 (clang-1300.0.29.30)\"\n    },\n    \"copyright\": \"(C) 2013-2022 Niels Lohmann\",\n    \"name\": \"JSON for Modern C++\",\n    \"platform\": \"apple\",\n    \"url\": \"https://github.com/nlohmann/json\",\n    \"version\": {\n        \"major\": 3,\n        \"minor\": 10,\n        \"patch\": 5,\n        \"string\": \"3.10.5\"\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/number_float_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<double, json::number_float_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/number_float_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/number_integer_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::int64_t, json::number_integer_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/number_integer_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/number_unsigned_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::uint64_t, json::number_unsigned_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/number_unsigned_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/object.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON objects\n    json j_no_init_list = json::object();\n    json j_empty_init_list = json::object({});\n    json j_list_of_pairs = json::object({ {\"one\", 1}, {\"two\", 2} });\n\n    // serialize the JSON objects\n    std::cout << j_no_init_list << '\\n';\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_list_of_pairs << '\\n';\n\n    // example for an exception\n    try\n    {\n        // can only create an object from a list of pairs\n        json j_invalid_object = json::object({{ \"one\", 1, 2 }});\n    }\n    catch (json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/object.output",
    "content": "{}\n{}\n{\"one\":1,\"two\":2}\n[json.exception.type_error.301] cannot create object from initializer list\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/object_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::map<json::string_t, json>, json::object_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/object_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__ValueType.cpp",
    "content": "#include <iostream>\n#include <unordered_map>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    // use implicit conversions\n    bool v1 = json_types[\"boolean\"];\n    int v2 = json_types[\"number\"][\"integer\"];\n    short v3 = json_types[\"number\"][\"integer\"];\n    float v4 = json_types[\"number\"][\"floating-point\"];\n    int v5 = json_types[\"number\"][\"floating-point\"];\n    std::string v6 = json_types[\"string\"];\n    std::vector<short> v7 = json_types[\"array\"];\n    std::unordered_map<std::string, json> v8 = json_types;\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (auto i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n\n    // example for an exception\n    try\n    {\n        bool v1 = json_types[\"string\"];\n    }\n    catch (json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__ValueType.output",
    "content": "1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\nstring: \"Hello, world!\"\nnumber: {\"floating-point\":17.23,\"integer\":42}\nnull: null\nboolean: true\narray: [1,2,3,4,5]\n[json.exception.type_error.302] type must be boolean, but is string\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__equal.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.000000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" == \" << array_2 << \" \" << (array_1 == array_2) << '\\n';\n    std::cout << object_1 << \" == \" << object_2 << \" \" << (object_1 == object_2) << '\\n';\n    std::cout << number_1 << \" == \" << number_2 << \" \" << (number_1 == number_2) << '\\n';\n    std::cout << string_1 << \" == \" << string_2 << \" \" << (string_1 == string_2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__equal.output",
    "content": "[1,2,3] == [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} == {\"A\":\"a\",\"B\":\"b\"} true\n17 == 17.0 true\n\"foo\" == \"bar\" false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__equal__nullptr_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array = {1, 2, 3};\n    json object = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json number = 17;\n    json string = \"foo\";\n    json null;\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array << \" == nullptr \" << (array == nullptr) << '\\n';\n    std::cout << object << \" == nullptr \" << (object == nullptr) << '\\n';\n    std::cout << number << \" == nullptr \" << (number == nullptr) << '\\n';\n    std::cout << string << \" == nullptr \" << (string == nullptr) << '\\n';\n    std::cout << null << \" == nullptr \" << (null == nullptr) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__equal__nullptr_t.output",
    "content": "[1,2,3] == nullptr false\n{\"A\":\"a\",\"B\":\"b\"} == nullptr false\n17 == nullptr false\n\"foo\" == nullptr false\nnull == nullptr true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__greater.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" > \" << array_2 << \" \" << (array_1 > array_2) << '\\n';\n    std::cout << object_1 << \" > \" << object_2 << \" \" << (object_1 > object_2) << '\\n';\n    std::cout << number_1 << \" > \" << number_2 << \" \" << (number_1 > number_2) << '\\n';\n    std::cout << string_1 << \" > \" << string_2 << \" \" << (string_1 > string_2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__greater.output",
    "content": "[1,2,3] > [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} > {\"A\":\"a\",\"B\":\"b\"} false\n17 > 17.0000000000001 false\n\"foo\" > \"bar\" true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__greaterequal.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" >= \" << array_2 << \" \" << (array_1 >= array_2) << '\\n';\n    std::cout << object_1 << \" >= \" << object_2 << \" \" << (object_1 >= object_2) << '\\n';\n    std::cout << number_1 << \" >= \" << number_2 << \" \" << (number_1 >= number_2) << '\\n';\n    std::cout << string_1 << \" >= \" << string_2 << \" \" << (string_1 >= string_2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__greaterequal.output",
    "content": "[1,2,3] >= [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} >= {\"A\":\"a\",\"B\":\"b\"} true\n17 >= 17.0000000000001 false\n\"foo\" >= \"bar\" true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__less.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" == \" << array_2 << \" \" << (array_1 < array_2) << '\\n';\n    std::cout << object_1 << \" == \" << object_2 << \" \" << (object_1 < object_2) << '\\n';\n    std::cout << number_1 << \" == \" << number_2 << \" \" << (number_1 < number_2) << '\\n';\n    std::cout << string_1 << \" == \" << string_2 << \" \" << (string_1 < string_2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__less.output",
    "content": "[1,2,3] == [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} == {\"A\":\"a\",\"B\":\"b\"} false\n17 == 17.0000000000001 true\n\"foo\" == \"bar\" false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__lessequal.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" <= \" << array_2 << \" \" << (array_1 <= array_2) << '\\n';\n    std::cout << object_1 << \" <= \" << object_2 << \" \" << (object_1 <= object_2) << '\\n';\n    std::cout << number_1 << \" <= \" << number_2 << \" \" << (number_1 <= number_2) << '\\n';\n    std::cout << string_1 << \" <= \" << string_2 << \" \" << (string_1 <= string_2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__lessequal.output",
    "content": "[1,2,3] <= [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} <= {\"A\":\"a\",\"B\":\"b\"} true\n17 <= 17.0000000000001 true\n\"foo\" <= \"bar\" false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__notequal.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.000000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" != \" << array_2 << \" \" << (array_1 != array_2) << '\\n';\n    std::cout << object_1 << \" != \" << object_2 << \" \" << (object_1 != object_2) << '\\n';\n    std::cout << number_1 << \" != \" << number_2 << \" \" << (number_1 != number_2) << '\\n';\n    std::cout << string_1 << \" != \" << string_2 << \" \" << (string_1 != string_2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__notequal.output",
    "content": "[1,2,3] != [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} != {\"A\":\"a\",\"B\":\"b\"} false\n17 != 17.0 false\n\"foo\" != \"bar\" true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__notequal__nullptr_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array = {1, 2, 3};\n    json object = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json number = 17;\n    json string = \"foo\";\n    json null;\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array << \" != nullptr \" << (array != nullptr) << '\\n';\n    std::cout << object << \" != nullptr \" << (object != nullptr) << '\\n';\n    std::cout << number << \" != nullptr \" << (number != nullptr) << '\\n';\n    std::cout << string << \" != nullptr \" << (string != nullptr) << '\\n';\n    std::cout << null << \" != nullptr \" << (null != nullptr) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__notequal__nullptr_t.output",
    "content": "[1,2,3] != nullptr true\n{\"A\":\"a\",\"B\":\"b\"} != nullptr true\n17 != nullptr true\n\"foo\" != nullptr true\nnull != nullptr false\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__value_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call operator value_t()\n    json::value_t t_null = j_null;\n    json::value_t t_boolean = j_boolean;\n    json::value_t t_number_integer = j_number_integer;\n    json::value_t t_number_unsigned = j_number_unsigned;\n    json::value_t t_number_float = j_number_float;\n    json::value_t t_object = j_object;\n    json::value_t t_array = j_array;\n    json::value_t t_string = j_string;\n\n    // print types\n    std::cout << std::boolalpha;\n    std::cout << (t_null == json::value_t::null) << '\\n';\n    std::cout << (t_boolean == json::value_t::boolean) << '\\n';\n    std::cout << (t_number_integer == json::value_t::number_integer) << '\\n';\n    std::cout << (t_number_unsigned == json::value_t::number_unsigned) << '\\n';\n    std::cout << (t_number_float == json::value_t::number_float) << '\\n';\n    std::cout << (t_object == json::value_t::object) << '\\n';\n    std::cout << (t_array == json::value_t::array) << '\\n';\n    std::cout << (t_string == json::value_t::string) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator__value_t.output",
    "content": "true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_deserialize.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create stream with serialized JSON\n    std::stringstream ss;\n    ss << R\"({\n        \"number\": 23,\n        \"string\": \"Hello, world!\",\n        \"array\": [1, 2, 3, 4, 5],\n        \"boolean\": false,\n        \"null\": null\n    })\";\n\n    // create JSON value and read the serialization from the stream\n    json j;\n    ss >> j;\n\n    // serialize JSON\n    std::cout << std::setw(2) << j << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_deserialize.output",
    "content": "{\n  \"array\": [\n    1,\n    2,\n    3,\n    4,\n    5\n  ],\n  \"boolean\": false,\n  \"null\": null,\n  \"number\": 23,\n  \"string\": \"Hello, world!\"\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_literal_json.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n\n    std::cout << std::setw(2) << j << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_literal_json.output",
    "content": "{\n  \"answer\": 42,\n  \"hello\": \"world\"\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_literal_json_pointer.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n    auto val = j[\"/hello\"_json_pointer];\n\n    std::cout << std::setw(2) << val << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_literal_json_pointer.output",
    "content": "\"world\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_serialize.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n\n    // serialize without indentation\n    std::cout << j_object << \"\\n\\n\";\n    std::cout << j_array << \"\\n\\n\";\n\n    // serialize with indentation\n    std::cout << std::setw(4) << j_object << \"\\n\\n\";\n    std::cout << std::setw(2) << j_array << \"\\n\\n\";\n    std::cout << std::setw(1) << std::setfill('\\t') << j_object << \"\\n\\n\";\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operator_serialize.output",
    "content": "{\"one\":1,\"two\":2}\n\n[1,2,4,8,16]\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n[\n  1,\n  2,\n  4,\n  8,\n  16\n]\n\n{\n\t\"one\": 1,\n\t\"two\": 2\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__key_type.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"] << \"\\n\\n\";\n\n    // change element with key \"three\"\n    object[\"three\"] = 3;\n\n    // output changed array\n    std::cout << std::setw(4) << object << \"\\n\\n\";\n\n    // mention nonexisting key\n    object[\"four\"];\n\n    // write to nonexisting key\n    object[\"five\"][\"really\"][\"nested\"] = true;\n\n    // output changed object\n    std::cout << std::setw(4) << object << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__key_type.output",
    "content": "2\n\n{\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n\n{\n    \"five\": {\n        \"really\": {\n            \"nested\": true\n        }\n    },\n    \"four\": null,\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__key_type_const.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    const json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"] << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__key_type_const.output",
    "content": "2\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__size_type.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json array = {1, 2, 3, 4, 5};\n\n    // output element at index 3 (fourth element)\n    std::cout << array[3] << '\\n';\n\n    // change last element to 6\n    array[array.size() - 1] = 6;\n\n    // output changed array\n    std::cout << array << '\\n';\n\n    // write beyond array limit\n    array[10] = 11;\n\n    // output changed array\n    std::cout << array << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__size_type.output",
    "content": "4\n[1,2,3,4,6]\n[1,2,3,4,6,null,null,null,null,null,11]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__size_type_const.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    const json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorarray__size_type_const.output",
    "content": "\"third\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorjson_pointer.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j[\"/number\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j[\"/string\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j[\"/array\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j[\"/array/1\"_json_pointer] << '\\n';\n\n    // writing access\n\n    // change the string\n    j[\"/string\"_json_pointer] = \"bar\";\n    // output the changed string\n    std::cout << j[\"string\"] << '\\n';\n\n    // \"change\" a nonexisting object entry\n    j[\"/boolean\"_json_pointer] = true;\n    // output the changed object\n    std::cout << j << '\\n';\n\n    // change an array element\n    j[\"/array/1\"_json_pointer] = 21;\n    // \"change\" an array element with nonexisting index\n    j[\"/array/4\"_json_pointer] = 44;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n\n    // \"change\" the array element past the end\n    j[\"/array/-\"_json_pointer] = 55;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorjson_pointer.output",
    "content": "1\n\"foo\"\n[1,2]\n2\n\"bar\"\n{\"array\":[1,2],\"boolean\":true,\"number\":1,\"string\":\"bar\"}\n[1,21,null,null,44]\n[1,21,null,null,44,55]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorjson_pointer_const.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    const json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j[\"/number\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j[\"/string\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j[\"/array\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j[\"/array/1\"_json_pointer] << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/operatorjson_pointer_const.output",
    "content": "1\n\"foo\"\n[1,2]\n2\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/ordered_map.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\n// simple output function\ntemplate<typename Map>\nvoid output(const char* prefix, const Map& m)\n{\n    std::cout << prefix << \" = { \";\n    for (auto& element : m)\n    {\n        std::cout << element.first << \":\" << element.second << ' ';\n    }\n    std::cout << \"}\" << std::endl;\n}\n\nint main()\n{\n    // create and fill two maps\n    nlohmann::ordered_map<std::string, std::string> m_ordered;\n    m_ordered[\"one\"] = \"eins\";\n    m_ordered[\"two\"] = \"zwei\";\n    m_ordered[\"three\"] = \"drei\";\n\n    std::map<std::string, std::string> m_std;\n    m_std[\"one\"] = \"eins\";\n    m_std[\"two\"] = \"zwei\";\n    m_std[\"three\"] = \"drei\";\n\n    // output: m_ordered is ordered by insertion order, m_std is ordered by key\n    output(\"m_ordered\", m_ordered);\n    output(\"m_std\", m_std);\n\n    // erase and re-add \"one\" key\n    m_ordered.erase(\"one\");\n    m_ordered[\"one\"] = \"eins\";\n\n    m_std.erase(\"one\");\n    m_std[\"one\"] = \"eins\";\n\n    // output: m_ordered shows newly added key at the end; m_std is again ordered by key\n    output(\"m_ordered\", m_ordered);\n    output(\"m_std\", m_std);\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/ordered_map.output",
    "content": "m_ordered = { one:eins two:zwei three:drei }\nm_std = { one:eins three:drei two:zwei }\nm_ordered = { two:zwei three:drei one:eins }\nm_std = { one:eins three:drei two:zwei }\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/other_error.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // executing a failing JSON Patch operation\n        json value = R\"({\n            \"best_biscuit\": {\n                \"name\": \"Oreo\"\n            }\n        })\"_json;\n        json patch = R\"([{\n            \"op\": \"test\",\n            \"path\": \"/best_biscuit/name\",\n            \"value\": \"Choco Leibniz\"\n        }])\"_json;\n        value.patch(patch);\n    }\n    catch (json::other_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << std::endl;\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/other_error.output",
    "content": "message: [json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/best_biscuit/name\",\"value\":\"Choco Leibniz\"}\nexception id: 501\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/out_of_range.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for an invalid index\n        json j = {1, 2, 3, 4};\n        j.at(4) = 10;\n    }\n    catch (json::out_of_range& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << std::endl;\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/out_of_range.output",
    "content": "message: [json.exception.out_of_range.401] array index 4 is out of range\nexception id: 401\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__allow_exceptions.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // an invalid JSON text\n    std::string text = R\"(\n    {\n        \"key\": \"value without closing quotes\n    }\n    )\";\n\n    // parse with exceptions\n    try\n    {\n        json j = json::parse(text);\n    }\n    catch (json::parse_error& e)\n    {\n        std::cout << e.what() << std::endl;\n    }\n\n    // parse without exceptions\n    json j = json::parse(text, nullptr, false);\n\n    if (j.is_discarded())\n    {\n        std::cout << \"the input is invalid JSON\" << std::endl;\n    }\n    else\n    {\n        std::cout << \"the input is valid JSON: \" << j << std::endl;\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__allow_exceptions.output",
    "content": "[json.exception.parse_error.101] parse error at line 4, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"value without closing quotes<U+000A>'\nthe input is invalid JSON\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__array__parser_callback_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    char text[] = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__array__parser_callback_t.output",
    "content": "{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__contiguouscontainer__parser_callback_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a JSON text given as std::vector\n    std::vector<std::uint8_t> text = {'[', '1', ',', '2', ',', '3', ']', '\\0'};\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__contiguouscontainer__parser_callback_t.output",
    "content": "[\n    1,\n    2,\n    3\n]\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__istream__parser_callback_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    auto text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // fill a stream with JSON text\n    std::stringstream ss;\n    ss << text;\n\n    // parse and serialize JSON\n    json j_complete = json::parse(ss);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // fill a stream with JSON text\n    ss.clear();\n    ss << text;\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(ss, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__istream__parser_callback_t.output",
    "content": "{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__iterator_pair.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a JSON text given an input with other values\n    std::vector<std::uint8_t> input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'};\n\n    // parse and serialize JSON\n    json j_complete = json::parse(input.begin(), input.begin() + 7);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__iterator_pair.link",
    "content": "<a target=\"_blank\" href=\"https://wandbox.org/permlink/hUJYo1HWmfTBLMGn\"><b>online</b></a>"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__iterator_pair.output",
    "content": "[\n    1,\n    2,\n    3\n]\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__pointers.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a JSON text given as string that is not null-terminated\n    const char* ptr = \"[1,2,3]another value\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(ptr, ptr + 7);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__pointers.link",
    "content": "<a target=\"_blank\" href=\"https://wandbox.org/permlink/AWbpa8e1xRV3y4MM\"><b>online</b></a>"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__pointers.output",
    "content": "[\n    1,\n    2,\n    3\n]\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__string__parser_callback_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    auto text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(text, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse__string__parser_callback_t.output",
    "content": "{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse_error.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // parsing input with a syntax error\n        json::parse(\"[1,2,3,]\");\n    }\n    catch (json::parse_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n'\n                  << \"byte position of error: \" << e.byte << std::endl;\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/parse_error.output",
    "content": "message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nexception id: 101\nbyte position of error: 8\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/patch.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"baz\": \"qux\",\n          \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the patch\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ]\n    )\"_json;\n\n    // apply the patch\n    json patched_doc = doc.patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << doc << \"\\n\\n\"\n              << std::setw(4) << patched_doc << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/patch.output",
    "content": "{\n    \"baz\": \"qux\",\n    \"foo\": \"bar\"\n}\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/push_back.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.push_back(6);\n    array += 7;\n    null += \"first\";\n    null += \"second\";\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/push_back.output",
    "content": "[1,2,3,4,5]\nnull\n[1,2,3,4,5,6,7]\n[\"first\",\"second\"]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/push_back__initializer_list.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values:\n    object.push_back({\"three\", 3});  // object is extended\n    object += {\"four\", 4};           // object is extended\n    null.push_back({\"five\", 5});     // null is converted to array\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // would throw:\n    //object.push_back({1, 2, 3});\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/push_back__initializer_list.output",
    "content": "{\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n[[\"five\",5]]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/push_back__object_t__value.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    object.push_back(json::object_t::value_type(\"three\", 3));\n    object += json::object_t::value_type(\"four\", 4);\n    null += json::object_t::value_type(\"A\", \"a\");\n    null += json::object_t::value_type(\"B\", \"b\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/push_back__object_t__value.output",
    "content": "{\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n{\"A\":\"a\",\"B\":\"b\"}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/rbegin.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-beginning\n    json::reverse_iterator it = array.rbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/rbegin.output",
    "content": "5\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/rend.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-end\n    json::reverse_iterator it = array.rend();\n\n    // increment the iterator to point to the first element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/rend.output",
    "content": "1\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/sax_parse.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; not inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"value: null\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"value: \" + std::string(val ? \"true\" : \"false\"));\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"value: \" + std::to_string(val));\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"value: \" + std::to_string(val));\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"value: \" + s);\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"value: \" + val);\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start: object\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end: object\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start: array\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end: array\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key: \" + val);\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"error: \" + std::string(ex.what()));\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    auto text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793],\n            \"Distance\": 12.723374634\n        }\n    }\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse and serialize JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << \"(\" << event << \") \";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/sax_parse.output",
    "content": "(start: object) (key: Image) (start: object) (key: Width) (value: 800) (key: Height) (value: 600) (key: Title) (value: View from 15th Floor) (key: Thumbnail) (start: object) (key: Url) (value: http://www.example.com/image/481989943) (key: Height) (value: 125) (key: Width) (value: 100) (end: object) (key: Animated) (value: false) (key: IDs) (start: array) (value: 116) (value: 943) (value: 234) (value: 38793) (end: array) (key: Distance) (value: 12.723374634) (end: object) (end: object) \nresult: true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/size.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call size()\n    std::cout << j_null.size() << '\\n';\n    std::cout << j_boolean.size() << '\\n';\n    std::cout << j_number_integer.size() << '\\n';\n    std::cout << j_number_float.size() << '\\n';\n    std::cout << j_object.size() << '\\n';\n    std::cout << j_object_empty.size() << '\\n';\n    std::cout << j_array.size() << '\\n';\n    std::cout << j_array_empty.size() << '\\n';\n    std::cout << j_string.size() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/size.output",
    "content": "0\n1\n1\n1\n2\n0\n5\n0\n1\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/std_hash.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << \"hash(null) = \" << std::hash<json> {}(json(nullptr)) << '\\n'\n              << \"hash(false) = \" << std::hash<json> {}(json(false)) << '\\n'\n              << \"hash(0) = \" << std::hash<json> {}(json(0)) << '\\n'\n              << \"hash(0U) = \" << std::hash<json> {}(json(0U)) << '\\n'\n              << \"hash(\\\"\\\") = \" << std::hash<json> {}(json(\"\")) << '\\n'\n              << \"hash({}) = \" << std::hash<json> {}(json::object()) << '\\n'\n              << \"hash([]) = \" << std::hash<json> {}(json::array()) << '\\n'\n              << \"hash({\\\"hello\\\": \\\"world\\\"}) = \" << std::hash<json> {}(\"{\\\"hello\\\": \\\"world\\\"}\"_json)\n              << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/std_hash.output",
    "content": "hash(null) = 2654435769\nhash(false) = 2654436030\nhash(0) = 2654436095\nhash(0U) = 2654436156\nhash(\"\") = 11160318156688833227\nhash({}) = 2654435832\nhash([]) = 2654435899\nhash({\"hello\": \"world\"}) = 3701319991624763853\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/std_swap.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j1 = {{\"one\", 1}, {\"two\", 2}};\n    json j2 = {1, 2, 4, 8, 16};\n\n    std::cout << \"j1 = \" << j1 << \" | j2 = \" << j2 << '\\n';\n\n    // swap values\n    std::swap(j1, j2);\n\n    std::cout << \"j1 = \" << j1 << \" | j2 = \" << j2 << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/std_swap.output",
    "content": "j1 = {\"one\":1,\"two\":2} | j2 = [1,2,4,8,16]\nj1 = [1,2,4,8,16] | j2 = {\"one\":1,\"two\":2}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/string_t.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::string, json::string_t>::value << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/string_t.output",
    "content": "true\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__array_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = {{\"array\", {1, 2, 3, 4}}};\n\n    // create an array_t\n    json::array_t array = {\"Snap\", \"Crackle\", \"Pop\"};\n\n    // swap the array stored in the JSON value\n    value[\"array\"].swap(array);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"array = \" << array << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__array_t.output",
    "content": "value = {\"array\":[\"Snap\",\"Crackle\",\"Pop\"]}\narray = [1,2,3,4]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__binary_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a binary value\n    json value = json::binary({1, 2, 3});\n\n    // create a binary_t\n    json::binary_t binary = {{4, 5, 6}};\n\n    // swap the object stored in the JSON value\n    value.swap(binary);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"binary = \" << json(binary) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__binary_t.output",
    "content": "value = {\"bytes\":[4,5,6],\"subtype\":null}\nbinary = {\"bytes\":[1,2,3],\"subtype\":null}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__object_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = { {\"translation\", {{\"one\", \"eins\"}, {\"two\", \"zwei\"}}} };\n\n    // create an object_t\n    json::object_t object = {{\"cow\", \"Kuh\"}, {\"dog\", \"Hund\"}};\n\n    // swap the object stored in the JSON value\n    value[\"translation\"].swap(object);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"object = \" << object << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__object_t.output",
    "content": "value = {\"translation\":{\"cow\":\"Kuh\",\"dog\":\"Hund\"}}\nobject = {\"one\":\"eins\",\"two\":\"zwei\"}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__reference.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create two JSON values\n    json j1 = {1, 2, 3, 4, 5};\n    json j2 = {{\"pi\", 3.141592653589793}, {\"e\", 2.718281828459045}};\n\n    // swap the values\n    j1.swap(j2);\n\n    // output the values\n    std::cout << \"j1 = \" << j1 << '\\n';\n    std::cout << \"j2 = \" << j2 << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__reference.output",
    "content": "j1 = {\"e\":2.718281828459045,\"pi\":3.141592653589793}\nj2 = [1,2,3,4,5]\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__string_t.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = { \"the good\", \"the bad\", \"the ugly\" };\n\n    // create string_t\n    json::string_t string = \"the fast\";\n\n    // swap the object stored in the JSON value\n    value[1].swap(string);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"string = \" << string << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/swap__string_t.output",
    "content": "value = [\"the good\",\"the fast\",\"the ugly\"]\nstring = the bad\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_bson.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to BSON\n    std::vector<std::uint8_t> v = json::to_bson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << \" \";\n    }\n    std::cout << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_bson.output",
    "content": "0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 \n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_cbor.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to CBOR\n    std::vector<std::uint8_t> v = json::to_cbor(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << \" \";\n    }\n    std::cout << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_cbor.output",
    "content": "0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_msgpack.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to MessagePack\n    std::vector<std::uint8_t> v = json::to_msgpack(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << \" \";\n    }\n    std::cout << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_msgpack.output",
    "content": "0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_string.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\nusing std::to_string;\n\nint main()\n{\n    // create values\n    json j = {{\"one\", 1}, {\"two\", 2}};\n    int i = 42;\n\n    // use ADL to select best to_string function\n    auto j_str = to_string(j);  // calling nlohmann::to_string\n    auto i_str = to_string(i);  // calling std::to_string\n\n    // serialize without indentation\n    std::cout << j_str << \"\\n\\n\"\n              << i_str << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_string.output",
    "content": "{\"one\":1,\"two\":2}\n\n42\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_ubjson.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// function to print UBJSON's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << (char)byte;\n    }\n    else\n    {\n        std::cout << (int)byte;\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to UBJSON\n    std::vector<std::uint8_t> v = json::to_ubjson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << std::endl;\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to UBJSON using default representation\n    std::vector<std::uint8_t> v_array = json::to_ubjson(array);\n    // serialize it to UBJSON using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_ubjson(array, true);\n    // serialize it to UBJSON using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_ubjson(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << std::endl;\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << std::endl;\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/to_ubjson.output",
    "content": "{i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/type.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type()\n    std::cout << std::boolalpha;\n    std::cout << (j_null.type() == json::value_t::null) << '\\n';\n    std::cout << (j_boolean.type() == json::value_t::boolean) << '\\n';\n    std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\\n';\n    std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\\n';\n    std::cout << (j_number_float.type() == json::value_t::number_float) << '\\n';\n    std::cout << (j_object.type() == json::value_t::object) << '\\n';\n    std::cout << (j_array.type() == json::value_t::array) << '\\n';\n    std::cout << (j_string.type() == json::value_t::string) << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/type.output",
    "content": "true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/type_error.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling push_back() on a string value\n        json j = \"string\";\n        j.push_back(\"another string\");\n    }\n    catch (json::type_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << std::endl;\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/type_error.output",
    "content": "message: [json.exception.type_error.308] cannot use push_back() with string\nexception id: 308\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/type_name.cpp",
    "content": "#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type_name()\n    std::cout << j_null << \" is a \" << j_null.type_name() << '\\n';\n    std::cout << j_boolean << \" is a \" << j_boolean.type_name() << '\\n';\n    std::cout << j_number_integer << \" is a \" << j_number_integer.type_name() << '\\n';\n    std::cout << j_number_unsigned << \" is a \" << j_number_unsigned.type_name() << '\\n';\n    std::cout << j_number_float << \" is a \" << j_number_float.type_name() << '\\n';\n    std::cout << j_object << \" is an \" << j_object.type_name() << '\\n';\n    std::cout << j_array << \" is an \" << j_array.type_name() << '\\n';\n    std::cout << j_string << \" is a \" << j_string.type_name() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/type_name.output",
    "content": "null is a null\ntrue is a boolean\n-17 is a number\n42 is a number\n23.42 is a number\n{\"one\":1,\"two\":2} is an object\n[1,2,4,8,16] is an array\n\"Hello, world\" is a string\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/unflatten.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create JSON value\n    json j_flattened =\n    {\n        {\"/answer/everything\", 42},\n        {\"/happy\", true},\n        {\"/list/0\", 1},\n        {\"/list/1\", 0},\n        {\"/list/2\", 2},\n        {\"/name\", \"Niels\"},\n        {\"/nothing\", nullptr},\n        {\"/object/currency\", \"USD\"},\n        {\"/object/value\", 42.99},\n        {\"/pi\", 3.141}\n    };\n\n    // call unflatten()\n    std::cout << std::setw(4) << j_flattened.unflatten() << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/unflatten.output",
    "content": "{\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/update.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2);\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2, true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/update.output",
    "content": "{\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/update__range.cpp",
    "content": "#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2.begin(), o2.end());\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2.begin(), o2.end(), true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/examples/update__range.output",
    "content": "{\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/index.md",
    "content": "# JSON for Modern C++\n\nThese pages contain the API documentation of JSON for Modern C++, a C++11 header-only JSON class.\n\n# Contents\n\n- Classes\n  - @link nlohmann::basic_json `basic_json`@endlink -- class template for JSON values\n  - @link nlohmann::json `json`@endlink -- the default specialization of `basic_json`, defined as `basic_json<>`\n- [Functions](functions_func.html)\n  - object inspection\n    - @link nlohmann::basic_json::dump dump @endlink -- value serialization\n    - @link nlohmann::basic_json::type type @endlink -- type of the value\n    - @link nlohmann::basic_json::is_primitive is_primitive @endlink,\n      @link nlohmann::basic_json::is_structured is_structured @endlink,\n      @link nlohmann::basic_json::is_null is_null @endlink,\n      @link nlohmann::basic_json::is_boolean is_boolean @endlink,\n      @link nlohmann::basic_json::is_number is_number @endlink,\n      @link nlohmann::basic_json::is_number_integer is_number_integer @endlink,\n      @link nlohmann::basic_json::is_number_unsigned is_number_unsigned @endlink,\n      @link nlohmann::basic_json::is_number_float is_number_float @endlink,\n      @link nlohmann::basic_json::is_object is_object @endlink,\n      @link nlohmann::basic_json::is_array is_array @endlink,\n      @link nlohmann::basic_json::is_string is_string @endlink,\n      @link nlohmann::basic_json::is_discarded is_discarded @endlink,\n      @link nlohmann::basic_json::is_binary is_binary @endlink -- check for value type\n    - @link nlohmann::basic_json::operator value_t() const operator value_t @endlink -- type of the value (implicit conversion)\n  - value access\n    - @link nlohmann::basic_json::get get @endlink -- get a value\n    - @link nlohmann::basic_json::get_ptr get_ptr @endlink -- get a value pointer\n    - @link nlohmann::basic_json::get_ref get_ref @endlink -- get a value reference\n    - @link nlohmann::basic_json::get_binary get_binary @endlink -- get a binary value\n    - @link nlohmann::basic_json::operator ValueType() const operator ValueType @endlink -- get a value (implicit conversion)\n    - @link nlohmann::basic_json::value value @endlink -- get a value from an object and return default value if key is not present\n  - exceptions\n    - @link nlohmann::basic_json::parse_error parse_error @endlink for exceptions indicating a parse error\n    - @link nlohmann::basic_json::invalid_iterator invalid_iterator @endlink for exceptions indicating errors with iterators\n    - @link nlohmann::basic_json::type_error type_error @endlink for exceptions indicating executing a member function with a wrong type\n    - @link nlohmann::basic_json::out_of_range out_of_range @endlink for exceptions indicating access out of the defined range\n    - @link nlohmann::basic_json::other_error other_error @endlink for exceptions indicating other library errors\n  - lexicographical comparison operators\n    - @link nlohmann::basic_json::operator== operator== @endlink\n    - @link nlohmann::basic_json::operator!= operator!= @endlink\n    - @link nlohmann::basic_json::operator< operator<= @endlink\n    - @link nlohmann::basic_json::operator<= operator< @endlink\n    - @link nlohmann::basic_json::operator> operator> @endlink\n    - @link nlohmann::basic_json::operator>= operator>= @endlink\n  - serialization\n    - @link nlohmann::basic_json::dump dump @endlink serialize to string\n    - @link nlohmann::basic_json::operator<<(std::ostream&, const basic_json &) operator<< @endlink serialize to stream\n  - deserialization / parsing\n    - @link nlohmann::basic_json::parse parse @endlink parse from input (string, file, etc.) and return JSON value\n    - @link nlohmann::basic_json::sax_parse sax_parse @endlink parse from input (string, file, etc.) and generate SAX events\n    - @link nlohmann::basic_json::operator>>(std::istream&, basic_json&) operator>> @endlink parse from stream\n    - @link nlohmann::basic_json::accept accept @endlink check for syntax errors without parsing\n    - @link nlohmann::json_sax SAX interface @endlink define a user-defined SAX event consumer\n    - @link nlohmann::basic_json::parser_callback_t callback interface @endlink register a callback to the parse function\n  - [binary formats](binary_formats.md):\n    - CBOR: @link nlohmann::basic_json::from_cbor from_cbor @endlink / @link nlohmann::basic_json::to_cbor to_cbor @endlink\n    - MessagePack: @link nlohmann::basic_json::from_msgpack from_msgpack @endlink / @link nlohmann::basic_json::to_msgpack to_msgpack @endlink\n    - UBJSON: @link nlohmann::basic_json::from_ubjson from_ubjson @endlink / @link nlohmann::basic_json::to_ubjson to_ubjson @endlink\n    - BSON: @link nlohmann::basic_json::from_bson from_bson @endlink / @link nlohmann::basic_json::to_bson to_bson @endlink\n- Types\n  - @link nlohmann::basic_json::array_t arrays @endlink\n  - @link nlohmann::basic_json::object_t objects @endlink\n  - @link nlohmann::basic_json::string_t strings @endlink\n  - @link nlohmann::basic_json::boolean_t booleans @endlink\n  - numbers\n    - @link nlohmann::basic_json::number_integer_t signed integers @endlink\n    - @link nlohmann::basic_json::number_unsigned_t unsigned integers @endlink\n    - @link nlohmann::basic_json::number_float_t floating-point @endlink\n  - @link nlohmann::basic_json::binary_t binary values @endlink\n- further JSON standards\n  - @link nlohmann::json_pointer JSON Pointer @endlink (RFC 6901)\n  - @link nlohmann::basic_json::patch JSON Patch @endlink (RFC 6902)\n  - @link nlohmann::basic_json::merge_patch JSON Merge Patch @endlink (RFC 7396)\n\n# Container function overview\n\nThe container functions known from STL have been extended to support the different value types from JSON. However, not all functions can be applied to all value types. Note that the signature of some functions differ between the types; for instance, `at` may be called with either a string to address a key in an object or with an integer to address a value in an array.\n\nNote that this table only lists those exceptions thrown due to the type. For instance, the @link nlohmann::basic_json::at(const typename object_t::key_type & key) `at` @endlink function will always throw a @link nlohmann::basic_json::type_error `json::type_error` @endlink exception when called for a string type. When called for an array, it *may* throw an @link nlohmann::basic_json::out_of_range `json::out_of_range` @endlink exception if the passed index is invalid.\n\n<table>\n  <tr>\n    <th rowspan=\"2\">group</th>\n    <th rowspan=\"2\">function</th>\n    <th colspan=\"6\">JSON value type</th>\n  </tr>\n  <tr>\n    <th>object</th>\n    <th>array</th>\n    <th>string</th>\n    <th>number</th>\n    <th>boolean</th>\n    <th>null</th>\n  </tr>\n  <tr>\n    <td rowspan=\"8\">iterators</td>\n    <td>`begin`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::begin `begin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::begin `begin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::begin `begin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::begin `begin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::begin `begin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::begin `begin` @endlink (returns `end()`)</td>\n  </tr>\n  <tr>\n    <td>`cbegin`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cbegin `cbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cbegin `cbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cbegin `cbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cbegin `cbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cbegin `cbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cbegin `cbegin` @endlink (returns `cend()`)</td>\n  </tr>\n  <tr>\n    <td>`end`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::end `end` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::end `end` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::end `end` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::end `end` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::end `end` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::end `end` @endlink</td>\n  </tr>\n  <tr>\n    <td>`cend`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cend `cend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cend `cend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cend `cend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cend `cend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cend `cend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::cend `cend` @endlink</td>\n  </tr>\n  <tr>\n    <td>`rbegin`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rbegin `rbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rbegin `rbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rbegin `rbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rbegin `rbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rbegin `rbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rbegin `rbegin` @endlink</td>\n  </tr>\n  <tr>\n    <td>`crbegin`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crbegin `crbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crbegin `crbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crbegin `crbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crbegin `crbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crbegin `crbegin` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crbegin `crbegin` @endlink</td>\n  </tr>\n  <tr>\n    <td>`rend`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rend `rend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rend `rend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rend `rend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rend `rend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rend `rend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::rend `rend` @endlink</td>\n  </tr>\n  <tr>\n    <td>`crend`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crend `crend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crend `crend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crend `crend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crend `crend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crend `crend` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::crend `crend` @endlink</td>\n  </tr>\n  <tr>\n    <td rowspan=\"4\">element<br>access</td>\n    <td>`at`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::at(const typename object_t::key_type & key) `at` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::at(size_type) `at` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>\n  </tr>\n  <tr>\n    <td>`operator[]`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::operator[](const typename object_t::key_type &key) `operator[]` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::operator[](size_type) `operator[]` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (305)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (305)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (305)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::operator[](const typename object_t::key_type & key) `operator[]` @endlink (creates object)<br>@link nlohmann::basic_json::operator[](size_type) `operator[]` @endlink (creates array)</td>\n  </tr>\n  <tr>\n    <td>`front`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::front `front` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::front `front` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::front `front` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::front `front` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::front `front` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::invalid_iterator `json::invalid_iterator` @endlink (214)</td>\n  </tr>\n  <tr>\n    <td>`back`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::back `back` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::back `back` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::back `back` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::back `back` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::back `back` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::invalid_iterator `json::invalid_iterator` @endlink (214)</td>\n  </tr>\n  <tr>\n    <td rowspan=\"3\">capacity</td>\n    <td>`empty`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::empty `empty` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::empty `empty` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::empty `empty` @endlink (returns `false`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::empty `empty` @endlink (returns `false`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::empty `empty` @endlink (returns `false`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::empty `empty` @endlink (returns `true`)</td>\n  </tr>\n  <tr>\n    <td>`size`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::size `size` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::size `size` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::size `size` @endlink (returns `1`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::size `size` @endlink (returns `1`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::size `size` @endlink (returns `1`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::size `size` @endlink (returns `0`)</td>\n  </tr>\n  <tr>\n    <td>`max_size_`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::max_size `max_size` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::max_size `max_size` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::max_size `max_size` @endlink (returns `1`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::max_size `max_size` @endlink (returns `1`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::max_size `max_size` @endlink (returns `1`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::max_size `max_size` @endlink (returns `0`)</td>\n  </tr>\n  <tr>\n    <td rowspan=\"7\">modifiers</td>\n    <td>`clear`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::clear `clear` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::clear `clear` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::clear `clear` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::clear `clear` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::clear `clear` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::clear `clear` @endlink</td>\n  </tr>\n  <tr>\n    <td>`insert`</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::insert `insert` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>\n  </tr>\n  <tr>\n    <td>`erase`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::erase `erase` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::erase `erase` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::erase `erase` @endlink (converts to null)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::erase `erase` @endlink (converts to null)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::erase `erase` @endlink (converts to null)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (307)</td>\n  </tr>\n  <tr>\n    <td>`push_back`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::push_back(const typename object_t::value_type & val) `push_back` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::push_back(const nlohmann::basic_json &) `push_back` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (308)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (308)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (308)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::push_back(const typename object_t::value_type & val) `push_back` @endlink (creates object)<br>@link nlohmann::basic_json::push_back(const nlohmann::basic_json &) `push_back` @endlink (creates array)</td>\n  </tr>\n  <tr>\n    <td>`emplace` / `emplace_back`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::emplace() `emplace` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::emplace_back() `emplace_back` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (311)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (311)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (311)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::emplace() `emplace` @endlink (creates object)<br>@link nlohmann::basic_json::emplace_back() `emplace_back` @endlink (creates array)</td>\n  </tr>\n  <tr>\n    <td>`update`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::update() `update` @endlink</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>\n    <td class=\"nok_throws\">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>\n  </tr>\n  <tr>\n    <td>`swap`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::swap `swap` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::swap `swap` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::swap `swap` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::swap `swap` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::swap `swap` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::swap `swap` @endlink</td>\n  </tr>\n  <tr>\n    <td rowspan=\"3\">lookup</td>\n    <td>`find`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::find `find` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::find `find` @endlink (returns `end()`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::find `find` @endlink (returns `end()`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::find `find` @endlink (returns `end()`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::find `find` @endlink (returns `end()`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::find `find` @endlink (returns `end()`)</td>\n  </tr>\n  <tr>\n    <td>`count`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::count `count` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::count `count` @endlink (returns `0`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::count `count` @endlink (returns `0`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::count `count` @endlink (returns `0`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::count `count` @endlink (returns `0`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::count `count` @endlink (returns `0`)</td>\n  </tr>\n  <tr>\n    <td>`contains`</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::contains `contains` @endlink</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::contains `contains` @endlink (returns `false`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::contains `contains` @endlink (returns `false`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::contains `contains` @endlink (returns `false`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::contains `contains` @endlink (returns `false`)</td>\n    <td class=\"ok_green\">@link nlohmann::basic_json::contains `contains` @endlink (returns `false`)</td>\n  </tr>\n</table>\n\n@copyright Copyright &copy; 2013-2022 Niels Lohmann. The code is licensed under the [MIT License](http://opensource.org/licenses/MIT).\n\n@author [Niels Lohmann](http://nlohmann.me)\n@see https://github.com/nlohmann/json to download the source code\n\n@version 3.10.5\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/Makefile",
    "content": "# serve the site locally\nserve: prepare_files\n\tvenv/bin/mkdocs serve\n\nbuild: prepare_files\n\tvenv/bin/mkdocs build\n\n# create files that are not versioned inside the mkdocs folder\nprepare_files: clean\n\t# create subfolders\n\tmkdir docs/examples\n\t# copy images\n\tcp -vr ../json.gif docs/images\n\t# copy examples\n\tcp -vr ../examples/*.cpp ../examples/*.output docs/examples\n\n# clean subfolders\nclean:\n\trm -fr docs/images/json.gif docs/examples\n\n# publish site to GitHub pages\npublish: prepare_files\n\tvenv/bin/mkdocs gh-deploy --clean --force\n\n# install a Python virtual environment\ninstall_venv: requirements.txt\n\tpython3 -mvenv venv\n\tvenv/bin/pip install wheel\n\tvenv/bin/pip install -r requirements.txt\n\n# uninstall the virtual environment\nuninstall_venv: clean\n\trm -fr venv\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/adl_serializer/from_json.md",
    "content": "# <small>nlohmann::adl_serializer::</small>from_json\n\n```cpp\n// (1)\ntemplate<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto from_json(BasicJsonType && j, TargetType& val) noexcept(\n    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))\n-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())\n\n// (2)\ntemplate<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto from_json(BasicJsonType && j) noexcept(\nnoexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))\n-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))\n```\n\nThis function is usually called by the [`get()`](../basic_json/get.md) function of the\n[basic_json](../basic_json) class (either explicit or via conversion operators).\n\n1. This function is chosen for default-constructible value types.\n2. This function is chosen for value types which are not default-constructible.\n\n## Parameters\n\n`j` (in)\n:   JSON value to read from\n\n`val` (out)\n:   value to write to\n\n## Return value\n\nCopy of the JSON value, converted to `ValueType`\n\n!!! note\n\n    This documentation page is a stub.\n\n## Version history\n\n- Added in version 2.1.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/adl_serializer/index.md",
    "content": "# <small>nlohmann::</small>adl_serializer\n\n```cpp\ntemplate<typename, typename>\nstruct adl_serializer;\n```\n\nSerializer that uses ADL ([Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)) to choose\n`to_json`/`from_json` functions from the types' namespaces.\n\nIt is implemented similar to\n\n```cpp\ntemplate<typename ValueType>\nstruct adl_serializer {\n    template<typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) {\n        // calls the \"to_json\" method in T's namespace\n    }\n\n    template<typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n        // same thing, but with the \"from_json\" method\n    }\n};\n```\n\n## Member functions\n\n- [**from_json**](from_json.md) - convert a JSON value to any value type\n- [**to_json**](to_json.md) - convert any value type to a JSON value\n\n## Version history\n\n- Added in version 2.1.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/adl_serializer/to_json.md",
    "content": "# <small>nlohmann::adl_serializer::</small>to_json\n\n```cpp\ntemplate<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto to_json(BasicJsonType& j, TargetType && val) noexcept(\n    noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))\n-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())\n```\n\nThis function is usually called by the constructors of the [basic_json](../basic_json) class.\n\n## Parameters\n\n`j` (out)\n:   JSON value to write to\n\n`val` (in)\n:   value to read from\n\n!!! note\n\n    This documentation page is a stub.\n\n## Version history\n\n- Added in version 2.1.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/accept.md",
    "content": "# <small>nlohmann::basic_json::</small>accept\n\n```cpp\n// (1)\ntemplate<typename InputType>\nstatic bool accept(InputType&& i,\n                   const bool ignore_comments = false);\n\n// (2)\ntemplate<typename IteratorType>\nstatic bool accept(IteratorType first, IteratorType last,\n                   const bool ignore_comments = false);\n```\n\nChecks whether the input is valid JSON.\n\n1. Reads from a compatible input.\n2. Reads from a pair of character iterators\n    \n    The value_type of the iterator must be an integral type with size of 1, 2 or 4 bytes, which will be interpreted\n    respectively as UTF-8, UTF-16 and UTF-32.\n    \nUnlike the [`parse`](parse.md) function, this function neither throws an exception in case of invalid JSON input\n(i.e., a parse error) nor creates diagnostic information.\n\n## Template parameters\n\n`InputType`\n:   A compatible input, for instance:\n    \n    - an `std::istream` object\n    - a `FILE` pointer\n    - a C-style array of characters\n    - a pointer to a null-terminated string of single byte characters\n    - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.\n\n`IteratorType`\n:   a compatible iterator type\n\n## Parameters\n\n`i` (in)\n:   Input to parse from.\n\n`ignore_comments` (in)\n:   whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error\n    (`#!cpp false`); (optional, `#!cpp false` by default)\n\n`first` (in)\n:   iterator to start of character range\n\n`last` (in)\n:   iterator to end of character range\n\n## Return value\n\nWhether the input is valid JSON.\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the length of the input. The parser is a predictive LL(1) parser.\n\n## Notes\n\n(1) A UTF-8 byte order mark is silently ignored.\n\n## Examples\n\n??? example\n\n    The example below demonstrates the `accept()` function reading from a string.\n\n    ```cpp\n    --8<-- \"examples/accept__string.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/accept__string.output\"\n    ```\n\n## See also\n\n- [parse](parse.md) - deserialize from a compatible input\n- [operator>>](operator_gtgt.md) - deserialize from stream\n\n## Version history\n\n- Added in version 3.0.0.\n- Ignoring comments via `ignore_comments` added in version 3.9.0.\n\n!!! warning \"Deprecation\"\n\n    Overload (2) replaces calls to `accept` with a pair of iterators as their first parameter which has been\n    deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n    `#!cpp accept({ptr, ptr+len}, ...);` with `#!cpp accept(ptr, ptr+len, ...);`.\n\n    You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated\n    function.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/array.md",
    "content": "# <small>nlohmann::basic_json::</small>array\n\n```cpp\nstatic basic_json array(initializer_list_t init = {});\n```\n\nCreates a JSON array value from a given initializer list. That is, given a list of values `a, b, c`, creates the JSON\nvalue `#!json [a, b, c]`. If the initializer list is empty, the empty array `#!json []` is created.\n\n## Parameters\n\n`init` (in)\n:   initializer list with JSON values to create an array from (optional)\n\n## Return value\n\nJSON array value\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the size of `init`.\n\n## Notes\n\nThis function is only needed to express two edge cases that cannot be realized with the initializer list constructor\n([`basic_json(initializer_list_t, bool, value_t)`](basic_json.md)). These cases are:\n\n1. creating an array whose elements are all pairs whose first element is a string -- in this case, the initializer list\n   constructor would create an object, taking the first elements as keys\n2. creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty\n   object\n\n## Examples\n\n??? example\n\n    The following code shows an example for the `array` function.\n\n    ```cpp\n    --8<-- \"examples/array.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/array.output\"\n    ```\n\n## See also\n\n- [`basic_json(initializer_list_t)`](basic_json.md) - create a JSON value from an initializer list\n- [`object`](object.md) - create a JSON object value from an initializer list\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/array_t.md",
    "content": "# <small>nlohmann::basic_json::</small>array_t\n\n```cpp\nusing array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n```\n\nThe type used to store JSON arrays.\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:\n> An array is an ordered sequence of zero or more values.\n\nTo store objects in C++, a type is defined by the template parameters explained below.\n\n## Template parameters\n\n`ArrayType`\n:   container type to store arrays (e.g., `std::vector` or `std::list`)\n\n`AllocatorType`\n:   the allocator to use for objects (e.g., `std::allocator`)\n\n## Notes\n\n#### Default type\n\nWith the default values for `ArrayType` (`std::vector`) and `AllocatorType` (`std::allocator`), the default value for\n`array_t` is:\n\n```cpp\nstd::vector<\n  basic_json, // value_type\n  std::allocator<basic_json> // allocator_type\n>\n```\n\n#### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:\n> An implementation may set limits on the maximum depth of nesting.\n\nIn this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be\nintroduced by the compiler or runtime environment. A theoretical limit can be queried by calling the\n[`max_size`](max_size.md) function of a JSON array.\n\n#### Storage\n\nArrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type\n`#!cpp array_t*` must be dereferenced.\n\n## Examples\n\n??? example\n\n    The following code shows that `array_t` is by default, a typedef to `#!cpp std::vector<nlohmann::json>`.\n     \n    ```cpp\n    --8<-- \"examples/array_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/array_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/at.md",
    "content": "# <small>nlohmann::basic_json::</small>at\n\n```cpp\n// (1)\nreference at(size_type idx);\nconst_reference at(size_type idx) const;\n\n// (2)\nreference at(const typename object_t::key_type& key);\nconst_reference at(const typename object_t::key_type& key) const;\n\n// (3)\nreference at(const json_pointer& ptr);\nconst_reference at(const json_pointer& ptr) const;\n```\n\n1. Returns a reference to the array element at specified location `idx`, with bounds checking.\n2. Returns a reference to the object element at with specified key `key`, with bounds checking.\n3. Returns a reference to the element at with specified JSON pointer `ptr`, with bounds checking.\n\n## Parameters\n\n`idx` (in)\n:   index of the element to access\n\n`key` (in)\n:   object key of the elements to remove\n    \n`ptr` (in)\n:   JSON pointer to the desired element\n    \n## Return value\n\n1. reference to the element at index `idx`\n2. reference to the element at key `key`\n3. reference to the element pointed to by `ptr`\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the JSON value is not an array;\n      in this case, calling `at` with an index makes no sense. See example below.\n    - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if the index `idx` is out of\n      range of the array; that is, `idx >= size()`. See example below.\n2. The function can throw the following exceptions:\n    - Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the JSON value is not an object;\n      in this case, calling `at` with a key makes no sense. See example below.\n    - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if the key `key` is not\n      stored in the object; that is, `find(key) == end()`. See example below.\n3. The function can throw the following exceptions:\n    - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in the passed\n      JSON pointer `ptr` begins with '0'. See example below.\n    - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in the passed\n      JSON pointer `ptr` is not a number. See example below.\n    - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index in the passed\n      JSON pointer `ptr` is out of range. See example below.\n    - Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index '-' is used\n      in the passed JSON pointer `ptr`. As `at` provides checked access (and no elements are implicitly inserted), the\n      index '-' is always invalid. See example below.\n    - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if the JSON pointer describes a\n      key of an object which cannot be found. See example below.\n    - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if the JSON pointer `ptr` can\n      not be resolved. See example below.\n\n## Complexity\n\n1. Constant\n2. Logarithmic in the size of the container.\n3. Constant\n\n## Examples\n\n??? example \"Example: (1) access specified array element with bounds checking\"\n\n    The example below shows how array elements can be read and written using `at()`. It also demonstrates the different\n    exceptions that can be thrown.\n    \n    ```cpp\n    --8<-- \"examples/at__size_type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/at__size_type.output\"\n    ```\n\n??? example \"Example: (1) access specified array element with bounds checking\"\n\n    The example below shows how array elements can be read using `at()`. It also demonstrates the different exceptions\n    that can be thrown.\n        \n    ```cpp\n    --8<-- \"examples/at__size_type_const.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/at__size_type_const.output\"\n    ```\n\n??? example \"Example: (2) access specified object element with bounds checking\"\n\n    The example below shows how object elements can be read and written using `at()`. It also demonstrates the different\n    exceptions that can be thrown.\n        \n    ```cpp\n    --8<-- \"examples/at__object_t_key_type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/at__object_t_key_type.output\"\n    ```\n\n??? example \"Example (2) access specified object element with bounds checking\"\n\n    The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions\n    that can be thrown.\n        \n    ```cpp\n    --8<-- \"examples/at__object_t_key_type_const.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/at__object_t_key_type_const.output\"\n    ```\n\n??? example \"Example (3) access specified element via JSON Pointer\"\n\n    The example below shows how object elements can be read and written using `at()`. It also demonstrates the different\n    exceptions that can be thrown.\n        \n    ```cpp\n    --8<-- \"examples/at_json_pointer.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/at_json_pointer.output\"\n    ```\n\n??? example \"Example (3) access specified element via JSON Pointer\"\n\n    The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions\n    that can be thrown.\n        \n    ```cpp\n    --8<-- \"examples/at_json_pointer_const.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/at_json_pointer_const.output\"\n    ```\n\n## See also\n\n- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference\n- see [`value`](value.md) for access with default value\n\n## Version history\n\n1. Added in version 1.0.0.\n2. Added in version 1.0.0.\n3. Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/back.md",
    "content": "# <small>nlohmann::basic_json::</small>back\n\n```cpp\nreference back();\n\nconst_reference back() const;\n```\n\nReturns a reference to the last element in the container. For a JSON container `c`, the expression `c.back()` is\nequivalent to\n\n```cpp\nauto tmp = c.end();\n--tmp;\nreturn *tmp;\n```\n    \n## Return value\n\nIn case of a structured type (array or object), a reference to the last element is returned. In case of number, string,\nboolean, or binary values, a reference to the value is returned.\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n\nIf the JSON value is `#!json null`, exception\n[`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) is thrown.\n\n## Complexity\n\nConstant.\n\n## Notes\n\n!!! danger\n\n    Calling `back` on an empty array or object is undefined behavior and is **guarded by an assertion**!\n\n## Examples\n\n??? example\n\n    The following code shows an example for `back()`.\n     \n    ```cpp\n    --8<-- \"examples/back.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/back.output\"\n    ```\n\n## See also\n\n- [front](front.md) to access the first element\n\n## Version history\n\n- Added in version 1.0.0.\n- Adjusted code to return reference to binary values in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/basic_json.md",
    "content": "# <small>nlohmann::basic_json::</small>basic_json\n\n```cpp\n// (1)\nbasic_json(const value_t v);\n\n// (2)\nbasic_json(std::nullptr_t = nullptr) noexcept;\n\n// (3)\ntemplate<typename CompatibleType>\nbasic_json(CompatibleType&& val) noexcept(noexcept(\n           JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),\n                                      std::forward<CompatibleType>(val))));\n\n// (4)\ntemplate<typename BasicJsonType>\nbasic_json(const BasicJsonType& val);\n\n// (5)\nbasic_json(initializer_list_t init,\n           bool type_deduction = true,\n           value_t manual_type = value_t::array);\n\n// (6)\nbasic_json(size_type cnt, const basic_json& val);\n\n// (7)\nbasic_json(iterator first, iterator last);\nbasic_json(const_iterator first, const_iterator last);\n\n// (8)\nbasic_json(const basic_json& other);\n\n// (9)\nbasic_json(basic_json&& other) noexcept;\n```\n\n1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends\n   on the type:\n   \n    | Value type | initial value  |\n    |------------|----------------|\n    | null       | `#!json null`  |\n    | boolean    | `#!json false` |\n    | string     | `#!json \"\"`    |\n    | number     | `#!json 0`     |\n    | object     | `#!json {}`    |\n    | array      | `#!json []`    |\n    | binary     | empty array    |\n\n    The postcondition of this constructor can be restored by calling [`clear()`](clear.md).\n\n2. Create a `#!json null` JSON value. It either takes a null pointer as parameter (explicitly creating `#!json null`)\n   or no parameter (implicitly creating `#!json null`). The passed null pointer itself is not read -- it is only used to\n   choose the right constructor.\n\n3. This is a \"catch all\" constructor for all compatible JSON types; that is, types for which a `to_json()` method\n   exists. The constructor forwards the parameter `val` to that method (to `json_serializer<U>::to_json` method with\n   `U = uncvref_t<CompatibleType>`, to be exact).\n   \n    Template type `CompatibleType` includes, but is not limited to, the following types:\n\n    - **arrays**: [`array_t`](array_t.md) and all kinds of compatible containers such as `std::vector`, `std::deque`,\n     `std::list`, `std::forward_list`, `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, `std::multiset`,\n     and `std::unordered_multiset` with a `value_type` from which a `basic_json` value can be constructed.\n    - **objects**: [`object_t`](object_t.md) and all kinds of compatible associative containers such as `std::map`,\n     `std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with a `key_type` compatible to `string_t`\n     and a `value_type` from which a `basic_json` value can be constructed.\n    - **strings**: `string_t`, string literals, and all compatible string containers can be used.\n    - **numbers**: [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md),\n     [`number_float_t`](number_float_t.md), and all convertible number types such as `int`, `size_t`, `int64_t`, `float`\n     or `double` can be used.\n    - **boolean**: `boolean_t` / `bool` can be used.\n    - **binary**: `binary_t` / `std::vector<uint8_t>` may be used; unfortunately because string literals cannot be\n     distinguished from binary character arrays by the C++ type system, all types compatible with `const char*` will be\n     directed to the string constructor instead. This is both for backwards compatibility, and due to the fact that a\n     binary type is not a standard JSON type.\n    \n    See the examples below.\n\n4. This is a constructor for existing `basic_json` types. It does not hijack copy/move constructors, since the parameter\n   has different template arguments than the current ones.\n\n    The constructor tries to convert the internal `m_value` of the parameter.\n\n5. Creates a JSON value of type array or object from the passed initializer list `init`. In case `type_deduction` is\n   `#!cpp true` (default), the type of the JSON value to be created is deducted from the initializer list `init`\n   according to the following rules:\n   \n    1. If the list is empty, an empty JSON object value `{}` is created.\n    2. If the list consists of pairs whose first element is a string, a JSON object value is created where the first\n      elements of the pairs are treated as keys and the second elements are as values.\n    3. In all other cases, an array is created.\n    \n    The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:\n    \n    1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object.\n    2. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be\n       of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an\n       object.\n    3. In all other cases, the initializer list could not be interpreted as JSON object type, so interpreting it as JSON\n       array type is safe.\n    \n    With the rules described above, the following JSON values cannot be expressed by an initializer list:\n    \n    - the empty array (`#!json []`): use `array(initializer_list_t)` with an empty initializer list in this case\n    - arrays whose elements satisfy rule 2: use `array(initializer_list_t)` with the same initializer list in this case\n   \n    Function [`array()`](array.md) and [`object()`](object.md) force array and object creation from initializer lists,\n    respectively.\n        \n6. Constructs a JSON array value by creating `cnt` copies of a passed value. In case `cnt` is `0`, an empty array is\n   created.\n\n7. Constructs the JSON value with the contents of the range `[first, last)`. The semantics depends on the different\n   types a JSON value can have:\n\n    - In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206)\n      is thrown.\n    - In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be\n      `end()`. In this case, the value is copied. Otherwise,\n      [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown.\n    - In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or\n      `std::map`; that is, a JSON array or object is constructed from the values in the range.\n\n8. Creates a copy of a given JSON value.\n\n9. Move constructor. Constructs a JSON value with the contents of the given value `other` using move semantics. It\n   \"steals\" the resources from `other` and leaves it as JSON `#!json null` value.\n\n## Template parameters\n\n`CompatibleType`\n:   a type such that:\n\n    - `CompatibleType` is not derived from `std::istream`,\n    - `CompatibleType` is not `basic_json` (to avoid hijacking copy/move constructors),\n    - `CompatibleType` is not a different `basic_json` type (i.e. with different template arguments)\n    - `CompatibleType` is not a `basic_json` nested type (e.g., `json_pointer`, `iterator`, etc.)\n    - `json_serializer<U>` (with `U = uncvref_t<CompatibleType>`) has a `to_json(basic_json_t&, CompatibleType&&)`\n       method\n\n`BasicJsonType`:\n:   a type such that:\n\n    - `BasicJsonType` is a `basic_json` type.\n    - `BasicJsonType` has different template arguments than `basic_json_t`.\n\n`U`:\n:   `uncvref_t<CompatibleType>`\n\n## Parameters\n\n`v` (in)\n:   the type of the value to create\n\n`val` (in)\n:   the value to be forwarded to the respective constructor\n\n`init` (in)\n:   initializer list with JSON values\n\n`type_deduction` (in)\n:   internal parameter; when set to `#!cpp true`, the type of the JSON value is deducted from the initializer list\n    `init`; when set to `#!cpp false`, the type provided via `manual_type` is forced. This mode is used by the functions\n    `array(initializer_list_t)` and `object(initializer_list_t)`.\n\n`manual_type` (in)\n:   internal parameter; when `type_deduction` is set to `#!cpp false`, the created JSON value will use the provided type\n    (only `value_t::array` and `value_t::object` are valid); when `type_deduction` is set to `#!cpp true`, this\n    parameter has no effect\n\n`cnt` (in)\n:   the number of JSON copies of `val` to create\n\n`first` (in)\n:   begin of the range to copy from (included)\n\n`last` (in)\n:   end of the range to copy from (excluded)\n\n`other` (in)\n:   the JSON value to copy/move\n\n## Exception safety\n\n1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.\n2. No-throw guarantee: this constructor never throws exceptions.\n3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no\n   `to_json()` function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any\n   JSON value.\n4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no\n   `to_json()` function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any\n   JSON value.\n5. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.\n6. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.\n7. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.\n8. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.\n9. No-throw guarantee: this constructor never throws exceptions.\n\n## Exceptions\n\n1. /\n2. The function does not throw exceptions.\n3. /\n4. /\n5. The function can throw the following exceptions:\n    - Throws [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `type_deduction` is\n      `#!cpp false`, `manual_type` is `value_t::object`, but `init` contains an element which is not a pair whose first\n      element is a string. In this case, the constructor could not create an object. If `type_deduction` would have been\n      `#!cpp true`, an array would have been created. See `object(initializer_list_t)` for an example.\n6. /\n7. The function can throw the following exceptions:\n    - Throws [`invalid_iterator.201`](../../home/exceptions.md#jsonexceptioninvalid_iterator201) if iterators `first`\n      and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range\n      `[first, last)` is undefined.\n    - Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first`\n      and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first\n      element anymore. In this case, the range `[first, last)` is undefined. See example code below.\n    - Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first`\n      and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined.\n8. /\n9. The function does not throw exceptions.\n\n## Complexity\n\n1. Constant.\n2. Constant.\n3. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()`\n   method.\n4. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()`\n   method.\n5. Linear in the size of the initializer list `init`.\n6. Linear in `cnt`.\n7. Linear in distance between `first` and `last`.\n8. Linear in the size of `other`.\n9. Constant.\n\n## Notes\n\n- Overload 5:\n\n    !!! note\n\n        When used without parentheses around an empty initializer list, `basic_json()` is called instead of this\n        function, yielding the JSON `#!json null` value.\n\n- Overload 7:\n\n    !!! info \"Preconditions\"\n\n        - Iterators `first` and `last` must be initialized. **This precondition is enforced with an assertion (see\n          warning).** If assertions are switched off, a violation of this precondition yields undefined behavior.\n        - Range `[first, last)` is valid. Usually, this precondition cannot be checked efficiently. Only certain edge\n          cases are detected; see the description of the exceptions above. A violation of this precondition yields\n          undefined behavior.\n    \n    !!! warning\n\n        A precondition is enforced with a runtime assertion that will result in calling `std::abort` if this\n        precondition is not met. Assertions can be disabled by defining `NDEBUG` at compile time. See\n        <https://en.cppreference.com/w/cpp/error/assert> for more information.\n    \n- Overload 8:\n\n    !!! info \"Postcondition\"\n\n        `#!cpp *this == other`\n\n- Overload 9:\n\n    !!! info \"Postconditions\"\n\n        - `#!cpp `*this` has the same value as `other` before the call.\n        - `other` is a JSON `#!json null` value\n\n## Examples\n\n??? example \"Example: (1) create an empty value with a given type\"\n\n    The following code shows the constructor for different `value_t` values.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__value_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__value_t.output\"\n    ```\n\n??? example \"Example: (2) create a `#!json null` object\"\n\n    The following code shows the constructor with and without a null pointer parameter.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__nullptr_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__nullptr_t.output\"\n    ```\n\n??? example \"Example: (3) create a JSON value from compatible types\"\n\n    The following code shows the constructor with several compatible types.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__CompatibleType.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__CompatibleType.output\"\n    ```\n\n??? example \"Example: (5) create a container (array or object) from an initializer list\"\n\n    The example below shows how JSON values are created from initializer lists.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__list_init_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__list_init_t.output\"\n    ```\n\n??? example \"Example: (6) construct an array with count copies of given value\"\n\n    The following code shows examples for creating arrays with several copies of a given value.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__size_type_basic_json.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__size_type_basic_json.output\"\n    ```\n\n??? example \"Example: (7) construct a JSON container given an iterator range\"\n\n    The example below shows several ways to create JSON values by specifying a subrange with iterators.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__InputIt_InputIt.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__InputIt_InputIt.output\"\n    ```\n\n??? example \"Example: (8) copy constructor\"\n\n    The following code shows an example for the copy constructor.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__basic_json.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__basic_json.output\"\n    ```\n\n??? example \"Example: (9) move constructor\"\n\n    The code below shows the move constructor explicitly called via `std::move`.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__moveconstructor.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__moveconstructor.output\"\n    ```\n\n## Version history\n\n1. Since version 1.0.0.\n2. Since version 1.0.0.\n3. Since version 2.1.0.\n4. Since version 3.2.0.\n5. Since version 1.0.0.\n6. Since version 1.0.0.\n7. Since version 1.0.0.\n8. Since version 1.0.0.\n9. Since version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/begin.md",
    "content": "# <small>nlohmann::basic_json::</small>begin\n\n```cpp\niterator begin() noexcept;\nconst_iterator begin() const noexcept;\n```\n\nReturns an iterator to the first element.\n\n![Illustration from cppreference.com](../../images/range-begin-end.svg)\n\n## Return value\n\niterator to the first element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `begin()`.\n    \n    ```cpp\n    --8<-- \"examples/begin.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/begin.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/binary.md",
    "content": "# <small>nlohmann::basic_json::</small>binary\n\n```cpp\n// (1)\nstatic basic_json binary(const typename binary_t::container_type& init);\nstatic basic_json binary(typename binary_t::container_type&& init);\n\n// (2)\nstatic basic_json binary(const typename binary_t::container_type& init,\n                         std::uint8_t subtype);\nstatic basic_json binary(typename binary_t::container_type&& init,\n                         std::uint8_t subtype);\n```\n\n1. Creates a JSON binary array value from a given binary container.\n2. Creates a JSON binary array value from a given binary container with subtype.\n \nBinary values are part of various binary formats, such as CBOR, MessagePack, and BSON. This constructor is used to\ncreate a value for serialization to those formats.\n\n## Parameters\n\n`init` (in)\n:   container containing bytes to use as binary type\n\n`subtype` (in)\n:   subtype to use in CBOR, MessagePack, and BSON\n\n## Return value\n\nJSON binary array value\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the size of `init`; constant for `typename binary_t::container_type&& init` versions.\n\n## Notes\n\nNote, this function exists because of the difficulty in correctly specifying the correct template overload in the\nstandard value ctor, as both JSON arrays and JSON binary arrays are backed with some form of a `std::vector`. Because\nJSON binary arrays are a non-standard extension it was decided that it would be best to prevent automatic initialization\nof a binary array type, for backwards compatibility and so it does not happen on accident.\n\n## Examples\n\n??? example\n\n    The following code shows how to create a binary value.\n     \n    ```cpp\n    --8<-- \"examples/binary.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/binary.output\"\n    ```\n\n## Version history\n\n- Added in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/binary_t.md",
    "content": "# <small>nlohmann::basic_json::</small>binary_t\n\n```cpp\nusing binary_t = byte_container_with_subtype<BinaryType>;\n```\n\nThis type is a type designed to carry binary data that appears in various serialized formats, such as CBOR's Major Type\n2, MessagePack's bin, and BSON's generic binary subtype. This type is NOT a part of standard JSON and exists solely for\ncompatibility with these binary types. As such, it is simply defined as an ordered sequence of zero or more byte values.\n\nAdditionally, as an implementation detail, the subtype of the binary data is carried around as a `std::uint64_t`, which\nis compatible with both of the binary data formats that use binary subtyping, (though the specific numbering is\nincompatible with each other, and it is up to the user to translate between them). The subtype is added to `BinaryType`\nvia the helper type [byte_container_with_subtype](../byte_container_with_subtype/index.md).\n\n[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type as:\n> Major type 2: a byte string. The string's length in bytes is represented following the rules for positive integers\n> (major type 0).\n\n[MessagePack's documentation on the bin type\nfamily](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) describes this type as:\n> Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array.\n\n[BSON's specifications](http://bsonspec.org/spec.html) describe several binary types; however, this type is intended to\nrepresent the generic binary type which has the description:\n> Generic binary subtype - This is the most commonly used binary subtype and should be the 'default' for drivers and\n> tools.\n\nNone of these impose any limitations on the internal representation other than the basic unit of storage be some type of\narray whose parts are decomposable into bytes.\n\nThe default representation of this binary format is a `#!cpp std::vector<std::uint8_t>`, which is a very common way to\nrepresent a byte array in modern C++.\n\n## Template parameters\n\n`BinaryType`\n:   container type to store arrays\n\n## Notes\n\n#### Default type\n\nThe default values for `BinaryType` is `#!cpp std::vector<std::uint8_t>`.\n\n#### Storage\n\nBinary Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of the\ntype `#!cpp binary_t*` must be dereferenced.\n\n#### Notes on subtypes\n\n- CBOR\n    - Binary values are represented as byte strings. Subtypes are written as tags.\n\n- MessagePack\n    - If a subtype is given and the binary array contains exactly 1, 2, 4, 8, or 16 elements, the fixext family (fixext1,\n      fixext2, fixext4, fixext8) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is\n      then added as signed 8-bit integer.\n    - If no subtype is given, the bin family (bin8, bin16, bin32) is used.\n\n- BSON\n    - If a subtype is given, it is used and added as unsigned 8-bit integer.\n    - If no subtype is given, the generic binary subtype 0x00 is used.\n\n## Examples\n\n??? example\n\n    The following code shows that `binary_t` is by default, a typedef to\n    `#!cpp nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>`.\n     \n    ```cpp\n    --8<-- \"examples/binary_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/binary_t.output\"\n    ```\n\n## See also\n\n- [byte_container_with_subtype](../byte_container_with_subtype/index.md)\n\n## Version history\n\n- Added in version 3.8.0. Changed type of subtype to `std::uint64_t` in version 3.10.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/boolean_t.md",
    "content": "# <small>nlohmann::basic_json::</small>boolean_t\n\n```cpp\nusing boolean_t = BooleanType;\n```\n\nThe type used to store JSON booleans.\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals\n`#!json true` and `#!json false`.\n\nTo store objects in C++, a type is defined by the template parameter  `BooleanType` which chooses the type to use.\n\n## Notes\n\n#### Default type\n\nWith the default values for `BooleanType` (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`.\n\n#### Storage\n\nBoolean values are stored directly inside a `basic_json` type.\n\n## Examples\n\n??? example\n\n    The following code shows that `boolean_t` is by default, a typedef to `#!cpp bool`.\n     \n    ```cpp\n    --8<-- \"examples/boolean_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/boolean_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/cbegin.md",
    "content": "# <small>nlohmann::basic_json::</small>cbegin\n\n```cpp\nconst_iterator cbegin() const noexcept;\n```\n\nReturns an iterator to the first element.\n\n![Illustration from cppreference.com](../../images/range-begin-end.svg)\n\n## Return value\n\niterator to the first element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `cbegin()`.\n    \n    ```cpp\n    --8<-- \"examples/cbegin.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/cbegin.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md",
    "content": "# <small>nlohmann::basic_json::</small>cbor_tag_handler_t\n\n```cpp\nenum class cbor_tag_handler_t\n{\n    error,\n    ignore,\n    store\n};\n```\n\nThis enumeration is used in the [`from_cbor`](from_cbor.md) function to choose how to treat tags:\n\nerror\n:   throw a `parse_error` exception in case of a tag\n\nignore\n:   ignore tags\n\nstore\n:   store tagged values as binary container with subtype (for bytes 0xd8..0xdb)\n\n## Version history\n\n- Added in version 3.9.0. Added value `store` in 3.10.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/cend.md",
    "content": "# <small>nlohmann::basic_json::</small>cend\n\n```cpp\nconst_iterator cend() const noexcept;\n```\n\nReturns an iterator to one past the last element.\n\n![Illustration from cppreference.com](../../images/range-begin-end.svg)\n\n## Return value\n\niterator one past the last element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `cend()`.\n    \n    ```cpp\n    --8<-- \"examples/cend.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/cend.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/clear.md",
    "content": "# <small>nlohmann::basic_json::</small>clear\n\n```cpp\nvoid clear() noexcept;\n```\n\nClears the content of a JSON value and resets it to the default value as if [`basic_json(value_t)`](basic_json.md) would\nhave been called with the current value type from [`type()`](type.md):\n\n| Value type | initial value        |\n|------------|----------------------|\n| null       | `null`               |\n| boolean    | `false`              |\n| string     | `\"\"`                 |\n| number     | `0`                  |\n| binary     | An empty byte vector |\n| object     | `{}`                 |\n| array      | `[]`                 |\n\nHas the same effect as calling\n\n```.cpp\n*this = basic_json(type());\n```\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nLinear in the size of the JSON value.\n\n## Notes\n\nAll iterators, pointers and references related to this container are invalidated.\n\n## Examples\n\n??? example\n\n    The example below shows the effect of `clear()` to different\n    JSON types.\n    \n    ```cpp\n    --8<-- \"examples/clear.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/clear.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Added support for binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/contains.md",
    "content": "# <small>nlohmann::basic_json::</small>contains\n\n```cpp\n// (1)\ntemplate<typename KeyT>\nbool contains(KeyT && key) const;\n\n// (2)\nbool contains(const json_pointer& ptr) const;\n```\n\n1. Check whether an element exists in a JSON object with key equivalent to `key`. If the element is not found or the \n   JSON value is not an object, `#!cpp false` is returned.\n2. Check whether the given JSON pointer `ptr` can be resolved in the current JSON value.\n\n## Template parameters\n\n`KeyT`\n:   A type for an object key other than `basic_json::json_pointer`.\n\n## Parameters\n\n`key` (in)\n:   key value to check its existence.\n\n`ptr` (in)\n:   JSON pointer to check its existence.\n\n## Return value\n\n1. `#!cpp true` if an element with specified `key` exists. If no such element with such key is found or the JSON value\n   is not an object, `#!cpp false` is returned.\n2. `#!cpp true` if the JSON pointer can be resolved to a stored value, `#!cpp false` otherwise.\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\n1. The function does not throw exceptions.\n2. The function can throw the following exceptions:\n    - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index begins with\n      `0`.\n    - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index was not a\n      number.\n\n## Complexity\n\nLogarithmic in the size of the JSON object.\n\n## Notes\n\n1. This method always returns `#!cpp false` when executed on a JSON type that is not an object.\n2. This method can be executed on any JSON value type.\n\n!!! info \"Postconditions\"\n\n    If `#!cpp j.contains(x)` returns `#!c true` for a key or JSON pointer `x`, then it is safe to call `j[x]`.\n\n## Examples\n\n??? example \"Example (1) check with key\"\n\n    The example shows how `contains()` is used.\n    \n    ```cpp\n    --8<-- \"examples/contains.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/contains.output\"\n    ```\n\n??? example \"Example (1) check with JSON pointer\"\n\n    The example shows how `contains()` is used.\n    \n    ```cpp\n    --8<-- \"examples/contains_json_pointer.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/contains_json_pointer.output\"\n    ```\n\n## Version history\n\n1. Added in version 3.6.0.\n2. Added in version 3.7.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/count.md",
    "content": "# <small>nlohmann::basic_json::</small>count\n\n```cpp\ntemplate<typename KeyT>\nsize_type count(KeyT&& key) const;\n```\n\nReturns the number of elements with key `key`. If `ObjectType` is the default `std::map` type, the return value will\nalways be `0` (`key` was not found) or `1` (`key` was found).\n\n## Template parameters\n\n`KeyT`\n:   A type for an object key.\n\n## Parameters\n\n`key` (in)\n:   key value of the element to count.\n    \n## Return value\n\nNumber of elements with key `key`. If the JSON value is not an object, the return value will be `0`.\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Complexity\n\nLogarithmic in the size of the JSON object.\n\n## Notes\n\nThis method always returns `0` when executed on a JSON type that is not an object.\n\n## Examples\n\n??? example\n\n    The example shows how `count()` is used.\n    \n    ```cpp\n    --8<-- \"examples/count.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/count.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/crbegin.md",
    "content": "# <small>nlohmann::basic_json::</small>crbegin\n\n```cpp\nconst_reverse_iterator crbegin() const noexcept;\n```\n\nReturns an iterator to the reverse-beginning; that is, the last element.\n\n![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)\n\n## Return value\n\nreverse iterator to the first element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `crbegin()`.\n    \n    ```cpp\n    --8<-- \"examples/crbegin.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/crbegin.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/crend.md",
    "content": "# <small>nlohmann::basic_json::</small>crend\n\n```cpp\nconst_reverse_iterator crend() const noexcept;\n```\n\nReturns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder,\nattempting to access it results in undefined behavior.\n\n![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)\n\n## Return value\n\nreverse iterator to the element following the last element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `eend()`.\n    \n    ```cpp\n    --8<-- \"examples/crend.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/crend.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/diff.md",
    "content": "# <small>nlohmann::basic_json::</small>diff\n\n```cpp\nstatic basic_json diff(const basic_json& source,\n                       const basic_json& target);\n```\n\nCreates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling\n[`patch`](patch.md) function.\n\nFor two JSON values `source` and `target`, the following code yields always `#!cpp true`:\n```cpp\nsource.patch(diff(source, target)) == target;\n```\n\n## Parameters\n\n`source` (in)\n:   JSON value to compare from\n\n`target` (in)\n:   JSON value to compare against\n\n## Return value\n\na JSON patch to convert the `source` to `target`\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the lengths of `source` and `target`.\n\n## Notes\n\nCurrently, only `remove`, `add`, and `replace` operations are generated.\n          \n## Examples\n\n??? example\n\n    The following code shows how a JSON patch is created as a diff for two JSON values.\n     \n    ```cpp\n    --8<-- \"examples/diff.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/diff.output\"\n    ```\n\n## See also\n\n- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)\n\n## Version history\n\n- Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/dump.md",
    "content": "# <small>nlohmann::basic_json::</small>dump\n\n```cpp\nstring_t dump(const int indent = -1,\n              const char indent_char = ' ',\n              const bool ensure_ascii = false,\n              const error_handler_t error_handler = error_handler_t::strict) const;\n```\n\nSerialization function for JSON values. The function tries to mimic Python's\n[`json.dumps()` function](https://docs.python.org/2/library/json.html#json.dump), and currently  supports its `indent`\nand `ensure_ascii` parameters.\n    \n## Parameters\n\n`indent` (in)\n:   If `indent` is nonnegative, then array elements and object members will be pretty-printed with that indent level. An\n    indent level of `0` will only insert newlines. `-1` (the default) selects the most compact representation.\n\n`indent_char` (in)\n:   The character to use for indentation if `indent` is greater than `0`. The default is ` ` (space).\n\n`ensure_ascii` (in)\n:   If `ensure_ascii` is true, all non-ASCII characters in the output are escaped with `\\uXXXX` sequences, and the\n    result consists of ASCII characters only.\n\n`error_handler` (in)\n:   how to react on decoding errors; there are three possible values (see [`error_handler_t`](error_handler_t.md):\n    `strict` (throws and exception in case a decoding error occurs; default), `replace` (replace invalid UTF-8 sequences\n    with U+FFFD), and `ignore` (ignore invalid UTF-8 sequences during serialization; all bytes are copied to the output\n    unchanged)).\n    \n## Return value\n\nstring containing the serialization of the JSON value\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes to any JSON value.\n\n## Exceptions\n\nThrows [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value\nis not UTF-8 encoded and `error_handler` is set to `strict`\n\n## Complexity\n\nLinear.\n\n## Notes\n\nBinary values are serialized as object containing two keys:\n\n- \"bytes\": an array of bytes as integers\n- \"subtype\": the subtype as integer or `#!json null` if the binary has no subtype\n\n## Examples\n\n??? example\n\n    The following example shows the effect of different `indent`, `indent_char`, and `ensure_ascii` parameters to the\n    result of the serialization.\n\n    ```cpp\n    --8<-- \"examples/dump.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/dump.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Indentation character `indent_char`, option `ensure_ascii` and exceptions added in version 3.0.0.\n- Error handlers added in version 3.4.0.\n- Serialization of binary values added in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/emplace.md",
    "content": "# <small>nlohmann::basic_json::</small>emplace\n\n```cpp\ntemplate<class... Args>\nstd::pair<iterator, bool> emplace(Args&& ... args);\n```\n\nInserts a new element into a JSON object constructed in-place with the given `args` if there is no element with the key\nin the container. If the function is called on a JSON null value, an empty object is created before appending the value\ncreated from `args`.\n\n## Template parameters\n\n`Args`\n:   compatible types to create a `basic_json` object\n\n## Parameters\n\n`args` (in)\n:   arguments to forward to a constructor of `basic_json`\n\n## Return value\n\na pair consisting of an iterator to the inserted element, or the already-existing element if no insertion happened, and\na `#!cpp bool` denoting whether the insertion took place.\n\n## Exceptions\n\nThrows [`type_error.311`](../../home/exceptions.md#jsonexceptiontype_error311) when called on a type other than JSON\nobject or `#!json null`; example: `\"cannot use emplace() with number\"`\n\n## Complexity\n\nLogarithmic in the size of the container, O(log(`size()`)).\n\n## Examples\n\n??? example\n\n    The example shows how `emplace()` can be used to add elements to a JSON object. Note how the `#!json null` value was\n    silently converted to a JSON object. Further note how no value is added if there was already one value stored with\n    the same key.\n            \n    ```cpp\n    --8<-- \"examples/emplace.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/emplace.output\"\n    ```\n\n## Version history\n\n- Since version 2.0.8.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/emplace_back.md",
    "content": "# <small>nlohmann::basic_json::</small>emplace_back\n\n```cpp\ntemplate<class... Args>\nreference emplace_back(Args&& ... args);\n```\n\nCreates a JSON value from the passed parameters `args` to the end of the JSON value. If the function is called on a JSON\n`#!json null` value, an empty array is created before appending the value created from `args`.\n\n## Template parameters\n\n`Args`\n:   compatible types to create a `basic_json` object\n\n## Parameters\n\n`args` (in)\n:   arguments to forward to a constructor of `basic_json`\n\n## Return value\n\nreference to the inserted element\n\n## Exceptions\n\nThrows [`type_error.311`](../../home/exceptions.md#jsonexceptiontype_error311) when called on a type other than JSON\narray or `#!json null`; example: `\"cannot use emplace_back() with number\"`\n\n## Complexity\n\nAmortized constant.\n\n## Examples\n\n??? example\n\n    The example shows how `emplace_back()` can be used to add elements to a JSON array. Note how the `null` value was\n    silently converted to a JSON array.\n        \n    ```cpp\n    --8<-- \"examples/emplace_back.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/emplace_back.output\"\n    ```\n\n## Version history\n\n- Since version 2.0.8.\n- Returns reference since 3.7.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/empty.md",
    "content": "# <small>nlohmann::basic_json::</small>empty\n\n```cpp\nbool empty() const noexcept;\n```\n\nChecks if a JSON value has no elements (i.e. whether its [`size()`](size.md) is `0`).\n    \n## Return value\n\nThe return value depends on the different types and is defined as follows:\n\n| Value type | return value                           |\n|------------|----------------------------------------|\n| null       | `#!cpp true`                           |\n| boolean    | `#!cpp false`                          |\n| string     | `#!cpp false`                          |\n| number     | `#!cpp false`                          |\n| binary     | `#!cpp false`                          |\n| object     | result of function `object_t::empty()` |\n| array      | result of function `array_t::empty()`  |\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the\n[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `empty()` functions have\nconstant complexity.\n\n## Possible implementation\n\n```cpp\nbool empty() const noexcept\n{\n    return size() == 0;\n}\n```\n\n## Notes\n\nThis function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container\nitself is empty which is `#!cpp false` in the case of a string.\n\n## Examples\n\n??? example\n\n    The following code uses `empty()` to check if a JSON object contains any elements.\n    \n    ```cpp\n    --8<-- \"examples/empty.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/empty.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended to return `#!cpp false` for binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/end.md",
    "content": "# <small>nlohmann::basic_json::</small>end\n\n```cpp\niterator end() noexcept;\nconst_iterator end() const noexcept;\n```\n\nReturns an iterator to one past the last element.\n\n![Illustration from cppreference.com](../../images/range-begin-end.svg)\n\n## Return value\n\niterator one past the last element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `end()`.\n    \n    ```cpp\n    --8<-- \"examples/end.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/end.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/erase.md",
    "content": "# <small>nlohmann::basic_json::</small>erase\n\n```cpp\n// (1)\niterator erase(iterator pos);\nconst_iterator erase(const_iterator pos);\n\n// (2)\niterator erase(iterator first, iterator last);\nconst_iterator erase(const_iterator first, const_iterator last);\n\n// (3)\nsize_type erase(const typename object_t::key_type& key);\n\n// (4)\nvoid erase(const size_type idx);\n```\n\n1. Removes an element from a JSON value specified by iterator `pos`. The iterator `pos` must be valid and\n   dereferenceable. Thus, the `end()` iterator (which is valid, but is not dereferenceable) cannot be used as a value for\n   `pos`.\n   \n    If called on a primitive type other than `#!json null`, the resulting JSON value will be `#!json null`.\n\n2. Remove an element range specified by `[first; last)` from a JSON value. The iterator `first` does not need to be\n   dereferenceable if `first == last`: erasing an empty range is a no-op.\n   \n    If called on a primitive type other than `#!json null`, the resulting JSON value will be `#!json null`.\n\n3. Removes an element from a JSON object by key.\n\n4. Removes an element from a JSON array by index.\n\n## Parameters\n\n`pos` (in)\n:   iterator to the element to remove\n\n`first` (in)\n:   iterator to the beginning of the range to remove\n\n`last` (in)\n:   iterator past the end of the range to remove\n\n`key` (in)\n:   object key of the elements to remove\n    \n`idx` (in)\n:   array index of the element to remove\n    \n## Return value\n\n1. Iterator following the last removed element. If the iterator `pos` refers to the last element, the `end()` iterator\n   is returned.\n2. Iterator following the last removed element. If the iterator `last` refers to the last element, the `end()` iterator\n   is returned.\n3. Number of elements removed. If `ObjectType` is the default `std::map` type, the return value will always be `0`\n   (`key` was not found) or `1` (`key` was found).\n4. /\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if called on a `null` value;\n      example: `\"cannot use erase() with null\"`\n    - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an\n      iterator which does not belong to the current JSON value; example: `\"iterator does not fit current value\"`\n    - Throws [`invalid_iterator.205`](../../home/exceptions.md#jsonexceptioninvalid_iterator205) if called on a\n      primitive type with invalid iterator (i.e., any iterator which is not `begin()`); example: `\"iterator out of\n      range\"`\n2. The function can throw the following exceptions:\n    - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if called on a `null` value;\n      example: `\"cannot use erase() with null\"`\n    - Throws [`invalid_iterator.203`](../../home/exceptions.md#jsonexceptioninvalid_iterator203) if called on iterators\n      which does not belong to the current JSON value; example: `\"iterators do not fit current value\"`\n    - Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if called on a\n      primitive type with invalid iterators (i.e., if `first != begin()` and `last != end()`); example: `\"iterators out\n      of range\"`\n3. The function can throw the following exceptions:\n    - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) when called on a type other than\n      JSON object; example: `\"cannot use erase() with null\"`\n4. The function can throw the following exceptions:\n    - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) when called on a type other than\n      JSON object; example: `\"cannot use erase() with null\"`\n    - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) when `idx >= size()`; example:\n      `\"array index 17 is out of range\"`\n\n## Complexity\n\n1. The complexity depends on the type:\n       - objects: amortized constant\n       - arrays: linear in distance between `pos` and the end of the container\n       - strings and binary: linear in the length of the member\n       - other types: constant\n2. The complexity depends on the type:\n       - objects: `log(size()) + std::distance(first, last)`\n       - arrays: linear in the distance between `first` and `last`, plus linear\n         in the distance between `last` and end of the container\n       - strings and binary: linear in the length of the member\n       - other types: constant\n3. `log(size()) + count(key)`\n4. Linear in distance between `idx` and the end of the container.\n\n## Notes\n\n1. Invalidates iterators and references at or after the point of the `erase`, including the `end()` iterator.\n2. /\n3. References and iterators to the erased elements are invalidated. Other references and iterators are not affected.\n4. /\n\n## Examples\n\n??? example \"Example: (1) remove element given an iterator\"\n\n    The example shows the effect of `erase()` for different JSON types using an iterator.\n    \n    ```cpp\n    --8<-- \"examples/erase__IteratorType.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/erase__IteratorType.output\"\n    ```\n\n??? example \"Example: (2) remove elements given an iterator range\"\n\n    The example shows the effect of `erase()` for different JSON types using an iterator range.\n    \n    ```cpp\n    --8<-- \"examples/erase__IteratorType_IteratorType.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/erase__IteratorType_IteratorType.output\"\n    ```\n\n??? example \"Example: (3) remove element from a JSON object given a key\"\n\n    The example shows the effect of `erase()` for different JSON types using an object key.\n    \n    ```cpp\n    --8<-- \"examples/erase__key_type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/erase__key_type.output\"\n    ```\n\n??? example \"Example: (4) remove element from a JSON array given an index\"\n\n    The example shows the effect of `erase()` using an array index.\n    \n    ```cpp\n    --8<-- \"examples/erase__size_type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/erase__size_type.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Added support for binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/error_handler_t.md",
    "content": "# <small>nlohmann::basic_json::</small>error_handler_t\n\n```cpp\nenum class error_handler_t {\n    strict,\n    replace,\n    ignore\n};\n```\n\nThis enumeration is used in the [`dump`](dump.md) function to choose how to treat decoding errors while serializing a\n`basic_json` value. Three values are differentiated:\n\nstrict\n:   throw a `type_error` exception in case of invalid UTF-8\n\nreplace\n:   replace invalid UTF-8 sequences with U+FFFD (� REPLACEMENT CHARACTER)\n\nignore\n:   ignore invalid UTF-8 sequences; all bytes are copied to the output unchanged\n\n## Version history\n\n- Added in version 3.4.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/exception.md",
    "content": "# <small>nlohmann::basic_json::</small>exception\n\n```cpp\nclass exception : public std::exception;\n```\n\nThis class is an extension of [`std::exception`](https://en.cppreference.com/w/cpp/error/exception) objects with a\nmember `id` for exception ids. It is used as the base class for all exceptions thrown by the `basic_json` class. This\nclass can hence be used as \"wildcard\" to catch exceptions, see example below.\n\n```plantuml\nstd::exception <|-- basic_json::exception\nbasic_json::exception <|-- basic_json::parse_error\nbasic_json::exception <|-- basic_json::invalid_iterator\nbasic_json::exception <|-- basic_json::type_error\nbasic_json::exception <|-- basic_json::out_of_range\nbasic_json::exception <|-- basic_json::other_error\n\ninterface std::exception {}\n\nclass basic_json::exception #FFFF00 {\n    + const int id\n    + const char* what() const\n}\n\nclass basic_json::parse_error {\n    + const std::size_t byte\n}\n```\n\nSubclasses:\n\n- [`parse_error`](parse_error.md) for exceptions indicating a parse error\n- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators\n- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type\n- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range\n- [`other_error`](other_error.md) for exceptions indicating other library errors\n\n## Member functions\n\n- **what** - returns explanatory string\n\n## Member variables\n\n- **id** - the id of the exception\n\n## Notes\n\nTo have nothrow-copy-constructible exceptions, we internally use `std::runtime_error` which can cope with\narbitrary-length error messages. Intermediate strings are built with static functions and then passed to the actual\nconstructor.\n\n## Examples\n\n??? example\n\n    The following code shows how arbitrary library exceptions can be caught.\n    \n    ```cpp\n    --8<-- \"examples/exception.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/exception.output\"\n    ```\n\n## See also\n\n[List of exceptions](127.0.0.1:8000/home/exceptions/)\n\n## Version history\n\n- Since version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/find.md",
    "content": "# <small>nlohmann::basic_json::</small>find\n\n```cpp\ntemplate<typename KeyT>\niterator find(KeyT&& key);\n\ntemplate<typename KeyT>\nconst_iterator find(KeyT&& key) const;\n```\n\nFinds an element in a JSON object with key equivalent to `key`. If the element is not found or the JSON value is not an\nobject, `end()` is returned.\n\n## Template parameters\n\n`KeyT`\n:   A type for an object key.\n\n## Parameters\n\n`key` (in)\n:   key value of the element to search for.\n    \n## Return value\n\nIterator to an element with key equivalent to `key`. If no such element is found or the JSON value is not an object,\npast-the-end (see `end()`) iterator is returned.\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Complexity\n\nLogarithmic in the size of the JSON object.\n\n## Notes\n\nThis method always returns `end()` when executed on a JSON type that is not an object.\n\n## Examples\n\n??? example\n\n    The example shows how `find()` is used.\n    \n    ```cpp\n    --8<-- \"examples/find__key_type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/find__key_type.output\"\n    ```\n\n## See also\n\n- [contains](contains.md) checks whether a key exists\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/flatten.md",
    "content": "# <small>nlohmann::basic_json::</small>flatten\n\n```cpp\nbasic_json flatten() const;\n```\n\nThe function creates a JSON object whose keys are JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901))\nand whose values are all primitive (see [`is_primitive()`](is_primitive.md) for more information). The original JSON\nvalue can be restored using the [`unflatten()`](unflatten.md) function.\n    \n## Return value\n\nan object that maps JSON pointers to primitive values\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Complexity\n\nLinear in the size the JSON value.\n\n## Notes\n\nEmpty objects and arrays are flattened to `#!json null` and will not be reconstructed correctly by the\n[`unflatten()`](unflatten.md) function.\n\n## Examples\n\n??? example\n\n    The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers.\n    \n    ```cpp\n    --8<-- \"examples/flatten.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/flatten.output\"\n    ```\n\n## See also\n\n- [unflatten](unflatten.md) the reverse function\n\n## Version history\n\n- Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/from_bson.md",
    "content": "# <small>nlohmann::basic_json::</small>from_bson\n\n```cpp\n// (1)\ntemplate<typename InputType>\nstatic basic_json from_bson(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true);\n// (2)\ntemplate<typename IteratorType>\nstatic basic_json from_bson(IteratorType first, IteratorType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true);\n```\n\nDeserializes a given input to a JSON value using the BSON (Binary JSON) serialization format.\n\n1. Reads from a compatible input.\n2. Reads from an iterator range.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/bson.md).\n\n## Template parameters\n\n`InputType`\n:   A compatible input, for instance:\n    \n    - an `std::istream` object\n    - a `FILE` pointer\n    - a C-style array of characters\n    - a pointer to a null-terminated string of single byte characters\n    - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.\n\n`IteratorType`\n:   a compatible iterator type\n\n## Parameters\n\n`i` (in)\n:   an input in BSON format convertible to an input adapter\n\n`first` (in)\n:   iterator to start of the input\n\n`last` (in)\n:   iterator to end of the input\n\n`strict` (in)\n:   whether to expect the input to be consumed until EOF (`#!cpp true` by default)\n\n`allow_exceptions` (in)\n:   whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)\n\n## Return value\n\ndeserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be\n`value_t::discarded`.  The latter can be checked with [`is_discarded`](is_discarded.md).\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n\nThrows [`parse_error.114`](../../home/exceptions.md#jsonexceptionparse_error114) if an unsupported BSON record type is\nencountered.\n\n## Complexity\n\nLinear in the size of the input.\n\n## Examples\n\n??? example\n\n    The example shows the deserialization of a byte vector in BSON format to a JSON value.\n     \n    ```cpp\n    --8<-- \"examples/from_bson.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/from_bson.output\"\n    ```\n\n## See also\n\n- [BSON specification](http://bsonspec.org/spec.html)\n- [to_bson](to_bson.md) for the analogous serialization\n- [from_cbor](from_cbor.md) for the related CBOR format\n- [from_msgpack](from_msgpack.md) for the related MessagePack format\n- [from_ubjson](from_ubjson.md) for the related UBJSON format\n\n## Version history\n\n- Added in version 3.4.0.\n\n!!! warning \"Deprecation\"\n\n    - Overload (2) replaces calls to `from_bson` with a pointer and a length as first two parameters, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_bson(ptr, len, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`.\n    - Overload (2) replaces calls to `from_bson` with a pair of iterators as their first parameter, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_bson({ptr, ptr+len}, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`.\n\n    You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated\n    function.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/from_cbor.md",
    "content": "# <small>nlohmann::basic_json::</small>from_cbor\n\n```cpp\n// (1)\ntemplate<typename InputType>\nstatic basic_json from_cbor(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);\n\n// (2)\ntemplate<typename IteratorType>\nstatic basic_json from_cbor(IteratorType first, IteratorType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);\n```\n\nDeserializes a given input to a JSON value using the CBOR (Concise Binary Object Representation) serialization format.\n\n1. Reads from a compatible input.\n2. Reads from an iterator range.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/cbor.md).\n\n## Template parameters\n\n`InputType`\n:   A compatible input, for instance:\n    \n    - an `std::istream` object\n    - a `FILE` pointer\n    - a C-style array of characters\n    - a pointer to a null-terminated string of single byte characters\n    - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.\n\n`IteratorType`\n:   a compatible iterator type\n\n## Parameters\n\n`i` (in)\n:   an input in CBOR format convertible to an input adapter\n\n`first` (in)\n:   iterator to start of the input\n\n`last` (in)\n:   iterator to end of the input\n\n`strict` (in)\n:   whether to expect the input to be consumed until EOF (`#!cpp true` by default)\n\n`allow_exceptions` (in)\n:   whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)\n\n`tag_handler` (in)\n:   how to treat CBOR tags (optional, `error` by default); see [`cbor_tag_handler_t`](cbor_tag_handler_t.md) for more\n    information\n\n## Return value\n\ndeserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be\n`value_t::discarded`.  The latter can be checked with [`is_discarded`](is_discarded.md).\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n \n- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or\n  the end of file was not reached when `strict` was set to true\n- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from CBOR were\n  used in the given input or if the input is not valid CBOR\n- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as map key,\n  but not found\n\n## Complexity\n\nLinear in the size of the input.\n\n## Examples\n\n??? example\n\n    The example shows the deserialization of a byte vector in CBOR format to a JSON value.\n     \n    ```cpp\n    --8<-- \"examples/from_cbor.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/from_cbor.output\"\n    ```\n\n## Version history\n\n- Added in version 2.0.9.\n- Parameter `start_index` since version 2.1.1.\n- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0.\n- Added `allow_exceptions` parameter in version 3.2.0.\n- Added `tag_handler` parameter in version 3.9.0.\n\n!!! warning \"Deprecation\"\n\n    - Overload (2) replaces calls to `from_cbor` with a pointer and a length as first two parameters, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_cbor(ptr, len, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`.\n    - Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_cbor({ptr, ptr+len}, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`.\n\n    You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated\n    function.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/from_msgpack.md",
    "content": "# <small>nlohmann::basic_json::</small>from_msgpack\n\n```cpp\n// (1)\ntemplate<typename InputType>\nstatic basic_json from_msgpack(InputType&& i,\n                               const bool strict = true,\n                               const bool allow_exceptions = true);\n// (2)\ntemplate<typename IteratorType>\nstatic basic_json from_msgpack(IteratorType first, IteratorType last,\n                               const bool strict = true,\n                               const bool allow_exceptions = true);\n```\n\nDeserializes a given input to a JSON value using the MessagePack serialization format.\n\n1. Reads from a compatible input.\n2. Reads from an iterator range.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/messagepack.md).\n\n## Template parameters\n\n`InputType`\n:   A compatible input, for instance:\n    \n    - an `std::istream` object\n    - a `FILE` pointer\n    - a C-style array of characters\n    - a pointer to a null-terminated string of single byte characters\n    - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.\n\n`IteratorType`\n:   a compatible iterator type\n\n## Parameters\n\n`i` (in)\n:   an input in MessagePack format convertible to an input adapter\n\n`first` (in)\n:   iterator to start of the input\n\n`last` (in)\n:   iterator to end of the input\n\n`strict` (in)\n:   whether to expect the input to be consumed until EOF (`#!cpp true` by default)\n\n`allow_exceptions` (in)\n:   whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)\n\n## Return value\n\ndeserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be\n`value_t::discarded`.  The latter can be checked with [`is_discarded`](is_discarded.md).\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n\n- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or\n  the end of  file was not reached when `strict` was set to true\n- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from\n  MessagePack were used in the given input or if the input is not valid MessagePack\n- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as map key,\n  but not found\n\n## Complexity\n\nLinear in the size of the input.\n\n## Examples\n\n??? example\n\n    The example shows the deserialization of a byte vector in MessagePack format to a JSON value.\n     \n    ```cpp\n    --8<-- \"examples/from_msgpack.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/from_msgpack.output\"\n    ```\n\n## Version history\n\n- Added in version 2.0.9.\n- Parameter `start_index` since version 2.1.1.\n- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0.\n- Added `allow_exceptions` parameter in version 3.2.0.\n\n!!! warning \"Deprecation\"\n\n    - Overload (2) replaces calls to `from_msgpack` with a pointer and a length as first two parameters, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_msgpack(ptr, len, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`.\n    - Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_msgpack({ptr, ptr+len}, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`.\n\n    You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated\n    function.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/from_ubjson.md",
    "content": "# <small>nlohmann::basic_json::</small>from_ubjson\n\n```cpp\n// (1)\ntemplate<typename InputType>\nstatic basic_json from_ubjson(InputType&& i,\n                              const bool strict = true,\n                              const bool allow_exceptions = true);\n// (2)\ntemplate<typename IteratorType>\nstatic basic_json from_ubjson(IteratorType first, IteratorType last,\n                              const bool strict = true,\n                              const bool allow_exceptions = true);\n```\n\nDeserializes a given input to a JSON value using the UBJSON (Universal Binary JSON) serialization format.\n\n1. Reads from a compatible input.\n2. Reads from an iterator range.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/ubjson.md).\n\n## Template parameters\n\n`InputType`\n:   A compatible input, for instance:\n    \n    - an `std::istream` object\n    - a `FILE` pointer\n    - a C-style array of characters\n    - a pointer to a null-terminated string of single byte characters\n    - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.\n\n`IteratorType`\n:   a compatible iterator type\n\n## Parameters\n\n`i` (in)\n:   an input in UBJSON format convertible to an input adapter\n\n`first` (in)\n:   iterator to start of the input\n\n`last` (in)\n:   iterator to end of the input\n\n`strict` (in)\n:   whether to expect the input to be consumed until EOF (`#!cpp true` by default)\n\n`allow_exceptions` (in)\n:   whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)\n\n## Return value\n\ndeserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be\n`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md).\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n\n- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or\n  the end of file was not reached when `strict` was set to true\n- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs\n- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string could not be parsed \n  successfully\n\n## Complexity\n\nLinear in the size of the input.\n\n## Examples\n\n??? example\n\n    The example shows the deserialization of a byte vector in UBJSON format to a JSON value.\n     \n    ```cpp\n    --8<-- \"examples/from_ubjson.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/from_ubjson.output\"\n    ```\n\n## Version history\n\n- Added in version 3.1.0.\n- Added `allow_exceptions` parameter in version 3.2.0.\n\n!!! warning \"Deprecation\"\n\n    - Overload (2) replaces calls to `from_ubjson` with a pointer and a length as first two parameters, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_ubjson(ptr, len, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`.\n    - Overload (2) replaces calls to `from_ubjson` with a pair of iterators as their first parameter, which has been\n      deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n      `#!cpp from_ubjson({ptr, ptr+len}, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`.\n\n    You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated\n    function.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/front.md",
    "content": "# <small>nlohmann::basic_json::</small>front\n\n```cpp\nreference front();\nconst_reference front() const;\n```\n\nReturns a reference to the first element in the container. For a JSON container `#!cpp c`, the expression\n`#!cpp c.front()` is equivalent to `#!cpp *c.begin()`.\n    \n## Return value\n\nIn case of a structured type (array or object), a reference to the first element is returned. In case of number, string,\nboolean, or binary values, a reference to the value is returned.\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n\nIf the JSON value is `#!json null`, exception\n[`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) is thrown.\n\n## Complexity\n\nConstant.\n\n## Notes\n\n!!! danger\n\n    Calling `front` on an empty array or object is undefined behavior and is **guarded by an assertion**!\n\n## Examples\n\n??? example\n\n    The following code shows an example for `front()`.\n     \n    ```cpp\n    --8<-- \"examples/front.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/front.output\"\n    ```\n\n## See also\n\n- [back](back.md) to access the last element\n\n## Version history\n\n- Added in version 1.0.0.\n- Adjusted code to return reference to binary values in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/get.md",
    "content": "# <small>nlohmann::basic_json::</small>get\n\n```cpp\n// (1)\ntemplate<typename ValueType>\nValueType get() const noexcept(\n    noexcept(JSONSerializer<ValueType>::from_json(\n        std::declval<const basic_json_t&>(), std::declval<ValueType&>())));\n\n// (2)\ntemplate<typename BasicJsonType>\nBasicJsonType get() const;\n\n// (3)\ntemplate<typename PointerType>\nPointerType get_ptr();\n\ntemplate<typename PointerType>\nconstexpr const PointerType get_ptr() const noexcept;\n```\n\n1. Explicit type conversion between the JSON value and a compatible value which is\n   [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and\n   [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). The value is converted by\n   calling the `json_serializer<ValueType>` `from_json()` method.\n   \n    The function is equivalent to executing\n    ```cpp\n    ValueType ret;\n    JSONSerializer<ValueType>::from_json(*this, ret);\n    return ret;\n    ```\n\n    This overload is chosen if:\n    \n    - `ValueType` is not `basic_json`,\n    - `json_serializer<ValueType>` has a `from_json()` method of the form\n      `void from_json(const basic_json&, ValueType&)`, and\n    - `json_serializer<ValueType>` does not have a `from_json()` method of the form\n      `ValueType from_json(const basic_json&)`\n\n    If the type is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and\n    **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible), the value is\n    converted by calling the `json_serializer<ValueType>` `from_json()` method.\n   \n    The function is then equivalent to executing\n    ```cpp\n    return JSONSerializer<ValueTypeCV>::from_json(*this);\n    ``` \n   \n    This overload is chosen if:\n    \n    - `ValueType` is not `basic_json` and\n    - `json_serializer<ValueType>` has a `from_json()` method of the form\n     `ValueType from_json(const basic_json&)`\n\n    If `json_serializer<ValueType>` has both overloads of `from_json()`, the latter one is chosen.\n\n2. Overload for `basic_json` specializations. The function is equivalent to executing\n    ```cpp\n    return *this;\n    ```\n\n3. Explicit pointer access to the internally stored JSON value. No copies are made.\n\n## Template parameters\n\n`ValueType`\n:   the value type to return\n\n`BasicJsonType`\n:   a specialization of `basic_json`\n\n`PointerType`\n:   pointer type; must be a pointer to [`array_t`](array_t.md), [`object_t`](object_t.md), [`string_t`](string_t.md),\n    [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or\n    [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md).\n    Other types will not compile.\n\n## Return value\n\n1. copy of the JSON value, converted to `ValueType`\n2. a copy of `#!cpp *this`, converted into `BasicJsonType`\n3. pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `#!cpp nullptr`\n   otherwise\n\n## Exceptions\n\nDepends on what `json_serializer<ValueType>` `from_json()` method throws\n\n## Notes\n\n!!! warning\n\n    Writing data to the pointee (overload 3) of the result yields an undefined state.\n\n## Examples\n\n??? example\n\n    The example below shows several conversions from JSON values\n    to other types. There a few things to note: (1) Floating-point numbers can\n    be converted to integers, (2) A JSON array can be converted to a standard\n    `std::vector<short>`, (3) A JSON object can be converted to C++\n    associative containers such as `std::unordered_map<std::string, json>`.\n        \n    ```cpp\n    --8<-- \"examples/get__ValueType_const.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/get__ValueType_const.output\"\n    ```\n\n??? example\n\n    The example below shows how pointers to internal values of a JSON value can be requested. Note that no type\n    conversions are made and a `#cpp nullptr` is returned if the value and the requested pointer type does not match.\n        \n    ```cpp\n    --8<-- \"examples/get__PointerType.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/get__PointerType.output\"\n    ```\n\n## Version history\n\n1. Since version 2.1.0.\n2. Since version 2.1.0. Extended to work with other specializations of `basic_json` in version 3.2.0.\n3. Since version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/get_allocator.md",
    "content": "# <small>nlohmann::basic_json::</small>get_allocator\n\n```cpp\nstatic allocator_type get_allocator();\n```\n\nReturns the allocator associated with the container.\n    \n## Return value\n\nassociated allocator\n\n## Version history\n\n- Unknown.\n\n!!! note\n\n    This documentation page is a stub.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/get_binary.md",
    "content": "# <small>nlohmann::basic_json::</small>get_binary\n\n```cpp\nbinary_t& get_binary();\n\nconst binary_t& get_binary() const;\n```\n\nReturns a reference to the stored binary value.\n\n## Return value\n\nReference to binary value.\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\nThrows [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if the value is not binary\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows how to query a binary value.\n     \n    ```cpp\n    --8<-- \"examples/get_binary.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/get_binary.output\"\n    ```\n\n## Version history\n\n- Added in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/get_ptr.md",
    "content": "# <small>nlohmann::basic_json::</small>get_ptr\n\n```cpp\ntemplate<typename PointerType>\nPointerType get_ptr() noexcept;\n\ntemplate<typename PointerType>\nconstexpr const PointerType get_ptr() const noexcept;\n```\n\nImplicit pointer access to the internally stored JSON value. No copies are made.\n\n## Template parameters\n\n`PointerType`\n:   pointer type; must be a pointer to [`array_t`](array_t.md), [`object_t`](object_t.md), [`string_t`](string_t.md),\n    [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or\n    [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md).\n    Other types will not compile.\n\n## Return value\n\npointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `#!cpp nullptr`\notherwise\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Notes\n\n!!! warning\n\n    Writing data to the pointee of the result yields an undefined state.\n\n## Examples\n\n??? example\n\n    The example below shows how pointers to internal values of a JSON value can be requested. Note that no type\n    conversions are made and a `#!cpp nullptr` is returned if the value and the requested pointer type does not match.\n    \n    ```cpp\n    --8<-- \"examples/get_ptr.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/get_ptr.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended to binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/get_ref.md",
    "content": "# <small>nlohmann::basic_json::</small>get_ref\n\n```cpp\ntemplate<typename ReferenceType>\nReferenceType get_ref();\n\ntemplate<typename ReferenceType>\nconst ReferenceType get_ref() const;\n```\n\nImplicit reference access to the internally stored JSON value. No copies are made.\n\n## Template parameters\n\n`ReferenceType`\n:   reference type; must be a reference to [`array_t`](array_t.md), [`object_t`](object_t.md),\n    [`string_t`](string_t.md), [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or\n    [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md).\n    Enforced by static assertion.\n\n## Return value\n\nreference to the internally stored JSON value if the requested reference type fits to the JSON value; throws\n[`type_error.303`](../../home/exceptions.md#jsonexceptiontype_error303) otherwise\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\nThrows [`type_error.303`](../../home/exceptions.md#jsonexceptiontype_error303) if the requested reference type does not\nmatch the stored JSON value type; example: `\"incompatible ReferenceType for get_ref, actual type is binary\"`.\n\n## Complexity\n\nConstant.\n\n## Notes\n\n!!! warning\n\n    Writing data to the referee of the result yields an undefined state.\n\n## Examples\n\n??? example\n\n    The example shows several calls to `get_ref()`.\n    \n    ```cpp\n    --8<-- \"examples/get_ref.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/get_ref.output\"\n    ```\n\n## Version history\n\n- Added in version 1.1.0.\n- Extended to binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/get_to.md",
    "content": "# <small>nlohmann::basic_json::</small>get_to\n\n```cpp\ntemplate<typename ValueType>\nValueType& get_to(ValueType& v) const noexcept(\n    noexcept(JSONSerializer<ValueType>::from_json(\n        std::declval<const basic_json_t&>(), v)));\n```\n\nExplicit type conversion between the JSON value and a compatible value. The value is filled into the input parameter by\ncalling the `json_serializer<ValueType>` `from_json()` method.\n\nThe function is equivalent to executing\n```cpp\nValueType v;\nJSONSerializer<ValueType>::from_json(*this, v);\n```\n\nThis overload is chosen if:\n\n- `ValueType` is not `basic_json`,\n- `json_serializer<ValueType>` has a `from_json()` method of the form `void from_json(const basic_json&, ValueType&)`\n\n## Template parameters\n\n`ValueType`\n:   the value type to return\n\n## Return value\n\nthe input parameter, allowing chaining calls\n\n## Exceptions\n\nDepends on what `json_serializer<ValueType>` `from_json()` method throws\n\n## Examples\n\n??? example\n\n    The example below shows several conversions from JSON values to other types. There a few things to note: (1)\n    Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard\n    `#!cpp std::vector<short>`, (3) A JSON object can be converted to C++ associative containers such as\n    `#cpp std::unordered_map<std::string, json>`.\n        \n    ```cpp\n    --8<-- \"examples/get_to.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/get_to.output\"\n    ```\n\n## Version history\n\n- Since version 3.3.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/index.md",
    "content": "# <small>nlohmann::</small>basic_json\n\n<small>Defined in header `<nlohmann/json.hpp>`</small>\n\n```cpp\ntemplate<\n    template<typename U, typename V, typename... Args> class ObjectType = std::map,\n    template<typename U, typename... Args> class ArrayType = std::vector,\n    class StringType = std::string,\n    class BooleanType = bool,\n    class NumberIntegerType = std::int64_t,\n    class NumberUnsignedType = std::uint64_t,\n    class NumberFloatType = double,\n    template<typename U> class AllocatorType = std::allocator,\n    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,\n    class BinaryType = std::vector<std::uint8_t>\n>\nclass basic_json;\n```\n\n## Template parameters\n\n| Template parameter   | Description                                                               | Derived type                                |\n|----------------------|---------------------------------------------------------------------------|---------------------------------------------|\n| `ObjectType`         | type for JSON objects                                                     | [`object_t`](object_t.md)                   |\n| `ArrayType`          | type for JSON arrays                                                      | [`array_t`](array_t.md)                     |\n| `StringType`         | type for JSON strings and object keys                                     | [`string_t`](string_t.md)                   |\n| `BooleanType`        | type for JSON booleans                                                    | [`boolean_t`](boolean_t.md)                 |\n| `NumberIntegerType`  | type for JSON integer numbers                                             | [`number_integer_t`](number_integer_t.md)   |\n| `NumberUnsignedType` | type for JSON unsigned integer numbers                                    | [`number_unsigned_t`](number_unsigned_t.md) |\n| `NumberFloatType`    | type for JSON floating-point numbers                                      | [`number_float_t`](number_float_t.md)       |\n| `AllocatorType`      | type of the allocator to use                                              |                                             |\n| `JSONSerializer`     | the serializer to resolve internal calls to `to_json()` and `from_json()` | [`json_serializer`](json_serializer.md)     |\n| `BinaryType`         | type for binary arrays                                                    | [`binary_t`](binary_t.md)                   |\n\n## Specializations\n\n- [**json**](../json.md) - default specialization\n- [**ordered_json**](../ordered_json.md) - specialization that maintains the insertion order of object keys\n\n## Iterator invalidation\n\nTodo\n\n## Requirements\n\nThe class satisfies the following concept requirements:\n\n### Basic\n\n- [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): JSON values can be default\n  constructed. The result will be a JSON null value.\n- [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): A JSON value can be constructed\n  from an rvalue argument.\n- [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): A JSON value can be\n  copy-constructed from an lvalue expression.\n- [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): A JSON value van be assigned from an\n  rvalue argument.\n- [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): A JSON value can be copy-assigned from\n  an lvalue expression.\n- [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): JSON values can be destructed.\n\n### Layout\n\n- [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): JSON values have\n  [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): All non-static data\n  members are private and standard layout types, the class has no virtual functions or (virtual) base classes.\n\n### Library-wide\n\n- [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): JSON values can be compared with\n  `==`, see [`operator==`](operator_eq.md).\n- [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): JSON values can be compared with\n  `<`, see [`operator<`](operator_le).\n- [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): Any JSON lvalue or rvalue of can be swapped with\n  any lvalue or rvalue of other compatible types, using unqualified function `swap`.\n- [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): JSON values can be compared against\n  `std::nullptr_t` objects which are used to model the `null` value.\n\n### Container\n\n- [Container](https://en.cppreference.com/w/cpp/named_req/Container): JSON values can be used like STL containers and\n  provide iterator access.\n- [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer): JSON values can be used like\n  STL containers and provide reverse iterator access.\n\n## Member types\n\n- [**adl_serializer**](../adl_serializer) - the default serializer\n- [**value_t**](value_t.md) - the JSON type enumeration\n- [**json_pointer**](../json_pointer/index.md) - JSON Pointer implementation\n- [**json_serializer**](json_serializer.md) - type of the serializer to for conversions from/to JSON\n- [**error_handler_t**](error_handler_t.md) - type to choose behavior on decoding errors\n- [**cbor_tag_handler_t**](cbor_tag_handler_t.md) - type to choose how to handle CBOR tags\n- **initializer_list_t** - type for initializer lists of `basic_json` values\n- [**input_format_t**](input_format_t.md) - type to choose the format to parse\n- [**json_sax_t**](../json_sax/index.md) - type for SAX events\n\n### Exceptions\n\n- [**exception**](exception.md) - general exception of the `basic_json` class\n    - [**parse_error**](parse_error.md) - exception indicating a parse error\n    - [**invalid_iterator**](invalid_iterator.md) - exception indicating errors with iterators\n    - [**type_error**](type_error.md) - exception indicating executing a member function with a wrong type\n    - [**out_of_range**](out_of_range.md) - exception indicating access out of the defined range\n    - [**other_error**](other_error.md) - exception indicating other library errors\n\n### Container types\n\n| Type                     | Definition                                                                                                |\n|--------------------------|-----------------------------------------------------------------------------------------------------------|\n| `value_type`             | `#!cpp basic_json`                                                                                        |\n| `reference`              | `#!cpp value_type&`                                                                                       |\n| `const_reference`        | `#!cpp const value_type&`                                                                                 |\n| `difference_type`        | `#!cpp std::ptrdiff_t`                                                                                    |\n| `size_type`              | `#!cpp std::size_t`                                                                                       |\n| `allocator_type`         | `#!cpp AllocatorType<basic_json>`                                                                         |\n| `pointer`                | `#!cpp std::allocator_traits<allocator_type>::pointer`                                                    |\n| `const_pointer`          | `#!cpp std::allocator_traits<allocator_type>::const_pointer`                                              |\n| `iterator`               | [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator)          |\n| `const_iterator`         | constant [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) |\n| `reverse_iterator`       | reverse iterator, derived from `iterator`                                                                 |\n| `const_reverse_iterator` | reverse iterator, derived from `const_iterator`                                                           |\n| `iteration_proxy`        | helper type for [`items`](items.md) function                                                              |\n\n### JSON value data types\n\n- [**array_t**](array_t.md) - type for arrays\n- [**binary_t**](binary_t.md) - type for binary arrays\n- [**boolean_t**](boolean_t.md) - type for booleans\n- [**number_float_t**](number_float_t.md) - type for numbers (floating-point)\n- [**number_integer_t**](number_integer_t.md) - type for numbers (integer)\n- [**number_unsigned_t**](number_unsigned_t.md) - type for numbers (unsigned)\n- [**object_comparator_t**](object_comparator_t.md) - comparator for objects\n- [**object_t**](object_t.md) - type for objects\n- [**string_t**](string_t.md) - type for strings\n\n### Parser callback\n\n- [**parse_event_t**](parse_event_t.md) - parser event types\n- [**parser_callback_t**](parser_callback_t.md) - per-element parser callback type\n\n## Member functions\n\n- [(constructor)](basic_json.md)\n- [(destructor)](~basic_json.md)\n- [**operator=**](operator=.md) - copy assignment\n- [**array**](array_t.md) (_static_) - explicitly create an array\n- [**binary**](binary.md) (_static_) - explicitly create a binary array\n- [**object**](object_t.md) (_static_) - explicitly create an object\n\n### Object inspection\n\nFunctions to inspect the type of a JSON value.\n\n- [**type**](type.md) - return the type of the JSON value\n- [**operator value_t**](operator_value_t.md) - return the type of the JSON value\n- [**type_name**](type_name.md) - return the type as string\n- [**is_primitive**](is_primitive.md) - return whether type is primitive\n- [**is_structured**](is_structured.md) - return whether type is structured\n- [**is_null**](is_null.md) - return whether value is null\n- [**is_boolean**](is_boolean.md) - return whether value is a boolean\n- [**is_number**](is_number.md) - return whether value is a number\n- [**is_number_integer**](is_number_integer.md) - return whether value is an integer number\n- [**is_number_unsigned**](is_number_unsigned.md) - return whether value is an unsigned integer number\n- [**is_number_float**](is_number_float.md) - return whether value is a floating-point number\n- [**is_object**](is_object.md) - return whether value is an object\n- [**is_array**](is_array.md) - return whether value is an array\n- [**is_string**](is_string.md) - return whether value is a string\n- [**is_binary**](is_binary.md) - return whether value is a binary array\n- [**is_discarded**](is_discarded.md) - return whether value is discarded\n\n### Value access\n\nDirect access to the stored value of a JSON value.\n\n- [**get**](get.md) - get a value\n- [**get_to**](get_to.md) - get a value and write it to a destination\n- [**get_ptr**](get_ptr.md) - get a pointer value\n- [**get_ref**](get_ref.md) - get a reference value\n- [**operator ValueType**](operator_ValueType.md) - get a value\n- [**get_binary**](get_binary.md) - get a binary value\n\n### Element access\n\nAccess to the JSON value\n\n- [**at**](at.md) - access specified element with bounds checking\n- [**operator[]**](operator[].md) - access specified element\n- [**value**](value.md) - access specified object element with default value\n- [**front**](front.md) - access the first element\n- [**back**](back.md) - access the last element\n\n### Lookup\n\n- [**find**](find.md) - find an element in a JSON object\n- [**count**](count.md) - returns the number of occurrences of a key in a JSON object\n- [**contains**](contains.md) - check the existence of an element in a JSON object\n\n### Iterators\n\n- [**begin**](begin.md) - returns an iterator to the first element\n- [**cbegin**](cbegin.md) - returns a const iterator to the first element\n- [**end**](end.md) - returns an iterator to one past the last element\n- [**cend**](cend.md) - returns a const iterator to one past the last element\n- [**rbegin**](rbegin.md) - returns an iterator to the reverse-beginning\n- [**rend**](rend.md) - returns an iterator to the reverse-end\n- [**crbegin**](crbegin.md) - returns a const iterator to the reverse-beginning\n- [**crend**](crend.md) - returns a const iterator to the reverse-end\n- [**items**](items.md) - wrapper to access iterator member functions in range-based for\n\n### Capacity\n\n- [**empty**](empty.md) - checks whether the container is empty\n- [**size**](size.md) - returns the number of elements\n- [**max_size**](max_size.md) - returns the maximum possible number of elements\n\n### Modifiers\n\n- [**clear**](clear.md) - clears the contents\n- [**push_back**](push_back.md) - add a value to an array/object\n- [**operator+=**](operator+=.md) - add a value to an array/object\n- [**emplace_back**](emplace_back.md) - add a value to an array\n- [**emplace**](emplace.md) - add a value to an object if key does not exist\n- [**erase**](erase.md) - remove elements\n- [**insert**](insert.md) - inserts elements\n- [**update**](update.md) - updates a JSON object from another object, overwriting existing keys \n- [**swap**](swap.md) - exchanges the values\n\n### Lexicographical comparison operators\n\n- [**operator==**](operator_eq.md) - comparison: equal\n- [**operator!=**](operator_ne.md) - comparison: not equal\n- [**operator<**](operator_lt.md) - comparison: less than\n- [**operator<=**](operator_le.md) - comparison: less than or equal\n- [**operator>**](operator_gt.md) - comparison: greater than\n- [**operator>=**](operator_ge.md) - comparison: greater than or equal\n\n### Serialization / Dumping\n\n- [**dump**](dump.md) - serialization\n\n### Deserialization / Parsing\n\n- [**parse**](parse.md) (_static_) - deserialize from a compatible input\n- [**accept**](accept.md) (_static_) - check if the input is valid JSON\n- [**sax_parse**](sax_parse.md) (_static_) - generate SAX events\n\n### JSON Pointer functions\n\n- [**flatten**](flatten.md) - return flattened JSON value\n- [**unflatten**](unflatten.md) - unflatten a previously flattened JSON value\n\n### JSON Patch functions\n\n- [**patch**](patch.md) - applies a JSON patch\n- [**diff**](diff.md) (_static_) - creates a diff as a JSON patch\n\n### JSON Merge Patch functions\n\n- [**merge_patch**](merge_patch.md) - applies a JSON Merge Patch\n\n## Static functions\n\n- [**meta**](meta.md) - returns version information on the library\n- [**get_allocator**](get_allocator.md) - returns the allocator associated with the container\n\n### Binary formats\n\n- [**from_bson**](from_bson.md) (_static_) - create a JSON value from an input in BSON format\n- [**from_cbor**](from_cbor.md) (_static_) - create a JSON value from an input in CBOR format\n- [**from_msgpack**](from_msgpack.md) (_static_) - create a JSON value from an input in MessagePack format\n- [**from_ubjson**](from_ubjson.md) (_static_) - create a JSON value from an input in UBJSON format\n- [**to_bson**](to_bson.md) (_static_) - create a BSON serialization of a given JSON value\n- [**to_cbor**](to_cbor.md) (_static_) - create a CBOR serialization of a given JSON value\n- [**to_msgpack**](to_msgpack.md) (_static_) - create a MessagePack serialization of a given JSON value\n- [**to_ubjson**](to_ubjson.md) (_static_) - create a UBJSON serialization of a given JSON value\n\n## Non-member functions\n\n- [**operator<<(std::ostream&)**](operator_ltlt.md) - serialize to stream\n- [**operator>>(std::istream&)**](operator_gtgt.md) - deserialize from stream\n- [**to_string**](to_string.md) - user-defined `to_string` function for JSON values\n\n## Literals\n\n- [**operator\"\"_json**](operator_literal_json.md) - user-defined string literal for JSON values\n- [**operator\"\"_json_pointer**](operator_literal_json_pointer.md) - user-defined string literal for JSON pointers\n\n## Helper classes\n\n- [**std::hash&lt;basic_json&gt;**](std_hash.md) - return a hash value for a JSON object\n- [**std::swap&lt;basic_json&gt;**](std_swap.md) - exchanges the values of two JSON objects\n\n## Example\n\n??? example\n\n    The example shows how the library is used.\n    \n    ```cpp\n    --8<-- \"examples/README.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/README.output\"\n    ```\n\n## See also\n\n- [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259)\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/input_format_t.md",
    "content": "# <small>nlohmann::basic_json::</small>input_format_t\n\n```cpp\nenum class input_format_t {\n    json,\n    cbor,\n    msgpack,\n    ubjson,\n    bson\n};\n```\n\nThis enumeration is used in the [`sax_parse`](sax_parse.md) function to choose the input format to parse:\n\njson\n:   JSON (JavaScript Object Notation)\n\ncbor\n:   CBOR (Concise Binary Object Representation)\n\nmsgpack\n:   MessagePack\n\nubjson\n:   UBJSON (Universal Binary JSON)\n\nbson\n:   BSON (Binary JSON)\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/insert.md",
    "content": "# <small>nlohmann::basic_json::</small>insert\n\n```cpp\n// (1)\niterator insert(const_iterator pos, const basic_json& val);\niterator insert(const_iterator pos, basic_json&& val);\n\n// (2)\niterator insert(const_iterator pos, size_type cnt, const basic_json& val);\n\n// (3)\niterator insert(const_iterator pos, const_iterator first, const_iterator last);\n\n// (4)\niterator insert(const_iterator pos, initializer_list_t ilist);\n\n// (5)\nvoid insert(const_iterator first, const_iterator last);\n```\n\n1. Inserts element `val` into array before iterator `pos`.\n2. Inserts `cnt` copies of `val` into array before iterator `pos`.\n3. Inserts elements from range `[first, last)` into array before iterator `pos`.\n4. Inserts elements from initializer list `ilist` into array before iterator `pos`.\n5. Inserts elements from range `[first, last)` into object.\n\n## Parameters\n\n`pos` (in)\n:   iterator before which the content will be inserted; may be the `end()` iterator\n\n`val` (in)\n:   value to insert\n\n`cnt` (in)\n:   number of copies of `val` to insert\n\n`first` (in)\n:   begin of the range of elements to insert\n\n`last` (in)\n:   end of the range of elements to insert\n\n`ilist` (in)\n:   initializer list to insert the values from\n    \n## Return value\n\n1. iterator pointing to the inserted `val`.\n2. iterator pointing to the first element inserted, or `pos` if `#!cpp cnt==0`\n3. iterator pointing to the first element inserted, or `pos` if `#!cpp first==last`\n4. iterator pointing to the first element inserted, or `pos` if `ilist` is empty\n5. /\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than\n      arrays; example: `\"cannot use insert() with string\"`\n    - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an\n      iterator which does not belong to the current JSON value; example: `\"iterator does not fit current value\"`\n2. The function can throw the following exceptions:\n    - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than\n      arrays; example: `\"cannot use insert() with string\"`\n    - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an\n      iterator which does not belong to the current JSON value; example: `\"iterator does not fit current value\"`\n3. The function can throw the following exceptions:\n    - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than\n      arrays; example: `\"cannot use insert() with string\"`\n    - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an\n      iterator which does not belong to the current JSON value; example: `\"iterator does not fit current value\"`\n    - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last`\n      do not belong to the same JSON value; example: `\"iterators do not fit\"`\n    - Throws [`invalid_iterator.211`](../../home/exceptions.md#jsonexceptioninvalid_iterator211) if `first` or `last`\n      are iterators into container for which insert is called; example: `\"passed iterators may not belong to container\"`\n4. The function can throw the following exceptions:\n    - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than\n      arrays; example: `\"cannot use insert() with string\"`\n    - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an\n      iterator which does not belong to the current JSON value; example: `\"iterator does not fit current value\"`\n5. The function can throw the following exceptions:\n    - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than\n      objects; example: `\"cannot use insert() with string\"`\n    - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an\n      iterator which does not belong to the current JSON value; example: `\"iterator does not fit current value\"`\n    - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last`\n      do not belong to the same JSON value; example: `\"iterators do not fit\"`\n\n## Complexity\n\n1. Constant plus linear in the distance between `pos` and end of the container.\n2. Linear in `cnt` plus linear in the distance between `pos` and end of the container.\n3. Linear in `#!cpp std::distance(first, last)` plus linear in the distance between `pos` and end of the container.\n4. Linear in `ilist.size()` plus linear in the distance between `pos` and end of the container.\n5. Logarithmic: `O(N*log(size() + N))`, where `N` is the number of elements to insert.\n\n## Examples\n\n??? example \"Example (1): insert element into array\"\n\n    The example shows how `insert()` is used.\n    \n    ```cpp\n    --8<-- \"examples/insert.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/insert.output\"\n    ```\n\n??? example \"Example (2): insert copies of element into array\"\n\n    The example shows how `insert()` is used.\n    \n    ```cpp\n    --8<-- \"examples/insert__count.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/insert__count.output\"\n    ```\n\n??? example \"Example (3): insert range of elements into array\"\n\n    The example shows how `insert()` is used.\n    \n    ```cpp\n    --8<-- \"examples/insert__range.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/insert__range.output\"\n    ```\n\n??? example \"Example (4): insert elements from initializer list into array\"\n\n    The example shows how `insert()` is used.\n    \n    ```cpp\n    --8<-- \"examples/insert__ilist.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/insert__ilist.output\"\n    ```\n\n??? example \"Example (5): insert range of elements into object\"\n\n    The example shows how `insert()` is used.\n    \n    ```cpp\n    --8<-- \"examples/insert__range_object.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/insert__range_object.output\"\n    ```\n\n## Version history\n\n1. Added in version 1.0.0.\n2. Added in version 1.0.0.\n3. Added in version 1.0.0.\n4. Added in version 1.0.0.\n5. Added in version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/invalid_iterator.md",
    "content": "# <small>nlohmann::basic_json::</small>invalid_iterator\n\n```cpp\nclass invalid_iterator : public exception;\n```\n\nThis exception is thrown if iterators passed to a library function do not match the expected semantics.\n\nExceptions have ids 2xx (see [list of iterator errors](../../home/exceptions.md#iterator-errors)).\n\n```plantuml\nstd::exception <|-- basic_json::exception\nbasic_json::exception <|-- basic_json::parse_error\nbasic_json::exception <|-- basic_json::invalid_iterator\nbasic_json::exception <|-- basic_json::type_error\nbasic_json::exception <|-- basic_json::out_of_range\nbasic_json::exception <|-- basic_json::other_error\n\ninterface std::exception {}\n\nclass basic_json::exception {\n    + const int id\n    + const char* what() const\n}\n\nclass basic_json::parse_error {\n    + const std::size_t byte\n}\n\nclass basic_json::invalid_iterator #FFFF00 {}\n```\n\n## Member functions\n\n- **what** - returns explanatory string\n\n## Member variables\n\n- **id** - the id of the exception\n\n## Examples\n\n??? example\n\n    The following code shows how a `invalid_iterator` exception can be caught.\n    \n    ```cpp\n    --8<-- \"examples/invalid_iterator.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/invalid_iterator.output\"\n    ```\n\n## See also\n\n- [List of iterator errors](../../home/exceptions.md#iterator-errors)\n- [`parse_error`](parse_error.md) for exceptions indicating a parse error\n- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type\n- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range\n- [`other_error`](other_error.md) for exceptions indicating other library errors\n\n## Version history\n\n- Since version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_array.md",
    "content": "# <small>nlohmann::basic_json::</small>is_array\n\n```cpp\nconstexpr bool is_array() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is an array.\n    \n## Return value\n\n`#!cpp true` if type is an array, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_array()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_array.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_array.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_binary.md",
    "content": "# <small>nlohmann::basic_json::</small>is_binary\n\n```cpp\nconstexpr bool is_binary() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is binary array.\n    \n## Return value\n\n`#!cpp true` if type is binary, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_binary()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_binary.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_binary.output\"\n    ```\n\n## Version history\n\n- Added in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_boolean.md",
    "content": "# <small>nlohmann::basic_json::</small>is_boolean\n\n```cpp\nconstexpr bool is_boolean() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is `#!json true` or `#!json false`.\n    \n## Return value\n\n`#!cpp true` if type is boolean, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_boolean()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_boolean.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_boolean.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_discarded.md",
    "content": "# <small>nlohmann::basic_json::</small>is_discarded\n\n```cpp\nconstexpr bool is_discarded() const noexcept;\n```\n\nThis function returns `#!cpp true` for a JSON value if either:\n\n- the value was discarded during parsing with a callback function (see [`parser_callback_t`](parser_callback_t.md)), or\n- the value is the result of parsing invalid JSON with parameter `allow_exceptions` set to `#!cpp false`; see\n  [`parse`](parse.md) for more information.\n\n## Return value\n\n`#!cpp true` if type is discarded, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Notes\n\n!!! note\n\n    Discarded values are never compared equal with [`operator==`](operator_eq.md). That is, checking whether a JSON\n    value `j` is discarded will only work via:\n    \n    ```cpp\n    j.is_discarded()\n    ```\n    \n    because\n    \n    ```cpp\n    j == json::value_t::discarded\n    ```\n    \n    will always be `#!cpp false`.\n\n!!! note\n\n    When a value is discarded by a callback function (see [`parser_callback_t`](parser_callback_t.md)) during parsing,\n    then it is removed when it is part of a structured value. For instance, if the second value of an array is discared,\n    instead of `#!json [null, discarded, false]`, the array `#!json [null, false]` is returned. Only if the top-level\n    value is discarded, the return value of the `parse` call is discarded.\n\nThis function will always be `#!cpp false` for JSON values after parsing. That is, discarded values can only occur\nduring parsing, but will be removed when inside a structured value or replaced by null in other cases.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_discarded()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_discarded.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_discarded.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_null.md",
    "content": "# <small>nlohmann::basic_json::</small>is_null\n\n```cpp\nconstexpr bool is_null() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is `#!json null`.\n    \n## Return value\n\n`#!cpp true` if type is `#!json null`, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_null()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_null.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_null.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_number.md",
    "content": "# <small>nlohmann::basic_json::</small>is_number\n\n```cpp\nconstexpr bool is_number() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is a number. This includes both integer (signed and\nunsigned) and floating-point values.\n    \n## Return value\n\n`#!cpp true` if type is number (regardless whether integer, unsigned integer or floating-type), `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Possible implementation\n\n```cpp\nconstexpr bool is_number() const noexcept\n{\n    return is_number_integer() || is_number_float();\n}\n```\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_number()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_number.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_number.output\"\n    ```\n\n## See also\n\n- [is_number_integer()](is_number_integer.md) check if value is an integer or unsigned integer number\n- [is_number_unsigned()](is_number_unsigned.md) check if value is an unsigned integer number\n- [is_number_float()](is_number_float.md) check if value is a floating-point number\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended to also return `#!cpp true` for unsigned integers in 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_number_float.md",
    "content": "# <small>nlohmann::basic_json::</small>is_number_float\n\n```cpp\nconstexpr bool is_number_float() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is a floating-point number. This excludes signed and\nunsigned integer values.\n    \n## Return value\n\n`#!cpp true` if type is a floating-point number, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_number_float()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_number_float.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_number_float.output\"\n    ```\n\n## See also\n\n- [is_number()](is_number.md) check if value is a number\n- [is_number_integer()](is_number_integer.md) check if value is an integer or unsigned integer number\n- [is_number_unsigned()](is_number_unsigned.md) check if value is an unsigned integer number\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_number_integer.md",
    "content": "# <small>nlohmann::basic_json::</small>is_number_integer\n\n```cpp\nconstexpr bool is_number_integer() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is a signed or unsigned integer number. This excludes\nfloating-point values.\n    \n## Return value\n\n`#!cpp true` if type is an integer or unsigned integer number, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_number_integer()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_number_integer.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_number_integer.output\"\n    ```\n\n## See also\n\n- [is_number()](is_number.md) check if value is a number\n- [is_number_unsigned()](is_number_unsigned.md) check if value is an unsigned integer number\n- [is_number_float()](is_number_float.md) check if value is a floating-point number\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended to also return `#!cpp true` for unsigned integers in 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_number_unsigned.md",
    "content": "# <small>nlohmann::basic_json::</small>is_number_unsigned\n\n```cpp\nconstexpr bool is_number_unsigned() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is an unsigned integer number. This excludes\nfloating-point and signed integer values.\n    \n## Return value\n\n`#!cpp true` if type is an unsigned integer number, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_number_unsigned()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_number_unsigned.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_number_unsigned.output\"\n    ```\n\n## See also\n\n- [is_number()](is_number.md) check if value is a number\n- [is_number_integer()](is_number_integer.md) check if value is an integer or unsigned integer number\n- [is_number_float()](is_number_float.md) check if value is a floating-point number\n\n## Version history\n\n- Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_object.md",
    "content": "# <small>nlohmann::basic_json::</small>is_object\n\n```cpp\nconstexpr bool is_object() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is an object.\n    \n## Return value\n\n`#!cpp true` if type is an object, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_object()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_object.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_object.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_primitive.md",
    "content": "# <small>nlohmann::basic_json::</small>is_primitive\n\n```cpp\nconstexpr bool is_primitive() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON type is primitive (string, number, boolean, `#!json null`,\nbinary).\n    \n## Return value\n\n`#!cpp true` if type is primitive (string, number, boolean, `#!json null`, or binary), `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Possible implementation\n\n```cpp\nconstexpr bool is_primitive() const noexcept\n{\n    return is_null() || is_string() || is_boolean() || is_number() || is_binary();\n}\n```\n\n## Notes\n\nThe term *primitive* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259):\n\n> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and\n> arrays).\n\nThis library extends primitive types to binary types, because binary types are  roughly comparable to strings. Hence,\n`is_primitive()` returns `#!cpp true` for binary values.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_primitive()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_primitive.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_primitive.output\"\n    ```\n\n## See also\n\n- [is_structured()](is_structured.md) returns whether JSON value is structured\n- [is_null()](is_null.md) returns whether JSON value is `null`\n- [is_string()](is_string.md) returns whether JSON value is a string\n- [is_boolean()](is_boolean.md) returns whether JSON value is a boolean\n- [is_number()](is_number.md) returns whether JSON value is a number\n- [is_binary()](is_binary.md) returns whether JSON value is a binary array\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended to return `#!cpp true` for binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_string.md",
    "content": "# <small>nlohmann::basic_json::</small>is_string\n\n```cpp\nconstexpr bool is_string() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON value is a string.\n    \n## Return value\n\n`#!cpp true` if type is a string, `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_string()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_string.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_string.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/is_structured.md",
    "content": "# <small>nlohmann::basic_json::</small>is_structured\n\n```cpp\nconstexpr bool is_structured() const noexcept;\n```\n\nThis function returns `#!cpp true` if and only if the JSON type is structured (array or object).\n    \n## Return value\n\n`#!cpp true` if type is structured (array or object), `#!cpp false` otherwise.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Possible implementation\n\n```cpp\nconstexpr bool is_primitive() const noexcept\n{\n    return is_array() || is_object();\n}\n```\n\n## Notes\n\nThe term *structured* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259):\n\n> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and\n> arrays).\n\nNote that though strings are containers in C++, they are treated as primitive values in JSON.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `is_structured()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/is_structured.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/is_structured.output\"\n    ```\n\n## See also\n\n- [is_primitive()](is_primitive.md) returns whether JSON value is primitive\n- [is_array()](is_array.md) returns whether value is an array\n- [is_object()](is_object.md) returns whether value is an object\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/items.md",
    "content": "# <small>nlohmann::basic_json::</small>items\n\n```cpp\niteration_proxy<iterator> items() noexcept;\niteration_proxy<const_iterator> items() const noexcept;\n```\n\nThis function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a\nreference to the JSON values is returned, so there is no access to the underlying iterator.\n\nFor loop without `items()` function:\n\n```cpp\nfor (auto it = j_object.begin(); it != j_object.end(); ++it)\n{\n    std::cout << \"key: \" << it.key() << \", value:\" << it.value() << '\\n';\n}\n```\n\nRange-based for loop without `items()` function:\n\n```cpp\nfor (auto it : j_object)\n{\n    // \"it\" is of type json::reference and has no key() member\n    std::cout << \"value: \" << it << '\\n';\n}\n```\n\nRange-based for loop with `items()` function:\n\n```cpp\nfor (auto& el : j_object.items())\n{\n    std::cout << \"key: \" << el.key() << \", value:\" << el.value() << '\\n';\n}\n```\n\nThe `items()` function also allows using\n[structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) (C++17):\n\n```cpp\nfor (auto& [key, val] : j_object.items())\n{\n    std::cout << \"key: \" << key << \", value:\" << val << '\\n';\n}\n```\n\n## Return value\n\niteration proxy object wrapping the current value with an interface to use in range-based for loops\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nConstant.\n\n## Notes\n\nWhen iterating over an array, `key()` will return the index of the element as string (see example). For primitive types\n(e.g., numbers), `key()` returns an empty string.\n\n!!! warning\n\n    Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See\n    <https://github.com/nlohmann/json/issues/2040> for more information.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `items()`.\n    \n    ```cpp\n    --8<-- \"examples/items.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/items.output\"\n    ```\n\n## Version history\n\n- Added `iterator_wrapper` in version 3.0.0.\n- Added `items` and deprecated `iterator_wrapper` in version 3.1.0.\n- Added structured binding support in version 3.5.0.\n\n!!! warning \"Deprecation\"\n\n    This function replaces the static function `iterator_wrapper` which was introduced in version 1.0.0, but has been\n    deprecated in version 3.1.0. Function `iterator_wrapper` will be removed in version 4.0.0. Please replace all\n    occurrences of `#!cpp iterator_wrapper(j)` with `#!cpp j.items()`.\n\n    You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated\n    function.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/json_serializer.md",
    "content": "# <small>nlohmann::basic_json::</small>json_serializer\n\n```cpp\ntemplate<typename T, typename SFINAE>\nusing json_serializer = JSONSerializer<T, SFINAE>;\n```\n\n## Template parameters\n\n`T`\n:   type to convert; will be used in the `to_json`/`from_json` functions\n\n`SFINAE`\n:   type to add compile type checks via SFINAE; usually `#!cpp void`\n\n## Notes\n\n#### Default type\n\nThe default values for `json_serializer` is [`adl_serializer`](../adl_serializer).\n\n## Version history\n\n- Since version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/max_size.md",
    "content": "# <small>nlohmann::basic_json::</small>max_size\n\n```cpp\nsize_type max_size() const noexcept;\n```\n\nReturns the maximum number of elements a JSON value is able to hold due to system or library implementation limitations,\ni.e. `std::distance(begin(), end())` for the JSON value.\n    \n## Return value\n\nThe return value depends on the different types and is defined as follows:\n\n| Value type | return value                              |\n|------------|-------------------------------------------|\n| null       | `0` (same as [`size()`](size.md))         |\n| boolean    | `1` (same as [`size()`](size.md))         |\n| string     | `1` (same as [`size()`](size.md))         |\n| number     | `1` (same as [`size()`](size.md))         |\n| binary     | `1` (same as [`size()`](size.md))         |\n| object     | result of function `object_t::max_size()` |\n| array      | result of function `array_t::max_size()`  |\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the\n[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `max_size()` functions have\nconstant complexity.\n\n## Notes\n\nThis function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of\nstring elements the JSON value can store which is `1`.\n\n## Examples\n\n??? example\n\n    The following code calls `max_size()` on the different value types. Note the output is implementation specific.\n        \n    ```cpp\n    --8<-- \"examples/max_size.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/max_size.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended to return `1` for binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/merge_patch.md",
    "content": "# <small>nlohmann::basic_json::</small>merge_patch\n\n```cpp\nvoid merge_patch(const basic_json& apply_patch);\n```\n\nThe merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of\nmodifications to a target resource's content. This function applies a merge patch to the current JSON value.\n\nThe function implements the following algorithm from Section 2 of\n[RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):\n\n```python\ndefine MergePatch(Target, Patch):\n  if Patch is an Object:\n    if Target is not an Object:\n      Target = {} // Ignore the contents and set it to an empty Object\n    for each Name/Value pair in Patch:\n      if Value is null:\n        if Name exists in Target:\n          remove the Name/Value pair from Target\n      else:\n        Target[Name] = MergePatch(Target[Name], Value)\n    return Target\n  else:\n    return Patch\n```\n\nThereby, `Target` is the current object; that is, the patch is applied to the current value.\n\n## Parameters\n\n`apply_patch` (in)\n:   the patch to apply\n\n## Complexity\n\nLinear in the lengths of `apply_patch`.\n\n## Examples\n\n??? example\n\n    The following code shows how a JSON Merge Patch is applied to a JSON document.\n     \n    ```cpp\n    --8<-- \"examples/merge_patch.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/merge_patch.output\"\n    ```\n\n## See also\n\n- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)\n- [patch](patch.md) apply a JSON patch\n\n## Version history\n\n- Added in version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/meta.md",
    "content": "# <small>nlohmann::basic_json::</small>meta\n\n```cpp\nstatic basic_json meta();\n```\n\nThis function returns a JSON object with information about the library, including the version number and information on\nthe platform and compiler.\n    \n## Return value\n\nJSON object holding version information\n\n| key         | description                                                                                                                                                                                                                                                                    |\n|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `compiler`  | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). |\n| `copyright` | The copyright line for the library as string.                                                                                                                                                                                                                                  |\n| `name`      | The name of the library as string.                                                                                                                                                                                                                                             |\n| `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.                                                                                                                                                                             |\n| `url`       | The URL of the project as string.                                                                                                                                                                                                                                              |\n| `version`   | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).                                                                                  |\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes to any JSON value.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example output of the `meta()`\n    function.\n    \n    ```cpp\n    --8<-- \"examples/meta.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/meta.output\"\n    ```\n\n## Version history\n\n- Added in version 2.1.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/number_float_t.md",
    "content": "# <small>nlohmann::basic_json::</small>number_float_t\n\n```cpp\nusing number_float_t = NumberFloatType;\n```\n\nThe type used to store JSON numbers (floating-point).\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:\n> The representation of numbers is similar to that used in most programming languages. A number is represented in base\n> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may\n> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that\n> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.\n\nThis description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is\nknown whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different\ntypes, [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md) and `number_float_t` are\nused.\n\nTo store floating-point numbers in C++, a type is defined by the template parameter `NumberFloatType` which chooses the\ntype to use.\n\n## Notes\n\n#### Default type\n\nWith the default values for `NumberFloatType` (`double`), the default value for `number_float_t` is `#!cpp double`.\n\n#### Default behavior\n\n- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in floating-point literals will be\n  ignored. Internally, the value will be stored as decimal number. For instance, the C++ floating-point literal `01.2`\n  will be serialized to `1.2`. During deserialization, leading zeros yield an error.\n- Not-a-number (NaN) values will be serialized to `null`.\n\n#### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) states:\n> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software\n> that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good\n> interoperability can be achieved by implementations that expect no more precision or range than these provide, in the\n> sense that implementations will approximate JSON numbers within the expected precision.\n\nThis implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values\nsmaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally\nand be serialized to `null`.\n\n#### Storage\n\nFloating-point number values are stored directly inside a `basic_json` type.\n\n## Examples\n\n??? example\n\n    The following code shows that `number_float_t` is by default, a typedef to `#!cpp double`.\n     \n    ```cpp\n    --8<-- \"examples/number_float_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/number_float_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/number_integer_t.md",
    "content": "# <small>nlohmann::basic_json::</small>number_integer_t\n\n```cpp\nusing number_integer_t = NumberIntegerType;\n```\n\nThe type used to store JSON numbers (integers).\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:\n> The representation of numbers is similar to that used in most programming languages. A number is represented in base\n> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may\n> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that\n> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.\n\nThis description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is\nknown whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different\ntypes, `number_integer_t`,  [`number_unsigned_t`](number_unsigned_t.md) and [`number_float_t`](number_float_t.md) are\nused.\n\nTo store integer numbers in C++, a type is defined by the template parameter `NumberIntegerType` which chooses the type\nto use.\n\n## Notes\n\n#### Default type\n\nWith the default values for `NumberIntegerType` (`std::int64_t`), the default value for `number_integer_t` is\n`#!cpp std::int64_t`.\n\n#### Default behavior\n\n- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an\n  interpretation as octal number. Internally, the value will be stored as decimal number. For instance, the C++ integer\n  literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error.\n- Not-a-number (NaN) values will be serialized to `null`.\n\n#### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:\n> An implementation may set limits on the range and precision of numbers.\n\nWhen the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and\nthe minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of\nrange will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers\nwill be automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md).\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:\n> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are\n> interoperable in the sense that implementations will agree exactly on their numeric values.\n\nAs this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is\ninteroperable.\n\n#### Storage\n\nInteger number values are stored directly inside a `basic_json` type.\n\n## Examples\n\n??? example\n\n    The following code shows that `number_integer_t` is by default, a typedef to `#!cpp std::int64_t`.\n     \n    ```cpp\n    --8<-- \"examples/number_integer_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/number_integer_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/number_unsigned_t.md",
    "content": "# <small>nlohmann::basic_json::</small>number_unsigned_t\n\n```cpp\nusing number_unsigned_t = NumberUnsignedType;\n```\n\nThe type used to store JSON numbers (unsigned).\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:\n> The representation of numbers is similar to that used in most programming languages. A number is represented in base\n> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may\n> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that\n> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.\n\nThis description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is\nknown whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different\ntypes, [`number_integer_t`](number_integer_t.md), `number_unsigned_t` and [`number_float_t`](number_float_t.md) are\nused.\n\nTo store unsigned integer numbers in C++, a type is defined by the template parameter `NumberUnsignedType` which chooses\nthe type to use.\n\n## Notes\n\n#### Default type\n\nWith the default values for `NumberUnsignedType` (`std::uint64_t`), the default value for `number_unsigned_t` is\n`#!cpp std::uint64_t`.\n\n#### Default behavior\n\n- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an\n  interpretation as octal number. Internally, the value will be stored as decimal number. For instance, the C++ integer \n  literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error.\n- Not-a-number (NaN) values will be serialized to `null`.\n\n#### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:\n> An implementation may set limits on the range and precision of numbers.\n\nWhen the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and\nthe minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow\nwhen used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored\nas [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md).\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:\n> Note that when such software is used, numbers that are integers and are in the range \\f$[-2^{53}+1, 2^{53}-1]\\f$ are\n> interoperable in the sense that implementations will agree exactly on their numeric values.\n\nAs this range is a subrange (when considered in conjunction with the `number_integer_t` type) of the exactly supported\nrange [0, UINT64_MAX], this class's integer type is interoperable.\n\n#### Storage\n\nInteger number values are stored directly inside a `basic_json` type.\n\n## Examples\n\n??? example\n\n    The following code shows that `number_unsigned_t` is by default, a typedef to `#!cpp std::uint64_t`.\n     \n    ```cpp\n    --8<-- \"examples/number_unsigned_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/number_unsigned_t.output\"\n    ```\n\n## Version history\n\n- Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/object.md",
    "content": "# <small>nlohmann::basic_json::</small>object\n\n```cpp\nstatic basic_json object(initializer_list_t init = {});\n```\n\nCreates a JSON object value from a given initializer list. The initializer lists elements must be pairs, and their first\nelements must be strings. If the initializer list is empty, the empty object `#!json {}` is created.\n\n## Parameters\n\n`init` (in)\n:   initializer list with JSON values to create an object from (optional)\n\n## Return value\n\nJSON object value\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n\nThrows [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `init` is not a list of pairs whose\nfirst elements are strings. In this case, no object can be created. When such a value is passed to\n`basic_json(initializer_list_t, bool, value_t)`, an array would have been created from the passed initializer list\n`init`. See example below.\n\n## Complexity\n\nLinear in the size of `init`.\n\n## Notes\n\nThis function is only added for symmetry reasons. In contrast to the related function `array(initializer_list_t)`, there\nare no cases which can only be expressed by this function. That is, any initializer list `init` can also be passed to\nthe initializer list constructor `basic_json(initializer_list_t, bool, value_t)`.\n    \n## Examples\n\n??? example\n\n    The following code shows an example for the `object` function.\n\n    ```cpp\n    --8<-- \"examples/object.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/object.output\"\n    ```\n\n## See also\n\n- [`basic_json(initializer_list_t)`](basic_json.md) - create a JSON value from an initializer list\n- [`array`](array.md) - create a JSON array value from an initializer list\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/object_comparator_t.md",
    "content": "# <small>nlohmann::basic_json::</small>object_comparator_t\n\n```cpp\nusing object_comparator_t = std::less<StringType>;  // until C++14\n\nusing object_comparator_t = std::less<>;            // since C++14\n```\n\nThe comparator used in [`object_t`](object_t.md).\n\nWhen C++14 is detected, a transparent com parator is used which, when combined with perfect forwarding on find() and\ncount() calls, prevents unnecessary string construction.\n\n## Version history\n\n- Unknown.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/object_t.md",
    "content": "# <small>nlohmann::basic_json::</small>object_t\n\n```cpp\nusing object_t = ObjectType<StringType,\n                            basic_json,\n                            object_comparator_t,\n                            AllocatorType<std::pair<const StringType, basic_json>>>;\n```\n\nThe type used to store JSON objects.\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:\n> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a\n> string, number, boolean, null, object, or array.\n\nTo store objects in C++, a type is defined by the template parameters described below.\n\n## Template parameters\n\n`ObjectType`\n:   the container to store objects (e.g., `std::map` or `std::unordered_map`)\n\n`StringType`\n:   the type of the keys or names (e.g., `std::string`). The comparison function `std::less<StringType>` is used to\n    order elements inside the container.\n\n`AllocatorType`\n:   the allocator to use for objects (e.g., `std::allocator`)\n\n## Notes\n\n#### Default type\n\nWith the default values for `ObjectType` (`std::map`), `StringType` (`std::string`), and `AllocatorType`\n(`std::allocator`), the default value for `object_t` is:\n\n```cpp\n// until C++14\nstd::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<std::string>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n\n// since C++14\nstd::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n```\n\nSee [`object_comparator_t`](object_comparator_t.md) for more information.\n\n#### Behavior\n\nThe choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following\nbehavior:\n\n- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that\n  object will agree on the name-value mappings.\n- When the names within an object are not unique, it is unspecified which one of the values for a given key will be\n  chosen. For instance, `#!json {\"key\": 2, \"key\": 1}` could be equal to either `#!json {\"key\": 1}` or\n  `#!json {\"key\": 2}`.\n- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see\n  [`dump`](dump.md)) in this order. For instance, `#!json {\"b\": 1, \"a\": 2}` and `#!json {\"a\": 2, \"b\": 1}` will be stored\n  and serialized as `#!json {\"a\": 2, \"b\": 1}`.\n- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense\n  that they will not be affected by these differences. For instance, `#!json {\"b\": 1, \"a\": 2}` and\n  `#!json {\"a\": 2, \"b\": 1}` will be treated as equal.\n\n#### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:\n> An implementation may set limits on the maximum depth of nesting.\n\nIn this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be\nintroduced by the compiler or runtime environment. A theoretical limit can be queried by calling the\n[`max_size`](max_size.md) function of a JSON object.\n\n#### Storage\n\nObjects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type\n`object_t*` must be dereferenced.\n\n#### Object key order\n\nThe order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may\nreturn name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in\nalphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to\n[RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified \"unordered\" nature of JSON objects.\n\n## Examples\n\n??? example\n\n    The following code shows that `object_t` is by default, a typedef to `#!cpp std::map<json::string_t, json>`.\n     \n    ```cpp\n    --8<-- \"examples/object_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/object_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator+=.md",
    "content": "# <small>nlohmann::basic_json::</small>operator+=\n\n```cpp\n// (1)\nreference operator+=(basic_json&& val);\nreference operator+=(const basic_json& val);\n\n// (2)\nreference operator+=(const typename object_t::value_type& val);\n\n// (3)\nreference operator+=(initializer_list_t init);\n```\n\n1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an\n   empty array is created before appending `val`.\n\n2. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object\n   is created before inserting `val`.\n\n3. This function allows using `operator+=` with an initializer list. In case\n\n    1. the current value is an object,\n    2. the initializer list `init` contains only two elements, and\n    3. the first element of `init` is a string,\n\n    `init` is converted into an object element and added using `operator+=(const typename object_t::value_type&)`.\n    Otherwise, `init` is converted to a JSON value and added using `operator+=(basic_json&&)`.\n\n## Parameters\n\n`val` (in)\n:   the value to add to the JSON array/object\n\n`init` (in)\n:   an initializer list\n\n## Return value\n\n`#!cpp *this`\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than\n      JSON array or null; example: `\"cannot use operator+=() with number\"`\n2. The function can throw the following exceptions:\n    - Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than\n      JSON object or null; example: `\"cannot use operator+=() with number\"`\n\n## Complexity\n\n1. Amortized constant.\n2. Logarithmic in the size of the container, O(log(`size()`)).\n3. Linear in the size of the initializer list `init`.\n\n## Notes\n\n(3) This function is required to resolve an ambiguous overload error, because pairs like `{\"key\", \"value\"}` can be both\ninterpreted as `object_t::value_type` or `std::initializer_list<basic_json>`, see\n[#235](https://github.com/nlohmann/json/issues/235) for more information.\n\n## Examples\n\n??? example \"Example: (1) add element to array\"\n\n    The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value\n    was silently converted to a JSON array.\n    \n    ```cpp\n    --8<-- \"examples/push_back.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/push_back.output\"\n    ```\n\n??? example \"Example: (2) add element to object\"\n\n    The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value\n    was silently converted to a JSON object.\n\n    ```cpp\n    --8<-- \"examples/push_back__object_t__value.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/push_back__object_t__value.output\"\n    ```\n\n??? example \"Example: (3) add to object from initializer list\"\n\n    The example shows how initializer lists are treated as objects when possible.\n\n    ```cpp\n    --8<-- \"examples/push_back__initializer_list.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/push_back__initializer_list.output\"\n    ```\n\n## Version history\n\n1. Since version 1.0.0.\n2. Since version 1.0.0.\n2. Since version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator=.md",
    "content": "# <small>nlohmann::basic_json::</small>operator=\n\n```cpp\nbasic_json& operator=(basic_json other) noexcept (\n    std::is_nothrow_move_constructible<value_t>::value &&\n    std::is_nothrow_move_assignable<value_t>::value &&\n    std::is_nothrow_move_constructible<json_value>::value &&\n    std::is_nothrow_move_assignable<json_value>::value\n);\n```\n\nCopy assignment operator. Copies a JSON value via the \"copy and swap\" strategy: It is expressed in terms of the copy\nconstructor, destructor, and the `swap()` member function.\n\n## Parameters\n\n`other` (in)\n:   value to copy from\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The code below shows and example for the copy assignment. It creates a copy of value `a` which is then swapped with\n    `b`. Finally, the copy of `a` (which is the null value after the swap) is destroyed.\n     \n    ```cpp\n    --8<-- \"examples/basic_json__copyassignment.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__copyassignment.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator[].md",
    "content": "# <small>nlohmann::basic_json::</small>operator[]\n\n```cpp\n// (1)\nreference operator[](size_type idx);\nconst_reference operator[](size_type idx) const;\n\n// (2)\nreference operator[](const typename object_t::key_type& key);\nconst_reference operator[](const typename object_t::key_type& key) const;\ntemplate<typename T>\nreference operator[](T* key);\ntemplate<typename T>\nconst_reference operator[](T* key) const;\n\n// (3)\nreference operator[](const json_pointer& ptr);\nconst_reference operator[](const json_pointer& ptr) const;\n```\n\n1. Returns a reference to the array element at specified location `idx`.\n2. Returns a reference to the object element at with specified key `key`.\n3. Returns a reference to the element at with specified JSON pointer `ptr`.\n\n## Template parameters\n\n`T`\n:   string literal convertible to `object_t::key_type`\n\n## Parameters\n\n`idx` (in)\n:   index of the element to access\n\n`key` (in)\n:   object key of the element to access\n    \n`ptr` (in)\n:   JSON pointer to the desired element\n    \n## Return value\n\n1. reference to the element at index `idx`\n2. reference to the element at key `key`\n3. reference to the element pointed to by `ptr`\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an array\n      or null; in that case, using the `[]` operator with an index makes no sense.\n2. The function can throw the following exceptions:\n    - Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an object\n      or null; in that case, using the `[]` operator with a key makes no sense.\n3. The function can throw the following exceptions:\n    - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in the passed\n      JSON pointer `ptr` begins with '0'.\n    - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in the passed\n      JSON pointer `ptr` is not a number.\n    - Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index '-' is used\n      in the passed JSON pointer `ptr` for the const version.\n    - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if the JSON pointer `ptr` can\n      not be resolved.\n\n## Complexity\n\n1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`.\n2. Logarithmic in the size of the container.\n3. Constant\n\n## Notes\n\n!!! danger\n\n    1. If the element with key `idx` does not exist, the behavior is undefined.\n    2. If the element with key `key` does not exist, the behavior is undefined and is **guarded by an assertion**!\n\n1. The non-const version may add values: If `idx` is beyond the range of the array (i.e., `idx >= size()`), then the\n   array is silently filled up with `#!json null` values to make `idx` a valid reference to the last stored element. In\n   case the value was `#!json null` before, it is converted to an array.\n\n2. If `key` is not found in the object, then it is silently added to the object and filled with a `#!json null` value to\n   make `key` a valid reference. In case the value was `#!json null` before, it is converted to an object.\n\n3. `null` values are created in arrays and objects if necessary.\n   \n    In particular:\n\n    - If the JSON pointer points to an object key that does not exist, it is created and filled with a `#!json null`\n      value before a reference to it is returned.\n    - If the JSON pointer points to an array index that does not exist, it is created and filled with a `#!json null`\n      value before a reference to it is returned. All indices between the current maximum and the given index are also\n      filled with `#!json null`.\n    - The special value `-` is treated as a synonym for the index past the end.\n\n## Examples\n\n??? example \"Example (1): access specified array element\"\n\n    The example below shows how array elements can be read and written using `[]` operator. Note the addition of\n    `#!json null` values.\n        \n    ```cpp\n    --8<-- \"examples/operatorarray__size_type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operatorarray__size_type.output\"\n    ```\n\n??? example \"Example (1): access specified array element\"\n\n    The example below shows how array elements can be read using the `[]` operator.\n\n    ```cpp\n    --8<-- \"examples/operatorarray__size_type_const.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operatorarray__size_type_const.output\"\n    ```\n\n??? example \"Example (2): access specified object element\"\n\n    The example below shows how object elements can be read and written using the `[]` operator.\n    \n    ```cpp\n    --8<-- \"examples/operatorarray__key_type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operatorarray__key_type.output\"\n    ```\n\n??? example \"Example (2): access specified object element\"\n\n    The example below shows how object elements can be read using the `[]` operator.\n    \n    ```cpp\n    --8<-- \"examples/operatorarray__key_type_const.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operatorarray__key_type_const.output\"\n    ```\n\n??? example \"Example (3): access specified element via JSON Pointer\"\n\n    The example below shows how values can be read and written using JSON Pointers.\n    \n    ```cpp\n    --8<-- \"examples/operatorjson_pointer.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operatorjson_pointer.output\"\n    ```\n\n??? example \"Example (3): access specified element via JSON Pointer\"\n\n    The example below shows how values can be read using JSON Pointers.\n    \n    ```cpp\n    --8<-- \"examples/operatorjson_pointer_const.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operatorjson_pointer_const.output\"\n    ```\n\n## See also\n\n- see [`at`](at.md) for access by reference with range checking\n- see [`value`](value.md) for access with default value\n\n## Version history\n\n1. Added in version 1.0.0.\n2. Added in version 1.0.0. Overloads for `T* key` added in version 1.1.0.\n3. Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_ValueType.md",
    "content": "# <small>nlohmann::basic_json::</small>operator ValueType\n\n```cpp\ntemplate<typename ValueType>\nJSON_EXPLICIT operator ValueType() const;\n```\n\nImplicit type conversion between the JSON value and a compatible value. The call is realized by calling\n[`get()`](get.md). See [Notes](#notes) for the meaning of `JSON_EXPLICIT`.\n\n## Template parameters\n\n`ValueType`\n:   the value type to return\n\n## Return value\n\ncopy of the JSON value, converted to `ValueType`\n\n## Exceptions\n\nDepends on what `json_serializer<ValueType>` `from_json()` method throws\n\n## Complexity\n\nLinear in the size of the JSON value.\n\n## Notes\n\nBy default `JSON_EXPLICIT` defined to the empty string, so the signature is:\n\n```cpp\ntemplate<typename ValueType>\noperator ValueType() const;\n```\n\nIf [`JSON_USE_IMPLICIT_CONVERSIONS`](../../features/macros.md#json_use_implicit_conversions) is set to `0`,\n`JSON_EXPLICIT` is defined to `#!cpp explicit`:\n\n```cpp\ntemplate<typename ValueType>\nexplicit operator ValueType() const;\n```\n\nThat is, implicit conversions can be switched off by defining\n[`JSON_USE_IMPLICIT_CONVERSIONS`](../../features/macros.md#json_use_implicit_conversions) to `0`.\n\n## Examples\n\n??? example\n\n    The example below shows several conversions from JSON values\n    to other types. There a few things to note: (1) Floating-point numbers can\n    be converted to integers, (2) A JSON array can be converted to a standard\n    `std::vector<short>`, (3) A JSON object can be converted to C++\n    associative containers such as `std::unordered_map<std::string, json>`.\n        \n    ```cpp\n    --8<-- \"examples/operator__ValueType.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__ValueType.output\"\n    ```\n\n## Version history\n\n- Since version 1.0.0.\n- Macros `JSON_EXPLICIT`/[`JSON_USE_IMPLICIT_CONVERSIONS`](../../features/macros.md#json_use_implicit_conversions) added\n  in version 3.9.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_eq.md",
    "content": "# <small>nlohmann::basic_json::</small>operator==\n\n```cpp\nbool operator==(const_reference lhs, const_reference rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator==(const_reference lhs, const ScalarType rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator==(ScalarType lhs, const const_reference rhs) noexcept;\n```\n\nCompares two JSON values for equality according to the following rules:\n\n- Two JSON values are equal if (1) they are not discarded, (2) they are from the same type, and (3) their stored values\n  are the same according to their respective `operator==`.\n- Integer and floating-point numbers are automatically converted before comparison. Note that two NaN values are always\n  treated as unequal.\n\n## Template parameters\n\n`ScalarType`\n:   a scalar type according to `std::is_scalar<ScalarType>::value`\n\n## Parameters\n\n`lhs` (in)\n:   first value to consider \n\n`rhs` (in)\n:   second value to consider \n\n## Return value\n\nwhether the values `lhs` and `rhs` are equal\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nLinear.\n\n## Notes\n\n!!! note\n\n    - NaN values never compare equal to themselves or to other NaN values.\n    - JSON `#!cpp null` values are all equal.\n    - Discarded values never compare equal to themselves.\n\n!!! note\n\n    Floating-point numbers inside JSON values numbers are compared with `json::number_float_t::operator==` which is\n    `double::operator==` by default. To compare floating-point while respecting an epsilon, an alternative\n    [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)\n    could be used, for instance\n    \n    ```cpp\n    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>\n    inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept\n    {\n        return std::abs(a - b) <= epsilon;\n    }\n    ```\n    \n    Or you can self-defined operator equal function like this:\n    \n    ```cpp\n    bool my_equal(const_reference lhs, const_reference rhs)\n    {\n        const auto lhs_type lhs.type();\n        const auto rhs_type rhs.type();\n        if (lhs_type == rhs_type)\n        {\n            switch(lhs_type)\n                // self_defined case\n                case value_t::number_float:\n                    return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();\n                // other cases remain the same with the original\n                ...\n        }\n    ...\n    }\n    ```\n\n## Examples\n\n??? example\n\n    The example demonstrates comparing several JSON types.\n        \n    ```cpp\n    --8<-- \"examples/operator__equal.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__equal.output\"\n    ```\n\n??? example\n\n    The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`).\n        \n    ```cpp\n    --8<-- \"examples/operator__equal__nullptr_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__equal__nullptr_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_ge.md",
    "content": "# <small>nlohmann::basic_json::</small>operator>=\n\n```cpp\nbool operator>=(const_reference lhs, const_reference rhs) noexcept,\n\ntemplate<typename ScalarType>\nbool operator>=(const_reference lhs, const ScalarType rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator>=(ScalarType lhs, const const_reference rhs) noexcept;\n```\n\nCompares whether one JSON value `lhs` is greater than or equal to another JSON value `rhs` by calculating\n`#!cpp !(lhs < rhs)`.\n\n## Template parameters\n\n`ScalarType`\n:   a scalar type according to `std::is_scalar<ScalarType>::value`\n\n## Parameters\n\n`lhs` (in)\n:   first value to consider \n\n`rhs` (in)\n:   second value to consider \n\n## Return value\n\nwhether `lhs` is less than or equal to `rhs`\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The example demonstrates comparing several JSON types.\n        \n    ```cpp\n    --8<-- \"examples/operator__greaterequal.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__greaterequal.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_gt.md",
    "content": "# <small>nlohmann::basic_json::</small>operator>\n\n```cpp\nbool operator>(const_reference lhs, const_reference rhs) noexcept,\n\ntemplate<typename ScalarType>\nbool operator>(const_reference lhs, const ScalarType rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator>(ScalarType lhs, const const_reference rhs) noexcept;\n```\n\nCompares whether one JSON value `lhs` is greater than another JSON value `rhs` by calculating `#!cpp !(lhs <= rhs)`.\n\n## Template parameters\n\n`ScalarType`\n:   a scalar type according to `std::is_scalar<ScalarType>::value`\n\n## Parameters\n\n`lhs` (in)\n:   first value to consider \n\n`rhs` (in)\n:   second value to consider \n\n## Return value\n\nwhether `lhs` is greater than `rhs`\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The example demonstrates comparing several JSON types.\n        \n    ```cpp\n    --8<-- \"examples/operator__greater.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__greater.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_gtgt.md",
    "content": "# operator>>(basic_json)\n\n```cpp\nstd::istream& operator>>(std::istream& i, basic_json& j);\n```\n\nDeserializes an input stream to a JSON value.\n\n## Parameters\n\n`i` (in, out)\n:   input stream to read a serialized JSON value from\n\n`j` (in, out)\n:   JSON value to write the deserialized input to\n\n## Return value\n\nthe stream `i`\n\n## Exceptions\n\n- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token.\n- Throws [`parse_error.102`](../../home/exceptions.md#jsonexceptionparse_error102) if to_unicode fails or surrogate \n  error.\n- Throws [`parse_error.103`](../../home/exceptions.md#jsonexceptionparse_error103) if to_unicode fails.\n\n## Complexity\n\nLinear in the length of the input. The parser is a predictive LL(1) parser.\n\n## Notes\n\nA UTF-8 byte order mark is silently ignored.\n\n## Examples\n\n??? example\n\n    The example below shows how a JSON value is constructed by reading a serialization from a stream.\n        \n    ```cpp\n    --8<-- \"examples/operator_deserialize.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator_deserialize.output\"\n    ```\n\n## See also\n\n- [accept](accept.md) - check if the input is valid JSON\n- [parse](parse.md) - deserialize from a compatible input\n\n## Version history\n\n- Added in version 1.0.0\n\n!!! warning \"Deprecation\"\n\n    This function replaces function `#!cpp std::istream& operator<<(basic_json& j, std::istream& i)` which has\n    been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `#!cpp j << i;`\n    with `#!cpp i >> j;`.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_le.md",
    "content": "# <small>nlohmann::basic_json::</small>operator<=\n\n```cpp\nbool operator<=(const_reference lhs, const_reference rhs) noexcept,\n\ntemplate<typename ScalarType>\nbool operator<=(const_reference lhs, const ScalarType rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator<=(ScalarType lhs, const const_reference rhs) noexcept;\n```\n\nCompares whether one JSON value `lhs` is less than or equal to another JSON value `rhs` by calculating\n`#cpp !(rhs < lhs)`.\n\n## Template parameters\n\n`ScalarType`\n:   a scalar type according to `std::is_scalar<ScalarType>::value`\n\n## Parameters\n\n`lhs` (in)\n:   first value to consider \n\n`rhs` (in)\n:   second value to consider \n\n## Return value\n\nwhether `lhs` is less than or equal to `rhs`\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The example demonstrates comparing several JSON types.\n        \n    ```cpp\n    --8<-- \"examples/operator__lessequal.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__lessequal.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_literal_json.md",
    "content": "# <small>nlohmann::basic_json::</small>operator\"\"_json\n\n```cpp\njson operator \"\" _json(const char* s, std::size_t n);\n```\n\nThis operator implements a user-defined string literal for JSON objects. It can be used by adding `#!cpp _json` to a\nstring literal and returns a [`json`](../json.md) object if no parse error occurred.\n\n## Parameters\n\n`s` (in)\n:   a string representation of a JSON object\n\n`n` (in)\n:   length of string `s`\n\n## Return value\n\n[`json`](../json.md) value parsed from `s`\n\n## Exceptions\n\nThe function can throw anything that [`parse(s, s+n)`](parse.md) would throw.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The following code shows how to create JSON values from string literals.\n     \n    ```cpp\n    --8<-- \"examples/operator_literal_json.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator_literal_json.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_literal_json_pointer.md",
    "content": "# <small>nlohmann::basic_json::</small>operator\"\"_json_pointer\n\n```cpp\njson_pointer operator \"\" _json_pointer(const char* s, std::size_t n);\n```\n\nThis operator implements a user-defined string literal for JSON Pointers. It can be used by adding `#!cpp _json_pointer`\nto a string literal and returns a [`json_pointer`](../json_pointer/index.md) object if no parse error occurred.\n\n## Parameters\n\n`s` (in)\n:   a string representation of a JSON Pointer\n\n`n` (in)\n:   length of string `s`\n\n## Return value\n\n[`json_pointer`](../json_pointer/index.md) value parsed from `s`\n\n## Exceptions\n\nThe function can throw anything that [`json_pointer::json_pointer`](../json_pointer/index.md) would throw.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The following code shows how to create JSON Pointers from string literals.\n     \n    ```cpp\n    --8<-- \"examples/operator_literal_json_pointer.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator_literal_json_pointer.output\"\n    ```\n\n## Version history\n\n- Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_lt.md",
    "content": "# <small>nlohmann::basic_json::</small>operator<\n\n```cpp\nbool operator<(const_reference lhs, const_reference rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator<(const_reference lhs, const ScalarType rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator<(ScalarType lhs, const const_reference rhs) noexcept;\n```\n\nCompares whether one JSON value `lhs` is less than another JSON value `rhs` according to the following rules:\n\n- If `lhs` and `rhs` have the same type, the values are compared using the default `<` operator.\n- Integer and floating-point numbers are automatically converted before comparison\n- Discarded values a\n- In case `lhs` and `rhs` have different types, the values are ignored and the order of the types is considered, which\n  is:\n    1. null\n    2. boolean\n    3. number (all types)\n    4. object\n    5. array\n    6. string\n    7. binary\n\n    For instance, any boolean value is considered less than any string.\n\n## Template parameters\n\n`ScalarType`\n:   a scalar type according to `std::is_scalar<ScalarType>::value`\n\n## Parameters\n\n`lhs` (in)\n:   first value to consider \n\n`rhs` (in)\n:   second value to consider \n\n## Return value\n\nwhether `lhs` is less than `rhs`\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The example demonstrates comparing several JSON types.\n        \n    ```cpp\n    --8<-- \"examples/operator__less.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__less.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_ltlt.md",
    "content": "# operator<<(basic_json)\n\n```cpp\nstd::ostream& operator<<(std::ostream& o, const basic_json& j);\n```\n\nSerialize the given JSON value `j` to the output stream `o`. The JSON value will be serialized using the\n[`dump`](dump.md) member function.\n\n- The indentation of the output can be controlled with the member variable `width` of the output stream `o`. For\n  instance, using the manipulator `std::setw(4)` on `o` sets the indentation level to `4` and the serialization result\n  is the same as calling `dump(4)`.\n- The indentation character can be controlled with the member variable `fill` of the output stream `o`. For instance,\n  the manipulator `std::setfill('\\\\t')` sets indentation to use a tab character rather than the default space character.\n\n## Parameters\n\n`o` (in, out)\n:   stream to serialize to\n\n`j` (in)\n:   JSON value to serialize\n\n## Return value\n\nthe stream `o`\n\n## Exceptions\n\nThrows [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value\nis not UTF-8 encoded. Note that unlike the [`dump`](dump.md) member functions, no `error_handler` can be set.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The example below shows the serialization with different parameters to `width` to adjust the indentation level.\n        \n    ```cpp\n    --8<-- \"examples/operator_serialize.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator_serialize.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0\n- Support for indentation character added in version 3.0.0.\n\n!!! warning \"Deprecation\"\n\n    This function replaces function `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` which has\n    been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `#!cpp j >> o;`\n    with `#!cpp o << j;`.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_ne.md",
    "content": "# <small>nlohmann::basic_json::</small>operator!=\n\n```cpp\nbool operator!=(const_reference lhs, const_reference rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator!=(const_reference lhs, const ScalarType rhs) noexcept;\n\ntemplate<typename ScalarType>\nbool operator!=(ScalarType lhs, const const_reference rhs) noexcept;\n```\n\nCompares two JSON values for inequality by calculating `#!cpp !(lhs == rhs)`.\n\n## Template parameters\n\n`ScalarType`\n:   a scalar type according to `std::is_scalar<ScalarType>::value`\n\n## Parameters\n\n`lhs` (in)\n:   first value to consider \n\n`rhs` (in)\n:   second value to consider \n\n## Return value\n\nwhether the values `lhs` and `rhs` are not equal\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nLinear.\n\n## Examples\n\n??? example\n\n    The example demonstrates comparing several JSON types.\n        \n    ```cpp\n    --8<-- \"examples/operator__notequal.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__notequal.output\"\n    ```\n\n??? example\n\n    The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`).\n        \n    ```cpp\n    --8<-- \"examples/operator__notequal__nullptr_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__notequal__nullptr_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/operator_value_t.md",
    "content": "# <small>nlohmann::basic_json::</small>operator value_t\n\n```cpp\nconstexpr operator value_t() const noexcept;\n```\n\nReturn the type of the JSON value as a value from the [`value_t`](value_t.md) enumeration.\n    \n## Return value\n\nthe type of the JSON value\n\n| Value type                | return value               |\n|---------------------------|----------------------------|\n| `#!json null`             | `value_t::null`            |\n| boolean                   | `value_t::boolean`         |\n| string                    | `value_t::string`          |\n| number (integer)          | `value_t::number_integer`  |\n| number (unsigned integer) | `value_t::number_unsigned` |\n| number (floating-point)   | `value_t::number_float`    |\n| object                    | `value_t::object`          |\n| array                     | `value_t::array`           |\n| binary                    | `value_t::binary`          |\n| discarded                 | `value_t::discarded`       |\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `operator value_t()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/operator__value_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/operator__value_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Added unsigned integer type in version 2.0.0.\n- Added binary type in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/other_error.md",
    "content": "# <small>nlohmann::basic_json::</small>other_error\n\n```cpp\nclass other_error : public exception;\n```\n\nThis exception is thrown in case of errors that cannot be classified with the other exception types.\n\nExceptions have ids 5xx (see [list of other errors](../../home/exceptions.md#further-exceptions)).\n\n```plantuml\nstd::exception <|-- basic_json::exception\nbasic_json::exception <|-- basic_json::parse_error\nbasic_json::exception <|-- basic_json::invalid_iterator\nbasic_json::exception <|-- basic_json::type_error\nbasic_json::exception <|-- basic_json::out_of_range\nbasic_json::exception <|-- basic_json::other_error\n\ninterface std::exception {}\n\nclass basic_json::exception {\n    + const int id\n    + const char* what() const\n}\n\nclass basic_json::parse_error {\n    + const std::size_t byte\n}\n\nclass basic_json::other_error #FFFF00 {}\n```\n\n## Member functions\n\n- **what** - returns explanatory string\n\n## Member variables\n\n- **id** - the id of the exception\n\n## Examples\n\n??? example\n\n    The following code shows how a `other_error` exception can be caught.\n    \n    ```cpp\n    --8<-- \"examples/other_error.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/other_error.output\"\n    ```\n\n## See also\n\n- [List of other errors](../../home/exceptions.md#further-exceptions)\n- [`parse_error`](parse_error.md) for exceptions indicating a parse error\n- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators\n- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type\n- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range\n\n## Version history\n\n- Since version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/out_of_range.md",
    "content": "# <small>nlohmann::basic_json::</small>out_of_range\n\n```cpp\nclass out_of_range : public exception;\n```\n\nThis exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for\ninstance in case of array indices or nonexisting object keys.\n\nExceptions have ids 4xx (see [list of out-of-range errors](../../home/exceptions.md#out-of-range)).\n\n```plantuml\nstd::exception <|-- basic_json::exception\nbasic_json::exception <|-- basic_json::parse_error\nbasic_json::exception <|-- basic_json::invalid_iterator\nbasic_json::exception <|-- basic_json::type_error\nbasic_json::exception <|-- basic_json::out_of_range\nbasic_json::exception <|-- basic_json::other_error\n\ninterface std::exception {}\n\nclass basic_json::exception {\n    + const int id\n    + const char* what() const\n}\n\nclass basic_json::parse_error {\n    + const std::size_t byte\n}\n\nclass basic_json::out_of_range #FFFF00 {}\n```\n\n## Member functions\n\n- **what** - returns explanatory string\n\n## Member variables\n\n- **id** - the id of the exception\n\n## Examples\n\n??? example\n\n    The following code shows how a `out_of_range` exception can be caught.\n    \n    ```cpp\n    --8<-- \"examples/out_of_range.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/out_of_range.output\"\n    ```\n\n## See also\n\n- [List of out-of-range errors](../../home/exceptions.md#out-of-range)\n- [`parse_error`](parse_error.md) for exceptions indicating a parse error\n- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators\n- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type\n- [`other_error`](other_error.md) for exceptions indicating other library errors\n\n## Version history\n\n- Since version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/parse.md",
    "content": "# <small>nlohmann::basic_json::</small>parse\n\n```cpp\n// (1)\ntemplate<typename InputType>\nstatic basic_json parse(InputType&& i,\n                        const parser_callback_t cb = nullptr,\n                        const bool allow_exceptions = true,\n                        const bool ignore_comments = false);\n\n// (2)\ntemplate<typename IteratorType>\nstatic basic_json parse(IteratorType first, IteratorType last,\n                        const parser_callback_t cb = nullptr,\n                        const bool allow_exceptions = true,\n                        const bool ignore_comments = false);\n```\n\n1. Deserialize from a compatible input.\n2. Deserialize from a pair of character iterators\n    \n    The `value_type` of the iterator must be an integral type with size of 1, 2 or 4 bytes, which will be interpreted\n    respectively as UTF-8, UTF-16 and UTF-32.\n\n## Template parameters\n\n`InputType`\n:   A compatible input, for instance:\n    \n    - an `std::istream` object\n    - a `FILE` pointer\n    - a C-style array of characters\n    - a pointer to a null-terminated string of single byte characters\n    - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators.\n\n`IteratorType`\n:   a compatible iterator type, for instance.\n\n    - a pair of `std::string::iterator` or `std::vector<std::uint8_t>::iterator`\n    - a pair of pointers such as `ptr` and `ptr + len`\n\n## Parameters\n\n`i` (in)\n:   Input to parse from.\n\n`cb` (in)\n:   a parser callback function of type [`parser_callback_t`](parser_callback_t.md) which is used to control the\n    deserialization by filtering unwanted values (optional)\n\n`allow_exceptions` (in)\n:    whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)\n\n`ignore_comments` (in)\n:   whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error\n    (`#!cpp false`); (optional, `#!cpp false` by default)\n\n`first` (in)\n:   iterator to start of character range\n\n`last` (in)\n:   iterator to end of character range\n\n## Return value\n\nDeserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be\n`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md).\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser\ncallback function `cb` or reading from (1) the input `i` or (2) the iterator range [`first`, `last`] has a\nsuper-linear complexity.\n\n## Notes\n\n(1) A UTF-8 byte order mark is silently ignored.\n\n## Examples\n\n??? example \"Parsing from a character array\"\n\n    The example below demonstrates the `parse()` function reading from an array.\n\n    ```cpp\n    --8<-- \"examples/parse__array__parser_callback_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__array__parser_callback_t.output\"\n    ```\n\n??? example \"Parsing from a string\"\n\n    The example below demonstrates the `parse()` function with and without callback function.\n\n    ```cpp\n    --8<-- \"examples/parse__string__parser_callback_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__string__parser_callback_t.output\"\n    ```\n\n??? example \"Parsing from an input stream\"\n\n    The example below demonstrates the `parse()` function with and without callback function.\n\n    ```cpp\n    --8<-- \"examples/parse__istream__parser_callback_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__istream__parser_callback_t.output\"\n    ```\n\n??? example \"Parsing from a contiguous container\"\n\n    The example below demonstrates the `parse()` function reading from a contiguous container.\n\n    ```cpp\n    --8<-- \"examples/parse__contiguouscontainer__parser_callback_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__contiguouscontainer__parser_callback_t.output\"\n    ```\n\n??? example \"Parsing from a non null-terminated string\"\n\n    The example below demonstrates the `parse()` function reading from a string that is not null-terminated.\n\n    ```cpp\n    --8<-- \"examples/parse__pointers.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__pointers.output\"\n    ```\n\n??? example \"Parsing from an iterator pair\"\n\n    The example below demonstrates the `parse()` function reading from an iterator pair.\n\n    ```cpp\n    --8<-- \"examples/parse__iterator_pair.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__iterator_pair.output\"\n    ```\n\n??? example \"Effect of `allow_exceptions` parameter\"\n\n    The example below demonstrates the effect of the `allow_exceptions` parameter in the ´parse()` function.\n\n    ```cpp\n    --8<-- \"examples/parse__allow_exceptions.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__allow_exceptions.output\"\n    ```\n\n## See also\n\n- [accept](accept.md) - check if the input is valid JSON\n- [operator>>](operator_gtgt.md) - deserialize from stream\n\n## Version history\n\n- Added in version 1.0.0.\n- Overload for contiguous containers (1) added in version 2.0.3.\n- Ignoring comments via `ignore_comments` added in version 3.9.0.\n\n!!! warning \"Deprecation\"\n\n    Overload (2) replaces calls to `parse` with a pair of iterators as their first parameter which has been\n    deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n    `#!cpp parse({ptr, ptr+len}, ...);` with `#!cpp parse(ptr, ptr+len, ...);`.\n\n    You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated\n    function.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/parse_error.md",
    "content": "# <small>nlohmann::basic_json::</small>parse_error\n\n```cpp\nclass parse_error : public exception;\n```\n\nThis exception is thrown by the library when a parse error occurs. Parse errors can occur during the deserialization of\nJSON text, BSON, CBOR, MessagePack, UBJSON, as well as when using JSON Patch.\n\nMember `byte` holds the byte index of the last read character in the input file (see note below).\n\nExceptions have ids 1xx (see [list of parse errors](../../home/exceptions.md#parse-errors)).\n\n```plantuml\nstd::exception <|-- basic_json::exception\nbasic_json::exception <|-- basic_json::parse_error\nbasic_json::exception <|-- basic_json::invalid_iterator\nbasic_json::exception <|-- basic_json::type_error\nbasic_json::exception <|-- basic_json::out_of_range\nbasic_json::exception <|-- basic_json::other_error\n\ninterface std::exception {}\n\nclass basic_json::exception {\n    + const int id\n    + const char* what() const\n}\n\nclass basic_json::parse_error #FFFF00 {\n    + const std::size_t byte\n}\n```\n\n## Member functions\n\n- **what** - returns explanatory string\n\n## Member variables\n\n- **id** - the id of the exception\n- **byte** - byte index of the parse error\n\n## Notes\n\nFor an input with $n$ bytes, 1 is the index of the first character and $n+1$ is the index of the terminating null byte\nor the end of file. This also holds true when reading a byte vector for binary formats.\n\n## Examples\n\n??? example\n\n    The following code shows how a `parse_error` exception can be caught.\n    \n    ```cpp\n    --8<-- \"examples/parse_error.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse_error.output\"\n    ```\n\n## See also\n\n- [List of parse errors](../../home/exceptions.md#parse-errors)\n- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators\n- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type\n- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range\n- [`other_error`](other_error.md) for exceptions indicating other library errors\n\n## Version history\n\n- Since version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/parse_event_t.md",
    "content": "# <small>nlohmann::basic_json::</small>parse_event_t\n\n```cpp\nenum class parse_event_t : std::uint8_t {\n    object_start,\n    object_end,\n    array_start,\n    array_end,\n    key,\n    value\n};\n```\n\nThe parser callback distinguishes the following events:\n\n- `object_start`: the parser read `{` and started to process a JSON object\n- `key`: the parser read a key of a value in an object\n- `object_end`: the parser read `}` and finished processing a JSON object\n- `array_start`: the parser read `[` and started to process a JSON array\n- `array_end`: the parser read `]` and finished processing a JSON array\n- `value`: the parser finished reading a JSON value\n\n## Examples\n\n![Example when certain parse events are triggered](../../images/callback_events.png)\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/parser_callback_t.md",
    "content": "# <small>nlohmann::basic_json::</small>parser_callback_t\n\n```cpp\ntemplate<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;\n```\n\nWith a parser callback function, the result of parsing a JSON text can be influenced. When passed to\n[`parse`](parse.md), it is called on certain events (passed as [`parse_event_t`](parse_event_t.md) via parameter\n`event`) with a set recursion depth `depth` and context JSON value `parsed`. The return value of the callback function\nis a boolean indicating whether the element that emitted the callback shall be kept or not.\n\nWe distinguish six scenarios (determined by the event type) in which the callback function can be called. The following\ntable describes the values of the parameters `depth`, `event`, and `parsed`.\n\n| parameter `event`             | description                                               | parameter `depth`                         | parameter `parsed`               |\n|-------------------------------|-----------------------------------------------------------|-------------------------------------------|----------------------------------|\n| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object  | depth of the parent of the JSON object    | a JSON value with type discarded |\n| `parse_event_t::key`          | the parser read a key of a value in an object             | depth of the currently parsed JSON object | a JSON string containing the key |\n| `parse_event_t::object_end`   | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object    | the parsed JSON object           |\n| `parse_event_t::array_start`  | the parser read `[` and started to process a JSON array   | depth of the parent of the JSON array     | a JSON value with type discarded |\n| `parse_event_t::array_end`    | the parser read `]` and finished processing a JSON array  | depth of the parent of the JSON array     | the parsed JSON array            |\n| `parse_event_t::value`        | the parser finished reading a JSON value                  | depth of the value                        | the parsed JSON value            |\n\n![Example when certain parse events are triggered](../../images/callback_events.png)\n\nDiscarding a value (i.e., returning `#!cpp false`) has different effects depending on the context in which function was\ncalled:\n\n- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never\n  read.\n- In case a value outside a structured type is skipped, it is replaced with `null`. This case happens if the top-level\n  element is skipped.\n\n## Parameters\n\n`depth` (in)\n:   the depth of the recursion during parsing\n\n`event` (in)\n:   an event of type [`parse_event_t`](parse_event_t.md) indicating the context in\n    the callback function has been called\n\n`parsed` (in, out)\n:    the current intermediate parse result; note that\n     writing to this value has no effect for `parse_event_t::key` events\n\n## Return value\n\nWhether the JSON value which called the function during parsing should be kept (`#!cpp true`) or not (`#!cpp false`). In\nthe latter case, it is either skipped completely or replaced by an empty discarded object.\n\n## Examples\n\n??? example\n\n    The example below demonstrates the `parse()` function with\n    and without callback function.\n\n    ```cpp\n    --8<-- \"examples/parse__string__parser_callback_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/parse__string__parser_callback_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/patch.md",
    "content": "# <small>nlohmann::basic_json::</small>patch\n\n```cpp\nbasic_json patch(const basic_json& json_patch) const;\n```\n\n[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to\na JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from\nthe patch.\n\n## Parameters\n\n`json_patch` (in)\n:   JSON patch document\n\n## Return value\n\npatched document\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Exceptions\n\n- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of\n  an array of objects.\n- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g.,\n  mandatory attributes are missing); example: `\"operation add must have member path\"`.\n- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range.\n- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch\n  could not be resolved successfully in the current JSON value; example: `\"key baz not found\"`.\n- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent\n  (\"add\", \"remove\", \"move\")\n- Throws [`out_of_range.501`](../../home/exceptions.md#jsonexceptionother_error501) if \"test\" operation was\n  unsuccessful.\n\n## Complexity\n\nLinear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is\naffected by the patch, the complexity can usually be neglected.\n\n## Notes\n\nThe application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception\nis thrown. In any case, the original value is not changed: the patch is applied to a copy of the value.\n\n## Examples\n\n??? example\n\n    The following code shows how a JSON patch is applied to a value.\n     \n    ```cpp\n    --8<-- \"examples/patch.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/patch.output\"\n    ```\n\n## See also\n\n- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)\n- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)\n- [merge_patch](merge_patch.md) applies a JSON Merge Patch\n\n## Version history\n\n- Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/push_back.md",
    "content": "# <small>nlohmann::basic_json::</small>push_back\n\n```cpp\n// (1)\nvoid push_back(basic_json&& val);\nvoid push_back(const basic_json& val);\n\n// (2)\nvoid push_back(const typename object_t::value_type& val);\n\n// (3)\nvoid push_back(initializer_list_t init);\n```\n\n1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an\n   empty array is created before appending `val`.\n\n2. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object\n   is created before inserting `val`.\n\n3. This function allows using `push_back` with an initializer list. In case\n\n    1. the current value is an object,\n    2. the initializer list `init` contains only two elements, and\n    3. the first element of `init` is a string,\n\n    `init` is converted into an object element and added using `push_back(const typename object_t::value_type&)`.\n    Otherwise, `init` is converted to a JSON value and added using `push_back(basic_json&&)`.\n\n## Parameters\n\n`val` (in)\n:   the value to add to the JSON array/object\n\n`init` (in)\n:   an initializer list\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than\n      JSON array or null; example: `\"cannot use push_back() with number\"`\n2. The function can throw the following exceptions:\n    - Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than\n      JSON object or null; example: `\"cannot use push_back() with number\"`\n\n## Complexity\n\n1. Amortized constant.\n2. Logarithmic in the size of the container, O(log(`size()`)).\n3. Linear in the size of the initializer list `init`.\n\n## Notes\n\n(3) This function is required to resolve an ambiguous overload error, because pairs like `{\"key\", \"value\"}` can be both\n    interpreted as `object_t::value_type` or `std::initializer_list<basic_json>`, see\n    [#235](https://github.com/nlohmann/json/issues/235) for more information.\n\n## Examples\n\n??? example \"Example: (1) add element to array\"\n\n    The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value\n    was silently converted to a JSON array.\n    \n    ```cpp\n    --8<-- \"examples/push_back.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/push_back.output\"\n    ```\n\n??? example \"Example: (2) add element to object\"\n\n    The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value\n    was silently converted to a JSON object.\n\n    ```cpp\n    --8<-- \"examples/push_back__object_t__value.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/push_back__object_t__value.output\"\n    ```\n\n??? example \"Example: (3) add to object from initializer list\"\n\n    The example shows how initializer lists are treated as objects when possible.\n\n    ```cpp\n    --8<-- \"examples/push_back__initializer_list.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/push_back__initializer_list.output\"\n    ```\n\n## Version history\n\n1. Since version 1.0.0.\n2. Since version 1.0.0.\n2. Since version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/rbegin.md",
    "content": "# <small>nlohmann::basic_json::</small>rbegin\n\n```cpp\nreverse_iterator rbegin() noexcept;\nconst_reverse_iterator rbegin() const noexcept;\n```\n\nReturns an iterator to the reverse-beginning; that is, the last element.\n\n![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)\n\n## Return value\n\nreverse iterator to the first element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `rbegin()`.\n    \n    ```cpp\n    --8<-- \"examples/rbegin.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/rbegin.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/rend.md",
    "content": "# <small>nlohmann::basic_json::</small>rend\n\n```cpp\nreverse_iterator rend() noexcept;\nconst_reverse_iterator rend() const noexcept;\n```\n\nReturns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder,\nattempting to access it results in undefined behavior.\n\n![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)\n\n## Return value\n\nreverse iterator to the element following the last element\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code shows an example for `eend()`.\n    \n    ```cpp\n    --8<-- \"examples/rend.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/rend.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/sax_parse.md",
    "content": "# <small>nlohmann::basic_json::</small>sax_parse\n\n```cpp\n// (1)\ntemplate <typename InputType, typename SAX>\nstatic bool sax_parse(InputType&& i,\n                      SAX* sax,\n                      input_format_t format = input_format_t::json,\n                      const bool strict = true,\n                      const bool ignore_comments = false);\n\n// (2)\ntemplate<class IteratorType, class SAX>\nstatic bool sax_parse(IteratorType first, IteratorType last,\n                      SAX* sax,\n                      input_format_t format = input_format_t::json,\n                      const bool strict = true,\n                      const bool ignore_comments = false);\n```\n\nRead from input and generate SAX events\n\n1. Read from a compatible input.\n2. Read from a pair of character iterators\n    \n    The value_type of the iterator must be an integral type with size of 1, 2 or 4 bytes, which will be interpreted\n    respectively as UTF-8, UTF-16 and UTF-32.\n\nThe SAX event lister must follow the interface of [`json_sax`](../json_sax/index.md).\n\n## Template parameters\n\n`InputType`\n:   A compatible input, for instance:\n    \n    - an `std::istream` object\n    - a `FILE` pointer\n    - a C-style array of characters\n    - a pointer to a null-terminated string of single byte characters\n    - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of\n      iterators.\n\n`IteratorType`\n:   Description\n\n`SAX`\n:   Description\n\n## Parameters\n\n`i` (in)\n:   Input to parse from.\n\n`sax` (in)\n:   SAX event listener\n\n`format` (in)\n:    the format to parse (JSON, CBOR, MessagePack, or UBJSON) (optional, `input_format_t::json` by default), see\n     [`input_format_t`](input_format_t.md) for more information\n\n`strict` (in)\n:   whether the input has to be consumed completely (optional, `#!cpp true` by default)\n\n`ignore_comments` (in)\n:   whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error\n    (`#!cpp false`); (optional, `#!cpp false` by default)\n\n`first` (in)\n:   iterator to start of character range\n\n`last` (in)\n:   iterator to end of character range\n\n## Return value\n\nreturn value of the last processed SAX event\n\n## Exception safety\n\n## Complexity\n\nLinear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the SAX\nconsumer `sax` has a super-linear complexity.\n\n## Notes\n\nA UTF-8 byte order mark is silently ignored.\n\n## Examples\n\n??? example\n\n    The example below demonstrates the `sax_parse()` function reading from string and processing the events with a\n    user-defined SAX event consumer.\n    \n    ```cpp\n    --8<-- \"examples/sax_parse.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/sax_parse.output\"\n    ```\n\n## Version history\n\n- Added in version 3.2.0.\n- Ignoring comments via `ignore_comments` added in version 3.9.0.\n\n!!! warning \"Deprecation\"\n\n    Overload (2) replaces calls to `sax_parse` with a pair of iterators as their first parameter which has been\n    deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like\n    `#!cpp sax_parse({ptr, ptr+len});` with `#!cpp sax_parse(ptr, ptr+len);`.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/size.md",
    "content": "# <small>nlohmann::basic_json::</small>size\n\n```cpp\nsize_type size() const noexcept;\n```\n\nReturns the number of elements in a JSON value.\n    \n## Return value\n\nThe return value depends on the different types and is defined as follows:\n\n| Value type | return value                        |\n|------------|-------------------------------------|\n| null       | `0`                                 |\n| boolean    | `1`                                 |\n| string     | `1`                                 |\n| number     | `1`                                 |\n| binary     | `1`                                 |\n| object     | result of function object_t::size() |\n| array      | result of function array_t::size()  |\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the\n[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `size()` functions have\nconstant complexity.\n\n## Notes\n\nThis function does not return the length of a string stored as JSON value -- it returns the number of elements in the\nJSON value which is `1` in the case of a string.\n\n## Examples\n\n??? example\n\n    The following code calls `size()` on the different value types.\n    \n    ```cpp\n    --8<-- \"examples/size.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/size.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended to return `1` for binary types in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/std_hash.md",
    "content": "# <small>std::</small>hash<nlohmann::basic_json\\>\n\n```cpp\nnamespace std {\n    struct hash<nlohmann::basic_json>;\n}\n```\n\nReturn a hash value for a JSON object. The hash function tries to rely on `std::hash` where possible. Furthermore, the\ntype of the JSON value is taken into account to have different hash values for `#!json null`, `#!cpp 0`, `#!cpp 0U`, and\n`#!cpp false`, etc.\n\n## Examples\n\n??? example\n\n    The example shows how to calculate hash values for different JSON values.\n     \n    ```cpp\n    --8<-- \"examples/std_hash.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/std_hash.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended for arbitrary basic_json types in version 3.10.5.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/std_swap.md",
    "content": "# std::swap<basic_json\\>\n\n```cpp\nnamespace std {\n    void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2);\n}\n```\n\nExchanges the values of two JSON objects.\n\n## Parameters\n\n`j1` (in, out)\n:   value to be replaced by `j2`\n\n`j2` (in, out)\n:   value to be replaced by `j1`\n\n## Possible implementation\n\n```cpp\nvoid swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2)\n{\n    j1.swap(j2);\n}\n```\n\n## Examples\n\n??? example\n\n    The following code shows how two values are swapped with `std::swap`.\n     \n    ```cpp\n    --8<-- \"examples/std_swap.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/std_swap.output\"\n    ```\n\n## See also\n\n- [swap](swap.md)\n\n## Version history\n\n- Added in version 1.0.0.\n- Extended for arbitrary basic_json types in version 3.10.5.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/string_t.md",
    "content": "# <small>nlohmann::basic_json::</small>string_t\n\n```cpp\nusing string_t = StringType;\n```\n\nThe type used to store JSON strings.\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:\n> A string is a sequence of zero or more Unicode characters.\n\nTo store objects in C++, a type is defined by the template parameter described below. Unicode values are split by the\nJSON class into byte-sized characters during deserialization.\n\n## Template parameters\n\n`StringType`\n:   the container to store strings (e.g., `std::string`). Note this container is used for keys/names in objects, see\n    [object_t](object_t.md).\n\n## Notes\n\n#### Default type\n\nWith the default values for `StringType` (`std::string`), the default value for `string_t` is `#!cpp std::string`.\n\n#### Encoding\n\nStrings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return\nthe number of bytes in the string rather than the number of characters or glyphs.\n\n#### String comparison\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) states:\n> Software implementations are typically required to test names of object members for equality. Implementations that\n> transform the textual representation into sequences of Unicode code units and then perform the comparison numerically,\n> code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or\n> inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may\n> incorrectly find that `\"a\\\\b\"` and `\"a\\u005Cb\"` are not equal.\n\nThis implementation is interoperable as it does compare strings code unit by code unit.\n\n#### Storage\n\nString values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type\n`string_t*` must be dereferenced.\n\n## Examples\n\n??? example\n\n    The following code shows that `string_t` is by default, a typedef to `#!cpp std::string`.\n     \n    ```cpp\n    --8<-- \"examples/string_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/string_t.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/swap.md",
    "content": "# <small>nlohmann::basic_json::</small>swap\n\n```cpp\n// (1)\nvoid swap(reference other) noexcept;\n\n// (2)\nvoid swap(reference left, reference right) noexcept;\n\n// (3)\nvoid swap(array_t& other);\n\n// (4)\nvoid swap(object_t& other);\n\n// (5)\nvoid swap(string_t& other);\n\n// (6)\nvoid swap(binary_t& other);\n\n// (7)\nvoid swap(typename binary_t::container_type& other);\n```\n\n1. Exchanges the contents of the JSON value with those of `other`. Does not invoke any move, copy, or swap operations on\n   individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. \n2. Exchanges the contents of the JSON value from `left` with those of `right`. Does not invoke any move, copy, or swap\n   operations on individual elements. All iterators and references remain valid. The past-the-end iterator is\n   invalidated. Implemented as a friend function callable via ADL.\n3. Exchanges the contents of a JSON array with those of `other`. Does not invoke any move, copy, or swap operations on\n   individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. \n4. Exchanges the contents of a JSON object with those of `other`. Does not invoke any move, copy, or swap operations on\n   individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.\n5. Exchanges the contents of a JSON string with those of `other`. Does not invoke any move, copy, or swap operations on\n   individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.\n6. Exchanges the contents of a binary value with those of `other`. Does not invoke any move, copy, or swap operations on\n   individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.\n7. Exchanges the contents of a binary value with those of `other`. Does not invoke any move, copy, or swap operations on\n   individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Unlike\n   version (6), no binary subtype is involved.\n\n## Parameters\n\n`other` (in, out)\n:   value to exchange the contents with\n\n`left` (in, out)\n:   value to exchange the contents with\n\n`right` (in, out)\n:   value to exchange the contents with\n\n## Exceptions\n\n1. No-throw guarantee: this function never throws exceptions.\n2. No-throw guarantee: this function never throws exceptions.\n3. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than\n   arrays; example: `\"cannot use swap() with boolean\"`\n4. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than\n   objects; example: `\"cannot use swap() with boolean\"`\n5. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than\n   strings; example: `\"cannot use swap() with boolean\"`\n6. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than\n   binaries; example: `\"cannot use swap() with boolean\"`\n7. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than\n   binaries; example: `\"cannot use swap() with boolean\"`\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example \"Example: Swap JSON value (1, 2)\"\n\n    The example below shows how JSON values can be swapped with `swap()`.\n    \n    ```cpp\n    --8<-- \"examples/swap__reference.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/swap__reference.output\"\n    ```\n\n??? example \"Example: Swap array (3)\"\n\n    The example below shows how arrays can be swapped with `swap()`.\n    \n    ```cpp\n    --8<-- \"examples/swap__array_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/swap__array_t.output\"\n    ```\n\n??? example \"Example: Swap object (4)\"\n\n    The example below shows how objects can be swapped with `swap()`.\n    \n    ```cpp\n    --8<-- \"examples/swap__object_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/swap__object_t.output\"\n    ```\n\n??? example \"Example: Swap string (5)\"\n\n    The example below shows how strings can be swapped with `swap()`.\n    \n    ```cpp\n    --8<-- \"examples/swap__string_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/swap__string_t.output\"\n    ```\n\n??? example \"Example: Swap string (6)\"\n\n    The example below shows how binary values can be swapped with `swap()`.\n    \n    ```cpp\n    --8<-- \"examples/swap__binary_t.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/swap__binary_t.output\"\n    ```\n\n## See also\n\n- [std::swap<basic_json\\>](std_swap.md)\n\n## Version history\n\n1. Since version 1.0.0.\n2. Since version 1.0.0.\n3. Since version 1.0.0.\n4. Since version 1.0.0.\n5. Since version 1.0.0.\n6. Since version 3.8.0.\n7. Since version 3.8.0."
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/to_bson.md",
    "content": "# <small>nlohmann::basic_json::</small>to_bson\n\n```cpp\n// (1)\nstatic std::vector<std::uint8_t> to_bson(const basic_json& j);\n\n// (2)\nstatic void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o);\nstatic void to_bson(const basic_json& j, detail::output_adapter<char> o);\n```\n\nBSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are stored as a single entity (a\nso-called document).\n\n1. Returns a byte vector containing the BSON serialization.\n2. Writes the BSON serialization to an output adapter.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/bson.md).\n\n## Parameters\n\n`j` (in)\n:   JSON value to serialize\n\n`o` (in)\n:   output adapter to write serialization to\n\n## Return value\n\n1. BSON serialization as byte vector\n2. /\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the size of the JSON value `j`.\n\n## Examples\n\n??? example\n\n    The example shows the serialization of a JSON value to a byte vector in BSON format.\n     \n    ```cpp\n    --8<-- \"examples/to_bson.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/to_bson.output\"\n    ```\n\n## Version history\n\n- Added in version 3.4.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/to_cbor.md",
    "content": "# <small>nlohmann::basic_json::</small>to_cbor\n\n```cpp\n// (1)\nstatic std::vector<std::uint8_t> to_cbor(const basic_json& j);\n\n// (2)\nstatic void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o);\nstatic void to_cbor(const basic_json& j, detail::output_adapter<char> o);\n```\n\nSerializes a given JSON value `j` to a byte vector using the CBOR (Concise Binary Object Representation) serialization\nformat. CBOR is a binary serialization format which aims to be more compact than JSON itself, yet more efficient to\nparse.\n\n1. Returns a byte vector containing the CBOR serialization.\n2. Writes the CBOR serialization to an output adapter.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/cbor.md).\n\n## Parameters\n\n`j` (in)\n:   JSON value to serialize\n\n`o` (in)\n:   output adapter to write serialization to\n\n## Return value\n\n1. CBOR serialization as byte vector\n2. /\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the size of the JSON value `j`.\n\n## Examples\n\n??? example\n\n    The example shows the serialization of a JSON value to a byte vector in CBOR format.\n     \n    ```cpp\n    --8<-- \"examples/to_cbor.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/to_cbor.output\"\n    ```\n\n## Version history\n\n- Added in version 2.0.9.\n- Compact representation of floating-point numbers added in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/to_msgpack.md",
    "content": "# <small>nlohmann::basic_json::</small>to_msgpack\n\n```cpp\n// (1)\nstatic std::vector<std::uint8_t> to_msgpack(const basic_json& j);\n\n// (2)\nstatic void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o);\nstatic void to_msgpack(const basic_json& j, detail::output_adapter<char> o);\n```\n\nSerializes a given JSON value `j` to a byte vector using the MessagePack serialization format. MessagePack is a binary\nserialization format which aims to be more compact than JSON itself, yet more efficient to parse.\n\n1. Returns a byte vector containing the MessagePack serialization.\n2. Writes the MessagePack serialization to an output adapter.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/messagepack.md).\n\n## Parameters\n\n`j` (in)\n:   JSON value to serialize\n\n`o` (in)\n:   output adapter to write serialization to\n\n## Return value\n\n1. MessagePack serialization as byte vector\n2. /\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the size of the JSON value `j`.\n\n## Examples\n\n??? example\n\n    The example shows the serialization of a JSON value to a byte vector in MessagePack format.\n     \n    ```cpp\n    --8<-- \"examples/to_msgpack.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/to_msgpack.output\"\n    ```\n\n## Version history\n\n- Added in version 2.0.9.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/to_string.md",
    "content": "# to_string(basic_json)\n\n```cpp\ntemplate <typename BasicJsonType>\nstd::string to_string(const BasicJsonType& j);\n```\n\nThis function implements a user-defined to_string for JSON objects.\n\n## Template parameters\n\n`BasicJsonType`\n:   a specialization of [`basic_json`](index.md)\n\n## Return value\n\nstring containing the serialization of the JSON value\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes to any JSON value.\n\n## Exceptions\n\nThrows [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value\nis not UTF-8 encoded\n\n## Complexity\n\nLinear.\n\n## Possible implementation\n\n```cpp\ntemplate <typename BasicJsonType>\nstd::string to_string(const BasicJsonType& j)\n{\n    return j.dump();\n}\n```\n\n## Examples\n\n??? example\n\n    The following code shows how the library's `to_string()` function integrates with others, allowing\n    argument-dependent lookup.\n     \n    ```cpp\n    --8<-- \"examples/to_string.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/to_string.output\"\n    ```\n\n## See also\n\n- [dump](dump.md)\n\n## Version history\n\nAdded in version 3.7.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/to_ubjson.md",
    "content": "# <small>nlohmann::basic_json::</small>to_ubjson\n\n```cpp\n// (1)\nstatic std::vector<std::uint8_t> to_ubjson(const basic_json& j,\n                                           const bool use_size = false,\n                                           const bool use_type = false);\n\n// (2)\nstatic void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                      const bool use_size = false, const bool use_type = false);\nstatic void to_ubjson(const basic_json& j, detail::output_adapter<char> o,\n                      const bool use_size = false, const bool use_type = false);\n```\n\nSerializes a given JSON value `j` to a byte vector using the UBJSON (Universal Binary JSON) serialization format. UBJSON\naims to be more compact than JSON itself, yet more efficient to parse.\n\n1. Returns a byte vector containing the UBJSON serialization.\n2. Writes the UBJSON serialization to an output adapter.\n\nThe exact mapping and its limitations is described on a [dedicated page](../../features/binary_formats/ubjson.md).\n\n## Parameters\n\n`j` (in)\n:   JSON value to serialize\n\n`o` (in)\n:   output adapter to write serialization to\n\n`use_size` (in)\n:   whether to add size annotations to container types; optional, `#!cpp false` by default.\n\n`use_type` (in)\n:   whether to add type annotations to container types (must be combined with `#!cpp use_size = true`); optional,\n    `#!cpp false` by default.\n\n## Return value\n\n1. UBJSON serialization as byte vector\n2. /\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no changes in the JSON value.\n\n## Complexity\n\nLinear in the size of the JSON value `j`.\n\n## Examples\n\n??? example\n\n    The example shows the serialization of a JSON value to a byte vector in UBJSON format.\n     \n    ```cpp\n    --8<-- \"examples/to_ubjson.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/to_ubjson.output\"\n    ```\n\n## Version history\n\n- Added in version 3.1.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/type.md",
    "content": "# <small>nlohmann::basic_json::</small>type\n\n```cpp\nconstexpr value_t type() const noexcept;\n```\n\nReturn the type of the JSON value as a value from the [`value_t`](value_t.md) enumeration.\n\n## Return value\n\nthe type of the JSON value\n\n| Value type                | return value               |\n|---------------------------|----------------------------|\n| `#!json null`             | `value_t::null`            |\n| boolean                   | `value_t::boolean`         |\n| string                    | `value_t::string`          |\n| number (integer)          | `value_t::number_integer`  |\n| number (unsigned integer) | `value_t::number_unsigned` |\n| number (floating-point)   | `value_t::number_float`    |\n| object                    | `value_t::object`          |\n| array                     | `value_t::array`           |\n| binary                    | `value_t::binary`          |\n| discarded                 | `value_t::discarded`       |\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `type()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/type.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/type.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Added unsigned integer type in version 2.0.0.\n- Added binary type in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/type_error.md",
    "content": "# <small>nlohmann::basic_json::</small>type_error\n\n```cpp\nclass type_error : public exception;\n```\n\nThis exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type\ndoes not match the expected semantics.\n\nExceptions have ids 3xx (see [list of type errors](../../home/exceptions.md#type-errors)).\n\n```plantuml\nstd::exception <|-- basic_json::exception\nbasic_json::exception <|-- basic_json::parse_error\nbasic_json::exception <|-- basic_json::invalid_iterator\nbasic_json::exception <|-- basic_json::type_error\nbasic_json::exception <|-- basic_json::out_of_range\nbasic_json::exception <|-- basic_json::other_error\n\ninterface std::exception {}\n\nclass basic_json::exception {\n    + const int id\n    + const char* what() const\n}\n\nclass basic_json::parse_error {\n    + const std::size_t byte\n}\n\nclass basic_json::type_error #FFFF00 {}\n```\n\n## Member functions\n\n- **what** - returns explanatory string\n\n## Member variables\n\n- **id** - the id of the exception\n\n## Examples\n\n??? example\n\n    The following code shows how a `type_error` exception can be caught.\n    \n    ```cpp\n    --8<-- \"examples/type_error.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/type_error.output\"\n    ```\n\n## See also\n\n- [List of type errors](../../home/exceptions.md#type-errors)\n- [`parse_error`](parse_error.md) for exceptions indicating a parse error\n- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators\n- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range\n- [`other_error`](other_error.md) for exceptions indicating other library errors\n\n## Version history\n\n- Since version 3.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/type_name.md",
    "content": "# <small>nlohmann::basic_json::</small>type_name\n\n```cpp\nconst char* type_name() const noexcept;\n```\n\nReturns the type name as string to be used in error messages -- usually to indicate that a function was called on a\nwrong JSON type.\n    \n## Return value\n\na string representation of the type ([`value_t`](value_t.md)):\n\n| Value type                                         | return value  |\n|----------------------------------------------------|---------------|\n| `#!json null`                                      | `\"null\"`      |\n| boolean                                            | `\"boolean\"`   |\n| string                                             | `\"string\"`    |\n| number (integer, unsigned integer, floating-point) | `\"number\"`    |\n| object                                             | `\"object\"`    |\n| array                                              | `\"array\"`     |\n| binary                                             | `\"binary\"`    |\n| discarded                                          | `\"discarded\"` |\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The following code exemplifies `type_name()` for all JSON types.\n    \n    ```cpp\n    --8<-- \"examples/type_name.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/type_name.output\"\n    ```\n\n## Version history\n\n- Added in version 1.0.0.\n- Part of the public API version since 2.1.0.\n- Changed return value to `const char*` and added `noexcept` in version 3.0.0.\n- Added support for binary type in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/unflatten.md",
    "content": "# <small>nlohmann::basic_json::</small>unflatten\n\n```cpp\nbasic_json unflatten() const;\n```\n\nThe function restores the arbitrary nesting of a JSON value that has been flattened before using the\n[`flatten()`](flatten.md) function. The JSON value must meet certain constraints:\n\n1. The value must be an object.\n2. The keys must be JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901))\n3. The mapped values must be primitive JSON types.\n    \n## Return value\n\nthe original JSON from a flattened version\n\n## Exception safety\n\nStrong exception safety: if an exception occurs, the original value stays intact.\n\n## Exceptions\n\nThe function can throw the following exceptions:\n\n- Throws [`type_error.314`](../../home/exceptions.md#jsonexceptiontype_error314) if value is not an object\n- Throws [`type_error.315`](../../home/exceptions.md#jsonexceptiontype_error315) if object values are not primitive\n\n## Complexity\n\nLinear in the size the JSON value.\n\n## Notes\n\nEmpty objects and arrays are flattened by [`flatten()`](flatten.md) to `#!json null` values and can not unflattened to\ntheir original type. Apart from this example, for a JSON value `j`, the following is always true:\n`#!cpp j == j.flatten().unflatten()`.\n\n## Examples\n\n??? example\n\n    The following code shows how a flattened JSON object is unflattened into the original nested JSON object.\n    \n    ```cpp\n    --8<-- \"examples/unflatten.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/unflatten.output\"\n    ```\n\n## See also\n\n- [flatten](flatten.md) the reverse function\n\n## Version history\n\n- Added in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/update.md",
    "content": "# <small>nlohmann::basic_json::</small>update\n\n```cpp\n// (1)\nvoid update(const_reference j, bool merge_objects = false);\n\n// (2)\nvoid update(const_iterator first, const_iterator last, bool merge_objects = false);\n```\n\n1. Inserts all values from JSON object `j`.\n2. Inserts all values from range `[first, last)`\n\nWhen `merge_objects` is `#!c false` (default), existing keys are overwritten. When `merge_objects` is `#!c true`,\nrecursively merges objects with common keys.\n\nThe function is motivated by Python's [dict.update](https://docs.python.org/3.6/library/stdtypes.html#dict.update)\nfunction.\n\n## Parameters\n\n`j` (in)\n:   JSON object to read values from\n\n`merge_objects` (in)\n:   when `#!c true`, existing keys are not overwritten, but contents of objects are merged recursively (default:\n    `#!c false`)\n\n`first` (in)\n:   begin of the range of elements to insert\n\n`last` (in)\n:   end of the range of elements to insert\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.312`](../../home/exceptions.md#jsonexceptiontype_error312) if called on JSON values other than\n      objects; example: `\"cannot use update() with string\"`\n2. The function can throw the following exceptions:\n    - Throws [`type_error.312`](../../home/exceptions.md#jsonexceptiontype_error312) if called on JSON values other than\n      objects; example: `\"cannot use update() with string\"`\n    - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an\n      iterator which does not belong to the current JSON value; example: `\"iterator does not fit current value\"`\n    - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last`\n      do not belong to the same JSON value; example: `\"iterators do not fit\"`\n\n## Complexity\n\n1. O(N*log(size() + N)), where N is the number of elements to insert.\n2. O(N*log(size() + N)), where N is the number of elements to insert.\n\n## Examples\n\n??? example\n\n    The example shows how `update()` is used.\n    \n    ```cpp\n    --8<-- \"examples/update.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/update.output\"\n    ```\n\n??? example\n\n    The example shows how `update()` is used.\n    \n    ```cpp\n    --8<-- \"examples/update__range.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/update__range.output\"\n    ```\n\n??? example\n\n    One common usecase for this function is the handling of user settings. Assume your application can configured in\n    some aspects:\n\n    ```json\n    {\n        \"color\": \"red\",\n        \"active\": true,\n        \"name\": {\"de\": \"Maus\", \"en\": \"mouse\"}\n    }\n    ```\n\n    The user may override the default settings selectively:\n\n    ```json\n    {\n        \"color\": \"blue\",\n        \"name\": {\"es\": \"ratón\"},\n    }\n    ```\n\n    Then `update` manages the merging of default settings and user settings:\n \n    ```cpp\n    auto user_settings = json::parse(\"config.json\");\n    auto effective_settings = get_default_settings();\n    effective_settings.update(user_settings);\n    ```\n    \n    Now `effective_settings` contains the default settings, but those keys set by the user are overwritten:\n\n    ```json\n    {\n        \"color\": \"blue\",\n        \"active\": true,\n        \"name\": {\"es\": \"ratón\"}\n    }\n    ```\n\n    Note existing keys were just overwritten. To merge objects, `merge_objects` setting should be set to `#!c true`:\n    \n    ```cpp\n    auto user_settings = json::parse(\"config.json\");\n    auto effective_settings = get_default_settings();\n    effective_settings.update(user_settings, true);\n    ```\n\n    ```json\n    {\n        \"color\": \"blue\",\n        \"active\": true,\n        \"name\": {\"de\": \"Maus\", \"en\": \"mouse\", \"es\": \"ratón\"}\n    }\n    ```\n\n## Version history\n\n- Added in version 3.0.0.\n- Added `merge_objects` parameter in 3.10.4.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/value.md",
    "content": "# <small>nlohmann::basic_json::</small>value\n\n```cpp\n// (1)\ntemplate<class ValueType>\nValueType value(const typename object_t::key_type& key,\n                const ValueType& default_value) const;\n\n// (2)\ntemplate<class ValueType>\nValueType value(const json_pointer& ptr,\n                const ValueType& default_value) const;\n```\n\n1. Returns either a copy of an object's element at the specified key `key` or a given default value if no element with\n   key `key` exists.\n   \n    The function is basically equivalent to executing\n    ```cpp\n    try {\n       return at(key);\n    } catch(out_of_range) {\n       return default_value;\n    }\n    ```\n\n2. Returns either a copy of an object's element at the specified JSON pointer `ptr` or a given default value if no value\n   at `ptr` exists.\n   \n    The function is basically equivalent to executing\n    ```cpp\n    try {\n       return at(ptr);\n    } catch(out_of_range) {\n       return default_value;\n    }\n    ```\n\n!!! note\n\n    - Unlike [`at`](at.md), this function does not throw if the given `key`/`ptr` was not found.\n    - Unlike [`operator[]`](operator[].md), this function does not implicitly add an element to the position defined by\n     `key`/`ptr` key. This function is furthermore also applicable to const objects.\n\n## Template parameters\n\n`ValueType` \n:   type compatible to JSON values, for instance `#!cpp int` for JSON integer numbers, `#!cpp bool` for JSON booleans,\n    or `#!cpp std::vector` types for JSON arrays. Note the type of the expected value at `key`/`ptr` and the default\n    value `default_value` must be compatible.\n\n## Parameters\n\n`key` (in)\n:   key of the element to access\n\n`default_value` (in)\n:   the value to return if key/ptr found no value\n\n`ptr` (in)\n:   a JSON pointer to the element to access\n\n## Return value\n\n1. copy of the element at key `key` or `default_value` if `key` is not found\n1. copy of the element at JSON Pointer `ptr` or `default_value` if no value for `ptr` is found\n\n## Exception safety\n\nStrong guarantee: if an exception is thrown, there are no\nchanges to any JSON value.\n\n## Exceptions\n\n1. The function can throw the following exceptions:\n    - Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `default_value` does not match\n      the type of the value at `key`\n    - Throws [`type_error.306`](../../home/exceptions.md#jsonexceptiontype_error306) if the JSON value is not an object;\n      in that case, using `value()` with a key makes no sense.\n2. The function can throw the following exceptions:\n    - Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `default_value` does not match\n      the type of the value at `ptr`\n    - Throws [`type_error.306`](../../home/exceptions.md#jsonexceptiontype_error306) if the JSON value is not an object;\n      in that case, using `value()` with a key makes no sense.\n\n## Complexity\n\n1. Logarithmic in the size of the container.\n2. Logarithmic in the size of the container.\n\n## Examples\n\n??? example \"Example (1): access specified object element with default value\"\n\n    The example below shows how object elements can be queried with a default value.\n    \n    ```cpp\n    --8<-- \"examples/basic_json__value.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__value.output\"\n    ```\n\n??? example \"Example (2): access specified object element via JSON Pointer with default value\"\n\n    The example below shows how object elements can be queried with a default value.\n    \n    ```cpp\n    --8<-- \"examples/basic_json__value_ptr.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/basic_json__value_ptr.output\"\n    ```\n\n## See also\n\n- see [`at`](at.md) for access by reference with range checking\n- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference\n\n## Version history\n\n1. Added in version 1.0.0.\n2. Added in version 2.0.2.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/value_t.md",
    "content": "# <small>nlohmann::basic_json::</small>value_t\n\n```cpp\nenum class value_t : std::uint8_t {\n    null,\n    object,\n    array,\n    string,\n    boolean,\n    number_integer,\n    number_unsigned,\n    number_float,\n    binary,\n    discarded\n};\n```\n\nThis enumeration collects the different JSON types. It is internally used to distinguish the stored values, and the\nfunctions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_array.md), [`is_string`](is_string.md),\n[`is_boolean`](is_boolean.md), [`is_number`](is_number.md) (with [`is_number_integer`](is_number_integer.md),\n[`is_number_unsigned`](is_number_unsigned.md), and [`is_number_float`](is_number_float.md)),\n[`is_discarded`](is_discarded.md), [`is_binary`](is_binary.md), [`is_primitive`](is_primitive.md), and\n[`is_structured`](is_structured.md) rely on it.\n\n## Notes\n\nThere are three enumeration entries (number_integer, number_unsigned, and number_float), because the library\ndistinguishes these three types for numbers: [`number_unsigned_t`](number_unsigned_t.md) is used for unsigned integers,\n[`number_integer_t`](number_integer_t.md) is used for signed integers, and [`number_float_t`](number_float_t.md) is used\nfor floating-point numbers or to approximate integers which do not fit in the limits of their respective type.\n\n## Version history\n\n- Added in version 1.0.0.\n- Added unsigned integer type in version 2.0.0.\n- Added binary type in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/basic_json/~basic_json.md",
    "content": "# <small>nlohmann::basic_json::</small>~basic_json\n\n```cpp\n~basic_json() noexcept;\n```\n\nDestroys the JSON value and frees all allocated memory.\n\n## Exception safety\n\nNo-throw guarantee: this member function never throws exceptions.\n\n## Complexity\n\nLinear.\n\n## Version history\n\n- Added in version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/byte_container_with_subtype/byte_container_with_subtype.md",
    "content": "# <small>nlohmann::byte_container_with_subtype::</small>byte_container_with_subtype\n\n```cpp\n// (1)\nbyte_container_with_subtype();\n\n// (2)\nbyte_container_with_subtype(const container_type& container);\nbyte_container_with_subtype(container_type&& container);\n\n// (3)\nbyte_container_with_subtype(const container_type& container, subtype_type subtype);\nbyte_container_with_subtype(container_type&& container, subtype_type subtype);\n```\n\n1. Create empty binary container without subtype.\n2. Create binary container without subtype.\n3. Create binary container with subtype.\n\n## Parameters\n\n`container` (in)\n:   binary container\n\n`subtype` (in)\n:   subtype\n\n## Version history\n\nSince version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/byte_container_with_subtype/clear_subtype.md",
    "content": "# <small>nlohmann::byte_container_with_subtype::</small>clear_subtype\n\n```cpp\nvoid clear_subtype() noexcept;\n```\n\nClears the binary subtype and flags the value as not having a subtype, which has implications for serialization; for\ninstance MessagePack will prefer the bin family over the ext family.\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Version history\n\nSince version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/byte_container_with_subtype/has_subtype.md",
    "content": "# <small>nlohmann::byte_container_with_subtype::</small>has_subtype\n\n```cpp\nconstexpr bool has_subtype() const noexcept;\n```\n\nReturns whether the value has a subtype.\n\n## Return value\n\nwhether the value has a subtype\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Version history\n\nSince version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/byte_container_with_subtype/index.md",
    "content": "# <small>nlohmann::</small>byte_container_with_subtype\n\n```cpp\ntemplate<typename BinaryType>\nclass byte_container_with_subtype : public BinaryType;\n```\n\nThis type extends the template parameter `BinaryType` provided to [`basic_json`](../basic_json/index.md) with a subtype\nused by BSON and MessagePack. This type exists so that the user does not have to specify a type themselves with a\nspecific naming scheme in  order to override the binary type.\n\n## Template parameters\n\n`BinaryType`\n:   container to store bytes (`#!cpp std::vector<std::uint8_t>` by default)\n\n## Member types\n\n- **container_type** - the type of the underlying container (`BinaryType`)\n- **subtype_type** - the type of the subtype (`#!cpp std::uint64_t`)\n\n## Member functions\n\n- [(constructor)](byte_container_with_subtype.md)\n- **operator==** - comparison: equal\n- **operator!=** - comparison: not equal\n- [**set_subtype**](subtype.md) - sets the binary subtype\n- [**subtype**](subtype.md) - return the binary subtype\n- [**has_subtype**](has_subtype.md) - return whether the value has a subtype\n- [**clear_subtype**](clear_subtype.md) - clears the binary subtype\n\n## Version history\n\n- Added in version 3.8.0.\n- Changed type of subtypes to `#!cpp std::uint64_t` in 3.10.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/byte_container_with_subtype/set_subtype.md",
    "content": "# <small>nlohmann::byte_container_with_subtype::</small>set_subtype\n\n```cpp\nvoid set_subtype(subtype_type subtype) noexcept;\n```\n\nSets the binary subtype of the value, also flags a binary JSON value as having a subtype, which has implications for\nserialization.\n\n## Parameters\n\n`subtype` (in)\n:   subtype to set\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Version history\n\nSince version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/byte_container_with_subtype/subtype.md",
    "content": "# <small>nlohmann::byte_container_with_subtype::</small>subtype\n\n```cpp\nconstexpr subtype_type subtype() const noexcept;\n```\n\nReturns the numerical subtype of the value if it has a subtype. If it does not have a subtype, this function will return\n`subtype_type(-1)` as a sentinel value.\n\n## Return value\n\nthe numerical subtype of the binary value, or `subtype_type(-1)` if no subtype is set\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Version history\n\n- Added in version 3.8.0\n- Fixed return value to properly return `subtype_type(-1)` as documented in version 3.10.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json.md",
    "content": "# <small>nlohmann::</small>json\n\n```cpp\nusing json = basic_json<>;\n```\n\nThis type is the default specialization of the [basic_json](basic_json/index.md) class which uses the standard template\ntypes.\n\n## Version history\n\nSince version 1.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/back.md",
    "content": "# <small>nlohmann::json_pointer::</small>back\n\n```cpp\nconst std::string& back() const;\n```\n\nReturn last reference token.\n\n## Return value\n\nLast reference token.\n\n## Exceptions\n\nThrows [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The example shows the usage of `back`.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__back.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__back.output\"\n    ```\n\n## Version history\n\nAdded in version 3.6.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/empty.md",
    "content": "# <small>nlohmann::json_pointer::</small>empty\n\n```cpp\nbool empty() const noexcept;\n```\n\nReturn whether pointer points to the root document.\n\n## Return value\n\n`#!cpp true` iff the JSON pointer points to the root document.\n\n## Exception safety\n\nNo-throw guarantee: this function never throws exceptions.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The example shows the result of `empty` for different JSON Pointers.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__empty.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__empty.output\"\n    ```\n\n## Version history\n\nAdded in version 3.6.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/index.md",
    "content": "# <small>nlohmann::</small>json_pointer\n\n```cpp\ntemplate<typename BasicJsonType>\nclass json_pointer;\n```\n\nA JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with\nfunctions [`at`](../basic_json/at.md) and [`operator[]`](../basic_json/operator%5B%5D.md). Furthermore, JSON pointers\nare the base for JSON patches.\n\n## Template parameters\n\n`BasicJsonType`\n:   a specialization of [`basic_json`](../basic_json/index.md)\n\n## Member functions\n\n- [(constructor)](json_pointer.md)\n- [**to_string**](to_string.md) - return a string representation of the JSON pointer\n- [**operator std::string**](operator_string.md) - return a string representation of the JSON pointer\n- [**operator/=**](operator_slasheq.md) - append to the end of the JSON pointer\n- [**operator/**](operator_slash.md) - create JSON Pointer by appending\n- [**parent_pointer**](parent_pointer.md) - returns the parent of this JSON pointer\n- [**pop_back**](pop_back.md) - remove last reference token\n- [**back**](back.md) - return last reference token\n- [**push_back**](push_back.md) - append an unescaped token at the end of the pointer\n- [**empty**](empty.md) - return whether pointer points to the root document\n\n## See also\n\n- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)\n\n## Version history\n\nAdded in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/json_pointer.md",
    "content": "# <small>nlohmann::json_pointer::</small>json_pointer\n\n```cpp\nexplicit json_pointer(const std::string& s = \"\");\n```\n\nCreate a JSON pointer according to the syntax described in\n[Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).\n\n## Parameters\n\n`s` (in)\n:    string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value\n\n## Exceptions\n\n- Throws [parse_error.107](../../home/exceptions.md#jsonexceptionparse_error107) if the given JSON pointer `s` is \n  nonempty and does not begin with a slash (`/`); see example below.\n- Throws [parse_error.108](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON\n  pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below.\n\n## Examples\n\n??? example\n\n    The example shows the construction several valid JSON pointers as well as the exceptional behavior.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer.output\"\n    ```\n\n## Version history\n\nAdded in version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/operator_slash.md",
    "content": "# <small>nlohmann::json_pointer::</small>operator/\n\n```cpp\n// (1)\njson_pointer operator/(const json_pointer& lhs, const json_pointer& rhs);\n\n// (2)\njson_pointer operator/(const json_pointer& lhs, std::string token);\n\n// (3)\njson_pointer operator/(const json_pointer& lhs, std::size_t array_idx);\n```\n\n1. create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer\n2. create a new JSON pointer by appending the unescaped token at the end of the JSON pointer\n3. create a new JSON pointer by appending the array-index-token at the end of the JSON pointer\n\n## Parameters\n\n`lhs` (in)\n:    JSON pointer\n\n`rhs` (in)\n:    JSON pointer to append\n\n`token` (in)\n:    reference token to append\n\n`array_idx` (in)\n:    array index to append\n\n## Return value\n\n1. a new JSON pointer with `rhs` appended to `lhs`\n2. a new JSON pointer with unescaped `token` appended to `lhs`\n3. a new JSON pointer with `array_idx` appended to `lhs`\n\n## Complexity\n\n1. Linear in the length of `lhs` and `rhs`.\n2. Linear in the length of `lhs`.\n3. Linear in the length of `lhs`.\n\n## Examples\n\n??? example\n\n    The example shows the usage of `operator/`.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__operator_add_binary.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__operator_add_binary.output\"\n    ```\n\n## Version history\n\n1. Added in version 3.6.0.\n2. Added in version 3.6.0.\n3. Added in version 3.6.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/operator_slasheq.md",
    "content": "# <small>nlohmann::json_pointer::</small>operator/=\n\n```cpp\n// (1)\njson_pointer& operator/=(const json_pointer& ptr);\n\n// (2)\njson_pointer& operator/=(std::string token);\n\n// (3)\njson_pointer& operator/=(std::size_t array_idx)\n```\n\n1. append another JSON pointer at the end of this JSON pointer\n2. append an unescaped reference token at the end of this JSON pointer\n3. append an array index at the end of this JSON pointer\n\n## Parameters\n\n`ptr` (in)\n:    JSON pointer to append\n\n`token` (in)\n:    reference token to append\n\n`array_idx` (in)\n:    array index to append\n\n## Return value\n\n1. JSON pointer with `ptr` appended\n2. JSON pointer with `token` appended without escaping `token`\n3. JSON pointer with `array_idx` appended\n\n## Complexity\n\n1. Linear in the length of `ptr`.\n2. Amortized constant.\n3. Amortized constant.\n\n## Examples\n\n??? example\n\n    The example shows the usage of `operator/=`.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__operator_add.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__operator_add.output\"\n    ```\n\n## Version history\n\n1. Added in version 3.6.0.\n2. Added in version 3.6.0.\n3. Added in version 3.6.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/operator_string.md",
    "content": "# <small>nlohmann::json_pointer::</small>operator std::string\n\n```cpp\noperator std::string() const\n```\n\nReturn a string representation of the JSON pointer.\n\n## Return value\n\nA string representation of the JSON pointer\n\n## Possible implementation\n\n```cpp\noperator std::string() const\n{\n    return to_string();\n}\n```\n\n## Version history\n\nSince version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/parent_pointer.md",
    "content": "# <small>nlohmann::json_pointer::</small>parent_pointer\n\n```cpp\njson_pointer parent_pointer() const;\n```\n\nReturns the parent of this JSON pointer.\n\n## Return value\n\nParent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned.\n\n## Complexity\n\nLinear in the length of the JSON pointer.\n\n## Examples\n\n??? example\n\n    The example shows the result of `parent_pointer` for different JSON Pointers.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__parent_pointer.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__parent_pointer.output\"\n    ```\n\n## Version history\n\nAdded in version 3.6.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/pop_back.md",
    "content": "# <small>nlohmann::json_pointer::</small>pop_back\n\n```cpp\nvoid pop_back();\n```\n\nRemove last reference token.\n\n## Exceptions\n\nThrows [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent.\n\n## Complexity\n\nConstant.\n\n## Examples\n\n??? example\n\n    The example shows the usage of `pop_back`.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__pop_back.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__pop_back.output\"\n    ```\n\n## Version history\n\nAdded in version 3.6.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/push_back.md",
    "content": "# <small>nlohmann::json_pointer::</small>push_back\n\n```cpp\nvoid push_back(const std::string& token);\n\nvoid push_back(std::string&& token);\n```\n\nAppend an unescaped token at the end of the reference pointer.\n\n## Parameters\n\n`token` (in)\n:   token to add\n\n## Complexity\n\nAmortized constant.\n\n## Examples\n\n??? example\n\n    The example shows the result of `push_back` for different JSON Pointers.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__push_back.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__push_back.output\"\n    ```\n\n## Version history\n\nAdded in version 3.6.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_pointer/to_string.md",
    "content": "# <small>nlohmann::json_pointer::</small>to_string\n\n```cpp\nstd::string to_string() const;\n```\n\nReturn a string representation of the JSON pointer.\n\n## Return value\n\nA string representation of the JSON pointer\n\n## Notes\n\nFor each JSON pointer `ptr`, it holds:\n\n```cpp\nptr == json_pointer(ptr.to_string());\n```\n\n## Examples\n\n??? example\n\n    The example shows the result of `to_string`.\n     \n    ```cpp\n    --8<-- \"examples/json_pointer__to_string.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/json_pointer__to_string.output\"\n    ```\n\n## Version history\n\nSince version 2.0.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/binary.md",
    "content": "# <small>nlohmann::json_sax::</small>binary\n\n```cpp\nvirtual bool binary(binary_t& val) = 0;\n```\n\nA binary value was read.\n\n## Parameters\n\n`val` (in)\n:   binary value\n\n## Return value\n\nWhether parsing should proceed.\n\n## Notes\n\nIt is safe to move the passed binary value.\n\n## Version history\n\n- Added in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/boolean.md",
    "content": "# <small>nlohmann::json_sax::</small>boolean\n\n```cpp\nvirtual bool boolean(bool val) = 0;\n```\n\nA boolean value was read.\n\n## Parameters\n\n`val` (in)\n:   boolean value\n\n## Return value\n\nWhether parsing should proceed.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/end_array.md",
    "content": "# <small>nlohmann::json_sax::</small>end_array\n\n```cpp\nvirtual bool end_array() = 0;\n```\n\nThe end of an array was read.\n\n## Return value\n\nWhether parsing should proceed.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/end_object.md",
    "content": "# <small>nlohmann::json_sax::</small>end_object\n\n```cpp\nvirtual bool end_object() = 0;\n```\n\nThe end of an object was read.\n\n## Return value\n\nWhether parsing should proceed.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/index.md",
    "content": "# <small>nlohmann::</small>json_sax\n\n```cpp\ntemplate<typename BasicJsonType>\nstruct json_sax;\n```\n\nThis class describes the SAX interface used by [sax_parse](../basic_json/sax_parse.md). Each function is called in\ndifferent situations while the input is parsed. The boolean return value informs the parser whether to continue\nprocessing the input.\n\n## Template parameters\n\n`BasicJsonType`\n:   a specialization of [`basic_json`](../basic_json/index.md)\n\n## Member types\n\n- [**number_integer_t**](../basic_json/number_integer_t.md) - `BasicJsonType`'s type for numbers (integer)\n- [**number_unsigned_t**](../basic_json/number_unsigned_t.md) - `BasicJsonType`'s  type for numbers (unsigned)\n- [**number_float_t**](../basic_json/number_float_t.md) - `BasicJsonType`'s type for numbers (floating-point)\n- [**string_t**](../basic_json/string_t.md) - `BasicJsonType`'s type for strings\n- [**binary_t**](../basic_json/binary_t.md) - `BasicJsonType`'s type for binary arrays\n\n## Member functions\n\n- [**binary**](binary.md) (_virtual_) - a binary value was read\n- [**boolean**](boolean.md) (_virtual_) - a boolean value was read\n- [**end_array**](end_array.md) (_virtual_) - the end of an array was read\n- [**end_object**](end_object.md) (_virtual_) - the end of an object was read\n- [**key**](key.md) (_virtual_) - an object key was read\n- [**null**](null.md) (_virtual_) - a null value was read\n- [**number_float**](number_float.md) (_virtual_) - a floating-point number was read\n- [**number_integer**](number_integer.md) (_virtual_) - an integer number was read\n- [**number_unsigned**](number_unsigned.md) (_virtual_) - an unsigned integer number was read\n- [**parse_error**](parse_error.md) (_virtual_) - a parse error occurred\n- [**start_array**](start_array.md) (_virtual_) - the beginning of an array was read\n- [**start_object**](start_object.md) (_virtual_) - the beginning of an object was read\n- [**string**](string.md) (_virtual_) - a string value was read\n\n## Version history\n\n- Added in version 3.2.0.\n- Support for binary values (`binary_t`, `binary`) added in version 3.8.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/key.md",
    "content": "# <small>nlohmann::json_sax::</small>key\n\n```cpp\nvirtual bool key(string_t& val) = 0;\n```\n\nAn object key was read.\n\n## Parameters\n\n`val` (in)\n:   object key\n\n## Return value\n\nWhether parsing should proceed.\n\n## Notes\n\nIt is safe to move the passed object key value.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/null.md",
    "content": "# <small>nlohmann::json_sax::</small>null\n\n```cpp\nvirtual bool null() = 0;\n```\n\nA null value was read.\n\n## Return value\n\nWhether parsing should proceed.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/number_float.md",
    "content": "# <small>nlohmann::json_sax::</small>number_float\n\n```cpp\nvirtual bool number_float(number_float_t val, const string_t& s) = 0;\n```\n\nA floating-point number was read.\n\n## Parameters\n\n`val` (in)\n:   floating-point value\n\n`s` (in)\n:   string representation of the original input\n\n## Return value\n\nWhether parsing should proceed.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/number_integer.md",
    "content": "# <small>nlohmann::json_sax::</small>number_integer\n\n```cpp\nvirtual bool number_integer(number_integer_t val) = 0;\n```\n\nAn integer number was read.\n\n## Parameters\n\n`val` (in)\n:   integer value\n\n## Return value\n\nWhether parsing should proceed.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/number_unsigned.md",
    "content": "# <small>nlohmann::json_sax::</small>number_unsigned\n\n```cpp\nvirtual bool number_unsigned(number_unsigned_t val) = 0;\n```\n\nAn unsigned integer number was read.\n\n## Parameters\n\n`val` (in)\n:   unsigned integer value\n\n## Return value\n\nWhether parsing should proceed.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/parse_error.md",
    "content": "# <small>nlohmann::json_sax::</small>parse_error\n\n```cpp\nvirtual bool parse_error(std::size_t position,\n                         const std::string& last_token,\n                         const detail::exception& ex) = 0;\n```\n\nA parse error occurred.\n\n## Parameters\n\n`position` (in)\n:   the position in the input where the error occurs\n\n`last_token` (in)\n:   the last read token\n\n`ex` (in)\n:   an exception object describing the error\n\n## Return value\n\nWhether parsing should proceed (**must return `#!cpp false`**).\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/start_array.md",
    "content": "# <small>nlohmann::json_sax::</small>start_array\n\n```cpp\nvirtual bool start_array(std::size_t elements) = 0;\n```\n\nThe beginning of an array was read.\n\n## Parameters\n\n`elements` (in)\n:   number of object elements or `#!cpp -1` if unknown\n\n## Return value\n\nWhether parsing should proceed.\n\n## Notes\n\nBinary formats may report the number of elements.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/start_object.md",
    "content": "# <small>nlohmann::json_sax::</small>start_object\n\n```cpp\nvirtual bool start_object(std::size_t elements) = 0;\n```\n\nThe beginning of an object was read.\n\n## Parameters\n\n`elements` (in)\n:   number of object elements or `#!cpp -1` if unknown\n\n## Return value\n\nWhether parsing should proceed.\n\n## Notes\n\nBinary formats may report the number of elements.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/json_sax/string.md",
    "content": "# <small>nlohmann::json_sax::</small>string\n\n```cpp\nvirtual bool string(string_t& val) = 0;\n```\n\nA string value was read.\n\n## Parameters\n\n`val` (in)\n:   string value\n\n## Return value\n\nWhether parsing should proceed.\n\n## Notes\n\nIt is safe to move the passed string value.\n\n## Version history\n\n- Added in version 3.2.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/macros/index.md",
    "content": "# Macros\n\nSome aspects of the library can be configured by defining preprocessor macros before including the `json.hpp` header.\n\n- [`JSON_ASSERT(x)`](json_assert.md)\n- `JSON_CATCH_USER(exception)`\n- `JSON_DIAGNOSTICS`\n- `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`\n- `JSON_NOEXCEPTION`\n- `JSON_NO_IO`\n- `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`\n- `JSON_THROW_USER(exception)`\n- `JSON_TRY_USER`\n- `JSON_USE_IMPLICIT_CONVERSIONS`\n- `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)`\n- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)`\n- `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)`\n- `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, `NLOHMANN_JSON_VERSION_PATCH`\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/macros/json_assert.md",
    "content": "# JSON_ASSERT(x)\n\n```cpp\nJSON_ASSERT(x)\n```\n\n## Default implementation\n\n```cpp\nassert(x);\n```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/ordered_json.md",
    "content": "# <small>nlohmann::</small>ordered_json\n\n```cpp\nusing ordered_json = basic_json<ordered_map>;\n```\n\nThis type preserves the insertion order of object keys.\n\n## See also\n\n- [ordered_map](ordered_map.md)\n\n## Version history\n\nSince version 3.9.0.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/api/ordered_map.md",
    "content": "# <small>nlohmann::</small>ordered_map\n\n```cpp\ntemplate<class Key, class T, class IgnoredLess = std::less<Key>,\n         class Allocator = std::allocator<std::pair<const Key, T>>>\nstruct ordered_map : std::vector<std::pair<const Key, T>, Allocator>;\n```\n\nA minimal map-like container that preserves insertion order for use within [`nlohmann::ordered_json`](ordered_json.md)\n(`nlohmann::basic_json<ordered_map>`).\n\n## Template parameters\n\n`Key`\n:   key type\n\n`T`\n:   mapped type\n\n`IgnoredLess`\n:   comparison function (ignored and only added to ensure compatibility with `#!cpp std::map`)\n\n`Allocator`\n:   allocator type\n\n## Member types\n\n- **key_type** - key type (`Key`)\n- **mapped_type** - mapped type (`T`)\n- **Container** - base container type (`#!cpp std::vector<std::pair<const Key, T>, Allocator>`)\n- **iterator**\n- **const_iterator**\n- **size_type**\n- **value_type**\n\n## Member functions\n\n- (constructor)\n- (destructor)\n- **emplace**\n- **operator\\[\\]**\n- **at**\n- **erase**\n- **count**\n- **find**\n- **insert**\n\n## Examples\n\n??? example\n\n    The example shows the different behavior of `std::map` and `nlohmann::ordered_map`.\n     \n    ```cpp\n    --8<-- \"examples/ordered_map.cpp\"\n    ```\n    \n    Output:\n    \n    ```json\n    --8<-- \"examples/ordered_map.output\"\n    ```\n\n## See also\n\n- [ordered_json](ordered_json.md)\n\n## Version history\n\n- Added in version 3.9.0 to implement [`nlohmann::ordered_json`](ordered_json.md).\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/arbitrary_types.md",
    "content": "# Arbitrary Types Conversions\n\nEvery type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:\n\n```cpp\nnamespace ns {\n    // a simple struct to model a person\n    struct person {\n        std::string name;\n        std::string address;\n        int age;\n    };\n}\n\nns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// convert to JSON: copy each value into the JSON object\njson j;\nj[\"name\"] = p.name;\nj[\"address\"] = p.address;\nj[\"age\"] = p.age;\n\n// ...\n\n// convert from JSON: copy each value from the JSON object\nns::person p {\n    j[\"name\"].get<std::string>(),\n    j[\"address\"].get<std::string>(),\n    j[\"age\"].get<int>()\n};\n```\n\nIt works, but that's quite a lot of boilerplate... Fortunately, there's a better way:\n\n```cpp\n// create a person\nns::person p {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// conversion: person -> json\njson j = p;\n\nstd::cout << j << std::endl;\n// {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n\n// conversion: json -> person\nauto p2 = j.get<ns::person>();\n\n// that's it\nassert(p == p2);\n```\n\n## Basic usage\n\nTo make this work with one of your types, you only need to provide two functions:\n\n```cpp\nusing json = nlohmann::json;\n\nnamespace ns {\n    void to_json(json& j, const person& p) {\n        j = json{ {\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age} };\n    }\n\n    void from_json(const json& j, person& p) {\n        j.at(\"name\").get_to(p.name);\n        j.at(\"address\").get_to(p.address);\n        j.at(\"age\").get_to(p.age);\n    }\n} // namespace ns\n```\n\nThat's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.\nLikewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.\n\nSome important things:\n\n* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).\n* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.\n* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)\n* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.\n* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.\n\n\n## Simplify your life with macros\n\nIf you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate.\n\nThere are two macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object:\n\n- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the namespace of the class/struct to create code for.\n- `NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)` is to be defined inside the class/struct to create code for. This macro can also access private members.\n\nIn both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members.\n\n!!! note\n\n    At most 64 member variables can be passed to `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` or `NLOHMANN_DEFINE_TYPE_INTRUSIVE`.\n\n??? example\n\n    The `to_json`/`from_json` functions for the `person` struct above can be created with:\n    \n    ```cpp\n    namespace ns {\n        NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n    }\n    ```\n    \n    Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed:\n    \n    ```cpp\n    namespace ns {\n        class address {\n          private:\n            std::string street;\n            int housenumber;\n            int postcode;\n            \n          public:\n            NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)\n        };\n    }\n    ```\n\n## How do I convert third-party types?\n\nThis requires a bit more advanced technique. But first, let's see how this conversion mechanism works:\n\nThe library uses **JSON Serializers** to convert types to json.\nThe default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)).\n\nIt is implemented like this (simplified):\n\n```cpp\ntemplate <typename T>\nstruct adl_serializer {\n    static void to_json(json& j, const T& value) {\n        // calls the \"to_json\" method in T's namespace\n    }\n\n    static void from_json(const json& j, T& value) {\n        // same thing, but with the \"from_json\" method\n    }\n};\n```\n\nThis serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`...\n\nTo solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example:\n\n```cpp\n// partial specialization (full specialization works too)\nnamespace nlohmann {\n    template <typename T>\n    struct adl_serializer<boost::optional<T>> {\n        static void to_json(json& j, const boost::optional<T>& opt) {\n            if (opt == boost::none) {\n                j = nullptr;\n            } else {\n              j = *opt; // this will call adl_serializer<T>::to_json which will\n                        // find the free function to_json in T's namespace!\n            }\n        }\n\n        static void from_json(const json& j, boost::optional<T>& opt) {\n            if (j.is_null()) {\n                opt = boost::none;\n            } else {\n                opt = j.get<T>(); // same as above, but with\n                                  // adl_serializer<T>::from_json\n            }\n        }\n    };\n}\n```\n\n## How can I use `get()` for non-default constructible/non-copyable types?\n\nThere is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:\n\n```cpp\nstruct move_only_type {\n    move_only_type() = delete;\n    move_only_type(int ii): i(ii) {}\n    move_only_type(const move_only_type&) = delete;\n    move_only_type(move_only_type&&) = default;\n\n    int i;\n};\n\nnamespace nlohmann {\n    template <>\n    struct adl_serializer<move_only_type> {\n        // note: the return type is no longer 'void', and the method only takes\n        // one argument\n        static move_only_type from_json(const json& j) {\n            return {j.get<int>()};\n        }\n\n        // Here's the catch! You must provide a to_json method! Otherwise, you\n        // will not be able to convert move_only_type to json, since you fully\n        // specialized adl_serializer on that type\n        static void to_json(json& j, move_only_type t) {\n            j = t.i;\n        }\n    };\n}\n```\n\n## Can I write my own serializer? (Advanced use)\n\nYes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/test/src/unit-udt.cpp) in the test suite, to see a few examples.\n\nIf you write your own serializer, you'll need to do a few things:\n\n- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`)\n- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods\n- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL\n\nHere is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.\n\n```cpp\n// You should use void as a second template argument\n// if you don't need compile-time checks on T\ntemplate<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>\nstruct less_than_32_serializer {\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, T value) {\n        // we want to use ADL, and call the correct to_json overload\n        using nlohmann::to_json; // this method is called by adl_serializer,\n                                 // this is where the magic happens\n        to_json(j, value);\n    }\n\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n        // same thing here\n        using nlohmann::from_json;\n        from_json(j, value);\n    }\n};\n```\n\nBe **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention:\n\n```cpp\ntemplate <typename T, void>\nstruct bad_serializer\n{\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) {\n      // this calls BasicJsonType::json_serializer<T>::to_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      j = value;\n    }\n\n    template <typename BasicJsonType>\n    static void to_json(const BasicJsonType& j, T& value) {\n      // this calls BasicJsonType::json_serializer<T>::from_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      value = j.template get<T>(); // oops!\n    }\n};\n```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/binary_formats/bson.md",
    "content": "# BSON\n\nBSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the\nembedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow\nrepresentation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type.\n\n!!! abstract \"References\"\n\n\t- [BSON Website](http://bsonspec.org) - the main source on BSON\n\t- [BSON Specification](http://bsonspec.org/spec.html) - the specification\n   \n\n## Serialization\n\nThe library uses the following mapping from JSON values types to BSON types:\n\n| JSON value type | value/range                               | BSON type | marker |\n|-----------------|-------------------------------------------|-----------|--------|\n| null            | `null`                                    | null      | 0x0A   |\n| boolean         | `true`, `false`                           | boolean   | 0x08   |\n| number_integer  | -9223372036854775808..-2147483649         | int64     | 0x12   |\n| number_integer  | -2147483648..2147483647                   | int32     | 0x10   |\n| number_integer  | 2147483648..9223372036854775807           | int64     | 0x12   |\n| number_unsigned | 0..2147483647                             | int32     | 0x10   |\n| number_unsigned | 2147483648..9223372036854775807           | int64     | 0x12   |\n| number_unsigned | 9223372036854775808..18446744073709551615 | --        | --     |\n| number_float    | *any value*                               | double    | 0x01   |\n| string          | *any value*                               | string    | 0x02   |\n| array           | *any value*                               | document  | 0x04   |\n| object          | *any value*                               | document  | 0x03   |\n| binary          | *any value*                               | binary    | 0x05   |\n\n!!! warning \"Incomplete mapping\"\n\n    The mapping is **incomplete**, since only JSON-objects (and things\n    contained therein) can be serialized to BSON.\n    Also, integers larger than 9223372036854775807 cannot be serialized to BSON,\n    and the keys may not contain U+0000, since they are serialized a\n    zero-terminated c-strings.\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/to_bson.cpp\"\n    ```\n    \n    Output:\n\n    ```c\n    --8<-- \"examples/to_bson.output\"\n    ```\n\n\n## Deserialization\n\nThe library maps BSON record types to JSON value types as follows:\n\n| BSON type             | BSON marker byte | JSON value type |\n|-----------------------|------------------|-----------------|\n| double                | 0x01             | number_float    |\n| string                | 0x02             | string          |\n| document              | 0x03             | object          |\n| array                 | 0x04             | array           |\n| binary                | 0x05             | binary          |\n| undefined             | 0x06             | *unsupported*   |\n| ObjectId              | 0x07             | *unsupported*   |\n| boolean               | 0x08             | boolean         |\n| UTC Date-Time         | 0x09             | *unsupported*   |\n| null                  | 0x0A             | null            |\n| Regular Expr.         | 0x0B             | *unsupported*   |\n| DB Pointer            | 0x0C             | *unsupported*   |\n| JavaScript Code       | 0x0D             | *unsupported*   |\n| Symbol                | 0x0E             | *unsupported*   |\n| JavaScript Code       | 0x0F             | *unsupported*   |\n| int32                 | 0x10             | number_integer  |\n| Timestamp             | 0x11             | *unsupported*   |\n| 128-bit decimal float | 0x13             | *unsupported*   |\n| Max Key               | 0x7F             | *unsupported*   |\n| Min Key               | 0xFF             | *unsupported*   |\n\n!!! warning \"Incomplete mapping\"\n\n    The mapping is **incomplete**. The unsupported mappings are indicated in the table above.\n\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/from_bson.cpp\"\n    ```\n\n    Output:\n\n    ```json\n    --8<-- \"examples/from_bson.output\"\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/binary_formats/cbor.md",
    "content": "# CBOR\n\nThe Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely\nsmall code size, fairly small message size, and extensibility without the need for version negotiation.\n\n!!! abstract \"References\"\n\n  \t- [CBOR Website](http://cbor.io) - the main source on CBOR\n    - [CBOR Playground](http://cbor.me) - an interactive webpage to translate between JSON and CBOR\n    - [RFC 7049](https://tools.ietf.org/html/rfc7049) - the CBOR specification\n\n## Serialization\n\nThe library uses the following mapping from JSON values types to CBOR types according to the CBOR specification (RFC 7049):\n\n| JSON value type | value/range                                | CBOR type                         | first byte |\n|-----------------|--------------------------------------------|-----------------------------------|------------|\n| null            | `null`                                     | Null                              | 0xF6       |\n| boolean         | `true`                                     | True                              | 0xF5       |\n| boolean         | `false`                                    | False                             | 0xF4       |\n| number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow) | 0x3B       |\n| number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow) | 0x3A       |\n| number_integer  | -32768..-129                               | Negative integer (2 bytes follow) | 0x39       |\n| number_integer  | -128..-25                                  | Negative integer (1 byte follow)  | 0x38       |\n| number_integer  | -24..-1                                    | Negative integer                  | 0x20..0x37 |\n| number_integer  | 0..23                                      | Integer                           | 0x00..0x17 |\n| number_integer  | 24..255                                    | Unsigned integer (1 byte follow)  | 0x18       |\n| number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow) | 0x19       |\n| number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow) | 0x1A       |\n| number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow) | 0x1B       |\n| number_unsigned | 0..23                                      | Integer                           | 0x00..0x17 |\n| number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)  | 0x18       |\n| number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow) | 0x19       |\n| number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow) | 0x1A       |\n| number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow) | 0x1B       |\n| number_float    | *any value representable by a float*       | Single-Precision Float            | 0xFA       |\n| number_float    | *any value NOT representable by a float*   | Double-Precision Float            | 0xFB       |\n| string          | *length*: 0..23                            | UTF-8 string                      | 0x60..0x77 |\n| string          | *length*: 23..255                          | UTF-8 string (1 byte follow)      | 0x78       |\n| string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)     | 0x79       |\n| string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)     | 0x7A       |\n| string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)     | 0x7B       |\n| array           | *size*: 0..23                              | array                             | 0x80..0x97 |\n| array           | *size*: 23..255                            | array (1 byte follow)             | 0x98       |\n| array           | *size*: 256..65535                         | array (2 bytes follow)            | 0x99       |\n| array           | *size*: 65536..4294967295                  | array (4 bytes follow)            | 0x9A       |\n| array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)            | 0x9B       |\n| object          | *size*: 0..23                              | map                               | 0xA0..0xB7 |\n| object          | *size*: 23..255                            | map (1 byte follow)               | 0xB8       |\n| object          | *size*: 256..65535                         | map (2 bytes follow)              | 0xB9       |\n| object          | *size*: 65536..4294967295                  | map (4 bytes follow)              | 0xBA       |\n| object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)              | 0xBB       |\n| binary          | *size*: 0..23                              | byte string                       | 0x40..0x57 |\n| binary          | *size*: 23..255                            | byte string (1 byte follow)       | 0x58       |\n| binary          | *size*: 256..65535                         | byte string (2 bytes follow)      | 0x59       |\n| binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)      | 0x5A       |\n| binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)      | 0x5B       |\n\nBinary values with subtype are mapped to tagged values (0xD8..0xDB) depending on the subtype, followed by a byte string,\nsee \"binary\" cells in the table above.\n\n!!! success \"Complete mapping\"\n\n\tThe mapping is **complete** in the sense that any JSON value type can be converted to a CBOR value.\n\n!!! info \"NaN/infinity handling\"\n\n\tIf NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to `null`.\n\n!!! info \"Unused CBOR types\"\n\n\tThe following CBOR types are not used in the conversion:\n\n      - UTF-8 strings terminated by \"break\" (0x7F)\n      - arrays terminated by \"break\" (0x9F)\n      - maps terminated by \"break\" (0xBF)\n      - byte strings terminated by \"break\" (0x5F)\n      - date/time (0xC0..0xC1)\n      - bignum (0xC2..0xC3)\n      - decimal fraction (0xC4)\n      - bigfloat (0xC5)\n      - expected conversions (0xD5..0xD7)\n      - simple values (0xE0..0xF3, 0xF8)\n      - undefined (0xF7)\n      - half-precision floats (0xF9)\n      - break (0xFF)\n\n!!! info \"Tagged items\"\n\n    Binary subtypes will be serialized as tagged items. See [binary values](../binary_values.md#cbor) for an example.\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/to_cbor.cpp\"\n    ```\n    \n    Output:\n\n    ```c\n    --8<-- \"examples/to_cbor.output\"\n    ```\n\n## Deserialization\n\nThe library maps CBOR types to JSON value types as follows:\n\n| CBOR type              | JSON value type | first byte |\n|------------------------|-----------------|------------|\n| Integer                | number_unsigned | 0x00..0x17 |\n| Unsigned integer       | number_unsigned | 0x18       |\n| Unsigned integer       | number_unsigned | 0x19       |\n| Unsigned integer       | number_unsigned | 0x1A       |\n| Unsigned integer       | number_unsigned | 0x1B       |\n| Negative integer       | number_integer  | 0x20..0x37 |\n| Negative integer       | number_integer  | 0x38       |\n| Negative integer       | number_integer  | 0x39       |\n| Negative integer       | number_integer  | 0x3A       |\n| Negative integer       | number_integer  | 0x3B       |\n| Byte string            | binary          | 0x40..0x57 |\n| Byte string            | binary          | 0x58       |\n| Byte string            | binary          | 0x59       |\n| Byte string            | binary          | 0x5A       |\n| Byte string            | binary          | 0x5B       |\n| UTF-8 string           | string          | 0x60..0x77 |\n| UTF-8 string           | string          | 0x78       |\n| UTF-8 string           | string          | 0x79       |\n| UTF-8 string           | string          | 0x7A       |\n| UTF-8 string           | string          | 0x7B       |\n| UTF-8 string           | string          | 0x7F       |\n| array                  | array           | 0x80..0x97 |\n| array                  | array           | 0x98       |\n| array                  | array           | 0x99       |\n| array                  | array           | 0x9A       |\n| array                  | array           | 0x9B       |\n| array                  | array           | 0x9F       |\n| map                    | object          | 0xA0..0xB7 |\n| map                    | object          | 0xB8       |\n| map                    | object          | 0xB9       |\n| map                    | object          | 0xBA       |\n| map                    | object          | 0xBB       |\n| map                    | object          | 0xBF       |\n| False                  | `false`         | 0xF4       |\n| True                   | `true`          | 0xF5       |\n| Null                   | `null`          | 0xF6       |\n| Half-Precision Float   | number_float    | 0xF9       |\n| Single-Precision Float | number_float    | 0xFA       |\n| Double-Precision Float | number_float    | 0xFB       |\n\n!!! warning \"Incomplete mapping\"\n\n\tThe mapping is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors:\n\n     - date/time (0xC0..0xC1)\n     - bignum (0xC2..0xC3)\n     - decimal fraction (0xC4)\n     - bigfloat (0xC5)\n     - expected conversions (0xD5..0xD7)\n     - simple values (0xE0..0xF3, 0xF8)\n     - undefined (0xF7)\n\n!!! warning \"Object keys\"\n\n\tCBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than UTF-8 strings are rejected.\n\n!!! warning \"Tagged items\"\n\n    Tagged items will throw a parse error by default. They can be ignored by passing `cbor_tag_handler_t::ignore` to function `from_cbor`. They can be stored by passing `cbor_tag_handler_t::store` to function `from_cbor`.\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/from_cbor.cpp\"\n    ```\n\n    Output:\n\n    ```json\n    --8<-- \"examples/from_cbor.output\"\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/binary_formats/index.md",
    "content": "# Binary Formats\n\nThough JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports\n\n- [BSON](bson.md) (Binary JSON),\n- [CBOR](cbor.md) (Concise Binary Object Representation),\n- [MessagePack](messagepack.md), and\n- [UBJSON](ubjson.md) (Universal Binary JSON)\n\nto efficiently encode JSON values to byte vectors and to decode such vectors.\n\n## Comparison\n\n### Completeness\n\n| Format      | Serialization                                 | Deserialization                              |\n|-------------|-----------------------------------------------|----------------------------------------------|\n| BSON        | incomplete: top-level value must be an object | incomplete, but all JSON types are supported |\n| CBOR        | complete                                      | incomplete, but all JSON types are supported |\n| MessagePack | complete                                      | complete                                     |\n| UBJSON      | complete                                      | complete                                     |\n\n### Binary values\n\n| Format      | Binary values | Binary subtypes |\n|-------------|---------------|-----------------|\n| BSON        | supported     | supported       |\n| CBOR        | supported     | supported       |\n| MessagePack | supported     | supported       |\n| UBJSON      | not supported | not supported   |\n\nSee [binary values](../binary_values.md) for more information.\n\n### Sizes\n\n| Format             | canada.json | twitter.json | citm_catalog.json | jeopardy.json |\n|--------------------|-------------|--------------|-------------------|---------------|\n| BSON               | 85,8 %      | 95,2 %       | 95,8 %            | 106,7 %       |\n| CBOR               | 50,5 %      | 86,3 %       | 68,4 %            | 88,0 %        |\n| MessagePack        | 50,6 %      | 86,0 %       | 68,5 %            | 87,9 %        |\n| UBJSON             | 53,2 %      | 91,3 %       | 78,2 %            | 96,6 %        |\n| UBJSON (size)      | 58,6 %      | 92,3 %       | 86,8 %            | 97,4 %        |\n| UBJSON (size+type) | 55,9 %      | 92,3 %       | 85,0 %            | 95,0 %        |\n\nSizes compared to minified JSON value.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/binary_formats/messagepack.md",
    "content": "# MessagePack\n\nMessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.\n\n!!! abstract \"References\"\n\n\t- [MessagePack website](https://msgpack.org)\n\t- [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md)\n\n## Serialization\n\nThe library uses the following mapping from JSON values types to MessagePack types according to the MessagePack specification:\n\n| JSON value type | value/range                              | MessagePack type | first byte |\n|-----------------|------------------------------------------|------------------|------------|\n| null            | `null`                                   | nil              | 0xC0       |\n| boolean         | `true`                                   | true             | 0xC3       |\n| boolean         | `false`                                  | false            | 0xC2       |\n| number_integer  | -9223372036854775808..-2147483649        | int64            | 0xD3       |\n| number_integer  | -2147483648..-32769                      | int32            | 0xD2       |\n| number_integer  | -32768..-129                             | int16            | 0xD1       |\n| number_integer  | -128..-33                                | int8             | 0xD0       |\n| number_integer  | -32..-1                                  | negative fixint  | 0xE0..0xFF |\n| number_integer  | 0..127                                   | positive fixint  | 0x00..0x7F |\n| number_integer  | 128..255                                 | uint 8           | 0xCC       |\n| number_integer  | 256..65535                               | uint 16          | 0xCD       |\n| number_integer  | 65536..4294967295                        | uint 32          | 0xCE       |\n| number_integer  | 4294967296..18446744073709551615         | uint 64          | 0xCF       |\n| number_unsigned | 0..127                                   | positive fixint  | 0x00..0x7F |\n| number_unsigned | 128..255                                 | uint 8           | 0xCC       |\n| number_unsigned | 256..65535                               | uint 16          | 0xCD       |\n| number_unsigned | 65536..4294967295                        | uint 32          | 0xCE       |\n| number_unsigned | 4294967296..18446744073709551615         | uint 64          | 0xCF       |\n| number_float    | *any value representable by a float*     | float 32         | 0xCA       |\n| number_float    | *any value NOT representable by a float* | float 64         | 0xCB       |\n| string          | *length*: 0..31                          | fixstr           | 0xA0..0xBF |\n| string          | *length*: 32..255                        | str 8            | 0xD9       |\n| string          | *length*: 256..65535                     | str 16           | 0xDA       |\n| string          | *length*: 65536..4294967295              | str 32           | 0xDB       |\n| array           | *size*: 0..15                            | fixarray         | 0x90..0x9F |\n| array           | *size*: 16..65535                        | array 16         | 0xDC       |\n| array           | *size*: 65536..4294967295                | array 32         | 0xDD       |\n| object          | *size*: 0..15                            | fix map          | 0x80..0x8F |\n| object          | *size*: 16..65535                        | map 16           | 0xDE       |\n| object          | *size*: 65536..4294967295                | map 32           | 0xDF       |\n| binary          | *size*: 0..255                           | bin 8            | 0xC4       |\n| binary          | *size*: 256..65535                       | bin 16           | 0xC5       |\n| binary          | *size*: 65536..4294967295                | bin 32           | 0xC6       |\n\n!!! success \"Complete mapping\"\n\n\tThe mapping is **complete** in the sense that any JSON value type can be converted to a MessagePack value.\n\n\tAny MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`.\n\n!!! warning \"Size constraints\"\n\n\tThe following values can **not** be converted to a MessagePack value:\n\n\t  - strings with more than 4294967295 bytes\n\t  - byte strings with more than 4294967295 bytes\n\t  - arrays with more than 4294967295 elements\n\t  - objects with more than 4294967295 elements\n\n!!! info \"NaN/infinity handling\"\n\n\tIf NaN or Infinity are stored inside a JSON number, they are serialized properly. function which serializes NaN or Infinity to `null`.\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/to_msgpack.cpp\"\n    ```\n    \n    Output:\n\n    ```c\n    --8<-- \"examples/to_msgpack.output\"\n    ```\n\n## Deserialization\n\nThe library maps MessagePack types to JSON value types as follows:\n\n| MessagePack type | JSON value type | first byte |\n|------------------|-----------------|------------|\n| positive fixint  | number_unsigned | 0x00..0x7F |\n| fixmap           | object          | 0x80..0x8F |\n| fixarray         | array           | 0x90..0x9F |\n| fixstr           | string          | 0xA0..0xBF |\n| nil              | `null`          | 0xC0       |\n| false            | `false`         | 0xC2       |\n| true             | `true`          | 0xC3       |\n| float 32         | number_float    | 0xCA       |\n| float 64         | number_float    | 0xCB       |\n| uint 8           | number_unsigned | 0xCC       |\n| uint 16          | number_unsigned | 0xCD       |\n| uint 32          | number_unsigned | 0xCE       |\n| uint 64          | number_unsigned | 0xCF       |\n| int 8            | number_integer  | 0xD0       |\n| int 16           | number_integer  | 0xD1       |\n| int 32           | number_integer  | 0xD2       |\n| int 64           | number_integer  | 0xD3       |\n| str 8            | string          | 0xD9       |\n| str 16           | string          | 0xDA       |\n| str 32           | string          | 0xDB       |\n| array 16         | array           | 0xDC       |\n| array 32         | array           | 0xDD       |\n| map 16           | object          | 0xDE       |\n| map 32           | object          | 0xDF       |\n| bin 8            | binary          | 0xC4       |\n| bin 16           | binary          | 0xC5       |\n| bin 32           | binary          | 0xC6       |\n| ext 8            | binary          | 0xC7       |\n| ext 16           | binary          | 0xC8       |\n| ext 32           | binary          | 0xC9       |\n| fixext 1         | binary          | 0xD4       |\n| fixext 2         | binary          | 0xD5       |\n| fixext 4         | binary          | 0xD6       |\n| fixext 8         | binary          | 0xD7       |\n| fixext 16        | binary          | 0xD8       |\n| negative fixint  | number_integer  | 0xE0-0xFF  |\n\n!!! info\n\n\tAny MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`.\n\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/from_msgpack.cpp\"\n    ```\n\n    Output:\n\n    ```json\n    --8<-- \"examples/from_msgpack.output\"\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/binary_formats/ubjson.md",
    "content": "# UBJSON\n\nUniversal Binary JSON (UBJSON) is a binary form directly imitating JSON, but requiring fewer bytes of data. It aims to achieve the generality of JSON, combined with being much easier to process than JSON.\n\n!!! abstract \"References\"\n\n\t- [UBJSON Website](http://ubjson.org)\n\n## Serialization\n\nThe library uses the following mapping from JSON values types to UBJSON types according to the UBJSON specification:\n\n| JSON value type | value/range                       | UBJSON type    | marker |\n|-----------------|-----------------------------------|----------------|--------|\n| null            | `null`                            | null           | `Z`    |\n| boolean         | `true`                            | true           | `T`    |\n| boolean         | `false`                           | false          | `F`    |\n| number_integer  | -9223372036854775808..-2147483649 | int64          | `L`    |\n| number_integer  | -2147483648..-32769               | int32          | `l`    |\n| number_integer  | -32768..-129                      | int16          | `I`    |\n| number_integer  | -128..127                         | int8           | `i`    |\n| number_integer  | 128..255                          | uint8          | `U`    |\n| number_integer  | 256..32767                        | int16          | `I`    |\n| number_integer  | 32768..2147483647                 | int32          | `l`    |\n| number_integer  | 2147483648..9223372036854775807   | int64          | `L`    |\n| number_unsigned | 0..127                            | int8           | `i`    |\n| number_unsigned | 128..255                          | uint8          | `U`    |\n| number_unsigned | 256..32767                        | int16          | `I`    |\n| number_unsigned | 32768..2147483647                 | int32          | `l`    |\n| number_unsigned | 2147483648..9223372036854775807   | int64          | `L`    |\n| number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`    |\n| number_float    | *any value*                       | float64        | `D`    |\n| string          | *with shortest length indicator*  | string         | `S`    |\n| array           | *see notes on optimized format*   | array          | `[`    |\n| object          | *see notes on optimized format*   | map            | `{`    |\n\n!!! success \"Complete mapping\"\n\n\tThe mapping is **complete** in the sense that any JSON value type can be converted to a UBJSON value.\n\n\tAny UBJSON output created by `to_ubjson` can be successfully parsed by `from_ubjson`.\n\n!!! warning \"Size constraints\"\n\n\tThe following values can **not** be converted to a UBJSON value:\n\n      - strings with more than 9223372036854775807 bytes (theoretical)\n\n!!! info \"Unused UBJSON markers\"\n\n\tThe following markers are not used in the conversion:\n    \n    - `Z`: no-op values are not created.\n    - `C`: single-byte strings are serialized with `S` markers.\n\n!!! info \"NaN/infinity handling\"\n\n\tIf NaN or Infinity are stored inside a JSON number, they are\n    serialized properly. This behavior differs from the `dump()`\n    function which serializes NaN or Infinity to `null`.\n\n!!! info \"Optimized formats\"\n\n\tThe optimized formats for containers are supported: Parameter\n    `use_size` adds size information to the beginning of a container and\n    removes the closing marker. Parameter `use_type` further checks\n    whether all elements of a container have the same type and adds the\n    type marker to the beginning of the container. The `use_type`\n    parameter must only be used together with `use_size = true`.\n\n    Note that `use_size = true` alone may result in larger representations -\n    the benefit of this parameter is that the receiving side is\n    immediately informed on the number of elements of the container.\n\n!!! info \"Binary values\"\n\n\tIf the JSON data contains the binary type, the value stored is a list\n    of integers, as suggested by the UBJSON documentation.  In particular,\n    this means that serialization and the deserialization of a JSON\n    containing binary values into UBJSON and back will result in a\n    different JSON object.\n\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/to_ubjson.cpp\"\n    ```\n\n    Output:\n\n    ```c\n    --8<-- \"examples/to_ubjson.output\"\n    ```\n\n## Deserialization\n\nThe library maps UBJSON types to JSON value types as follows:\n\n| UBJSON type | JSON value type                         | marker |\n|-------------|-----------------------------------------|--------|\n| no-op       | *no value, next value is read*          | `N`    |\n| null        | `null`                                  | `Z`    |\n| false       | `false`                                 | `F`    |\n| true        | `true`                                  | `T`    |\n| float32     | number_float                            | `d`    |\n| float64     | number_float                            | `D`    |\n| uint8       | number_unsigned                         | `U`    |\n| int8        | number_integer                          | `i`    |\n| int16       | number_integer                          | `I`    |\n| int32       | number_integer                          | `l`    |\n| int64       | number_integer                          | `L`    |\n| string      | string                                  | `S`    |\n| char        | string                                  | `C`    |\n| array       | array (optimized values are supported)  | `[`    |\n| object      | object (optimized values are supported) | `{`    |\n\n!!! success \"Complete mapping\"\n\n\tThe mapping is **complete** in the sense that any UBJSON value can be converted to a JSON value.\n\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/from_ubjson.cpp\"\n    ```\n\n    Output:\n\n    ```json\n    --8<-- \"examples/from_ubjson.output\"\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/binary_values.md",
    "content": "# Binary Values\n\nThe library implements several [binary formats](binary_formats/index.md) that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics define outside the library and only define a sequence of bytes to be stored.\n\nJSON itself does not have a binary value. As such, binary values are an extension that this library implements to store values received by a binary format. Binary values are never created by the JSON parser, and are only part of a serialized JSON text if they have been created manually or via a binary format.\n\n## API for binary values\n\n```plantuml\nclass json::binary_t {\n    -- setters --\n    +void set_subtype(std::uint64_t subtype)\n    +void clear_subtype()\n    -- getters --\n    +std::uint64_t subtype() const\n    +bool has_subtype() const\n}\n\n\"std::vector<uint8_t>\" <|-- json::binary_t\n```\n\nBy default, binary values are stored as `std::vector<std::uint8_t>`. This type can be changed by providing a template parameter to the `basic_json` type. To store binary subtypes, the storage type is extended and exposed as `json::binary_t`:\n\n```cpp\nauto binary = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE});\nauto binary_with_subtype = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n```\n\nThere are several convenience functions to check and set the subtype:\n\n```cpp\nbinary.has_subtype();                   // returns false\nbinary_with_subtype.has_subtype();      // returns true\n\nbinary_with_subtype.clear_subtype();\nbinary_with_subtype.has_subtype();      // returns true\n\nbinary_with_subtype.set_subtype(42);\nbinary.set_subtype(23);\n\nbinary.subtype();                       // returns 23\n```\n\nAs `json::binary_t` is subclassing `std::vector<std::uint8_t>`, all member functions are available:\n\n```cpp\nbinary.size();  // returns 4\nbinary[1];      // returns 0xFE\n```\n\nJSON values can be constructed from `json::binary_t`:\n\n```cpp\njson j = binary;\n```\n\nBinary values are primitive values just like numbers or strings:\n\n```cpp\nj.is_binary();    // returns true\nj.is_primitive(); // returns true\n```\n\nGiven a binary JSON value, the `binary_t` can be accessed by reference as via `get_binary()`:\n\n```cpp\nj.get_binary().has_subtype();  // returns true\nj.get_binary().size();         // returns 4\n```\n\nFor convenience, binary JSON values can be constructed via `json::binary`:\n\n```cpp\nauto j2 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 23);\nauto j3 = json::binary({0xCA, 0xFE, 0xBA, 0xBE});\n\nj2 == j;                        // returns true\nj3.get_binary().has_subtype();  // returns false\nj3.get_binary().subtype();      // returns std::uint64_t(-1) as j3 has no subtype\n```\n\n\n\n## Serialization\n\nBinary values are serialized differently according to the formats.\n\n### JSON\n\nJSON does not have a binary type, and this library does not introduce a new type as this would break conformance. Instead, binary values are serialized as an object with two keys: `bytes` holds an array of integers, and `subtype` is an integer or `null`.\n\n??? example\n\n    Code:\n\n    ```cpp\n    // create a binary value of subtype 42\n    json j;\n    j[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n    \n    // serialize to standard output\n    std::cout << j.dump(2) << std::endl;\n    ```\n    \n    Output:\n    \n    ```json\n    {\n      \"binary\": {\n        \"bytes\": [202, 254, 186, 190],\n        \"subtype\": 42\n      }\n    }\n    ```\n\n!!! warning \"No roundtrip for binary values\"\n\n    The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes.\n\n### BSON\n\n[BSON](binary_formats/bson.md) supports binary values and subtypes. If a subtype is given, it is used and added as unsigned 8-bit integer. If no subtype is given, the generic binary subtype 0x00 is used.\n\n??? example\n\n    Code:\n    \n    ```cpp\n    // create a binary value of subtype 42\n    json j;\n    j[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n    // convert to BSON\n    auto v = json::to_bson(j);      \n    ```\n            \n    `v` is a `std::vector<std::uint8t>` with the following 22 elements:\n    \n    ```c\n    0x16 0x00 0x00 0x00                         // number of bytes in the document\n        0x05                                    // binary value\n            0x62 0x69 0x6E 0x61 0x72 0x79 0x00  // key \"binary\" + null byte\n            0x04 0x00 0x00 0x00                 // number of bytes\n            0x2a                                // subtype\n            0xCA 0xFE 0xBA 0xBE                 // content\n    0x00                                        // end of the document\n    ```\n\n    Note that the serialization preserves the subtype, and deserializing `v` would yield the following value:\n\n    ```json\n    {\n      \"binary\": {\n        \"bytes\": [202, 254, 186, 190],\n        \"subtype\": 42\n      }\n    }\n    ```\n\n### CBOR\n\n[CBOR](binary_formats/cbor.md) supports binary values, but no subtypes. Subtypes will be serialized as tags. Any binary value will be serialized as byte strings. The library will choose the smallest representation using the length of the byte array.\n\n??? example\n\n    Code:\n    \n    ```cpp\n    // create a binary value of subtype 42\n    json j;\n    j[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n    // convert to CBOR\n    auto v = json::to_cbor(j);      \n    ```\n            \n    `v` is a `std::vector<std::uint8t>` with the following 15 elements:\n    \n    ```c\n    0xA1                                   // map(1)\n        0x66                               // text(6)\n            0x62 0x69 0x6E 0x61 0x72 0x79  // \"binary\"\n        0xD8 0x2A                          // tag(42)\n        0x44                               // bytes(4)\n            0xCA 0xFE 0xBA 0xBE            // content\n    ```\n\n    Note that the subtype is serialized as tag. However, parsing tagged values yield a parse error unless `json::cbor_tag_handler_t::ignore` or `json::cbor_tag_handler_t::store` is passed to `json::from_cbor`.\n\n    ```json\n    {\n      \"binary\": {\n        \"bytes\": [202, 254, 186, 190],\n        \"subtype\": null\n      }\n    }\n    ```\n\n### MessagePack\n\n[MessagePack](binary_formats/messagepack.md) supports binary values and subtypes. If a subtype is given, the ext family is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, ext8, ext16, and ext32. The subtype is then added as signed 8-bit integer.\n\nIf no subtype is given, the bin family (bin8, bin16, bin32) is used.\n\n??? example\n\n    Code:\n    \n    ```cpp\n    // create a binary value of subtype 42\n    json j;\n    j[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n    // convert to MessagePack\n    auto v = json::to_msgpack(j);      \n    ```\n            \n    `v` is a `std::vector<std::uint8t>` with the following 14 elements:\n    \n    ```c\n    0x81                                   // fixmap1\n        0xA6                               // fixstr6\n            0x62 0x69 0x6E 0x61 0x72 0x79  // \"binary\"\n        0xD6                               // fixext4\n            0x2A                           // subtype\n            0xCA 0xFE 0xBA 0xBE            // content\n    ```\n\n    Note that the serialization preserves the subtype, and deserializing `v` would yield the following value:\n\n    ```json\n    {\n      \"binary\": {\n        \"bytes\": [202, 254, 186, 190],\n        \"subtype\": 42\n      }\n    }\n    ```\n\n### UBJSON\n\n[UBJSON](binary_formats/ubjson.md) neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library.\n\n??? example\n\n    Code:\n    \n    ```cpp\n    // create a binary value of subtype 42 (will be ignored in UBJSON)\n    json j;\n    j[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n    // convert to UBJSON\n    auto v = json::to_msgpack(j);      \n    ```\n            \n    `v` is a `std::vector<std::uint8t>` with the following 20 elements:\n    \n    ```c\n    0x7B                                             // '{'\n        0x69 0x06                                    // i 6 (length of the key)\n        0x62 0x69 0x6E 0x61 0x72 0x79                // \"binary\"\n        0x5B                                         // '['\n            0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE  // content (each byte prefixed with 'U')\n        0x5D                                         // ']'\n    0x7D                                             // '}'\n    ```\n\n    The following code uses the type and size optimization for UBJSON:\n\n    ```cpp\n    // convert to UBJSON using the size and type optimization\n    auto v = json::to_ubjson(j, true, true);\n    ```\n\n    The resulting vector has 23 elements; the optimization is not effective for examples with few values:\n\n    ```c\n    0x7B                                // '{'\n        0x24                            // '$' type of the object elements\n        0x5B                            // '[' array\n        0x23 0x69 0x01                  // '#' i 1 number of object elements\n        0x69 0x06                       // i 6 (length of the key)\n        0x62 0x69 0x6E 0x61 0x72 0x79   // \"binary\"\n            0x24 0x55                   // '$' 'U' type of the array elements: unsigned integers\n            0x23 0x69 0x04              // '#' i 4 number of array elements\n            0xCA 0xFE 0xBA 0xBE         // content\n    ```\n\n    Note that subtype (42) is **not** serialized and that UBJSON has **no binary type**, and deserializing `v` would yield the following value:\n\n    ```json\n    {\n      \"binary\": [202, 254, 186, 190]\n    }\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/comments.md",
    "content": "# Comments\n\nThis library does not support comments *by default*. It does so for three reasons:\n\n1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript.\n2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012:\n\n\t> \tI removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability.  I know that the lack of comments makes some people sad, but it shouldn't. \n\n\t> \tSuppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.\n\n3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this.\n\nHowever, you can pass set parameter `ignore_comments` to `#!c true` in the parse function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace.\n\n!!! example\n\n    Consider the following JSON with comments.\n\n    ```json\n    {\n        // update in 2006: removed Pluto\n        \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                    \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n    }\n    ```\n    \n    When calling `parse` without additional argument, a parse error exception is thrown. If `ignore_comments` is set to `#! true`, the comments are ignored during parsing:\n\n    ```cpp\n    #include <iostream>\n    #include \"json.hpp\"\n    \n    using json = nlohmann::json;\n    \n    int main()\n    {\n        std::string s = R\"(\n        {\n            // update in 2006: removed Pluto\n            \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                        \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n        }\n        )\";\n        \n        try\n        {\n            json j = json::parse(s);\n        }\n        catch (json::exception &e)\n        {\n            std::cout << e.what() << std::endl;\n        }\n        \n        json j = json::parse(s,\n                             /* callback */ nullptr,\n                             /* allow exceptions */ true,\n                             /* ignore_comments */ true);\n        std::cout << j.dump(2) << '\\n';\n    }\n    ```\n\n    Output:\n    \n    ```\n    [json.exception.parse_error.101] parse error at line 3, column 9:\n    syntax error while parsing object key - invalid literal;\n    last read: '<U+000A>    {<U+000A>        /'; expected string literal\n    ```\n    \n    ```json\n    {\n      \"planets\": [\n        \"Mercury\",\n        \"Venus\",\n        \"Earth\",\n        \"Mars\",\n        \"Jupiter\",\n        \"Uranus\",\n        \"Neptune\"\n      ]\n    }\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/element_access/checked_access.md",
    "content": "# Checked access: at\n\n## Overview\n\nThe `#!cpp at()` member function performs checked access; that is, it returns a reference to the desired value if it exists and throws a [`basic_json::out_of_range` exception](../../home/exceptions.md#out-of-range) otherwise.\n\n??? example\n\n    Consider the following JSON value:\n    \n    ```json\n    {\n        \"name\": \"Mary Smith\",\n        \"age\": 42,\n        \"hobbies\": [\"hiking\", \"reading\"]\n    }\n    ```\n    \n    Assume the value is parsed to a `json` variable `j`.\n\n    | expression | value |\n    | ---------- | ----- |\n    | `#!cpp j`  | `#!json {\"name\": \"Mary Smith\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]}` |\n    | `#!cpp j.at(\"name\")`  | `#!json \"Mary Smith\"` |\n    | `#!cpp j.at(\"age\")`  | `#!json 42` |\n    | `#!cpp j.at(\"hobbies\")`  | `#!json [\"hiking\", \"reading\"]` |\n    | `#!cpp j.at(\"hobbies\").at(0)`  | `#!json \"hiking\"` |\n    | `#!cpp j.at(\"hobbies\").at(1)`  | `#!json \"reading\"` |\n\nThe return value is a reference, so it can be modified by the original value.\n\n??? example\n\n    ```cpp\n    j.at(\"name\") = \"John Smith\";\n    ```\n    \n    This code produces the following JSON value:\n    \n    ```json\n    {\n        \"name\": \"John Smith\",\n        \"age\": 42,\n        \"hobbies\": [\"hiking\", \"reading\"]\n    }\n    ```\n\nWhen accessing an invalid index (i.e., an index greater than or equal to the array size) or the passed object key is non-existing, an exception is thrown.\n\n??? example\n\n    ```cpp\n    j.at(\"hobbies\").at(3) = \"cooking\";\n    ```\n    \n    This code produces the following exception:\n    \n    ```\n    [json.exception.out_of_range.401] array index 3 is out of range\n    ```\n\n## Notes\n\n\n!!! failure \"Exceptions\"\n\n    - `at` can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error304) is thrown.\n    - [`basic_json::out_of_range` exception](../../home/exceptions.md#out-of-range) exceptions are thrown if the provided key is not found in an object or the provided index is invalid.\n\n## Summary\n\n| scenario                          | non-const value                                | const value                                    |\n|-----------------------------------|------------------------------------------------|------------------------------------------------|\n| access to existing object key     | reference to existing value is returned        | const reference to existing value is returned  |\n| access to valid array index       | reference to existing value is returned        | const reference to existing value is returned  |\n| access to non-existing object key | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown |\n| access to invalid array index     | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown |\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/element_access/default_value.md",
    "content": "# Access with default value: value\n\n## Overview\n\nIn many situations such as configuration files, missing values are not exceptional, but may be treated as if a default value was present.\n\n??? example\n\n    Consider the following JSON value:\n    \n    ```json\n    {\n        \"logOutput\": \"result.log\",\n        \"append\": true\n    }\n    ```\n    \n    Assume the value is parsed to a `json` variable `j`.\n\n    | expression | value |\n    | ---------- | ----- |\n    | `#!cpp j`  | `#!json {\"logOutput\": \"result.log\", \"append\": true}` |\n    | `#!cpp j.value(\"logOutput\", \"logfile.log\")`  | `#!json \"result.log\"` |\n    | `#!cpp j.value(\"append\", true)`  | `#!json true` |\n    | `#!cpp j.value(\"append\", false)`  | `#!json true` |\n    | `#!cpp j.value(\"logLevel\", \"verbose\")`  | `#!json \"verbose\"` |\n\n## Note\n\n!!! failure \"Exceptions\"\n\n    - `value` can only be used with objects. For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error306) is thrown.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/element_access/index.md",
    "content": "# Element Access\n\nThere are many ways elements in a JSON value can be accessed:\n\n- unchecked access via [`operator[]`](unchecked_access.md)\n- checked access via [`at`](checked_access.md)\n- access with default value via [`value`](default_value.md)\n- iterators\n- JSON pointers\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/element_access/unchecked_access.md",
    "content": "# Unchecked access: operator[]\n\n## Overview\n\nElements in a JSON object and a JSON array can be accessed via `#!cpp operator[]` similar to a `#!cpp std::map` and a `#!cpp std::vector`, respectively.\n\n??? example\n\n    Consider the following JSON value:\n    \n    ```json\n    {\n        \"name\": \"Mary Smith\",\n        \"age\": 42,\n        \"hobbies\": [\"hiking\", \"reading\"]\n    }\n    ```\n    \n    Assume the value is parsed to a `json` variable `j`.\n\n    | expression | value |\n    | ---------- | ----- |\n    | `#!cpp j`  | `#!json {\"name\": \"Mary Smith\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]}` |\n    | `#!cpp j[\"name\"]`  | `#!json \"Mary Smith\"` |\n    | `#!cpp j[\"age\"]`  | `#!json 42` |\n    | `#!cpp j[\"hobbies\"]`  | `#!json [\"hiking\", \"reading\"]` |\n    | `#!cpp j[\"hobbies\"][0]`  | `#!json \"hiking\"` |\n    | `#!cpp j[\"hobbies\"][1]`  | `#!json \"reading\"` |\n\nThe return value is a reference, so it can modify the original value. In case the passed object key is non-existing, a `#!json null` value is inserted which can be immediately be overwritten.\n\n??? example\n\n    ```cpp\n    j[\"name\"] = \"John Smith\";\n    j[\"maidenName\"] = \"Jones\";\n    ```\n    \n    This code produces the following JSON value:\n    \n    ```json\n    {\n        \"name\": \"John Smith\",\n        \"maidenName\": \"Jones\",\n        \"age\": 42,\n        \"hobbies\": [\"hiking\", \"reading\"]\n    }\n    ```\n\nWhen accessing an invalid index (i.e., an index greater than or equal to the array size), the JSON array is resized such that the passed index is the new maximal index. Intermediate values are filled with `#!json null`.\n\n??? example\n\n    ```cpp\n    j[\"hobbies\"][0] = \"running\";\n    j[\"hobbies\"][3] = \"cooking\";\n    ```\n    \n    This code produces the following JSON value:\n    \n    ```json\n    {\n        \"name\": \"John Smith\",\n        \"maidenName\": \"Jones\",\n        \"age\": 42,\n        \"hobbies\": [\"running\", \"reading\", null, \"cooking\"]\n    }\n    ```\n\n## Notes\n\n!!! info \"Design rationale\"\n\n    The library behaves differently to `#!cpp std::vector` and `#!cpp std::map`:\n    \n    - `#!cpp std::vector::operator[]` never inserts a new element.\n    - `#!cpp std::map::operator[]` is not available for const values.\n    \n    The type `#!cpp json` wraps all JSON value types. It would be impossible to remove `operator[]` for const objects. At the same time, inserting elements for non-const objects is really convenient as it avoids awkward `insert` calls. To this end, we decided to have an inserting non-const behavior for both arrays and objects.\n\n!!! info\n\n    The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no exception is thrown.\n\n!!! danger\n\n    - It is **undefined behavior** to access a const object with a non-existing key.\n    - It is **undefined behavior** to access a const array with an invalid index.\n    - In debug mode, an **assertion** will fire in both cases. You can disable assertions by defining the preprocessor symbol `#!cpp NDEBUG` or redefine the macro [`JSON_ASSERT(x)`](../macros.md#json_assertx).\n\n!!! failure \"Exceptions\"\n\n    `operator[]` can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error305) is thrown.\n\n## Summary\n\n| scenario                          | non-const value                                                                                                                                      | const value                                     |\n|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|\n| access to existing object key     | reference to existing value is returned                                                                                                              | const reference to existing value is returned   |\n| access to valid array index       | reference to existing value is returned                                                                                                              | const reference to existing value is returned   |\n| access to non-existing object key | reference to newly inserted `#!json null` value is returned                                                                                          | **undefined behavior**; assertion in debug mode |\n| access to invalid array index     | reference to newly inserted `#!json null` value is returned; any index between previous maximal index and passed index are filled with `#!json null` | **undefined behavior**; assertion in debug mode |\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/enum_conversion.md",
    "content": "# Specializing enum conversion\n\nBy default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an\nenum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be\nundefined or a different enum value than was originally intended.\n\nIt is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:\n\n```cpp\n// example enum type declaration\nenum TaskState {\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID=-1,\n};\n\n// map TaskState values to JSON as strings\nNLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {\n    {TS_INVALID, nullptr},\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n```\n\nThe `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState`\nwhile avoiding repetition and boilerplate serialization code.\n\n## Usage\n\n```cpp\n// enum to JSON as string\njson j = TS_STOPPED;\nassert(j == \"stopped\");\n\n// json string to enum\njson j3 = \"running\";\nassert(j3.get<TaskState>() == TS_RUNNING);\n\n// undefined json value to enum (where the first map entry above is the default)\njson jPi = 3.14;\nassert(jPi.get<TaskState>() == TS_INVALID );\n```\n\n## Notes\n\nJust as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,\n\n- `NLOHMANN_JSON_SERIALIZE_ENUM()` MUST be declared in your enum type's namespace (which can be the global namespace),\n  or the library will not be able to locate it, and it will default to integer serialization.\n- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.\n\nOther Important points:\n\n- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this\n  default pair carefully.\n- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the\n  map will be returned when converting to or from JSON.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/iterators.md",
    "content": "# Iterators\n\n## Overview\n\nA `basic_json` value is a container and allows access via iterators. Depending on the value type, `basic_json` stores zero or more values.\n\nAs for other containers, `begin()` returns an iterator to the first value and `end()` returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, `begin()` will return `end()`.\n\n![Illustration from cppreference.com](../images/range-begin-end.svg)\n\n### Iteration order for objects\n\nWhen iterating over objects, values are ordered with respect to the `object_comparator_t` type which defaults to `std::less`. See the [types documentation](types/index.md#key-order) for more information.\n\n??? example\n\n    ```cpp\n    // create JSON object {\"one\": 1, \"two\": 2, \"three\": 3}\n    json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n    \n    for (auto it = j.begin(); it != j.end(); ++it)\n    {\n        std::cout << *it << std::endl;\n    }\n    ```\n    \n    Output:\n    \n    ```json\n    1\n    3\n    2\n    ```\n    \n    The reason for the order is the lexicographic ordering of the object keys \"one\", \"three\", \"two\".\n\n### Access object key during iteration\n\nThe JSON iterators have two member functions, `key()` and `value()` to access the object key and stored value, respectively. When calling `key()` on a non-object iterator, an [invalid_iterator.207](../home/exceptions.md#jsonexceptioninvalid_iterator207) exception is thrown.\n\n??? example\n\n    ```cpp\n    // create JSON object {\"one\": 1, \"two\": 2, \"three\": 3}\n    json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n    \n    for (auto it = j.begin(); it != j.end(); ++it)\n    {\n        std::cout << it.key() << \" : \" << it.value() << std::endl;\n    }\n    ```\n    \n    Output:\n    \n    ```json\n    one : 1\n    three : 3\n    two : 2\n    ```\n\n### Range-based for loops\n\nC++11 allows using range-based for loops to iterate over a container.\n\n```cpp\nfor (auto it : j_object)\n{\n    // \"it\" is of type json::reference and has no key() member\n    std::cout << \"value: \" << it << '\\n';\n}\n```\n\nFor this reason, the `items()` function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator.\n\n```cpp\nfor (auto& el : j_object.items())\n{\n    std::cout << \"key: \" << el.key() << \", value:\" << el.value() << '\\n';\n}\n```\n\nThe items() function also allows using structured bindings (C++17):\n\n```cpp\nfor (auto& [key, val] : j_object.items())\n{\n    std::cout << \"key: \" << key << \", value:\" << val << '\\n';\n}\n```\n\n!!! note\n\n    When iterating over an array, `key()` will return the index of the element as string. For primitive types (e.g., numbers), `key()` returns an empty string.\n    \n!!! warning\n\n    Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See <https://github.com/nlohmann/json/issues/2040> for more information.\n\n### Reverse iteration order\n\n`rbegin()` and `rend()` return iterators in the reverse sequence.\n    \n![Illustration from cppreference.com](../images/range-rbegin-rend.svg)\n\n??? example\n\n    ```cpp\n    json j = {1, 2, 3, 4};\n\n    for (auto it = j.begin(); it != j.end(); ++it)\n    {\n        std::cout << *it << std::endl;\n    }\n    ```\n    \n    Output:\n    \n    ```json\n    4\n    3\n    2\n    1\n    ```\n\n### Iterating strings and binary values\n\nNote that \"value\" means a JSON value in this setting, not values stored in the underlying containers. That is, `*begin()` returns the complete string or binary array and is also safe the underlying string or binary array is empty.\n\n??? example\n\n    ```cpp\n    json j = \"Hello, world\";\n    for (auto it = j.begin(); it != j.end(); ++it)\n    {\n        std::cout << *it << std::endl;\n    }\n    ```\n    \n    Output:\n    \n    ```json\n    \"Hello, world\"\n    ```\n\n## Iterator invalidation\n\n| Operations | invalidated iterators |\n|------------|-----------------------|\n| `clear`    | all                   |\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/json_patch.md",
    "content": "# JSON Patch and Diff\n\n## Patches\n\nJSON Patch ([RFC 6902](https://tools.ietf.org/html/rfc6902)) defines a JSON document structure for expressing a sequence\nof operations to apply to a JSON document. With the `patch` function, a JSON Patch is applied to the current JSON value\nby executing all operations from the patch.\n\n??? example\n\n    The following code shows how a JSON patch is applied to a value.\n\n    ```cpp\n    --8<-- \"examples/patch.cpp\"\n    ```\n    \n    Output:\n\n    ```json\n    --8<-- \"examples/patch.output\"\n    ```\n\n## Diff\n\nThe library can also calculate a JSON patch (i.e., a **diff**) given two JSON values.\n\n!!! success \"Invariant\"\n\n    For two JSON values *source* and *target*, the following code yields always true:\n\n    ```cüü\n    source.patch(diff(source, target)) == target;\n    ```\n\n??? example\n\n    The following code shows how a JSON patch is created as a diff for two JSON values.\n\n    ```cpp\n    --8<-- \"examples/diff.cpp\"\n    ```\n    \n    Output:\n\n    ```json\n    --8<-- \"examples/diff.output\"\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/json_pointer.md",
    "content": "# JSON Pointer\n\nThe library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values.\n\n```cpp\n// a JSON value\njson j_original = R\"({\n  \"baz\": [\"one\", \"two\", \"three\"],\n  \"foo\": \"bar\"\n})\"_json;\n\n// access members with a JSON pointer (RFC 6901)\nj_original[\"/baz/1\"_json_pointer];\n// \"two\"\n```\n\n## See also\n\n- Class [`json_pointer`](../api/json_pointer/index.md)\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/macros.md",
    "content": "# Supported Macros\n\nSome aspects of the library can be configured by defining preprocessor macros before including the `json.hpp` header.\n\n## `JSON_ASSERT(x)`\n\nThe default value is `#!cpp assert(x)`.\n\n## `JSON_CATCH_USER(exception)`\n\nThis macro overrides `#!cpp catch` calls inside the library. The argument is the type of the exception to catch. As of\nversion 3.8.0, the library only catches `std::out_of_range` exceptions internally to rethrow them as\n[`json::out_of_range`](../home/exceptions.md#out-of-range) exceptions. The macro is always followed by a scope.\n\nSee [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.\n\n## `JSON_DIAGNOSTICS`\n\nThis macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable\n(default).\n\nWhen enabled, exception messages contain a [JSON Pointer](json_pointer.md) to the JSON value that triggered the\nexception, see [Extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) for an example. Note\nthat enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.\n\nThe diagnostics messages can also be controlled with the CMake option `JSON_Diagnostics` (`OFF` by default) which sets\n`JSON_DIAGNOSTICS` accordingly.\n\n## `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`\n\nThe library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view`\nsupport for C++17). For these new features, the library implements some preprocessor checks to determine the C++\nstandard. By defining any of these symbols, the internal check is overridden and the provided C++ version is\nunconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be\ndetected incorrectly.\n\n## `JSON_HAS_FILESYSTEM`, `JSON_HAS_EXPERIMENTAL_FILESYSTEM`\n\nWhen compiling with C++17, the library provides conversions from and to `std::filesystem::path`. As compiler support\nfor filesystem is limited, the library tries to detect whether `<filesystem>`/`std::filesystem` (`JSON_HAS_FILESYSTEM`)\nor `<experimental/filesystem>`/`std::experimental::filesystem` (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used.\nTo override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`.\n\n## `JSON_NOEXCEPTION`\n\nExceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. When defining `JSON_NOEXCEPTION`, `#!cpp try`\nis replaced by `#!cpp if (true)`, `#!cpp catch` is replaced by `#!cpp if (false)`, and `#!cpp throw` is replaced by\n`#!cpp std::abort()`.\n\nThe same effect is achieved by setting the compiler flag `-fno-exceptions`.\n\nNote the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not\navailable for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824).\n\n## `JSON_NO_IO`\n\nWhen defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions\nrelying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for\nsecurity reasons (e.g., Intel Software Guard Extensions (SGX)).\n\n## `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`\n\nWhen defined, the library will not create a compile error when a known unsupported compiler is detected. This allows to\nuse the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.\n\n## `JSON_THROW_USER(exception)`\n\nThis macro overrides `#!cpp throw` calls inside the library. The argument is the exception to be thrown. Note that\n`JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield\nundefined behavior.\n\nSee [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.\n\n## `JSON_TRY_USER`\n\nThis macro overrides `#!cpp try` calls inside the library. It has no arguments and is always followed by a scope.\n\nSee [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.\n\n## `JSON_USE_IMPLICIT_CONVERSIONS`\n\nWhen defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on.\n\n??? example\n\n    This is an example for an implicit conversion:\n    \n    ```cpp\n    json j = \"Hello, world!\";\n    std::string s = j;\n    ```\n    \n    When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be\n    written like this:\n\n    ```cpp\n    json j = \"Hello, world!\";\n    auto s = j.get<std::string>();\n    ```\n\nImplicit conversions can also be controlled with the CMake option `JSON_ImplicitConversions` (`ON` by default) which\nsets `JSON_USE_IMPLICIT_CONVERSIONS` accordingly.\n\n## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)`\n\nThis macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as\nserialization and (2) want to use the member variable names as object keys in that object.\n\nThe macro is to be defined inside the class/struct to create code for. Unlike\n[`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](#nlohmann_define_type_non_intrusivetype-member), it can access private members.\nThe first parameter is the name of the class/struct, and all remaining parameters name the members.\n\nSee [Simplify your life with macros](arbitrary_types.md#simplify-your-life-with-macros) for an example.\n\n## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)`\n\nThis macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as\nserialization and (2) want to use the member variable names as object keys in that object.\n\nThe macro is to be defined inside the namespace of the class/struct to create code for. Private members cannot be\naccessed. Use [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](#nlohmann_define_type_intrusivetype-member) in these scenarios. The\nfirst parameter is the name of the class/struct, and all remaining parameters name the members.\n\nSee [Simplify your life with macros](arbitrary_types.md#simplify-your-life-with-macros) for an example.\n\n## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)`\n\nThis macro simplifies the serialization/deserialization of enum types. See\n[Specializing enum conversion](enum_conversion.md) for more information.\n\n## `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, `NLOHMANN_JSON_VERSION_PATCH`\n\nThese macros are defined by the library and contain the version numbers according to\n[Semantic Versioning 2.0.0](https://semver.org).\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/merge_patch.md",
    "content": "# JSON Merge Patch\n\nThe library supports JSON Merge Patch ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format.\nThe merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value.\n\nInstead of using [JSON Pointer](json_pointer.md) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified.\n\n??? example\n\n    The following code shows how a JSON Merge Patch is applied to a JSON document.\n\n    ```cpp\n    --8<-- \"examples/merge_patch.cpp\"\n    ```\n    \n    Output:\n\n    ```json\n    --8<-- \"examples/merge_patch.output\"\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/object_order.md",
    "content": "# Object Order\n\nThe [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as \"an unordered collection of zero or more name/value pairs\". As such, an implementation does not need to preserve any specific order of object keys.\n\nThe default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**.\n\n??? example\n\n    ```cpp\n    #include <iostream>\n    #include \"json.hpp\"\n    \n    using json = nlohmann::json;\n    \n    int main()\n    {\n        json j;\n        j[\"one\"] = 1;\n        j[\"two\"] = 2;\n        j[\"three\"] = 3;\n        \n        std::cout << j.dump(2) << '\\n';\n    }\n    ```\n    \n    Output:\n\n    ```json\n    {\n      \"one\": 1,\n      \"three\": 3,\n      \"two\": 2\n    }\n    ```\n\nIf you do want to preserve the **insertion order**, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179).\n\n??? example\n\n    ```cpp\n    #include <iostream>\n    #include <nlohmann/json.hpp>\n    \n    using ordered_json = nlohmann::ordered_json;\n    \n    int main()\n    {\n        ordered_json j;\n        j[\"one\"] = 1;\n        j[\"two\"] = 2;\n        j[\"three\"] = 3;\n        \n        std::cout << j.dump(2) << '\\n';\n    }\n    ```\n    \n    Output:\n    \n    ```json\n    {\n      \"one\": 1,\n      \"two\": 2,\n      \"three\": 3\n    }\n    ```\n\nAlternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/parsing/index.md",
    "content": "# Parsing\n\n!!! note\n\n    This page is under construction.\n\n## Input\n\n## SAX vs. DOM parsing\n\n## Exceptions\n\nSee [parsing and exceptions](parse_exceptions.md).\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/parsing/parse_exceptions.md",
    "content": "# Parsing and Exceptions\n\nWhen the input is not valid JSON, an exception of type [`parse_error`](../../home/exceptions.md#parse-errors) is thrown. This exception contains the position in the input where the error occurred, together with a diagnostic message and the last read input token. The exceptions page contains a [list of examples for parse error exceptions](../../home/exceptions.md#parse-errors). In case you process untrusted input, always enclose your code with a `#!cpp try`/`#!cpp catch` block, like\n\n```cpp\njson j;\ntry\n{\n    j = json::parse(my_input);\n}\ncatch (json::parse_error& ex)\n{\n    std::cerr << \"parse error at byte \" << ex.byte << std::endl;\n}\n```\n\nIn case exceptions are undesired or not supported by the environment, there are different ways to proceed:\n\n\n## Switch off exceptions\n\nThe `parse()` function accepts as last parameter a `#!cpp bool` variable `allow_exceptions` which controls whether an exception is thrown when a parse error occurs (`#!cpp true`, default) or whether a discarded value should be returned (`#!cpp false`).\n\n```cpp\njson j = json::parse(my_input, nullptr, false);\nif (j.is_discarded())\n{\n    std::cerr << \"parse error\" << std::endl;\n}\n```\n\nNote there is no diagnostic information available in this scenario.\n\n## Use accept() function\n\nAlternatively, function `accept()` can be used which does not return a `json` value, but a `#!cpp bool` indicating whether the input is valid JSON.\n\n```cpp\nif (!json::accept(my_input))\n{\n    std::cerr << \"parse error\" << std::endl;\n}\n```\n\nAgain, there is no diagnostic information available.\n\n\n## User-defined SAX interface\n\nFinally, you can implement the [SAX interface](sax_interface.md) and decide what should happen in case of a parse error.\n\nThis function has the following interface:\n\n```cpp\nbool parse_error(std::size_t position,\n                 const std::string& last_token,\n                 const json::exception& ex);\n```\n\nThe return value indicates whether the parsing should continue, so the function should usually return `#!cpp false`.\n\n??? example\n\n    ```cpp\n    #include <iostream>\n    #include \"json.hpp\"\n    \n    using json = nlohmann::json;\n    \n    class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>\n    {\n      public:\n        sax_no_exception(json& j)\n          : nlohmann::detail::json_sax_dom_parser<json>(j, false)\n        {}\n        \n        bool parse_error(std::size_t position,\n                         const std::string& last_token,\n                         const json::exception& ex)\n        {\n            std::cerr << \"parse error at input byte \" << position << \"\\n\"\n                      << ex.what() << \"\\n\"\n                      << \"last read: \\\"\" << last_token << \"\\\"\"\n                      << std::endl;\n            return false;\n        }\n    };\n    \n    int main()\n    {\n        std::string myinput = \"[1,2,3,]\";\n    \n        json result;\n        sax_no_exception sax(result);\n        \n        bool parse_result = json::sax_parse(myinput, &sax);\n        if (!parse_result)\n        {\n            std::cerr << \"parsing unsuccessful!\" << std::endl;\n        }\n        \n        std::cout << \"parsed value: \" << result << std::endl;\n    }\n    ```\n\n    Output:\n    \n    ```\n    parse error at input byte 8\n    [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n    last read: \"3,]\"\n    parsing unsuccessful!\n    parsed value: [1,2,3]\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/parsing/parser_callbacks.md",
    "content": "# Parser Callbacks\n\n## Overview\n\nWith a parser callback function, the result of parsing a JSON text can be influenced. When passed to `parse`, it is called on certain events\n(passed as `parse_event_t` via parameter `event`) with a set recursion depth `depth` and context JSON value `parsed`. The return value of the\ncallback function is a boolean indicating whether the element that emitted the callback shall be kept or not.\n\nThe type of the callback function is:\n\n```cpp\ntemplate<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;\n```\n\n\n## Callback event types\n\nWe distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values\nof the parameters `depth`, `event`, and `parsed`.\n\n| parameter `event`             | description                                               | parameter `depth`                         | parameter `parsed`               |\n|-------------------------------|-----------------------------------------------------------|-------------------------------------------|----------------------------------|\n| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object  | depth of the parent of the JSON object    | a JSON value with type discarded |\n| `parse_event_t::key`          | the parser read a key of a value in an object             | depth of the currently parsed JSON object | a JSON string containing the key |\n| `parse_event_t::object_end`   | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object    | the parsed JSON object           |\n| `parse_event_t::array_start`  | the parser read `[` and started to process a JSON array   | depth of the parent of the JSON array     | a JSON value with type discarded |\n| `parse_event_t::array_end`    | the parser read `]` and finished processing a JSON array  | depth of the parent of the JSON array     | the parsed JSON array            |\n| `parse_event_t::value`        | the parser finished reading a JSON value                  | depth of the value                        | the parsed JSON value            |\n\n??? example\n\n    When parsing the following JSON text,\n    \n    ```json\n    {\n        \"name\": \"Berlin\",\n        \"location\": [\n            52.519444,\n            13.406667\n        ]\n    }\n    ```\n    \n    these calls are made to the callback function:\n    \n    | event          | depth | parsed |\n    | -------------- | ----- | ------ |\n    | `object_start` | 0     | *discarded* |\n    | `key`          | 1     | `#!json \"name\"` |\n    | `value`        | 1     | `#!json \"Berlin\"` |\n    | `key`          | 1     | `#!json \"location\"` |\n    | `array_start`  | 1     | *discarded* |\n    | `value`        | 2     | `#!json 52.519444` |\n    | `value`        | 2     | `#!json 13.406667` |\n    | `array_end`    | 1     | `#!json [52.519444,13.406667]` |\n    | `object_end`   | 0     | `#!json {\"location\":[52.519444,13.406667],\"name\":\"Berlin\"}` |\n\n## Return value\n\nDiscarding a value (i.e., returning `#!c false`) has different effects depending on the context in which function was called:\n\n- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read.\n- In case a value outside a structured type is skipped, it is replaced with `#!json null`. This case happens if the top-level element is skipped.\n\n??? example\n\n    The example below demonstrates the `parse()` function with and without callback function.\n\n    ```cpp\n    --8<-- \"examples/parse__string__parser_callback_t.cpp\"\n    ```\n    \n    Output:\n\n    ```json\n    --8<-- \"examples/parse__string__parser_callback_t.output\"\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/parsing/sax_interface.md",
    "content": "# SAX Interface\n\nThe library uses a SAX-like interface with the following functions:\n\n```plantuml\ninterface json::sax_t {\n    + {abstract} bool null()\n\n    + {abstract} bool boolean(bool val)\n\n    + {abstract} bool number_integer(number_integer_t val)\n    + {abstract} bool number_unsigned(number_unsigned_t val)\n\n    + {abstract} bool number_float(number_float_t val, const string_t& s)\n\n    + {abstract} bool string(string_t& val)\n    + {abstract} bool binary(binary_t& val)\n\n    + {abstract} bool start_object(std::size_t elements)\n    + {abstract} bool end_object()\n    + {abstract} bool start_array(std::size_t elements)\n    + {abstract} bool end_array()\n    + {abstract} bool key(string_t& val)\n\n    + {abstract} bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex)\n}\n```\n\n```cpp\n// called when null is parsed\nbool null();\n\n// called when a boolean is parsed; value is passed\nbool boolean(bool val);\n\n// called when a signed or unsigned integer number is parsed; value is passed\nbool number_integer(number_integer_t val);\nbool number_unsigned(number_unsigned_t val);\n\n// called when a floating-point number is parsed; value and original string is passed\nbool number_float(number_float_t val, const string_t& s);\n\n// called when a string is parsed; value is passed and can be safely moved away\nbool string(string_t& val);\n// called when a binary value is parsed; value is passed and can be safely moved away\nbool binary(binary& val);\n\n// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)\nbool start_object(std::size_t elements);\nbool end_object();\nbool start_array(std::size_t elements);\nbool end_array();\n// called when an object key is parsed; value is passed and can be safely moved away\nbool key(string_t& val);\n\n// called when a parse error occurs; byte position, the last token, and an exception is passed\nbool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex);\n```\n\nThe return value of each function determines whether parsing should proceed.\n\nTo implement your own SAX handler, proceed as follows:\n\n1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax<json>` as base class, but you can also use any class where the functions described above are implemented and public.\n2. Create an object of your SAX interface class, e.g. `my_sax`.\n3. Call `#!cpp bool json::sax_parse(input, &my_sax);` where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.\n\nNote the `sax_parse` function only returns a `#!cpp bool` indicating the result of the last executed SAX event. It does not return `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file `json_sax.hpp`.\n\n## See also\n\n- [json_sax](../../api/json_sax/index.md) - documentation of the SAX interface\n- [sax_parse](../../api/basic_json/sax_parse.md) - SAX parser\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/types/index.md",
    "content": "# Types\n\nThis page gives an overview how JSON values are stored and how this can be configured.\n\n## Overview\n\nBy default, JSON values are stored as follows:\n\n| JSON type | C++ type                                      |\n|-----------|-----------------------------------------------|\n| object    | `std::map<std::string, basic_json>`           |\n| array     | `std::vector<basic_json>`                     |\n| null      | `std::nullptr_t`                              |\n| string    | `std::string`                                 |\n| boolean   | `bool`                                        |\n| number    | `std::int64_t`, `std::uint64_t`, and `double` |\n\nNote there are three different types for numbers - when parsing JSON text, the best fitting type is chosen.\n\n## Storage\n\n```plantuml\nenum value_t {\n    null\n    object\n    array\n    string\n    boolean\n    number_integer\n    number_unsigned\n    number_float\n    binary\n    discarded\n}\n\nclass json_value << (U,orchid) >> {\n    object_t* object\n    array_t* array\n    string_t* string\n    binary_t* binary\n    boolean_t boolean\n    number_integer_t number_integer\n    number_unsigned_t number_unsigned\n    number_float_t number_float\n}\n\nclass basic_json {\n    -- type and value --\n    value_t m_type\n    json_value m_value\n    -- derived types --\n    + <u>typedef</u> object_t\n    + <u>typedef</u> array_t\n    + <u>typedef</u> binary_t\n    + <u>typedef</u> boolean_t\n    + <u>typedef</u> number_integer_t\n    + <u>typedef</u> number_unsigned_t\n    + <u>typedef</u> number_float_t\n}\n\nbasic_json .. json_value\nbasic_json .. value_t\n```\n\n## Template arguments\n\nThe data types to store a JSON value are derived from the template arguments passed to class `basic_json`:\n\n```cpp\ntemplate<\n    template<typename U, typename V, typename... Args> class ObjectType = std::map,\n    template<typename U, typename... Args> class ArrayType = std::vector,\n    class StringType = std::string,\n    class BooleanType = bool,\n    class NumberIntegerType = std::int64_t,\n    class NumberUnsignedType = std::uint64_t,\n    class NumberFloatType = double,\n    template<typename U> class AllocatorType = std::allocator,\n    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,\n    class BinaryType = std::vector<std::uint8_t>\n>\nclass basic_json;\n```\n\nType `json` is an alias for `basic_json<>` and uses the default types.\n\nFrom the template arguments, the following types are derived:\n\n```cpp\nusing object_comparator_t = std::less<>;\nusing object_t = ObjectType<StringType, basic_json, object_comparator_t,\n                   AllocatorType<std::pair<const StringType, basic_json>>>;\n\nusing array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n\nusing string_t = StringType;\n\nusing boolean_t = BooleanType;\n\nusing number_integer_t = NumberIntegerType;\nusing number_unsigned_t = NumberUnsignedType;\nusing number_float_t = NumberFloatType;\n\nusing binary_t = nlohmann::byte_container_with_subtype<BinaryType>;\n```\n\n\n## Objects\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:\n\n> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.\n\n### Default type\n\nWith the default values for *ObjectType* (`std::map`), *StringType* (`std::string`), and *AllocatorType* (`std::allocator`), the default value for `object_t` is:\n\n```cpp\nstd::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n```\n\n### Behavior\n\nThe choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following behavior:\n\n- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings.\n- When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, `#!json {\"key\": 2, \"key\": 1}` could be equal to either `#!json {\"key\": 1}` or `#!json {\"key\": 2}`.\n- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see `dump`) in this order. For instance, both `#!json {\"b\": 1, \"a\": 2}` and `#!json {\"a\": 2, \"b\": 1}` will be stored and serialized as `#!json {\"a\": 2, \"b\": 1}`.\n- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, `#!json {\"b\": 1, \"a\": 2}` and `#!json {\"a\": 2, \"b\": 1}` will be treated as equal.\n\n### Key order\n\nThe order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified \"unordered\" nature of JSON objects.\n\n### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:\n\n> An implementation may set limits on the maximum depth of nesting.\n\nIn this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON object.\n\n### Storage\n\nObjects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type `object_t*` must be dereferenced.\n\n\n## Arrays\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:\n\n> An array is an ordered sequence of zero or more values.\n\n### Default type\n\nWith the default values for *ArrayType* (`std::vector`) and *AllocatorType* (`std::allocator`), the default value for `array_t` is:\n\n```cpp\nstd::vector<\n  basic_json, // value_type\n  std::allocator<basic_json> // allocator_type\n>\n```\n\n### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:\n\n> An implementation may set limits on the maximum depth of nesting.\n\nIn this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON array.\n\n### Storage\n\nArrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type `array_t*` must be dereferenced.\n\n\n## Strings\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:\n\n> A string is a sequence of zero or more Unicode characters.\n\nUnicode values are split by the JSON class into byte-sized characters during deserialization.\n\n### Default type\n\nWith the default values for *StringType* (`std::string`), the default value for `string_t` is `#!cpp std::string`.\n\n### Encoding\n\nStrings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return the number of **bytes** in the string rather than the number of characters or glyphs.\n\n### String comparison\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) states:\n\n> Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `\"a\\\\b\"` and `\"a\\u005Cb\"` are not equal.\n\nThis implementation is interoperable as it does compare strings code unit by code unit.\n\n### Storage\n\nString values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type `string_t*` must be dereferenced.\n\n\n## Booleans\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`.\n\n### Default type\n\nWith the default values for *BooleanType* (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`.\n\n### Storage\n\nBoolean values are stored directly inside a `basic_json` type.\n\n## Numbers\n\nSee the [number handling](number_handling.md) article for a detailed discussion on how numbers are handled by this library.\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:\n\n> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.\n\nThis description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, three different types, `number_integer_t`, `number_unsigned_t`, and `number_float_t` are used.\n\n### Default types\n\nWith the default values for *NumberIntegerType* (`std::int64_t`), the default value for `number_integer_t` is `std::int64_t`.\nWith the default values for *NumberUnsignedType* (`std::uint64_t`), the default value for `number_unsigned_t` is `std::uint64_t`.\nWith the default values for *NumberFloatType* (`#!cpp double`), the default value for `number_float_t` is `#!cpp double`.\n\n### Default behavior\n\n- The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as decimal number. For instance, the C++ integer literal `#!c 010` will be serialized to `#!c 8`. During deserialization, leading zeros yield an error.\n- Not-a-number (NaN) values will be serialized to `#!json null`.\n\n### Limits\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:\n\n> An implementation may set limits on the range and precision of numbers.\n\nWhen the default type is used, the maximal integer number that can be stored is `#!c 9223372036854775807` (`INT64_MAX`) and the minimal integer number that can be stored is `#!c -9223372036854775808` (`INT64_MIN`). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_unsigned_t` or `number_float_t`.\n\nWhen the default type is used, the maximal unsigned integer number that can be stored is `#!c 18446744073709551615` (`UINT64_MAX`) and the minimal integer number that can be stored is `#!c 0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will be automatically be stored as `number_integer_t` or `number_float_t`.\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:\n\n> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the sense that implementations will agree exactly on their numeric values.\n\nAs this range is a subrange of the exactly supported range [`INT64_MIN`, `INT64_MAX`], this class's integer type is interoperable.\n\n[RFC 8259](https://tools.ietf.org/html/rfc8259) states:\n\n> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.\n\nThis implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than `#!c -1.79769313486232e+308` and values greater than `#!c 1.79769313486232e+308` will be stored as NaN internally and be serialized to `#!json null`.\n\n### Storage\n\nInteger number values, unsigned integer number values, and floating-point number values are stored directly inside a `basic_json` type.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/features/types/number_handling.md",
    "content": "# Number Handling\n\nThis document describes how the library is handling numbers.\n\n## Background\n\nThis section briefly summarizes how the JSON specification describes how numbers should be handled.\n\n### JSON number syntax\n\nJSON defines the syntax of numbers as follows:\n\n!!! quote \"[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6\"\n\n    The representation of numbers is similar to that used in most\n    programming languages.  A number is represented in base 10 using\n    decimal digits.  It contains an integer component that may be\n    prefixed with an optional minus sign, which may be followed by a\n    fraction part and/or an exponent part.  Leading zeros are not\n    allowed.\n\n    A fraction part is a decimal point followed by one or more digits.\n    \n    An exponent part begins with the letter E in uppercase or lowercase,\n    which may be followed by a plus or minus sign.  The E and optional\n    sign are followed by one or more digits.\n\nThe following railroad diagram from [json.org](https://json.org) visualizes the number syntax:\n\n![Syntax for JSON numbers](../../images/json_syntax_number.png)\n\n### Number interoperability\n\nOn number interoperability, the following remarks are made:\n\n!!! quote \"[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6\"\n\n    This specification allows implementations to set limits on the range\n    and precision of numbers accepted.  Since software that implements\n    IEEE 754 binary64 (double precision) numbers [IEEE754] is generally\n    available and widely used, good interoperability can be achieved by\n    implementations that expect no more precision or range than these\n    provide, in the sense that implementations will approximate JSON\n    numbers within the expected precision.  A JSON number such as 1E400\n    or 3.141592653589793238462643383279 may indicate potential\n    interoperability problems, since it suggests that the software that\n    created it expects receiving software to have greater capabilities\n    for numeric magnitude and precision than is widely available.\n    \n    Note that when such software is used, numbers that are integers and\n    are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the\n    sense that implementations will agree exactly on their numeric\n    values.\n\n## Library implementation\n\nThis section describes how the above number specification is implemented by this library.\n\n### Number storage\n\nIn the default [`json`](../../api/json.md) type, numbers are stored as `#!c std::uint64_t`, `#!c std::int64_t`, and\n`#!c double`,  respectively. Thereby, `#!c std::uint64_t` and `#!c std::int64_t` are used only if they can store the \nnumber without loss of  precision. If this is impossible (e.g., if the number is too large), the number is stored as\n`#!c double`.\n\n!!! info \"Notes\"\n\n    - Numbers with a decimal digit or scientific notation are always stored as `#!c double`.\n    - The number types can be changed, see [Template number types](#template-number-types). \n    - As of version 3.9.1, the conversion is realized by\n      [`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul),\n      [`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and\n      [`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof), respectively.\n\n!!! example \"Examples\"\n\n    - Integer `#!c -12345678912345789123456789` is smaller than `#!c INT64_MIN` and will be stored as floating-point\n      number `#!c -1.2345678912345788e+25`.\n    - Integer `#!c 1E3` will be stored as floating-point number `#!c 1000.0`.\n\n### Number limits\n\n- Any 64-bit signed or unsigned integer can be stored without loss of precision.\n- Numbers exceeding the limits of `#!c double` (i.e., numbers that after conversion via\n[`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof) are not satisfying\n[`std::isfinite`](https://en.cppreference.com/w/cpp/numeric/math/isfinite) such as `#!c 1E400`) will throw exception\n[`json.exception.out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406) during parsing.\n- Floating-point numbers are rounded to the next number representable as `double`. For instance\n`#!c 3.141592653589793238462643383279` is stored as [`0x400921fb54442d18`](https://float.exposed/0x400921fb54442d18).\nThis is the same behavior as the code `#!c double x = 3.141592653589793238462643383279;`.\n\n!!! success \"Interoperability\"\n\n    - The library interoperable with respect to the specification, because its supported range $[-2^{63}, 2^{64}-1]$ is\n      larger than the described range $[-2^{53}+1, 2^{53}-1]$.\n    - All integers outside the range $[-2^{63}, 2^{64}-1]$, as well as floating-point numbers are stored as `double`.\n      This also concurs with the specification above.\n\n### Zeros\n\nThe JSON number grammar allows for different ways to express zero, and this library will store zeros differently:\n\n| Literal | Stored value and type  | Serialization |\n|---------|------------------------|---------------|\n| `0`     | `#!c std::uint64_t(0)` | `0`           |\n| `-0`    | `#!c std::int64_t(0)`  | `0`           |\n| `0.0`   | `#!c double(0.0)`      | `0.0`         |\n| `-0.0`  | `#!c double(-0.0)`     | `-0.0`        |\n| `0E0`   | `#!c double(0.0)`      | `0.0`         |\n| `-0E0`  | `#!c double(-0.0)`     | `-0.0`        |\n\nThat is, `-0` is stored as a signed integer, but the serialization does not reproduce the `-`.\n\n### Number serialization\n\n- Integer numbers are serialized as is; that is, no scientific notation is used.\n- Floating-point numbers are serialized as specified by the `#!c %g` printf modifier with \n  [`std::numeric_limits<double>::max_digits10`](https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10)\n  significant digits. The rationale is to use the shortest representation while still allow round-tripping.\n\n!!! hint \"Notes regarding precision of floating-point numbers\"\n\n    As described above, floating-point numbers are rounded to the nearest double and serialized with the shortest\n    representation to allow round-tripping. This can yield confusing examples:\n\n    - The serialization can have fewer decimal places than the input: `#!c 2555.5599999999999` will be serialized as\n      `#!c 2555.56`. The reverse can also be true.\n    - The serialization can be in scientific notation even if the input is not: `#!c 0.0000972439793401814` will be \n      serialized as `#!c 9.72439793401814e-05`. The reverse can also be true: `#!c 12345E-5` will be serialized as\n      `#!c 0.12345`.\n    - Conversions from `#!c float` to `#!c double` can also introduce rounding errors:\n        ```cpp\n        float f = 0.3;\n        json j = f;\n        std::cout << j << '\\n';\n        ```\n        yields `#!c 0.30000001192092896`.\n\n    All examples here can be reproduced by passing the original double value to\n\n    ```cpp\n    std::printf(\"%.*g\\n\", std::numeric_limits<double>::max_digits10, double_value);\n    ```\n\n#### NaN handling\n\nNaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded:\n\n!!! quote \"[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6\"\n\n    Numeric values that cannot be represented in the grammar below (such\n    as Infinity and NaN) are not permitted.\n\nThat is, there is no way to *parse* a NaN value. However, NaN values can be stored in a JSON value by assignment.\n\nThis library serializes NaN values  as `#!js null`. This corresponds to the behavior of JavaScript's\n[`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) function.\n\n!!! example\n\n    The following example shows how a NaN value is stored in a `json` value.\n\n    ```cpp\n    int main()\n    {\n        double val = std::numeric_limits<double>::quiet_NaN();\n        std::cout << \"val=\" << val << std::endl;\n        json j = val;\n        std::cout << \"j=\" << j.dump() << std::endl;\n        val = j;\n        std::cout << \"val=\" << val << std::endl;\n    }\n    ```\n    \n    output:\n    \n    ```\n    val=nan\n    j=null\n    val=nan\n    ```\n\n### Number comparison\n\nFloating-point inside JSON values numbers are compared with `#!c json::number_float_t::operator==` which is\n`#!c double::operator==` by default.\n\n!!! example \"Alternative comparison functions\"\n\n    To compare floating-point while respecting an epsilon, an alternative\n    [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)\n    could be used, for instance\n    \n    ```cpp\n    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>\n    inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept\n    {\n        return std::abs(a - b) <= epsilon;\n    }\n    ```\n    Or you can self-define an operator equal function like this:\n    \n    ```cpp\n    bool my_equal(const_reference lhs, const_reference rhs)\n    {\n        const auto lhs_type lhs.type();\n        const auto rhs_type rhs.type();\n        if (lhs_type == rhs_type)\n        {\n            switch(lhs_type)\n            {\n                // self_defined case\n                case value_t::number_float:\n                    return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();\n        \n                // other cases remain the same with the original\n                ...\n            }\n        }\n        ...\n    }\n    ```\n    \n    (see [#703](https://github.com/nlohmann/json/issues/703) for more information.)\n    \n!!! note\n\n    NaN values never compare equal to themselves or to other NaN values. See [#514](https://github.com/nlohmann/json/issues/514).\n\n### Number conversion\n\nJust like the C++ language itself, the `get` family of functions allows conversions between unsigned and signed\nintegers, and  between integers and floating-point values to integers. This behavior may be surprising.\n\n!!! warning \"Unconditional number conversions\"\n\n    ```cpp hl_lines=\"3\"\n    double d = 42.3;                          // non-integer double value 42.3\n    json jd = d;                              // stores double value 42.3\n    std::int64_t i = jd.get<std::int64_t>();  // now i==42; no warning or error is produced\n    ```\n\n    Note the last line with throw a [`json.exception.type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302)\n    exception if `jd` is not a numerical type, for instance a string.\n\nThe rationale is twofold:\n\n1. JSON does not define a number type or precision (see [#json-specification](above)).\n2. C++ also allows to silently convert between number types.\n\n!!! success \"Conditional number conversion\"\n\n    The code above can be solved by explicitly checking the nature of the value with members such as\n    [`is_number_integer()`](../../api/basic_json/is_number_integer.md) or\n    [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md):\n\n    ```cpp hl_lines=\"2\"\n    // check if jd is really integer-valued\n    if (jd.is_number_integer())\n    {\n        // if so, do the conversion and use i\n        std::int64_t i = jd.get<std::int64_t>();\n        // ...\n    }\n    else\n    {\n        // otherwise, take appropriate action\n        // ...\n    }\n    ```\n\n    Note this approach also has the advantage that it can react on non-numerical JSON value types such as strings.\n\n    (Example taken from [#777](https://github.com/nlohmann/json/issues/777#issuecomment-459968458).)\n\n### Determine number types\n\nAs the example in [Number conversion](#number_conversion) shows, there are different functions to determine the type of\nthe stored number:\n\n- [`is_number()`](../../api/basic_json/is_number.md) returns `#!c true` for any number type\n- [`is_number_integer()`](../../api/basic_json/is_number_integer.md) returns `#!c true` for signed and unsigned integers\n- [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md) returns `#!c true` for unsigned integers only\n- [`is_number_float()`](../../api/basic_json/is_number_float.md) returns `#!c true` for floating-point numbers\n- [`type_name()`](../../api/basic_json/type_name.md) returns `#!c \"number\"` for any number type\n- [`type()`](../../api/basic_json/type.md) returns a different enumerator of\n  [`value_t`](../../api/basic_json/value_t.md) for all number types\n\n| function                                                             | unsigned integer  | signed integer   | floating-point | string         |\n|----------------------------------------------------------------------|-------------------|------------------|----------------|----------------|\n| [`is_number()`](../../api/basic_json/is_number.md)                   | `#!c true`        | `#!c true`       | `#!c true`     | `#!c false`    |\n| [`is_number_integer()`](../../api/basic_json/is_number_integer.md)   | `#!c true`        | `#!c true`       | `#!c false`    | `#!c false`    |\n| [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md) | `#!c true`        | `#!c false`      | `#!c false`    | `#!c false`    |\n| [`is_number_float()`](../../api/basic_json/is_number_float.md)       | `#!c false`       | `#!c false`      | `#!c true`     | `#!c false`    |\n| [`type_name()`](../../api/basic_json/type_name.md)                   | `#!c \"number\"`    | `#!c \"number\"`   | `#!c \"number\"` | `#!c \"string\"` |\n| [`type()`](../../api/basic_json/type.md)                             | `number_unsigned` | `number_integer` | `number_float` | `string`       |\n\n### Template number types\n\nThe number types can be changed with template parameters.\n\n| position | number type       | default type        | possible values                                |\n|----------|-------------------|---------------------|------------------------------------------------|\n| 5        | signed integers   | `#!c std::int64_t`  | `#!c std::int32_t`, `#!c std::int16_t`, etc.   |\n| 6        | unsigned integers | `#!c std::uint64_t` | `#!c std::uint32_t`, `#!c std::uint16_t`, etc. |\n| 7        | floating-point    | `#!c double`        | `#!c float`, `#!c long double`                 |\n\n!!! info \"Constraints on number types\"\n\n    - The type for signed integers must be convertible from `#!c long long`. The type for floating-point numbers is used\n      in case of overflow.\n    - The type for unsigned integers must be convertible from `#!c unsigned long long`.  The type for floating-point\n      numbers is used in case of overflow.\n    - The types for signed and unsigned integers must be distinct, see\n      [#2573](https://github.com/nlohmann/json/issues/2573).\n    - Only `#!c double`, `#!c float`, and `#!c long double` are supported for floating-point numbers.\n\n!!! example\n\n    A `basic_json` type that uses `#!c long double` as floating-point type.\n\n    ```cpp hl_lines=\"2\"\n    using json_ld = nlohmann::basic_json<std::map, std::vector, std::string, bool,\n                                         std::int64_t, std::uint64_t, long double>;\n    ```\n\n    Note values should then be parsed with `json_ld::parse` rather than `json::parse` as the latter would parse\n    floating-point values to `#!c double` before then converting them to `#!c long double`.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/home/code_of_conduct.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/home/design_goals.md",
    "content": "# Design goals\n\nThere are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals:\n\n- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples), and you'll know what I mean.\n\n- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.\n\n- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).\n\nOther aspects were not so important to us:\n\n- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs.\n\n- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set.\n\nSee the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/home/exceptions.md",
    "content": "# Exceptions\n\n## Overview\n\n### Base type\n\nAll exceptions inherit from class `json::exception` (which in turn inherits from `std::exception`). It is used as the base class for all exceptions thrown by the `basic_json` class. This class can hence be used as \"wildcard\" to catch exceptions.\n\n```plantuml\nstd::exception <|-- json::exception\njson::exception <|-- json::parse_error\njson::exception <|-- json::invalid_iterator\njson::exception <|-- json::type_error\njson::exception <|-- json::out_of_range\njson::exception <|-- json::other_error\n\ninterface std::exception {}\n\nclass json::exception {\n    + const int id\n    + const char* what() const\n}\n\nclass json::parse_error {\n    + const std::size_t byte\n}\n```\n\n### Switch off exceptions\n\nExceptions are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `#!cpp throw`), `JSON_TRY_USER` (overriding `#!cpp try`), and `JSON_CATCH_USER` (overriding `#!cpp catch`).\n\nNote that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.\n\n??? example\n\n    The code below switches off exceptions and creates a log entry with a detailed error message in case of errors.\n\n    ```cpp\n    #include <iostream>\n    \n    #define JSON_TRY_USER if(true)\n    #define JSON_CATCH_USER(exception) if(false)\n    #define JSON_THROW_USER(exception)                           \\\n        {std::clog << \"Error in \" << __FILE__ << \":\" << __LINE__ \\\n                   << \" (function \" << __FUNCTION__ << \") - \"    \\\n                   << (exception).what() << std::endl;           \\\n         std::abort();}\n    \n    #include <nlohmann/json.hpp>\n    ```\n\nNote the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824).\n\n### Extended diagnostic messages\n\nExceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult.\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/diagnostics_standard.cpp\"\n    ```\n    \n    Output:\n\n    ```\n    --8<-- \"examples/diagnostics_standard.output\"\n    ```\n\n    This exception can be hard to debug if storing the value `#!c \"12\"` and accessing it is further apart.\n\nTo create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that lead to the exception) can be created. That global context is provided as [JSON Pointer](../features/json_pointer.md).\n\nAs this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol [`JSON_DIAGNOSTICS`](../features/macros.md#json_diagnostics) to `1` before including `json.hpp`.\n\n??? example\n\n    ```cpp\n    --8<-- \"examples/diagnostics_extended.cpp\"\n    ```\n    \n    Output:\n\n    ```\n    --8<-- \"examples/diagnostics_extended.output\"\n    ```\n\n    Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type.\n\n\n## Parse errors\n\nThis exception is thrown by the library when a parse error occurs. Parse errors\ncan occur during the deserialization of JSON text, CBOR, MessagePack, as well\nas when using JSON Patch.\n\nExceptions have ids 1xx.\n\n!!! info \"Byte index\"\n\n    Member `byte` holds the byte index of the last read character in the input\n    file.\n\n    For an input with n bytes, 1 is the index of the first character and n+1\n    is the index of the terminating null byte or the end of file. This also\n    holds true when reading a byte vector (CBOR or MessagePack).\n\n??? example\n\n    The following code shows how a `parse_error` exception can be caught.\n\n    ```cpp\n    --8<-- \"examples/parse_error.cpp\"\n    ```\n    \n    Output:\n\n    ```\n    --8<-- \"examples/parse_error.output\"\n    ```\n\n\n### json.exception.parse_error.101\n\nThis error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member `byte` indicates the error position.\n\n!!! failure \"Example message\"\n\n    Input ended prematurely:\n\n    ```\n    [json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal\n    ```\n\n    No input:\n\n    ```\n    [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\n    ```\n\n    Control character was not escaped:\n\n    ```\n    [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\\\; last read: '\"<U+0009>'\"\n    ```\n\n    String was not closed:\n\n    ```\n    [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'\n    ```\n\n    Invalid number format:\n\n    ```\n    [json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'\n    ```\n\n    `\\u` was not be followed by four hex digits:\n\n    ```\n    [json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'\n    ```\n\n    Invalid UTF-8 surrogate pair:\n\n    ```\n    [json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\"\\uD7FF\\uDC00'\"\n    ```\n\n    Invalid UTF-8 byte:\n\n    ```\n    [json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"vous \\352t'\n    ```\n\n!!! tip\n\n    - Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened.\n    - Paste the input to a JSON validator like <http://jsonlint.com> or a tool like [jq](https://stedolan.github.io/jq/).\n\n### json.exception.parse_error.102\n\nJSON uses the `\\uxxxx` format to describe Unicode characters. Code points above 0xFFFF are split into two `\\uxxxx` entries (\"surrogate pairs\"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.\n\n!!! failure \"Example message\"\n\n    ```\n    parse error at 14: missing or wrong low surrogate\n    ```\n\n!!! note\n\n    This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used.\n\n### json.exception.parse_error.103\n\nUnicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.\n\n!!! failure \"Example message\"\n\n    ```\n    parse error: code points above 0x10FFFF are invalid\n    ```\n\n!!! note\n\n    This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used.\n\n### json.exception.parse_error.104\n\n[RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.104] parse error: JSON patch must be an array of objects\n    ```\n\n### json.exception.parse_error.105\n\nAn operation of a JSON Patch document must contain exactly one \"op\" member, whose value indicates the operation to perform. Its value must be one of \"add\", \"remove\", \"replace\", \"move\", \"copy\", or \"test\"; other values are errors.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.105] parse error: operation 'add' must have member 'value'\n    ```\n    ```\n    [json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'\n    ```\n    ```\n    [json.exception.parse_error.105] parse error: operation value 'foo' is invalid\n    ```\n\n### json.exception.parse_error.106\n\nAn array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\n    ```\n\n### json.exception.parse_error.107\n\nA JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'\n    ```\n\n### json.exception.parse_error.108\n\nIn a JSON Pointer, only `~0` and `~1` are valid escape sequences.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n    ```\n\n### json.exception.parse_error.109\n\nA JSON Pointer array index must be a number.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.109] parse error: array index 'one' is not a number\n    ```\n    ```\n    [json.exception.parse_error.109] parse error: array index '+1' is not a number\n    ```\n\n### json.exception.parse_error.110\n\nWhen parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input\n    ```\n    ```\n    [json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A\n    ```\n\n### json.exception.parse_error.112\n\nNot all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C\n    ```\n\n### json.exception.parse_error.113\n\nWhile parsing a map key, a value that is not a string has been read.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF\n    ```\n    ```\n    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF\n    ```\n    ```\n    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82\n    ```\n\n### json.exception.parse_error.114\n\nThe parsing of the corresponding BSON record type is not implemented (yet).\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF\n    ```\n\n### json.exception.parse_error.115\n\nA UBJSON high-precision number could not be parsed.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A\n    ```\n\n## Iterator errors\n\nThis exception is thrown if iterators passed to a library function do not match\nthe expected semantics.\n\nExceptions have ids 2xx.\n\n??? example\n\n    The following code shows how an `invalid_iterator` exception can be caught.\n\n    ```cpp\n    --8<-- \"examples/invalid_iterator.cpp\"\n    ```\n    \n    Output:\n\n    ```\n    --8<-- \"examples/invalid_iterator.output\"\n    ```\n\n### json.exception.invalid_iterator.201\n\nThe iterators passed to constructor `basic_json(InputIT first, InputIT last)` are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.201] iterators are not compatible\n    ```\n\n### json.exception.invalid_iterator.202\n\nIn the [erase](../api/basic_json/erase.md) or insert function, the passed iterator `pos` does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.202] iterator does not fit current value\n    ```\n    ```\n    [json.exception.invalid_iterator.202] iterators first and last must point to objects\n    ```\n\n### json.exception.invalid_iterator.203\n\nEither iterator passed to function [`erase(IteratorType first, IteratorType last`)](../api/basic_json/erase.md) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.203] iterators do not fit current value\n    ```\n\n### json.exception.invalid_iterator.204\n\nWhen an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an [erase](../api/basic_json/erase.md) function, this range has to be exactly (`begin(),` `end()),` because this is the only way the single stored value is expressed. All other ranges are invalid.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.204] iterators out of range\n    ```\n\n### json.exception.invalid_iterator.205\n\nWhen an iterator for a primitive type (number, boolean, or string) is passed to an [erase](../api/basic_json/erase.md) function, the iterator has to be the `begin()` iterator, because it is the only way to address the stored value. All other iterators are invalid.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.205] iterator out of range\n    ```\n\n### json.exception.invalid_iterator.206\n\nThe iterators passed to constructor `basic_json(InputIT first, InputIT last)` belong to a JSON null value and hence to not define a valid range.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.206] cannot construct with iterators from null\n    ```\n\n### json.exception.invalid_iterator.207\n\nThe `key()` member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.207] cannot use key() for non-object iterators\n    ```\n\n\n### json.exception.invalid_iterator.208\n\nThe `operator[]` to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.208] cannot use operator[] for object iterators\n    ```\n\n### json.exception.invalid_iterator.209\n\nThe offset operators (`+`, `-`, `+=`, `-=`) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.209] cannot use offsets with object iterators\n    ```\n\n### json.exception.invalid_iterator.210\n\nThe iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.210] iterators do not fit\n    ```\n\n### json.exception.invalid_iterator.211\n\nThe iterator range passed to the insert function must not be a subrange of the container to insert to.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.211] passed iterators may not belong to container\n    ```\n\n### json.exception.invalid_iterator.212\n\nWhen two iterators are compared, they must belong to the same container.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.212] cannot compare iterators of different containers\n    ```\n\n### json.exception.invalid_iterator.213\n\nThe order of object iterators cannot be compared, because JSON objects are unordered.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.213] cannot compare order of object iterators\n    ```\n\n### json.exception.invalid_iterator.214\n\nCannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to `begin()`.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.invalid_iterator.214] cannot get value\n    ```\n\n## Type errors\n\nThis exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics.\n\nExceptions have ids 3xx.\n\n??? example\n\n    The following code shows how a `type_error` exception can be caught.\n\n    ```cpp\n    --8<-- \"examples/type_error.cpp\"\n    ```\n    \n    Output:\n\n    ```\n    --8<-- \"examples/type_error.output\"\n    ```\n\n### json.exception.type_error.301\n\nTo create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.301] cannot create object from initializer list\n    ```\n\n### json.exception.type_error.302\n\nDuring implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.302] type must be object, but is null\n    ```\n    ```\n    [json.exception.type_error.302] type must be string, but is object\n    ```\n\n### json.exception.type_error.303\n\nTo retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\n    ```\n    ```\n    [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\"\n    ```\n\n### json.exception.type_error.304\n\nThe `at()` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.304] cannot use at() with string\n    ```\n    ```\n    [json.exception.type_error.304] cannot use at() with number\n    ```\n\n### json.exception.type_error.305\n\nThe `operator[]` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.305] cannot use operator[] with a string argument with array\n    ```\n    ```\n    [json.exception.type_error.305] cannot use operator[] with a numeric argument with object\n    ```\n\n### json.exception.type_error.306\n\nThe `value()` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.306] cannot use value() with number\n    ```\n\n### json.exception.type_error.307\n\nThe [`erase()`](../api/basic_json/erase.md) member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.307] cannot use erase() with string\n    ```\n\n### json.exception.type_error.308\n\nThe `push_back()` and `operator+=` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.308] cannot use push_back() with string\n    ```\n\n### json.exception.type_error.309\n\nThe `insert()` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.309] cannot use insert() with array\n    ```\n    ```\n    [json.exception.type_error.309] cannot use insert() with number\n    ```\n\n### json.exception.type_error.310\n\nThe `swap()` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.310] cannot use swap() with number\n    ```\n\n### json.exception.type_error.311\n\nThe `emplace()` and `emplace_back()` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.311] cannot use emplace() with number\n    ```\n    ```\n    [json.exception.type_error.311] cannot use emplace_back() with number\n    ```\n\n### json.exception.type_error.312\n\nThe `update()` member functions can only be executed for certain JSON types.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.312] cannot use update() with array\n    ```\n\n### json.exception.type_error.313\n\nThe `unflatten` function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well-defined.\n\n!!! failure \"Example message\"\n\n    ```\n    [json.exception.type_error.313] invalid value to unflatten\n    ```\n\n### json.exception.type_error.314\n\nThe `unflatten` function only works for an object whose keys are JSON Pointers.\n\n!!! failure \"Example message\"\n\n    Calling `unflatten()` on an array `#!json [1,2,3]`:\n\n    ```\n    [json.exception.type_error.314] only objects can be unflattened\n    ```\n\n### json.exception.type_error.315\n\nThe `unflatten()` function only works for an object whose keys are JSON Pointers and whose values are primitive.\n\n!!! failure \"Example message\"\n\n    Calling `unflatten()` on an object `#!json {\"/1\", [1,2,3]}`:\n\n    ```\n    [json.exception.type_error.315] values in object must be primitive\n    ```\n\n### json.exception.type_error.316\n\nThe `dump()` function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded.\n\n!!! failure \"Example message\"\n\n    Calling `dump()` on a JSON value containing an ISO 8859-1 encoded string:\n    ```\n    [json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F\n    ```\n\n!!! tip\n\n    - Store the source file with UTF-8 encoding.\n    - Pass an error handler as last parameter to the `dump()` function to avoid this exception:\n        - `json::error_handler_t::replace` will replace invalid bytes sequences with `U+FFFD` \n        - `json::error_handler_t::ignore` will silently ignore invalid byte sequences\n\n### json.exception.type_error.317\n\nThe dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON)\n\n!!! failure \"Example message\"\n\n    Serializing `#!json null` to BSON:\n    ```\n    [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null\n    ```\n    Serializing `#!json [1,2,3]` to BSON:\n    ```\n    [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array\n    ```\n\n!!! tip\n\n    Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {\"value\": true}`\n\n## Out of range\n\nThis exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance in case of array indices or nonexisting object keys.\n\nExceptions have ids 4xx.\n\n??? example\n\n    The following code shows how an `out_of_range` exception can be caught.\n\n    ```cpp\n    --8<-- \"examples/out_of_range.cpp\"\n    ```\n    \n    Output:\n\n    ```\n    --8<-- \"examples/out_of_range.output\"\n    ```\n\n### json.exception.out_of_range.401\n\nThe provided array index `i` is larger than `size-1`.\n\n!!! failure \"Example message\"\n\n    ```\n    array index 3 is out of range\n    ```\n\n### json.exception.out_of_range.402\n\nThe special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.\n\n!!! failure \"Example message\"\n\n    ```\n    array index '-' (3) is out of range\n    ```\n\n### json.exception.out_of_range.403\n\nThe provided key was not found in the JSON object.\n\n!!! failure \"Example message\"\n\n    ```\n    key 'foo' not found\n    ```\n\n### json.exception.out_of_range.404\n\nA reference token in a JSON Pointer could not be resolved.\n\n!!! failure \"Example message\"\n\n    ```\n    unresolved reference token 'foo'\n    ```\n\n### json.exception.out_of_range.405\n\nThe JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.\n\n!!! failure \"Example message\"\n\n    ```\n    JSON pointer has no parent\n    ```\n\n### json.exception.out_of_range.406\n\nA parsed number could not be stored as without changing it to NaN or INF.\n\n!!! failure \"Example message\"\n\n    ```\n    number overflow parsing '10E1000'\n    ```\n\n### json.exception.out_of_range.407\n\nUBJSON and BSON only support integer numbers up to 9223372036854775807.\n\n!!! failure \"Example message\"\n\n    ```\n    number overflow serializing '9223372036854775808'\n    ```\n\n!!! note\n\n    Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers, and this exception does not further occur. \n\n### json.exception.out_of_range.408\n\nThe size (following `#`) of an UBJSON array or object exceeds the maximal capacity.\n\n!!! failure \"Example message\"\n\n    ```\n    excessive array size: 8658170730974374167\n    ```\n\n### json.exception.out_of_range.409\n\nKey identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string.\n\n!!! failure \"Example message\"\n\n    ```\n    BSON key cannot contain code point U+0000 (at byte 2)\n    ```\n\n## Further exceptions\n\nThis exception is thrown in case of errors that cannot be classified with the\nother exception types.\n\nExceptions have ids 5xx.\n\n??? example\n\n    The following code shows how an `other_error` exception can be caught.\n\n    ```cpp\n    --8<-- \"examples/other_error.cpp\"\n    ```\n    \n    Output:\n\n    ```\n    --8<-- \"examples/other_error.output\"\n    ```\n\n### json.exception.other_error.501\n\nA JSON Patch operation 'test' failed. The unsuccessful operation is also printed.\n\n!!! failure \"Example message\"\n\n    Executing `#!json {\"op\":\"test\", \"path\":\"/baz\", \"value\":\"bar\"}` on `#!json {\"baz\": \"qux\"}`:\n\n    ```\n    [json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/baz\",\"value\":\"bar\"}\n    ```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/home/faq.md",
    "content": "# Frequently Asked Questions (FAQ)\n\n## Known bugs\n\n### Brace initialization yields arrays\n\n!!! question\n\n    Why does\n\n    ```cpp\n    json j{true};\n    ```\n\n    and\n\n    ```cpp\n    json j(true);\n    ```\n\n    yield different results (`#!json [true]` vs. `#!json true`)?\n\nThis is a known issue, and -- even worse -- the behavior differs between GCC and Clang. The \"culprit\" for this is the library's constructor overloads for initializer lists to allow syntax like\n\n```cpp\njson array = {1, 2, 3, 4};\n```\n\nfor arrays and\n\n```cpp\njson object = {{\"one\", 1}, {\"two\", 2}}; \n```\n\nfor objects.\n\n!!! tip\n\n    To avoid any confusion and ensure portable code, **do not** use brace initialization with the types `basic_json`, `json`, or `ordered_json` unless you want to create an object or array as shown in the examples above.\n\n## Limitations\n\n### Relaxed parsing\n\n!!! question\n\n\tCan you add an option to ignore trailing commas?\n\nThis library does not support any feature which would jeopardize interoperability.\n\n\n### Parse errors reading non-ASCII characters\n\n!!! question \"Questions\"\n\n\t- Why is the parser complaining about a Chinese character?\n\t- Does the library support Unicode?\n\t- I get an exception `[json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"Testé$')\"`\n\nThe library supports **Unicode input** as follows:\n\n- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1).\n- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers.\n- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors.\n- [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library.\n- Invalid surrogates (e.g., incomplete pairs such as `\\uDEAD`) will yield parse errors.\n- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.\n- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.\n\nIn most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows where Latin-1 or ISO 8859-1 is often the standard encoding.\n\n\n### Wide string handling\n\n!!! question\n\n    Why are wide strings (e.g., `std::wstring`) dumped as arrays of numbers?\n\nAs described [above](#parse-errors-reading-non-ascii-characters), the library assumes UTF-8 as encoding.  To store a wide string, you need to change the encoding.\n\n!!! example\n\n    ```cpp\n    #include <codecvt> // codecvt_utf8\n    #include <locale>  // wstring_convert\n    \n    // encoding function\n    std::string to_utf8(std::wstring& wide_string)\n    {\n        static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;\n        return utf8_conv.to_bytes(wide_string);\n    }\n    \n    json j;\n    std::wstring ws = L\"車B1234 こんにちは\";\n    \n    j[\"original\"] = ws;\n    j[\"encoded\"] = to_utf8(ws);\n    \n    std::cout << j << std::endl;\n    ```\n    \n    The result is:\n    \n    ```json\n    {\n      \"encoded\": \"車B1234 こんにちは\",\n      \"original\": [36554, 66, 49, 50, 51, 52, 32, 12371, 12435, 12395, 12385, 12399]\n    }\n    ```\n\n## Exceptions\n\n### Parsing without exceptions\n\n!!! question\n\n    Is it possible to indicate a parse error without throwing an exception?\n\nYes, see [Parsing and exceptions](../features/parsing/parse_exceptions.md).\n\n\n### Key name in exceptions\n\n!!! question\n\n\tCan I get the key of the object item that caused an exception?\n\nYes, you can. Please define the symbol [`JSON_DIAGNOSTICS`](../features/macros.md#json_diagnostics) to get [extended diagnostics messages](exceptions.md#extended-diagnostic-messages).\n\n\n## Serialization issues\n\n\n### Number precision\n\n!!! question\n\n\t- It seems that precision is lost when serializing a double.\n\t- Can I change the precision for floating-point serialization?\n\nThe library uses `std::numeric_limits<number_float_t>::digits10` (15 for IEEE `double`s) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip.\n\n!!! quote \"[cppreference.com](https://en.cppreference.com/w/cpp/types/numeric_limits/digits10)\"\n\n\tThe value of `std::numeric_limits<T>::digits10` is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow. \n\n!!! tip\n\n\tThe website https://float.exposed gives a good insight into the internal storage of floating-point numbers.\n\nSee [this section](../features/types/number_handling.md#number-serialization) on the library's number handling for more information.\n\n## Compilation issues\n\n### Android SDK\n\n!!! question\n\n\tWhy does the code not compile with Android SDK?\n\nAndroid defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.\n\n```ini\nAPP_STL := c++_shared\nNDK_TOOLCHAIN_VERSION := clang3.6\nAPP_CPPFLAGS += -frtti -fexceptions\n```\n\nThe code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10.\n\n\n### Missing STL function\n\n!!! question \"Questions\"\n\n\t- Why do I get a compilation error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`)?\n\t- Why does the code not compile with MinGW or Android SDK?\n\nThis is not an issue with the code,  but rather with the compiler itself. On Android, see above to build with a newer environment.  For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/home/license.md",
    "content": "# License\n\n<img align=\"right\" src=\"https://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png\">\n\nThe class is licensed under the [MIT License](https://opensource.org/licenses/MIT):\n\nCopyright &copy; 2013-2022 [Niels Lohmann](https://nlohmann.me)\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.\n\n* * *\n\nThe class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2008-2009 [Björn Hoehrmann](http://bjoern.hoehrmann.de/) <bjoern@hoehrmann.de>\n\nThe class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2009 [Florian Loitsch](https://florian.loitsch.com/)\n\nThe class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/home/releases.md",
    "content": "# Releases\n\n## v3.7.3\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.3/include.zip) (274 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.3/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.3/json.hpp) (791 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.3/json.hpp.asc) (1 KB)\n\nRelease date: 2019-11-17\nSHA-256: 3b5d2b8f8282b80557091514d8ab97e27f9574336c804ee666fda673a9b59926 (json.hpp), 87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014 (include.zip)\n\n### Summary\n\nThis release fixes a bug introduced in release 3.7.2 which could yield quadratic complexity in destructor calls. All changes are backward-compatible.\n\n### :bug: Bug Fixes\n\n- Removed `reserve()` calls from the destructor which could lead to quadratic complexity. #1837 #1838\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n\n## v3.7.2\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.2/include.zip) (274 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.2/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.2/json.hpp) (791 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.2/json.hpp.asc) (1 KB)\n\nRelease date: 2019-11-10\nSHA-256: 0a65fcbbe1b334d3f45c9498e5ee28c3f3b2428aea98557da4a3ff12f0f14ad6 (json.hpp), 67f69c9a93b7fa0612dc1b6273119d2c560317333581845f358aaa68bff8f087 (include.zip)\n\n### Summary\n\nProject [bad_json_parsers](https://github.com/lovasoa/bad_json_parsers) tested how JSON parser libraries react on **deeply nested inputs**. It turns out that this library segfaulted at a certain nesting depth. This bug was fixed with this release. **Now the parsing is only bounded by the available memory.** All changes are backward-compatible.\n\n### :bug: Bug Fixes\n\n* Fixed a bug that lead to stack overflow for deeply nested JSON values (objects, array) by changing the implementation of the destructor from a recursive to an iterative approach. #832, #1419, #1835\n\n### :hammer: Further Changes\n\n* Added WhiteStone Bolt. #1830\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.7.1\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.1/include.zip) (273 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.1/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.1/json.hpp) (789 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.1/json.hpp.asc) (1 KB)\n\nRelease date: 2019-11-06\nSHA-256: b5ba7228f3c22a882d379e93d08eab4349458ee16fbf45291347994eac7dc7ce (json.hpp), 77b9f54b34e7989e6f402afb516f7ff2830df551c3a36973085e2c7a6b1045fe (include.zip)\n\n### Summary\n\nThis release fixes several small bugs in the library. All changes are backward-compatible.\n\n### :bug: Bug Fixes\n\n- Fixed a segmentation fault when serializing `std::int64_t` minimum value. #1708 #1722\n- Fixed the [`contains()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_ab23b04802eb9da97dc3f664e54e09cb3.html#ab23b04802eb9da97dc3f664e54e09cb3) function for JSON Pointers. #1727 #1741\n- Fixed too lax SFINAE guard for conversion from `std::pair` and `std::tuple` to `json`. #1805 #1806 #1825 #1826\n- Fixed some regressions detected by UBSAN. Updated CI to use Clang-Tidy 7.1.0. #1716 #1728\n- Fixed integer truncation in `iteration_proxy`. #1797\n- Updated [Hedley](https://github.com/nemequ/hedley) to v11 to [fix a E2512 error](https://github.com/nemequ/hedley/issues/28) in MSVC. #1799\n- Fixed a compile error in enum deserialization of non non-default-constructible types. #1647 #1821\n- Fixed the conversion from `json` to `std::valarray`.\n\n### :zap: Improvements\n\n- The [`items()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) function can now be used with a custom string type. #1765\n- Made [`json_pointer::back`](https://nlohmann.github.io/json/classnlohmann_1_1json__pointer_a213bc67c32a30c68ac6bf06f5195d482.html#a213bc67c32a30c68ac6bf06f5195d482) `const`. #1764 #1769\n- Meson is part of the release archive. #1672 #1694 \n- Improved documentation on the Meson and Spack package manager. #1694 #1720\n\n### :hammer: Further Changes\n\n- Added GitHub Workflow with `ubuntu-latest`/GCC 7.4.0 as CI step.\n- Added GCC 9 to Travis CI to compile with C++20 support. #1724\n- Added MSVC 2019 to the AppVeyor CI. #1780\n- Added badge to [fuzzing status](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json).\n- Fixed some cppcheck warnings. #1760\n- Fixed several typos in the documentation. #1720 #1767 #1803\n- Added documentation on the `JSON_THROW_USER`, `JSON_TRY_USER`, and `JSON_CATCH_USER` macros to control user-defined exception handling.\n- Used GitHub's [CODEOWNERS](https://github.com/nlohmann/json/blob/develop/.github/CODEOWNERS) and [SECURITY](https://github.com/nlohmann/json/blob/develop/.github/SECURITY.md) feature.\n- Removed `GLOB` from CMake files. #1779\n- Updated to [Doctest](https://github.com/onqtam/doctest) 2.3.5.\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.7.0\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.7.0/include.zip) (143 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.7.0/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.7.0/json.hpp) (782 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.7.0/json.hpp.asc) (1 KB)\n\nRelease date: 2019-07-28\nSHA-256: a503214947952b69f0062f572cb74c17582a495767446347ce2e452963fc2ca4 (json.hpp), 541c34438fd54182e9cdc68dd20c898d766713ad6d901fb2c6e28ff1f1e7c10d (include.zip)\n\n### Summary\n\nThis release introduces a few convenience functions and performs a lot of house keeping (bug fixes and small improvements). All changes are backward-compatible.\n\n### :sparkles: New Features\n\n- Add overload of the **[`contains`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab23b04802eb9da97dc3f664e54e09cb3.html#ab23b04802eb9da97dc3f664e54e09cb3) function** to check if a JSON pointer is valid without throwing exceptions, just like its [counterpart for object keys](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9286acdc0578fc66e9346323e69fc0e3.html#a9286acdc0578fc66e9346323e69fc0e3). #1600\n- Add a function **[`to_string`](http://nlohmann.github.io/json/doxygen/namespacenlohmann_a6ce645a0b8717757e096a5b5773b7a16.html#a6ce645a0b8717757e096a5b5773b7a16)** to allow for generic conversion to strings. #916 #1585\n- Add **return value for the [`emplace_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_abf29131f898b05aad2c01a9c80e7a002.html#abf29131f898b05aad2c01a9c80e7a002) function**, returning a reference to the added element just like C++17 is [introducing this](https://en.cppreference.com/w/cpp/container/vector/emplace_back) for `std::vector`. #1609\n- Add info how to use the library with the **[pacman](https://wiki.archlinux.org/index.php/pacman) package manager** on MSYS2. #1670\n\n### :bug: Bug Fixes\n\n- Fix an issue where typedefs with certain names yielded a compilation error. #1642 #1643\n- Fix a conversion to `std::string_view` in the unit tests. #1634 #1639\n- Fix MSVC Debug build. #1536 #1570 #1608\n- Fix [`get_to`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a65753c68f06639eda0d355f919564e01.html#a65753c68f06639eda0d355f919564e01) method to clear existing content before writing. #1511 #1555\n- Fix a `-Wc++17-extensions` warning. `nodiscard` attributes are now only used with Clang when `-std=c++17` is used. #1535 #1551\n\n### :zap: Improvements\n\n- Switch from [Catch](https://github.com/philsquared/Catch) to **[doctest](https://github.com/onqtam/doctest)** for the unit tests which speeds up compilation and runtime of the 112,112,308 tests.\n- Add an explicit section to the [README](https://github.com/nlohmann/json/blob/develop/README.md) about the **frequently addressed topics** [character encoding](https://github.com/nlohmann/json#character-encoding), [comments in JSON](https://github.com/nlohmann/json#comments-in-json), and the [order of object keys](https://github.com/nlohmann/json#order-of-object-keys).\n\n### :hammer: Further Changes\n\n- Use [`GNUInstallDirs`](https://cmake.org/cmake/help/v3.0/module/GNUInstallDirs.html) to set library install directories. #1673\n- Fix links in the [README](https://github.com/nlohmann/json/blob/develop/README.md). #1620 #1621 #1622 #1623 #1625\n- Mention [`json` type](http://nlohmann.github.io/json/doxygen/namespacenlohmann_a2bfd99e845a2e5cd90aeaf1b1431f474.html#a2bfd99e845a2e5cd90aeaf1b1431f474) on the [documentation start page](http://nlohmann.github.io/json/doxygen/index.html). #1616\n- Complete documentation of [`value()` function](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_adcf8ca5079f5db993820bf50036bf45d.html#adcf8ca5079f5db993820bf50036bf45d) with respect to `type_error.302` exception. #1601\n- Fix links in the documentation. #1598\n- Add regression tests for MSVC. #1543 #1570\n- Use **[CircleCI](http://circleci.com)** for [continuous integration](https://circleci.com/gh/nlohmann/json).\n- Use **[Doozer](https://doozer.io)** for [continuous integration](https://doozer.io/nlohmann/json) on Linux (CentOS, Raspbian, Fedora)\n- Add tests to check each CMake flag (`JSON_BuildTests`, `JSON_Install`, `JSON_MultipleHeaders`, `JSON_Sanitizer`, `JSON_Valgrind`, `JSON_NoExceptions`, `JSON_Coverage`).\n- Use [Hedley](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros like `JSON_DEPRECATED`, `JSON_NODISCARD`, `JSON_LIKELY`, `JSON_UNLIKELY`, `JSON_HAS_CPP_14`, or `JSON_HAS_CPP_17`. Functions taking or returning pointers are annotated accordingly when a pointer will not be null.\n- Build and run tests on [AppVeyor](https://ci.appveyor.com/project/nlohmann/json) in DEBUG and RELEASE mode.\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.6.1\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip) (136 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.6.1/json.hpp) (711 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.6.1/json.hpp.asc) (1 KB)\n\nRelease date: 2019-03-20\nSHA-256: d2eeb25d2e95bffeb08ebb7704cdffd2e8fca7113eba9a0b38d60a5c391ea09a (json.hpp), 69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf (include.zip)\n\n### Summary\n\nThis release **fixes a regression and a bug** introduced by the earlier 3.6.0 release. All changes are backward-compatible.\n\n### :bug: Bug Fixes\n\n- Fixed regression of #590 which could lead to compilation errors with GCC 7 and GCC 8. #1530\n- Fixed a compilation error when `<Windows.h>` was included. #1531\n\n### :hammer: Further Changes\n\n- Fixed a warning for missing field initializers. #1527\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.6.0\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.6.0/include.zip) (136 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.6.0/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.6.0/json.hpp) (711 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.6.0/json.hpp.asc) (1 KB)\n\nRelease date: 2019-03-20\nSHA-256: ce9839370f28094c71107c405affb3b08c4a098154988014cbb0800b1c44a831 (json.hpp), 237c5e66e7f8186a02804ce9dbd5f69ce89fe7424ef84adf6142e973bd9532f4 (include.zip)\n\nℹ️ **This release introduced a regression. Please update to [version 3.6.1](https://github.com/nlohmann/json/releases/tag/v3.6.1)!**\n\n### Summary\n\nThis release adds some **convenience functions for JSON Pointers**, introduces a [`contains`](\nhttp://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a0a45fc740637123fdf05fef970f8be47.html#a0a45fc740637123fdf05fef970f8be47) function to check if a key is present in an object, and improves the **performance of integer serialization**. Furthermore, a lot of small bug fixes and improvements have been made. All changes are backward-compatible.\n\n### :sparkles: New Features\n\n- Overworked the public interface for JSON Pointers. The creation of JSON Pointers is simplified with [`operator/`](\nhttp://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a90a11fe6c7f37b1746a3ff9cb24b0d53.html#a90a11fe6c7f37b1746a3ff9cb24b0d53) and [`operator/=`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a7395bd0af29ac23fd3f21543c935cdfa.html#a7395bd0af29ac23fd3f21543c935cdfa). JSON Pointers can be inspected with [`empty`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a649252bda4a2e75a0915b11a25d8bcc3.html#a649252bda4a2e75a0915b11a25d8bcc3), [`back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a6bd5b554c10f15672135c216893eef31.html#a6bd5b554c10f15672135c216893eef31),  and [`parent_pointer`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_afdaacce1edb7145e0434e014f0e8685a.html#afdaacce1edb7145e0434e014f0e8685a), and manipulated with [`push_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a697d12b5bd6205f8866691b166b7c7dc.html#a697d12b5bd6205f8866691b166b7c7dc) and [`pop_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1json__pointer_a4b1ee4d511ca195bed896a3da47e264c.html#a4b1ee4d511ca195bed896a3da47e264c). #1434\n- Added a boolean method [`contains`](\nhttp://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a0a45fc740637123fdf05fef970f8be47.html#a0a45fc740637123fdf05fef970f8be47) to check whether an element exists in a JSON object with a given key. Returns false when called on non-object types. #1471 #1474\n\n### :bug: Bug Fixes\n\n- Fixed a compilation issues with libc 2.12. #1483 #1514\n- Fixed endian conversion on PPC64. #1489\n- Fixed library to compile with GCC 9. #1472 #1492\n- Fixed a compilation issue with GCC 7 on CentOS. #1496\n- Fixed an integer overflow. #1447\n- Fixed buffer flushing in serializer. #1445 #1446\n\n### :zap: Improvements\n\n- The performance of dumping integers has been greatly improved. #1411\n- Added CMake parameter `JSON_Install` to control whether the library should be installed (default: on). #1330\n- Fixed a lot of compiler and linter warnings. #1400 #1435 #1502\n- Reduced required CMake version from 3.8 to 3.1. #1409 #1428 #1441 #1498\n- Added `nodiscard` attribute to `meta()`, `array()`, `object()`, `from_cbor`, `from_msgpack`, `from_ubjson`, `from_bson`, and `parse`. #1433\n\n### :hammer: Further Changes\n\n- Added missing headers. #1500\n- Fixed typos and broken links in README. #1417 #1423 #1425 #1451 #1455 #1491\n- Fixed documentation of parse function. #1473\n- Suppressed warning that cannot be fixed inside the library. #1401 #1468\n- Imroved package manager suppert:\n\t- Updated Buckaroo instructions. #1495\n\t- Improved Meson support. #1463\n\t- Added Conda package manager documentation. #1430\n\t- Added NuGet package manager documentation. #1132\n- Continuous Integration\n\t- Removed unstable or deprecated Travis builders (Xcode 6.4 - 8.2) and added Xcode 10.1 builder.\n\t- Added Clang 7 to Travis CI.\n\t- Fixed AppVeyor x64 builds. #1374 #1414\n- Updated thirdparty libraries:\n\t- Catch 1.12.0 -> 1.12.2\n\t- Google Benchmark 1.3.0 -> 1.4.1\n\t- Doxygen 1.8.15 -> 1.8.16\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.5.0\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.5.0/include.zip) (133 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.5.0/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.5.0/json.hpp) (693 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.5.0/json.hpp.asc) (1 KB)\n\nRelease date: 2018-12-22\nSHA-256: 8a6dbf3bf01156f438d0ca7e78c2971bca50eec4ca6f0cf59adf3464c43bb9d5 (json.hpp), 3564da9c5b0cf2e032f97c69baedf10ddbc98030c337d0327a215ea72259ea21 (include.zip)\n\n### Summary\n\nThis release introduces the support for **structured bindings** and reading from **`FILE*`**. Besides, a few bugs have been fixed. All changes are backward-compatible.\n\n### :sparkles: New Features\n\n- **Structured bindings** are now supported for JSON objects and arrays via the [`items()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) member function, so finally this code is possible:\n  ```cpp\n  for (auto& [key, val] : j.items()) {\n      std::cout << key << ':' << val << '\\n';\n  }\n  ```  \n  #1388 #1391\n\n- Added support for **reading from `FILE*`** to support situations in which streams are nit available or would require too much RAM. #1370 #1392\n\n### :bug: Bug Fixes\n\n- The `eofbit` was not set for input streams when the end of a stream was reached while parsing. #1340 #1343\n- Fixed a bug in the SAX parser for BSON arrays.\n\n### :zap: Improvements\n\n- Added support for Clang 5.0.1 (PS4 version). #1341 #1342\n\n### :hammer: Further Changes\n\n- Added a warning for implicit conversions to the documentation: It is not recommended to use implicit conversions when reading **from** a JSON value. Details about this recommendation can be found [here](https://www.github.com/nlohmann/json/issues/958).  #1363\n- Fixed typos in the documentation. #1329 #1380 #1382\n- Fixed a C4800 warning. #1364\n- Fixed a `-Wshadow` warning #1346\n- Wrapped `std::snprintf` calls to avoid error in MSVC. #1337\n- Added code to allow installation via Meson. #1345\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.4.0\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.4.0/include.zip) (132 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.4.0/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.4.0/json.hpp) (689 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.4.0/json.hpp.asc) (1 KB)\n\nRelease date: 2018-10-30\nSHA-256: 63da6d1f22b2a7bb9e4ff7d6b255cf691a161ff49532dcc45d398a53e295835f (json.hpp), bfec46fc0cee01c509cf064d2254517e7fa80d1e7647fea37cf81d97c5682bdc (include.zip)\n\n### Summary\n\nThis release introduces three new features:\n\n- **BSON (Binary JSON)** is next to CBOR, MessagePack, and UBJSON the fourth binary (de)serialization format supported by the library.\n- **Adjustable error handlers for invalid Unicode** allows to specify the behavior when invalid byte sequences are serialized.\n- **Simplified enum/JSON mapping** with a macro in case the default mapping to integers is not desired.\n\nFurthermore, some effort has been invested in improving the **parse error messages**. Besides, a few bugs have been fixed. All changes are backward-compatible.\n\n### :sparkles: New Features\n\n- The library can read and write a subset of **[BSON](http://bsonspec.org/) (Binary JSON)**. All data types known from JSON are supported, whereas other types more tied to MongoDB such as timestamps, object ids, or binary data are currently not implemented. See [the README](https://github.com/nlohmann/json#binary-formats-bson-cbor-messagepack-and-ubjson) for examples. #1244 #1320\n- The behavior when the library encounters an invalid Unicode sequence during serialization can now be controlled by defining one of three **Unicode error handlers**: (1) throw an exception (default behavior), (2) replace invalid sequences by the Unicode replacement character (U+FFFD), or (3) ignore/filter invalid sequences. See the [documentation of the `dump` function](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) for examples. #1198 #1314\n- To easily specify a user-defined **enum/JSON mapping**, a macro `NLOHMANN_JSON_SERIALIZE_ENUM` has been introduced. See the [README section](https://github.com/nlohmann/json#specializing-enum-conversion) for more information. #1208 #1323\n\n### :bug: Bug Fixes\n\n- fixed truncation #1286 #1315\n- fixed an issue with std::pair #1299 #1301\n- fixed an issue with std::variant #1292 #1294\n- fixed a bug in the JSON Pointer parser\n\n### :zap: Improvements\n\n- The **diagnosis messages for parse errors** have been improved: error messages now indicated line/column positions where possible (in addition to a byte count) and also the context in which the error occurred (e.g., \"while parsing a JSON string\"). Example: error `parse error at 2: syntax error - invalid string: control character must be escaped; last read: '<U+0009>'` is now reported as `parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t; last read: '<U+0009>'`. #1280 #1288 #1303\n\n### :hammer: Further Changes\n\n- improved Meson documentation #1305\n- fixed some more linter warnings #1280\n- fixed Clang detection for third-party Google Benchmark library #1277\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.3.0\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.3.0/include.zip) (123 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.3.0/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.3.0/json.hpp) (635 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.3.0/json.hpp.asc) (1 KB)\n\nRelease date: 2018-10-05\nSHA-256: f1327bb60c58757a3dd2b0c9c45d49503d571337681d950ec621f8374bcc14d4 (json.hpp), 9588d63557333aaa485e92221ec38014a85a6134e7486fe3441e0541a5a89576 (include.zip)\n\n### Summary\n\nThis release adds support for **GCC 4.8**. Furthermore, it adds a function [**`get_to`**](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a8a3db7d78f74232d3a6fb8f1abf69709.html#a8a3db7d78f74232d3a6fb8f1abf69709) to write a JSON value to a passed reference. Another topic of this release was the **CMake support** which has been overworked and documented.\n\nBesides, a lot of bugs have been fixed and slight improvements have been made. All changes are backward-compatible.\n\n### :sparkles: New Features\n\n- The library can now also built with **GCC 4.8**. Though this compiler does not fully support C++11, it can successfully compile and run the test suite. Note that bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824) in GCC 4.8 still forbids to use multiline raw strings in arguments to macros. #1257\n- Added new function [**`get_to`**](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a8a3db7d78f74232d3a6fb8f1abf69709.html#a8a3db7d78f74232d3a6fb8f1abf69709) to write a JSON value to a passed reference. The destination type is automatically derived which allows more succinct code compared to the `get` function. #1227 #1231\n\n### :bug: Bug Fixes\n\n- Fixed a bug in the CMake file that made `target_link_libraries` to not properly include `nlohmann_json`. #1243 #1245 #1260\n- Fixed a warning in MSVC 2017 complaining about a constexpr if. #1204 #1268 #1272\n- Fixed a bug that prevented compilation with ICPC. #755 #1222\n- Improved the SFINAE correctness to fix a bug in the conversion operator. #1237 #1238\n- Fixed a `-Wctor-dtor-privacy` warning. #1224\n- Fixed a warning on a lambda in unevaluated context. #1225 #1230\n- Fixed a bug introduced in version 3.2.0 where defining `JSON_CATCH_USER` led to duplicate macro definition of `JSON_INTERNAL_CATCH`. #1213 #1214\n- Fixed a bug that prevented compilation with Clang 3.4.2 in RHEL 7. #1179 #1249\n\n### :zap: Improvements\n\n- Added [documentation on CMake integration](https://github.com/nlohmann/json#cmake) of the library. #1270\n- Changed the CMake file to use `find_package(nlohmann_json)` without installing the library. #1202\n- Improved error messages in case `operator[]` is used with the wrong combination (json.exception.type_error.305) of JSON container type and argument type. Example: \"cannot use operator[] with a string argument\". #1220 #1221\n- Added a license and version information to the Meson build file. #1252\n- Removed static assertions to indicated missing `to_json` or `from_json` functions as such assertions do not play well with SFINAE. These assertions also led to problems with GMock. #960 #1212 #1228\n- The test suite now does not wait forever if run in a wrong directory and input files are not found. #1262\n- The test suite does not show deprecation warnings for deprecated functions which frequently led to confusion. #1271\n\n### :hammer: Further Changes\n\n- GCC 4.8 and Xcode 10 were added to the [continuous integration suite](https://travis-ci.org/nlohmann/json) at Travis.\n- Added [lgtm](https://lgtm.com/projects/g/nlohmann/json/context:cpp) checks to pull requests.\n- Added tests for CMake integration. #1260\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n\n## v3.2.0\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.2.0/include.zip) (124 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.2.0/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.2.0/json.hpp) (636 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.2.0/json.hpp.asc) (1 KB)\n\nRelease date: 2018-08-20\nSHA-256: ce6b5610a051ec6795fa11c33854abebb086f0fd67c311f5921c3c07f9531b44 (json.hpp), 35ee642558b90e2f9bc758995c4788c4b4d4dec54eef95fb8f38cb4d49c8fc7c (include.zip)\n\n### Summary\n\nThis release introduces a [**SAX interface**](https://nlohmann.github.io/json/structnlohmann_1_1json__sax.html) to the library. While this may be a very special feature used by only few people, it allowed to unify all functions that consumed input and created some kind of JSON value. Internally, now all existing functions like `parse`, `accept`, `from_cbor`, `from_msgpack`, and `from_ubjson` use the SAX interface with different event processors. This allowed to separate the input processing from the value generation. Furthermore, throwing an exception in case of a parse error is now optional and up to the event processor. Finally, the JSON parser is now non-recursive (meaning it does not use the call stack, but `std::vector<bool>` to track the hierarchy of structured values) which allows to process nested input more efficiently.\n\nFurthermore, the library finally is able to parse from **wide string types**. This is the first step toward opening the library from UTF-8 to UTF-16 and UTF-32.\n\nThis release further fixes several bugs in the library. All changes are backward-compatible.\n\n### :sparkles: New Features\n\n- added a parser with a **SAX interface** (#971, #1153)\n- support to parse from **wide string types** `std::wstring`, `std::u16string`, and `std::u32string`; the input will be converted to UTF-8 (#1031)\n- added support for **`std::string_view`** when using C++17 (#1028)\n- allow to **roundtrip `std::map` and `std::unordered_map`** from JSON if key type is not convertible to string; in these cases, values are serialized to arrays of pairs (#1079, #1089, #1133, #1138)\n\n### :bug: Bug Fixes\n\n- allow to create `nullptr_t` from JSON allowing to properly roundtrip `null` values (#1169)\n- allow compare user-defined string types (#1130)\n- better support for algorithms using iterators from `items()` (#1045, #1134)\n- added parameter to avoid compilation error with MSVC 2015 debug builds (#1114)\n- re-added accidentally skipped unit tests (#1176)\n- fixed MSVC issue with `std::swap` (#1168)\n\n### :zap: Improvements\n\n- `key()` function for iterators returns a const reference rather than a string copy (#1098)\n- binary formats CBOR, MessagePack, and UBJSON now supports `float` as type for floating-point numbers (#1021)\n\n### :hammer: Further Changes\n\n- changed issue templates\n- improved continuous integration: added builders for Xcode 9.3 and 9.4, added builders for GCC 8 and Clang 6, added builder for MinGW, added builders for MSVC targeting x86\n- required CMake version is now at least 3.8 (#1040)\n- overworked CMake file wrt. packaging (#1048)\n- added package managers: Spack (#1041) and CocoaPods (#1148)\n- fixed Meson include directory (#1142)\n- preprocessor macro `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK` can skip the rejection of unsupported compilers - use at your own risk! (#1128)\n- preprocessor macro `JSON_INTERNAL_CATCH`/`JSON_INTERNAL_CATCH_USER` allows to control the behavior of exception handling inside the library (#1187)\n- added note on `char` to JSON conversion\n- added note how to send security-related issue via encrypted email\n- removed dependency to `std::stringstream` (#1117)\n- added SPDX-License-Identifier\n- added updated JSON Parsing Test Suite, described in [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.php)\n- updated to Catch 1.12.0\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n\n\n## v3.1.2\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.1.2/include.zip) (115 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.1.2/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.1.2/json.hpp) (582 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.1.2/json.hpp.asc) (1 KB)\n\nRelease date: 2018-03-14\nSHA-256: fbdfec4b4cf63b3b565d09f87e6c3c183bdd45c5be1864d3fcb338f6f02c1733 (json.hpp), 495362ee1b9d03d9526ba9ccf1b4a9c37691abe3a642ddbced13e5778c16660c (include.zip)\n\n### Summary\n\nThis release fixes several bugs in the library. All changes are backward-compatible.\n\n### :bug: Bug Fixes\n\n- Fixed a **memory leak** occurring in the parser callback (#1001).\n- Different **specializations of `basic_json`** (e.g., using different template arguments for strings or objects) can now be used in assignments (#972, #977, #986).\n- Fixed a logical error in an iterator range check (#992).\n\n### :zap: Improvements\n\n- The parser and the serialization now support **user-defined string types** (#1006, #1009).\n\n### :hammer: Further Changes\n\n- **[Clang Analyzer](http://clang-analyzer.llvm.org)** is now used as additional static analyzer; see `make clang_analyze`.\n- Overworked [README](https://github.com/nlohmann/json/blob/develop/README.md) by adding links to the [documentation](https://nlohmann.github.io/json/) (#981).\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n\n## v3.1.1\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.1.1/include.zip) (114 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.1.1/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.1.1/json.hpp) (577 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.1.1/json.hpp.asc) (1 KB)\n\nRelease date: 2018-02-13\nSHA-256: e14ce5e33d6a2daf748026bd4947f3d9686ca4cfd53d10c3da46a0a9aceb7f2e (json.hpp), fde771d4b9e4f222965c00758a2bdd627d04fb7b59e09b7f3d1965abdc848505 (include.zip)\n\n### Summary\n\nThis release fixes several bugs in the library. All changes are backward-compatible.\n\n### :bug: Bug Fixes\n\n- Fixed parsing of **CBOR strings with indefinite length** (#961). Earlier versions of this library misinterpreted the CBOR standard and rejected input with the `0x7F` start byte.\n- Fixed user-defined **conversion to vector type** (#924, #969). A wrong SFINAE check rejected code though a user-defined conversion was provided.\n- Fixed documentation of the parser behavior for **objects with duplicate keys** (#963). The exact behavior is not specified by [RFC 8259](https://tools.ietf.org/html/rfc8259) and the library now also provides no guarantee which object key is stored.\n- Added check to detect memory **overflow when parsing UBJSON containers** (#962). The optimized UBJSON format allowed for specifying an array with billions of `null` elements with a few bytes and the library did not check whether this size exceeded `max_size()`.\n\n### :hammer: Further Changes\n\n- [Code coverage](https://coveralls.io/github/nlohmann/json) is now calculated for the individual header files, allowing to find uncovered lines more quickly than by browsing through the single header version (#953, #957).\n- A Makefile target `run_benchmarks` was added to quickly build and run the benchmark suite.\n- The documentation was harmonized with respect to the header inclusion (#955). Now all examples and the README use `#include <nlohmann/json.hpp>` to allow for selecting `single_include` or `include` or whatever installation folder as include directory.\n- Added note on how to use the library with the [cget](http://cget.readthedocs.io/en/latest/) package manager (#954).\n\n### :fire: Deprecated functions\n\nThis release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) are deprecated. Please use the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) instead.\n- Functions [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3) and [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983) are deprecated. Please use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.1.0\n\n!!! summary \"Files\"\n\n    - [include.zip](https://github.com/nlohmann/json/releases/download/v3.1.0/include.zip) (114 KB)\n    - [include.zip.asc](https://github.com/nlohmann/json/releases/download/v3.1.0/include.zip.asc) (1 KB)\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.1.0/json.hpp) (577 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.1.0/json.hpp.asc) (1 KB)\n\nRelease date: 2018-02-01\nSHA-256: d40f614d10a6e4e4e80dca9463da905285f20e93116c36d97d4dc1aa63d10ba4 (json.hpp), 2b7234fca394d1e27b7e017117ed80b7518fafbb4f4c13a7c069624f6f924673 (include.zip)\n\n### Summary\n\nThis release adds support for the [**UBJSON**](http://ubjson.org) format and [**JSON Merge Patch**](https://tools.ietf.org/html/rfc7386). It also contains some minor changes and bug fixes. All changes are backward-compatible.\n\n### :sparkles: New features\n\n- The library now supports [**UBJSON**](http://ubjson.org) (Universal Binary JSON Specification) as binary format to read and write JSON values space-efficiently. See the [documentation overview](https://github.com/nlohmann/json/blob/develop/doc/binary_formats.md) for a comparison of the different formats CBOR, MessagePack, and UBJSON.\n- [**JSON Merge Patch**](https://tools.ietf.org/html/rfc7386) (RFC 7386) offers an intuitive means to describe patches between JSON values (#876, #877). See the documentation of [`merge_patch`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a0ec0cd19cce42ae6071f3cc6870ea295.html#a0ec0cd19cce42ae6071f3cc6870ea295) for more information.\n\n### :zap: Improvements\n\n- The library now uses the **Grisu2 algorithm** for printing floating-point numbers (based on the reference implementation by Florian Loitsch) which produces a short representation which is guaranteed to round-trip (#360, #935, #936).\n- The **UTF-8 handling** was further simplified by using the decoder of Björn Hoehrmann in more scenarios.\n\n### :truck: Reorganization\n\n- Though the library is released as a single header, its development got more and more complicated. With this release, the header is **split into several files** and the single-header file `json.hpp` can be generated from these development sources. In the repository, folder `include` contains the development sources and `single_include` contains the single `json.hpp` header (#700, #906, #907, #910, #911, #915, #920, #924, #925, #928, #944).\n- The split further allowed for a **forward declaration header** `include/nlohmann/json_fwd.hpp` to speed up compilation times (#314).\n\n### :hammer: Further changes\n\n- [Google Benchmark](https://github.com/google/benchmark) is now used for micro benchmarks (see `benchmarks` folder, #921).\n- The serialization (JSON and binary formats) now properly work with the libraries string template parameter, allowing for optimized string implementations to be used in constraint environments such as embedded software (#941, #950).\n- The exceptional behavior can now be overridden by defining macros `JSON_THROW_USER`, `JSON_TRY_USER`, and `JSON_CATCH_USER`, defining the behavior of `throw`, `try` and `catch`, respectively. This allows to switch off C++'s exception mechanism yet still execute user-defined code in case an error condition occurs (#938).\n- To facilitate the interplay with [flex](https://github.com/westes/flex) and [Bison](https://www.gnu.org/software/bison/), the library does not use the variable name `yytext` any more as it could clash with macro definitions (#933).\n- The library now defines `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and `NLOHMANN_JSON_VERSION_PATCH` to allow for conditional compilation based on the included library version (#943, #948).\n- A compilation error with ICC has been fixed (#947).\n- Typos and links in the documentation have been fixed (#900, #930).\n- A compiler error related to incomplete types has been fixed (#919).\n- The tests form the [UTF-8 decoder stress test](http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt) have been added to the test suite.\n\n### :fire: Deprecated functions\n\n- Function [`iterator_wrapper`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1592a06bc63811886ade4f9d965045e.html#af1592a06bc63811886ade4f9d965045e) has been deprecated (#874). Since its introduction, the name was up for discussion, as it was too technical. We now introduced the member function [`items()`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_afe3e137ace692efa08590d8df40f58dd.html#afe3e137ace692efa08590d8df40f58dd) with the same semantics. `iterator_wrapper` will be removed in the next major version (i.e., 4.0.0).\n\nFurthermore, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0):\n\n- [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3)\n- [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983)\n\nPlease use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.0.1\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.0.1/json.hpp) (502 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.0.1/json.hpp.asc) (1 KB)\n\nRelease date: 2017-12-29\nSHA-256: c9b3591f1bb94e723a0cd7be861733a3a555b234ef132be1e9027a0364118c4c\n\n### Summary\n\nThis release fixes small issues in the implementation of **JSON Pointer** and **JSON Patch**. All changes are backward-compatible.\n\n### Changes\n\n- :bug: The **\"copy\" operation of JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) requests that it is an error if the target path points into a non-existing array or object (see #894 for a detailed description). This release fixes the implementation to detect such invalid target paths and throw an exception.\n- :bug: An **array index in a JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) must be an integer. This release fixes the implementation to throw an exception in case invalid array indices such as `10e2` are used.\n- :white_check_mark: Added the [JSON Patch tests](https://github.com/json-patch/json-patch-tests) from Byron Ruth and Mike McCabe.\n- :memo: Fixed the documentation of the [`at(ptr)` function with JSON Pointers](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a8ab61397c10f18b305520da7073b2b45.html#a8ab61397c10f18b305520da7073b2b45) to list all possible exceptions (see #888).\n- :memo: Updated the [container overview documentation](https://nlohmann.github.io/json/) (see #883).\n- :wrench: The CMake files now respect the [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/module/CTest.html?highlight=build_testing) option (see #846, #885)\n- :rotating_light: Fixed some compiler warnings (see #858, #882).\n\n### Deprecated functions\n\n:fire: To unify the interfaces and to improve similarity with the STL, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0):\n\n- [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3)\n- [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983)\n\nPlease use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n## v3.0.0\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v3.0.0/json.hpp) (501 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v3.0.0/json.hpp.asc) (1 KB)\n\nRelease date: 2017-12-17\nSHA-256: 076d4a0cb890a3c3d389c68421a11c3d77c64bd788e85d50f1b77ed252f2a462\n\n### Summary\n\n<img src=\"https://user-images.githubusercontent.com/159488/34072418-8f5ba396-e287-11e7-9de7-8bc7482ac23c.png\" align=\"right\">\n\nAfter almost a year, here is finally a new release of JSON for Modern C++, and it is a major one! As we adhere to [semantic versioning](https://semver.org), this means the release includes some breaking changes, so please read the next section carefully before you update. But don't worry, we also added a few new features and put a lot of effort into fixing a lot of bugs and straighten out a few inconsistencies.\n\n### :boom: Breaking changes\n\nThis section describes changes that change the public API of the library and may require changes in code using a previous version of the library. In section \"Moving from 2.x.x to 3.0.0\" at the end of the release notes, we describe in detail how existing code needs to be changed.\n\n- The library now uses [**user-defined exceptions**](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9a0aced019cb1d65bb49703406c84970.html#a9a0aced019cb1d65bb49703406c84970) instead of re-using those defined in `<stdexcept>` (#244). This not only allows to add more information to the exceptions (every exception now has an identifier, and parse errors contain the position of the error), but also to easily catch all library exceptions with a single `catch(json::exception)`.\n- When strings with a different encoding as UTF-8 were stored in JSON values, their serialization could not be parsed by the library itself, as only UTF-8 is supported. To enforce this library limitation and improve consistency, **non-UTF-8 encoded strings now yield a `json::type_error` exception during serialization** (#838). The check for valid UTF-8 is realized with code from [Björn Hoehrmann](http://bjoern.hoehrmann.de/).\n- **NaN and infinity values can now be stored inside the JSON value** without throwing an exception. They are, however, still serialized as `null` (#388).\n- The library's iterator tag was changed from RandomAccessIterator to **[BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator)** (#593). Supporting RandomAccessIterator was incorrect as it assumed an ordering of values in a JSON objects which are unordered by definition.\n- The library does not include the standard headers `<iostream>`, `<ctype>`, and `<stdexcept>` any more. You may need to add these headers to code relying on them.\n- Removed constructor `explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)` which was deprecated in version 2.0.0 (#480).\n\n### :fire: Deprecated functions\n\nTo unify the interfaces and to improve similarity with the STL, the following functions are now deprecated and will be removed in the next major version (i.e., 4.0.0):\n\n- [`friend std::istream& operator<<(basic_json&, std::istream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ab7285a92514fcdbe6de505ebaba92ea3.html#ab7285a92514fcdbe6de505ebaba92ea3)\n- [`friend std::ostream& operator>>(const basic_json&, std::ostream&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9e06deabe69262c3ffc5533d32856983.html#a9e06deabe69262c3ffc5533d32856983)\n\nPlease use [`friend std::istream&  operator>>(std::istream&, basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aaf363408931d76472ded14017e59c9e8.html#aaf363408931d76472ded14017e59c9e8) and [`friend operator<<(std::ostream&, const basic_json&)`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5e34c5435e557d0bf666bd7311211405.html#a5e34c5435e557d0bf666bd7311211405) instead.\n\n### :sparkles: New features\n\nWith all this breaking and deprecation out of the way, let's talk about features!\n\n- We improved the **diagnostic information for syntax errors** (#301). Now, an exception [`json::parse_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1efc2468e6022be6e35fc2944cabe4d.html#af1efc2468e6022be6e35fc2944cabe4d) is thrown which contains a detailed message on the error, but also a member `byte` to indicate the byte offset in the input where the error occurred.\n- We added a **non-throwing syntax check** (#458): The new `accept` function returns a Boolean indicating whether the input is proper JSON. We also added a Boolean parameter `allow_exceptions` to the existing [`parse`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_aa9676414f2e36383c4b181fe856aa3c0.html#aa9676414f2e36383c4b181fe856aa3c0) functions to return a `discarded` value in case a syntax error occurs instead of throwing an exception.\n- An [`update`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a1cfa9ae5e7c2434cab4cfe69bffffe11.html#a1cfa9ae5e7c2434cab4cfe69bffffe11) function was added to **merge two JSON objects** (#428). In case you are wondering: the name was inspired by [Python](https://docs.python.org/2/library/stdtypes.html#dict.update).\n- The [`insert`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a1b0a4e60d56f1fe80501ed941e122892.html#a1b0a4e60d56f1fe80501ed941e122892) function now also supports an iterator range to add elements to an object.\n- The binary exchange formats **CBOR and MessagePack can now be parsed from input streams and written to output streams** (#477).\n- Input streams are now only read until the end of a JSON value instead of the end of the input (#367).\n- The serialization function [`dump`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a5adea76fedba9898d404fef8598aa663.html#a5adea76fedba9898d404fef8598aa663) now has two optional parameters `ensure_ascii` to **escape all non-ASCII characters** with `\\uxxxx` and an `indent_char` parameter to choose whether to **indent with spaces or tabs** (#654). \n- Added **built-in type support** for C arrays (#502), `std::pair` and `std::tuple` (#563, #614), `enum` and `enum class` (#545), `std::vector<bool>` (#494). Fixed support for `std::valarray` (#702), `std::array` (#553), and `std::map<std::string, std::string>` (#600, #607).\n\n### :hammer: Further changes\n\nFurthermore, there have been a lot of changes under the hood:\n\n- Replaced the [re2c](http://re2c.org) generated scanner by a self-coded version which allows for a better modularization of the parser and better diagnostics. To test the new scanner, we added millions (8,860,608 to be exact) of unit tests to check all valid and invalid byte sequences of the Unicode standard.\n- Google's OSS-Fuzz is still constantly fuzz-testing the library and found several issues that were fixed in this release (#497, #504, #514, #516, #518, #519, #575).\n- We now also ignore UTF-8 byte order marks when parsing from an iterator range (#602).\n- Values can be now moved from initializer lists (#663).\n- Updated to [Catch](https://github.com/catchorg/Catch2) 1.9.7. Unfortunately, Catch2 currently has some performance issues.\n- The non-exceptional paths of the library are now annotated with `__builtin_expect` to optimize branch prediction as long as no error occurs.\n- MSVC now produces a stack trace in MSVC if a `from_json` or `to_json` function was not found for a user-defined type. We also added a debug visualizer [`nlohmann_json.natvis`](https://github.com/nlohmann/json/blob/develop/nlohmann_json.natvis) for better debugging in MSVC (#844).\n- Overworked the documentation and added even more examples.\n- The build workflow now relies on CMake and CTest. Special flags can be chosen with CMake, including coverage (`JSON_Coverage`), compilation without exceptions (`JSON_NoExceptions`), LLVM sanitizers (`JSON_Sanitizer`), or execution with Valgrind (`JSON_Valgrind`).\n- Added support for package managers Meson (#576), Conan (#566), Hunter (#671, #829), and vcpkg (#753).\n- Added CI builders: Xcode 8.3, 9.0, 9.1, and 9.2; GCC 7.2; Clang 3.8, 3.9, 4.0, and 5.0; Visual Studio 2017. The library is further built with C++17 settings on the latest Clang, GCC, and MSVC version to quickly detect new issues.\n\n### Moving from 2.x.x to 3.0.0\n\n#### User-defined Exceptions\n\nThere are five different exceptions inheriting from [`json::exception`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a9a0aced019cb1d65bb49703406c84970.html#a9a0aced019cb1d65bb49703406c84970):\n\n- [`json::parse_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af1efc2468e6022be6e35fc2944cabe4d.html#af1efc2468e6022be6e35fc2944cabe4d) for syntax errors (including the binary formats),\n- [`json::invalid_iterator`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_ac13d32f7cbd02d616e71d8dc30dadcbf.html#ac13d32f7cbd02d616e71d8dc30dadcbf) for errors related to iterators,\n- [`json::type_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a4010e8e268fefd86da773c10318f2902.html#a4010e8e268fefd86da773c10318f2902) for errors where functions were called with the wrong JSON type,\n- [`json::out_of_range`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a28f7c2f087274a0012eb7a2333ee1580.html#a28f7c2f087274a0012eb7a2333ee1580) for range errors, and\n- [`json::other_error`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a3333a5a8714912adda33a35b369f7b3d.html#a3333a5a8714912adda33a35b369f7b3d) for miscellaneous errors.\n\nTo support these exception, the `try`/`catch` blocks of your code need to be adjusted:\n\n| new exception | previous exception |\n|:--|:--|\n| parse_error.101 | invalid_argument |\n| parse_error.102 | invalid_argument |\n| parse_error.103 | invalid_argument |\n| parse_error.104 | invalid_argument |\n| parse_error.105 | invalid_argument |\n| parse_error.106 | domain_error |\n| parse_error.107 | domain_error |\n| parse_error.108 | domain_error |\n| parse_error.109 | invalid_argument |\n| parse_error.110 | out_of_range |\n| parse_error.111 | invalid_argument |\n| parse_error.112 | invalid_argument |\n| invalid_iterator.201 | domain_error |\n| invalid_iterator.202 | domain_error |\n| invalid_iterator.203 | domain_error |\n| invalid_iterator.204 | out_of_range |\n| invalid_iterator.205 | out_of_range |\n| invalid_iterator.206 | domain_error |\n| invalid_iterator.207 | domain_error |\n| invalid_iterator.208 | domain_error |\n| invalid_iterator.209 | domain_error |\n| invalid_iterator.210 | domain_error |\n| invalid_iterator.211 | domain_error |\n| invalid_iterator.212 | domain_error |\n| invalid_iterator.213 | domain_error |\n| invalid_iterator.214 | out_of_range |\n| type_error.301 | domain_error |\n| type_error.302 | domain_error |\n| type_error.303 | domain_error |\n| type_error.304 | domain_error |\n| type_error.305 | domain_error |\n| type_error.306 | domain_error |\n| type_error.307 | domain_error |\n| type_error.308 | domain_error |\n| type_error.309 | domain_error |\n| type_error.310 | domain_error |\n| type_error.311 | domain_error |\n| type_error.313 | domain_error |\n| type_error.314 | domain_error |\n| type_error.315 | domain_error |\n| out_of_range.401 | out_of_range |\n| out_of_range.402 | out_of_range |\n| out_of_range.403 | out_of_range |\n| out_of_range.404 | out_of_range |\n| out_of_range.405 | domain_error |\n| other_error.501 | domain_error |\n\n#### Handling of NaN and INF\n\n- If an overflow occurs during parsing a number from a JSON text, an exception [`json::out_of_range`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a28f7c2f087274a0012eb7a2333ee1580.html#a28f7c2f087274a0012eb7a2333ee1580) is thrown so that the overflow is detected early and roundtripping is guaranteed.\n\n- NaN and INF floating-point values can be stored in a JSON value and are not replaced by null. That is, the basic_json class behaves like `double` in this regard (no exception occurs). However, NaN and INF are serialized to `null`.\n\n#### Removal of deprecated functions\n\nFunction `explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)` should be replaced by the `parse` function: Let `ss` be a stream and `cb` be a parse callback function.\n\nOld code:\n\n```cpp\njson j(ss, cb);\n```\n\nNew code:\n\n```cpp\njson j = json::parse(ss, cb);\n```\n\nIf no callback function is used, also the following code works:\n\n```cpp\njson j;\nj << ss;\n```\n\nor\n\n```cpp\njson j;\nss >> j;\n```\n\n## v2.1.1\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.1.1/json.hpp) (437 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.1.1/json.hpp.asc) (1 KB)\n\nRelease date: 2017-02-25\nSHA-256: faa2321beb1aa7416d035e7417fcfa59692ac3d8c202728f9bcc302e2d558f57\n\n### Summary\n\nThis release **fixes a locale-related bug in the parser**. To do so, the whole number handling (lexer, parser, and also the serialization) have been overworked. Furthermore, a lot of small changes added up that were added to this release. All changes are backward-compatible.\n\n### Changes\n- :bug: Locales that have a different character than `.` as decimal separator (e.g., the Norwegian locale `nb_NO.UTF-8`) led to truncated number parsing or parse errors. The library now has been fixed to work with **any locale**. Note that `.` is still the only valid decimal separator for JSON input.\n- :bug: Numbers like `1.0` were correctly parsed as floating-point number, but serialized as integer (`1`). Now, **floating-point numbers correctly round trip**.\n- :bug: Parsing incorrect JSON numbers with leading 0 (`0123`) could yield a [buffer overflow](https://github.com/nlohmann/json/issues/452). This is fixed now by detecting such errors directly by the lexer.\n- :bug: Constructing a JSON value from a pointer was incorrectly interpreted as a Boolean; such code will now yield a compiler error.\n- :bug: Comparing a JSON number with `0` led to a comparison with `null`. This is fixed now.\n- :bug: All throw calls are now wrapped in macros.\n- :lock: Starting during the preparation of this release (since 8 February 2017), commits and released files are **cryptographically signed** with [this GPG key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69). Previous releases have also been signed.\n- :sparkles: The parser for MessagePack and CBOR now supports an optional start index parameter to define a byte offset for the parser.\n- :rotating_light: Some more warnings have been fixed. With Clang, the code compiles **without warnings** with `-Weverything` (well, it needs `-Wno-documentation-unknown-command` and `-Wno-deprecated-declarations`, but you get the point).\n- :hammer: The code can be compiled easier with many Android NDKs by avoiding macros like `UINT8_MAX` which previously required defining a preprocessor macro for compilation.\n- :zap: The unit tests now compile two times faster.\n- :heavy_plus_sign: [Cotire](https://github.com/sakra/cotire) is used to speed up the build.\n- :pencil2: Fixed a lot of typos in the documentation.\n- :memo: Added a section to the README file that lists all used [third-party code/tools](https://github.com/nlohmann/json#used-third-party-tools).\n- :memo: Added a note on constructing a string value vs. parsing.\n- :white_check_mark: The test suite now contains 11202597 unit tests.\n- :memo: Improved the [Doxygen documentation](https://nlohmann.github.io/json/) by shortening the template parameters of class `basic_json`.\n- :construction_worker: Removed Doozer.\n- :construction_worker: Added Codacity.\n- :arrow_up: Upgraded Catch to version 1.7.2.\n\n\n## v2.1.0\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.1.0/json.hpp) (426 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.1.0/json.hpp.asc) (1 KB)\n\n- Release date: 2017-01-28\n- SHA-256: a571dee92515b685784fd527e38405cf3f5e13e96edbfe3f03d6df2e363a767b\n\n### Summary\n\nThis release introduces a means to convert from/to user-defined types. The release is backwards compatible.\n\n![conversion](https://cloud.githubusercontent.com/assets/159488/22399173/aebe8f7a-e597-11e6-930f-7494ee615827.png)\n\n### Changes\n- :sparkles: The library now offers an elegant way to **convert from and to arbitrary value types**. All you need to do is to implement two functions: `to_json` and `from_json`. Then, a conversion is as simple as putting a `=` between variables. See the [README](https://github.com/nlohmann/json#arbitrary-types-conversions) for more information and examples.\n- :sparkles: **Exceptions can now be switched off.** This can be done by defining the preprocessor symbol `JSON_NOEXCEPTION` or by passing `-fno-exceptions` to your compiler. In case the code would usually thrown an exception, `abort()` is now called.\n- :sparkles: **Information on the library** can be queried with the new (static) function `meta()` which returns a JSON object with information on the version, compiler, and platform. See the [documentation]() for an example.\n- :bug: A bug in the CBOR parser was fixed which led to a buffer overflow.\n- :sparkles: The function [`type_name()`]() is now public. It allows to query the type of a JSON value as string.\n- :white_check_mark: Added the [Big List of Naughty Strings](https://github.com/minimaxir/big-list-of-naughty-strings) as test case.\n- :arrow_up: Updated to [Catch v1.6.0](https://github.com/philsquared/Catch/releases/tag/v1.6.0).\n- :memo: Some typos in the documentation have been fixed.\n\n\n## v2.0.10\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.10/json.hpp) (409 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.10/json.hpp.asc) (1 KB)\n\n- Release date: 2017-01-02\n- SHA-256: ec27d4e74e9ce0f78066389a70724afd07f10761009322dc020656704ad5296d\n\n### Summary\n\nThis release fixes several security-relevant bugs in the MessagePack and CBOR parsers. The fixes are backwards compatible.\n\n### Changes\n- :bug: Fixed a lot of **bugs in the CBOR and MesssagePack parsers**. These bugs occurred if invalid input was parsed and then could lead in buffer overflows. These bugs were found with Google's [OSS-Fuzz](https://github.com/google/oss-fuzz), see #405, #407, #408, #409, #411, and #412 for more information.\n- :construction_worker: We now also use the **[Doozer](https://doozer.io) continuous integration platform**.\n- :construction_worker: The complete test suite is now also run with **Clang's address sanitizer and undefined-behavior sanitizer**.\n- :white_check_mark: Overworked **fuzz testing**; CBOR and MessagePack implementations are now fuzz-tested. Furthermore, all fuzz tests now include a round trip which ensures created output can again be properly parsed and yields the same JSON value.\n- :memo: Clarified documentation of `find()` function to always return `end()` when called on non-object value types.\n- :hammer: Moved thirdparty test code to `test/thirdparty` directory.\n\n## v2.0.9\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.9/json.hpp) (406 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.9/json.hpp.asc) (1 KB)\n\n- Release date: 2016-12-16\n- SHA-256: fbf3396f13e187d6c214c297bddc742d918ea9b55e10bfb3d9f458b9bfdc22e5\n\n### Summary\n\nThis release implements with **[CBOR](http://cbor.io)** and **[MessagePack](http://msgpack.org)** two **binary serialization/deserialization formats**. It further contains some small fixes and improvements. The fixes are backwards compatible.\n\n![cbor](https://cloud.githubusercontent.com/assets/159488/22399181/d4d60d32-e597-11e6-8dcb-825abcf9ac2a.png)\n\n### Changes\n- :sparkles: The library can now read and write the binary formats **[CBOR](http://cbor.io)** (Concise Binary Object Representation) and **[MessagePack](http://msgpack.org)**. Both formats are aimed to produce a very compact representation of JSON which can be parsed very efficiently. See the  [README file](https://github.com/nlohmann/json#binary-formats-cbor-and-messagepack) for more information and examples.\n- :fire: simplified the iteration implementation allowing to remove dozens of lines of code\n- :bug: fixed an [integer overflow error](https://github.com/nlohmann/json/issues/389) detected by [Google's OSS-Fuzz](https://github.com/google/oss-fuzz)\n- :bug: suppressed documentation warnings inside the library to facilitate compilation with `-Wdocumentation`\n- :bug: fixed an overflow detection error in the number parser\n- :memo: updated [contribution guidelines](https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md) to a list of frequentely asked features that will most likely be never added to the library\n- :memo:  added a **table of contents** to the [README file](https://github.com/nlohmann/json/blob/develop/README.md) to add some structure\n- :memo: mentioned the many [examples](https://github.com/nlohmann/json/tree/develop/doc/examples) and the [documentation](https://nlohmann.github.io/json/) in the [README file]()\n- :hammer: split [unit tests](https://github.com/nlohmann/json/tree/develop/test/src) into individual independent binaries to speed up compilation and testing\n- :white_check_mark: the test suite now contains **11201886** tests\n\n## v2.0.8\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.8/json.hpp) (360 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.8/json.hpp.asc) (1 KB)\n\n- Release date: 2016-12-02\n- SHA-256: b70db0ad34f8e0e61dc3f0cbab88099336c9674c193d8a3439d93d6aca2d7120\n\n### Summary\n\nThis release combines a lot of small fixes and improvements. The fixes are backwards compatible.\n\n### Changes\n- :bug: fixed a bug that froze the parser if a passed file was not found (now, `std::invalid_argument` is thrown)\n- :bug: fixed a bug that lead to an error of a file at EOF was parsed again (now, `std::invalid_argument` is thrown)\n- :sparkles: the well known functions [`emplace`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_a602f275f0359ab181221384989810604.html#a602f275f0359ab181221384989810604) and [`emplace_back`](http://nlohmann.github.io/json/doxygen/classnlohmann_1_1basic__json_af8a435033327d9237da414afc1cce513.html#af8a435033327d9237da414afc1cce513) have been added to JSON values and work as expected\n- :zap: improved the performance of the serialization (`dump` function)\n- :zap: improved the performance of the deserialization (parser)\n- :construction_worker: some continuous integration images at [Travis](https://travis-ci.org/nlohmann/json) were added and retired; see [here](https://github.com/nlohmann/json#supported-compilers) for the current continuous integration setup\n- :construction_worker: the [Coverity scan](https://scan.coverity.com/projects/nlohmann-json) works again\n- :chart_with_upwards_trend: the benchmarking code has been improved to produce more stable results\n- :memo: the [README](https://github.com/nlohmann/json/blob/develop/README.md) file has been extended and includes more frequently asked examples\n- :white_check_mark: the test suite now contains 8905518 tests\n- :arrow_up: updated [Catch](https://github.com/philsquared/Catch) to version 1.5.8\n\n## v2.0.7\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.7/json.hpp) (355 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.7/json.hpp.asc) (1 KB)\n\n- Release date: 2016-11-02\n- SHA-256: 5545c323670f8165bae90b9dc6078825e86ec310d96cc4e5b47233ea43715bbf\n\n### Summary\n\nThis release fixes a few bugs in the JSON parser found in the [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.html) article. The fixes are backwards compatible.\n\n### Changes\n- The article [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.html) discusses a lot of pitfalls of the JSON specification. When investigating the published test cases, a few bugs in the library were found and fixed:\n  - Files with less than 5 bytes can now be parsed without error.\n  - The library now properly rejects any file encoding other than UTF-8. Furthermore, incorrect surrogate pairs are properly detected and rejected.\n  - The library now accepts all but one \"yes\" test (y_string_utf16.json): UTF-16 is not supported.\n  - The library rejects all but one \"no\" test (n_number_then_00.json): Null bytes are treated as end of file instead of an error. This allows to parse input from null-terminated strings.\n- The string length passed to a user-defined string literal is now exploited to choose a more efficient constructor.\n- A few grammar mistakes in the README file have been fixed.\n\n## v2.0.6\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.6/json.hpp) (349 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.6/json.hpp.asc) (1 KB)\n\n- Release date: 2016-10-15\n- SHA256: 459cc93d5e2f503e50c6d5876eb86bfea7daf405f5a567c5a2c9abc2383756ae\n\n### Summary\n\nThis release fixes the semantics of `operator[]` for JSON Pointers (see below). This fix is backwards compatible.\n\n### Changes\n- **`operator[]` for JSON Pointers** now behaves like the other versions of `operator[]` and transforms `null` values into objects or arrays if required. This allows to created nested structures like `j[\"/foo/bar/2\"] = 17` (yielding `{\"foo\": \"bar\": [null, null, 17]}`) without problems.\n- overworked a helper SFINAE function\n- fixed some documentation issues\n- fixed the CMake files to allow to run the test suite outside the main project directory\n- restored test coverage to 100%.\n\n## v2.0.5\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.5/json.hpp) (347 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.5/json.hpp.asc) (1 KB)\n\n- Release date: 2016-09-14\n- SHA-256: 8b7565263a44e2b7d3b89808bc73d2d639037ff0c1f379e3d56dbd77e00b98d9\n\n### Summary\n\nThis release fixes a regression bug in the stream parser (function `parse()` and the `<<`/`>>` operators). This fix is backwards compatible.\n\n### Changes\n- **Bug fix**: The end of a file stream was not detected properly which led to parse errors. This bug should have been fixed with 2.0.4, but there was still a flaw in the code.\n\n## v2.0.4\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.4/json.hpp) (347 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.4/json.hpp.asc) (1 KB)\n\n- Release date: 2016-09-11\n- SHA-256: 632ceec4c25c4e2153f71470d3a2b992c8355f6d8b4d627d05dd16095cd3aeda\n\n### Summary\n\nThis release fixes a bug in the stream parser (function `parse()` and the `<<`/`>>` operators). This fix is backwards compatible.\n\n### Changes\n- **Bug fix**: The end of a file stream was not detected properly which led to parse errors.\n- Fixed a compiler warning about an unused variable.\n\n## v2.0.3\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.3/json.hpp) (347 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.3/json.hpp.asc) (1 KB)\n\n- Release date: 2016-08-31\n- SHA-256: 535b73efe5546fde9e763c14aeadfc7b58183c0b3cd43c29741025aba6cf6bd3\n\n### Summary\n\nThis release combines a lot of small fixes and improvements. The release is backwards compatible.\n\n### Changes\n- The **parser/deserialization functions have been generalized** to process any contiguous sequence of 1-byte elements (e.g., `char`, `unsigned char`, `uint8_t`). This includes all kind of string representations (string literals, char arrays, `std::string`, `const char*`), contiguous containers (C-style arrays, `std::vector`, `std::array`, `std::valarray`, `std::initializer_list`). User-defined containers providing random-access iterator access via `std::begin` and `std::end` can be used as well. See the documentation ([1](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_ace63ac4eb1dd7251a259d32e397461a3.html#ace63ac4eb1dd7251a259d32e397461a3), [2](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a90f05d55d9d0702c075cd281fd0d85ae.html#a90f05d55d9d0702c075cd281fd0d85ae), [3](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aeffd70f622f8f2a51fd3d95af64b63a7.html#aeffd70f622f8f2a51fd3d95af64b63a7), [4](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa8dca2e91a6301c36890f844e64f0023.html#aa8dca2e91a6301c36890f844e64f0023)) for more information. Note that contiguous storage cannot be checked at compile time; if any of the parse functions are called with a noncompliant container, the behavior is undefined and will most likely yield segmentation violation. The preconditions are enforced by an assertion unless the library is compiled with preprocessor symbol `NDEBUG`.\n- As a general remark on **assertions**: The library uses assertions to preclude undefined behavior. A [prominent example](https://github.com/nlohmann/json/issues/289) for this is the `operator[]` for const JSON objects. The behavior of this const version of the operator is undefined if the given key does not exist in the JSON object, because unlike the non-const version, it cannot add a `null` value at the given key. Assertions can be switched of by defining the preprocessor symbol `NDEBUG`. See the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert) for more information.\n- In the course of cleaning up the parser/deserialization functions, the constructor [`basic_json(std::istream&, const parser_callback_t)`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a32350263eb105764844c5a85e156a255.html#a32350263eb105764844c5a85e156a255) has been **deprecated** and will be deleted with the next major release 3.0.0 to unify the interface of the library. Deserialization will be done by stream operators or by calling one of the `parse` functions. That is, calls like `json j(i);` for an input stream `i` need to be replaced by `json j = json::parse(i);`. Compilers will produce a deprecation warning if client code uses this function.\n- Minor improvements:\n  - Improved the performance of the serialization by avoiding the re-creation of a locale object.\n  - Fixed two MSVC warnings. Compiling the test suite with `/Wall` now only warns about non-inlined functions (C4710) and the deprecation of the constructor from input-stream (C4996).\n- Some project internals:\n  - <img align=\"right\" src=\"https://bestpractices.coreinfrastructure.org/assets/questions_page_badge-17b338c0e8528d695d8676e23f39f17ca2b89bb88176370803ee69aeebcb5be4.png\"> The project has qualified for the [Core Infrastructure Initiative Best Practices Badge](https://bestpractices.coreinfrastructure.org/projects/289). While most requirements where already satisfied, some led to a more explicit documentation of quality-ensuring procedures. For instance, static analysis is now executed with every commit on the build server. Furthermore, the [contribution guidelines document](https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md) how to communicate security issues privately.\n  - The test suite has been overworked and split into several files to allow for faster compilation and analysis. The execute the test suite, simply execute `make check`.\n  - The continuous integration with [Travis](https://travis-ci.org/nlohmann/json) was extended with Clang versions 3.6.0 to 3.8.1 and now includes 18 different compiler/OS combinations.\n  - An 11-day run of [American fuzzy lop](http://lcamtuf.coredump.cx/afl/) checked 962 million inputs on the parser and found no issue.\n\n## v2.0.2\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.2/json.hpp) (338 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.2/json.hpp.asc) (1 KB)\n\n- Release date: 2016-07-31\n- SHA-256: 8e97b7965b4594b00998d6704465412360e1a0ed927badb51ded8b82291a8f3d\n\n### Summary\n\nThis release combines a lot of small fixes and improvements. The release is backwards compatible.\n\n### Changes\n- The **parser** has been overworked, and a lot of small issues have been fixed:\n  - Improved parser performance by avoiding recursion and using move semantics for the return value.\n  - Unescaped control characters `\\x10`-`\\x1f` are not accepted any more.\n  - Fixed a bug in the parser when reading from an input stream.\n  - Improved test case coverage for UTF-8 parsing: now, all valid Unicode code points are tested both escaped and unescaped.\n  - The precision of output streams is now preserved by the parser.\n- Started to check the **code correctness** by proving termination of important loops. Furthermore, individual assertions have been replaced by a more systematic function which checks the class invariants. Note that assertions should be switched off in production by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert).\n- A lot of **code cleanup**: removed unused headers, fixed some compiler warnings, and fixed a build error for Windows-based Clang builds.\n- Added some compile-time checks:\n  - Unsupported compilers are rejected during compilation with an `#error` command.\n  - Static assertion prohibits code with incompatible pointer types used in `get_ptr()`.\n- Improved the [documentation](https://nlohmann.github.io/json/), and adjusted the documentation script to choose the correct version of `sed`.\n- Replaced a lot of \"raw loops\" by STL functions like `std::all_of`, `std::for_each`, or `std::accumulate`. This facilitates reasoning about termination of loops and sometimes allowed to simplify functions to a single return statement.\n- Implemented a `value()` function for JSON pointers (similar to `at` function).\n- The Homebrew formula (see [Integration](https://github.com/nlohmann/json#integration)) is now tested for all Xcode builds (6.1 - 8.x) with Travis.\n- Avoided output to `std::cout` in the test cases.\n\n## v2.0.1\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.1/json.hpp) (321 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.1/json.hpp.asc) (1 KB)\n\n- Release date: 2016-06-28\n- SHA-256: ef550fcd7df572555bf068e9ec4e9d3b9e4cdd441cecb0dcea9ea7fd313f72dd\n\n### Summary\n\nThis release fixes a performance regression in the JSON serialization (function `dump()`). This fix is backwards compatible.\n\n### Changes\n- The locale of the output stream (or the internal string stream if a JSON value is serialized to a string) is now adjusted once for the whole serialization instead of for each floating-point number.\n- The locale of an output stream is now correctly reset to the previous value by the JSON library.\n\n\n## v2.0.0\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v2.0.0/json.hpp) (321 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v2.0.0/json.hpp.asc) (1 KB)\n\n- Release date: 2016-06-24\n- SHA-256: ac9e1fb25c2ac9ca5fc501fcd2fe3281fe04f07018a1b48820e7b1b11491bb6c\n\n### Summary\n\nThis release adds several features such as JSON Pointers, JSON Patch, or support for 64 bit unsigned integers. Furthermore, several (subtle) bugs have been fixed.\n\nAs `noexcept` and `constexpr` specifier have been added to several functions, the public API has effectively been changed in a (potential) non-backwards compatible manner. As we adhere to [Semantic Versioning](http://semver.org), this calls for a new major version, so say hello to 2️⃣.0️⃣.0️⃣.\n\n### Changes\n- 🔟 A JSON value now uses `uint64_t` (default value for template parameter `NumberUnsignedType`) as data type for **unsigned integer** values. This type is used automatically when an unsigned number is parsed. Furthermore, constructors, conversion operators and an `is_number_unsigned()` test have been added.\n-  👉 **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) support: A JSON Pointer is a string (similar to an XPath expression) to address a value inside a structured JSON value. JSON Pointers can be used in `at()` and `operator[]` functions. Furthermore, JSON values can be “flattened” to key/value pairs using `flatten()` where each key is a JSON Pointer. The original value can be restored by “unflattening” the flattened value using `unflatten()`.\n- 🏥 **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) support. A JSON Patch is a JSON value that describes the required edit operations (add, change, remove, …) to transform a JSON value into another one. A JSON Patch can be created with function `diff(const basic_json&)` and applied with `patch(const basic_json&)`. Note the created patches use a rather primitive algorithm so far and leave room for improvement.\n- 🇪🇺 The code is now **locale-independent**: Floating-point numbers are always serialized with a period (`.`) as decimal separator and ignores different settings from the locale.\n- 🍺 **Homebrew** support: Install the library with `brew tap nlohmann/json && brew install nlohmann_json`.\n- Added constructor to create a JSON value by parsing a `std::istream` (e.g., `std::stringstream` or `std::ifstream`).\n- Added **`noexcept`** specifier to `basic_json(boolean_t)`, `basic_json(const number_integer_t)`, `basic_json(const int)`, `basic_json(const number_float_t)`, iterator functions (`begin()`, `end()`, etc.)\n- When parsing numbers, the sign of `0.0` (vs. `-0.0`) is preserved.\n- Improved MSVC 2015, Android, and MinGW support. See [README](https://github.com/nlohmann/json#supported-compilers) for more information.\n- Improved test coverage (added 2,225,386 tests).\n- Removed some misuses of `std::move`.\n- Fixed several compiler warnings.\n- Improved error messages from JSON parser.\n- Updated to [`re2c`](http://re2c.org) to version 0.16 to use a minimal DFAs for the lexer.\n- Updated test suite to use [Catch](https://github.com/philsquared/Catch) version 1.5.6.\n- Made type getters (`is_number`, etc.) and const value access `constexpr`.\n- Functions `push_back` and `operator+=` now work with key/value pairs passed as initializer list, e.g. `j_object += {\"key\", 1}`.\n- Overworked `CMakeLists.txt` to make it easier to integrate the library into other projects.\n\n### Notes\n- Parser error messages are still very vague and contain no information on the error location.\n- The implemented `diff` function is rather primitive and does not create minimal diffs.\n- The name of function `iteration_wrapper` may change in the future and the function will be deprecated in the next release.\n- Roundtripping (i.e., parsing a JSON value from a string, serializing it, and comparing the strings) of floating-point numbers is not 100% accurate. Note that [RFC 8259](https://tools.ietf.org/html/rfc8259) defines no format to internally represent numbers and states not requirement for roundtripping. Nevertheless, benchmarks like [Native JSON Benchmark](https://github.com/miloyip/nativejson-benchmark) treat roundtripping deviations as conformance errors.\n\n\n## v1.1.0\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v1.1.0/json.hpp) (257 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v1.1.0/json.hpp.asc) (1 KB)\n\n- Release date: 2016-01-24\n- SHA-256: c0cf0e3017798ca6bb18e757ebc570d21a3bdac877845e2b9e9573d183ed2f05\n\n### Summary\n\nThis release fixes several small bugs and adds functionality in a backwards-compatible manner. Compared to the [last version (1.0.0)](https://github.com/nlohmann/json/releases/tag/v1.0.0), the following changes have been made:\n\n### Changes\n- _Fixed_: **Floating-point numbers** are now serialized and deserialized properly such that rountripping works in more cases. [#185, #186, #190, #191, #194]\n- _Added_: The code now contains **assertions** to detect undefined behavior during development. As the standard function `assert` is used, the assertions can be switched off by defining the preprocessor symbol `NDEBUG` during compilation. [#168]\n- _Added_: It is now possible to get a **reference** to the stored values via the newly added function `get_ref()`. [#128, #184]\n- _Fixed_: Access to object values via keys (**`operator[]`**) now works with all kind of string representations. [#171, #189]\n- _Fixed_: The code now compiles again with **Microsoft Visual Studio 2015**. [#144, #167, #188]\n- _Fixed_: All required headers are now included.\n- _Fixed_: Typos and other small issues. [#162, #166,  #175, #177, #179, #180]\n\n### Notes\n\nThere are still known open issues (#178, #187) which will be fixed in version 2.0.0. However, these fixes will require a small API change and will not be entirely backwards-compatible.\n\n\n## v1.0.0\n\n!!! summary \"Files\"\n\n    - [json.hpp](https://github.com/nlohmann/json/releases/download/v1.0.0/json.hpp) (243 KB)\n    - [json.hpp.asc](https://github.com/nlohmann/json/releases/download/v1.0.0/json.hpp.asc) (1 KB)\n\n- Release date: 2015-12-28\n- SHA-256: 767dc2fab1819d7b9e19b6e456d61e38d21ef7182606ecf01516e3f5230446de\n\n### Summary\n\nThis is the first official release. Compared to the [prerelease version 1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1), only a few minor improvements have been made:\n\n### Changes\n- _Changed_: A **UTF-8 byte order mark** is silently ignored.\n- _Changed_: `sprintf` is no longer used.\n- _Changed_: `iterator_wrapper` also works for const objects; note: the name may change!\n- _Changed_: **Error messages** during deserialization have been improved.\n- _Added_: The `parse` function now also works with type `std::istream&&`.\n- _Added_: Function `value(key, default_value)` returns either a copy of an object's element at the specified key or a given default value if no element with the key exists.\n- _Added_: Public functions are tagged with the version they were introduced. This shall allow for better **versioning** in the future.\n- _Added_: All public functions and types are **documented** (see http://nlohmann.github.io/json/doxygen/) including executable examples.\n- _Added_: Allocation of all types (in particular arrays, strings, and objects) is now exception-safe.\n- _Added_: They descriptions of thrown exceptions have been overworked and are part of the tests suite and documentation.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/home/sponsors.md",
    "content": "# Sponsors\n\nYou can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann).\n\n## Named Sponsors\n\n- [Michael Hartmann](https://github.com/reFX-Mike)\n- [Stefan Hagen](https://github.com/sthagen)\n- [Steve Sperandeo](https://github.com/homer6)\n- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe)\n- [Steve Wagner](https://github.com/ciroque)\n\nThanks everyone!\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/index.md",
    "content": "# JSON for Modern C++\n\n![](images/json.gif)\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/cmake.md",
    "content": "# CMake\n\n## Integration\n\nYou can also use the `nlohmann_json::nlohmann_json` interface target in CMake.  This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.\n\n### External\n\nTo use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:\n\n```cmake\n# CMakeLists.txt\nfind_package(nlohmann_json 3.2.0 REQUIRED)\n...\nadd_library(foo ...)\n...\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n\nThe package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.\n\n### Embedded\n\nTo embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:\n\n```cmake\n# If you only include this third party in PRIVATE source files, you do not\n# need to install it when your main project gets installed.\n# set(JSON_Install OFF CACHE INTERNAL \"\")\n\n# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it\n# unintended consequences that will break the build.  It's generally\n# discouraged (although not necessarily well documented as such) to use\n# include(...) for pulling in other CMake projects anyways.\nadd_subdirectory(nlohmann_json)\n...\nadd_library(foo ...)\n...\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n\n### Embedded (FetchContent)\n\nSince CMake v3.11,\n[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can\nbe used to automatically download the repository as a dependency at configure type.\n\nExample:\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(json\n  GIT_REPOSITORY https://github.com/nlohmann/json\n  GIT_TAG v3.7.3)\n\nFetchContent_GetProperties(json)\nif(NOT json_POPULATED)\n  FetchContent_Populate(json)\n  add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)\nendif()\n\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n\n!!! Note\n\tThe repository <https://github.com/nlohmann/json> download size is quite large.\n\tYou might want to depend on a smaller repository. For instance, you might want to replace the URL above by\n\t<https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent>.\n\n### Supporting Both\n\nTo allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:\n\n``` cmake\n# Top level CMakeLists.txt\nproject(FOO)\n...\noption(FOO_USE_EXTERNAL_JSON \"Use an external JSON library\" OFF)\n...\nadd_subdirectory(thirdparty)\n...\nadd_library(foo ...)\n...\n# Note that the namespaced target will always be available regardless of the\n# import method\ntarget_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)\n```\n```cmake\n# thirdparty/CMakeLists.txt\n...\nif(FOO_USE_EXTERNAL_JSON)\n  find_package(nlohmann_json 3.2.0 REQUIRED)\nelse()\n  set(JSON_BuildTests OFF CACHE INTERNAL \"\")\n  add_subdirectory(nlohmann_json)\nendif()\n...\n```\n\n`thirdparty/nlohmann_json` is then a complete copy of this source tree.\n\n## CMake Options\n\n### `JSON_BuildTests`\n\nBuild the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.\n\n### `JSON_CI`\n\nEnable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default.\n\n### `JSON_Diagnostics`\n\nEnable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../features/macros.md#json_diagnostics). This option is `OFF` by default.\n\n### `JSON_FastTests`\n\nSkip expensive/slow test suites. This option is `OFF` by default. Depends on `JSON_BuildTests`.\n\n### `JSON_ImplicitConversions`\n\nEnable implicit conversions by defining macro [`JSON_USE_IMPLICIT_CONVERSIONS`](../features/macros.md#json_use_implicit_conversions). This option is `ON` by default.\n\n### `JSON_Install`\n\nInstall CMake targets during install step. This option is `ON` by default if the library's CMake project is the top project.\n\n### `JSON_MultipleHeaders`\n\nUse non-amalgamated version of the library. This option is `OFF` by default.\n\n### `JSON_SystemInclude`\n\nTreat the library headers like system headers (i.e., adding `SYSTEM` to the [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html) call) to checks for this library by tools like Clang-Tidy. This option is `OFF` by default.\n\n### `JSON_Valgrind`\n\nExecute test suite with [Valgrind](https://valgrind.org). This option is `OFF` by default. Depends on `JSON_BuildTests`.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/conan/CMakeLists.txt",
    "content": "project(json_example)\ncmake_minimum_required(VERSION 2.8.12)\nadd_definitions(\"-std=c++11\")\n\ninclude(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)\nconan_basic_setup()\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example ${CONAN_LIBS})\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/conan/Conanfile.txt",
    "content": "[requires]\nnlohmann_json/3.7.3\n\n[generators]\ncmake\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/conan/example.cpp",
    "content": "#include <nlohmann/json.hpp>\n#include <iostream>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << json::meta() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/example.cpp",
    "content": "#include <nlohmann/json.hpp>\n#include <iostream>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << json::meta() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/index.md",
    "content": "# Header only\n\n[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add\n\n```cpp\n#include <nlohmann/json.hpp>\n\n// for convenience\nusing json = nlohmann::json;\n```\n\nto the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).\n\nYou can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of `json_fwd.hpp` (as part of CMake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/package_managers.md",
    "content": "# Package Managers\n\nThroughout this page, we will describe how to compile the example file `example.cpp` below.\n\n```cpp\n--8<-- \"integration/example.cpp\"\n```\n\n## Homebrew\n\nIf you are using OS X and [Homebrew](http://brew.sh), just type\n\n```sh\nbrew install nlohmann-json\n```\n\nand you're set. If you want the bleeding edge rather than the latest release, use\n\n```sh\nbrew install nlohmann-json --HEAD\n```\n\ninstead. See [nlohmann-json](https://formulae.brew.sh/formula/nlohmann-json) for more information.\n\n??? example\n\n\t1. Create the following file:\n\n\t\t=== \"example.cpp\"\n\n\t\t\t```cpp\n\t\t\t--8<-- \"integration/example.cpp\"\n\t\t\t```\n\n\t2. Install the package\n\n\t\t```sh\n\t\tbrew install nlohmann-json\n\t\t```\n\n\t3. Determine the include path, which defaults to `/usr/local/Cellar/nlohmann-json/$version/include`, where `$version` is the version of the library, e.g. `3.7.3`. The path of the library can be determined with\n\n\t\t```sh\n\t\tbrew list nlohmann-json\n\t\t```\n\n\t4. Compile the code. For instance, the code can be compiled using Clang with\n\n\t\t```sh\n\t\tclang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std=c++11 -o example\n\t\t```\n\n## Meson\n\nIf you are using the [Meson Build System](http://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging.\n\nThe provided `meson.build` can also be used as an alternative to cmake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, simply have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly.\n\n## Conan\n\nIf you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `nlohmann_json/x.y.z` to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/conan-io/conan-center-index/issues) if you experience problems with the packages.\n\n??? example\n\n\t1. Create the following files:\n\n\t\t=== \"Conanfile.txt\"\n\t\t\t\n\t\t\t```ini\n\t\t\t--8<-- \"integration/conan/Conanfile.txt\"\n\t\t\t```\n\n\t\t=== \"CMakeLists.txt\"\n\n\t\t    ```cmake\n\t\t\t--8<-- \"integration/conan/CMakeLists.txt\"\n\t\t    ```\n\n\t\t=== \"example.cpp\"\n\n\t\t\t```cpp\n\t\t\t--8<-- \"integration/conan/example.cpp\"\n\t\t\t```\n\n\n\t2. Build:\n\n\t\t```sh\n\t\tmkdir build\n\t\tcd build\n\t\tconan install ..\n\t\tcmake ..\n\t\tcmake --build .\n\t\t```\n\n## Spack\n\nIf you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.\n\n## Hunter\n\nIf you are using [hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging.\n\n## Buckaroo\n\nIf you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example).\n\n## vcpkg\n\nIf you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can install the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) with `vcpkg install nlohmann-json` and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging.\n\n??? example\n\n\t1. Create the following files:\n\n\t\t=== \"CMakeLists.txt\"\n\n\t\t    ```cmake\n\t\t\t--8<-- \"integration/vcpkg/CMakeLists.txt\"\n\t\t    ```\n\n\t\t=== \"example.cpp\"\n\n\t\t\t```cpp\n\t\t\t--8<-- \"integration/vcpkg/example.cpp\"\n\t\t\t```\n\n    2. Install package:\n\n        ```sh\n        vcpkg install nlohmann-json\n        ```\n\n\t3. Build:\n\n\t\t```sh\n\t\tmkdir build\n\t\tcd build\n\t\tcmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake\n\t\tcmake --build .\n\t\t```\n\n    Note you need to adjust `/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake` to your system.\n\n## cget\n\nIf you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).\n\n## CocoaPods\n\nIf you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `\"nlohmann_json\", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).\n\n## NuGet\n\nIf you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please file issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).\n\n## Conda\n\nIf you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues).\n\n## MSYS2\n\nIf you are using [MSYS2](http://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages.\n\n## MacPorts\n\nIf you are using [MacPorts](https://ports.macports.org), execute `sudo port install nlohmann-json` to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package.\n\n## build2\n\nIf you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository http://cppget.org or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml).\nPlease file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages.\n\n## wsjcpp\n\nIf you are using [`wsjcpp`](http://wsjcpp.org), you can use the command `wsjcpp install \"https://github.com/nlohmann/json:develop\"` to get the latest version. Note you can change the branch \":develop\" to an existing tag or another branch.\n\n## CPM.cmake\n\nIf you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake:\n\n```cmake\nCPMAddPackage(\n    NAME nlohmann_json\n    GITHUB_REPOSITORY nlohmann/json\n    VERSION 3.9.1)\n```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/pkg-config.md",
    "content": "# Pkg-config\n\nIf you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed:\n\n```sh\npkg-config nlohmann_json --cflags\n```\n\nUsers of the [Meson build system](package_managers.md#meson) will also be able to use a system-wide library, which will be found by `pkg-config`:\n\n```meson\njson = dependency('nlohmann_json', required: true)\n```\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/vcpkg/CMakeLists.txt",
    "content": "project(json_example)\ncmake_minimum_required(VERSION 2.8.12)\n\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/docs/integration/vcpkg/example.cpp",
    "content": "#include <nlohmann/json.hpp>\n#include <iostream>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::cout << json::meta() << std::endl;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/mkdocs.yml",
    "content": "# Project information\nsite_name: JSON for Modern C++\nsite_author: Niels Lohmann\nsite_url: https://json.nlohmann.me/\n\n# Repository\nrepo_name: nlohmann/json\nrepo_url: https://github.com/nlohmann/json\nedit_uri: edit/develop/doc/mkdocs/docs\n\n# Copyright\ncopyright: Copyright &copy; 2013 - 2022 Niels Lohmann\n\n# Configuration\ntheme:\n  name: material\n  language: en\n  palette:\n    primary: indigo\n    accent: indigo\n  font:\n    text: Roboto\n    code: JetBrains Mono\n  features:\n    - navigation.instant\n    - navigation.tracking\n    - navigation.tabs\n    - navigation.indexes\n    - navigation.top\n\nnav:\n  - Home:\n    - index.md\n    - home/license.md\n    - \"Code of Conduct\": home/code_of_conduct.md\n    - \"FAQ\": home/faq.md\n    - home/exceptions.md\n    - home/releases.md\n    - home/design_goals.md\n    - home/sponsors.md\n  - Features:\n    - features/arbitrary_types.md\n    - Binary Formats:\n      - features/binary_formats/index.md\n      - features/binary_formats/bson.md\n      - features/binary_formats/cbor.md\n      - features/binary_formats/messagepack.md\n      - features/binary_formats/ubjson.md\n    - features/binary_values.md\n    - features/comments.md\n    - Element Access:\n      - features/element_access/index.md\n      - features/element_access/unchecked_access.md\n      - features/element_access/checked_access.md\n      - features/element_access/default_value.md\n    - features/iterators.md\n    - features/json_pointer.md\n    - features/json_patch.md\n    - features/merge_patch.md\n    - features/object_order.md\n    - Parsing:\n        - features/parsing/index.md\n        - features/parsing/parse_exceptions.md\n        - features/parsing/parser_callbacks.md\n        - features/parsing/sax_interface.md\n    - features/enum_conversion.md\n    - features/macros.md\n    - Types:\n        - features/types/index.md\n        - features/types/number_handling.md\n  - Integration:\n    - integration/index.md\n    - integration/cmake.md\n    - integration/package_managers.md\n    - integration/pkg-config.md\n  - API Documentation:\n      - basic_json:\n        - 'Overview': api/basic_json/index.md\n        - '(Constructor)': api/basic_json/basic_json.md\n        - '(Destructor)': api/basic_json/~basic_json.md\n        - 'accept': api/basic_json/accept.md\n        - 'array': api/basic_json/array.md\n        - 'array_t': api/basic_json/array_t.md\n        - 'at': api/basic_json/at.md\n        - 'back': api/basic_json/back.md\n        - 'begin': api/basic_json/begin.md\n        - 'binary': api/basic_json/binary.md\n        - 'binary_t': api/basic_json/binary_t.md\n        - 'boolean_t': api/basic_json/boolean_t.md\n        - 'cbegin': api/basic_json/cbegin.md\n        - 'cbor_tag_handler_t': api/basic_json/cbor_tag_handler_t.md\n        - 'cend': api/basic_json/cend.md\n        - 'clear': api/basic_json/clear.md\n        - 'contains': api/basic_json/contains.md\n        - 'count': api/basic_json/count.md\n        - 'crbegin': api/basic_json/crbegin.md\n        - 'crend': api/basic_json/crend.md\n        - 'diff': api/basic_json/diff.md\n        - 'dump': api/basic_json/dump.md\n        - 'emplace': api/basic_json/emplace.md\n        - 'emplace_back': api/basic_json/emplace_back.md\n        - 'empty': api/basic_json/empty.md\n        - 'end': api/basic_json/end.md\n        - 'erase': api/basic_json/erase.md\n        - 'error_handler_t': api/basic_json/error_handler_t.md\n        - 'exception': api/basic_json/exception.md\n        - 'find': api/basic_json/find.md\n        - 'flatten': api/basic_json/flatten.md\n        - 'from_bson': api/basic_json/from_bson.md\n        - 'from_cbor': api/basic_json/from_cbor.md\n        - 'from_msgpack': api/basic_json/from_msgpack.md\n        - 'from_ubjson': api/basic_json/from_ubjson.md\n        - 'front': api/basic_json/front.md\n        - 'get': api/basic_json/get.md\n        - 'get_allocator': api/basic_json/get_allocator.md\n        - 'get_binary': api/basic_json/get_binary.md\n        - 'get_ptr': api/basic_json/get_ptr.md\n        - 'get_ref': api/basic_json/get_ref.md\n        - 'get_to': api/basic_json/get_to.md\n        - 'std::hash&lt;basic_json&gt;': api/basic_json/std_hash.md\n        - 'input_format_t': api/basic_json/input_format_t.md\n        - 'insert': api/basic_json/insert.md\n        - 'invalid_iterator': api/basic_json/invalid_iterator.md\n        - 'is_array': api/basic_json/is_array.md\n        - 'is_binary': api/basic_json/is_binary.md\n        - 'is_boolean': api/basic_json/is_boolean.md\n        - 'is_discarded': api/basic_json/is_discarded.md\n        - 'is_null': api/basic_json/is_null.md\n        - 'is_number': api/basic_json/is_number.md\n        - 'is_number_float': api/basic_json/is_number_float.md\n        - 'is_number_integer': api/basic_json/is_number_integer.md\n        - 'is_number_unsigned': api/basic_json/is_number_unsigned.md\n        - 'is_object': api/basic_json/is_object.md\n        - 'is_primitive': api/basic_json/is_primitive.md\n        - 'is_string': api/basic_json/is_string.md\n        - 'is_structured': api/basic_json/is_structured.md\n        - 'items': api/basic_json/items.md\n        - 'json_serializer': api/basic_json/json_serializer.md\n        - 'max_size': api/basic_json/max_size.md\n        - 'meta': api/basic_json/meta.md\n        - 'merge_patch': api/basic_json/merge_patch.md\n        - 'number_float_t': api/basic_json/number_float_t.md\n        - 'number_integer_t': api/basic_json/number_integer_t.md\n        - 'number_unsigned_t': api/basic_json/number_unsigned_t.md\n        - 'object': api/basic_json/object.md\n        - 'object_comparator_t': api/basic_json/object_comparator_t.md\n        - 'object_t': api/basic_json/object_t.md\n        - 'operator ValueType': api/basic_json/operator_ValueType.md\n        - 'operator value_t': api/basic_json/operator_value_t.md\n        - 'operator[]': api/basic_json/operator[].md\n        - 'operator=': api/basic_json/operator=.md\n        - 'operator==': api/basic_json/operator_eq.md\n        - 'operator!=': api/basic_json/operator_ne.md\n        - 'operator<': api/basic_json/operator_lt.md\n        - 'operator<<': api/basic_json/operator_ltlt.md\n        - 'operator<=': api/basic_json/operator_le.md\n        - 'operator>': api/basic_json/operator_gt.md\n        - 'operator>>': api/basic_json/operator_gtgt.md\n        - 'operator>=': api/basic_json/operator_ge.md\n        - 'operator+=': api/basic_json/operator+=.md\n        - 'operator\"\"_json': api/basic_json/operator_literal_json.md\n        - 'operator\"\"_json_pointer': api/basic_json/operator_literal_json_pointer.md\n        - 'out_of_range': api/basic_json/out_of_range.md\n        - 'other_error': api/basic_json/other_error.md\n        - 'parse': api/basic_json/parse.md\n        - 'parse_error': api/basic_json/parse_error.md\n        - 'parse_event_t': api/basic_json/parse_event_t.md\n        - 'parser_callback_t': api/basic_json/parser_callback_t.md\n        - 'patch': api/basic_json/patch.md\n        - 'push_back': api/basic_json/push_back.md\n        - 'rbegin': api/basic_json/rbegin.md\n        - 'rend': api/basic_json/rend.md\n        - 'sax_parse': api/basic_json/sax_parse.md\n        - 'size': api/basic_json/size.md\n        - 'string_t': api/basic_json/string_t.md\n        - 'swap': api/basic_json/swap.md\n        - 'std::swap&lt;basic_json&gt;': api/basic_json/std_swap.md\n        - 'to_bson': api/basic_json/to_bson.md\n        - 'to_cbor': api/basic_json/to_cbor.md\n        - 'to_msgpack': api/basic_json/to_msgpack.md\n        - 'to_string': api/basic_json/to_string.md\n        - 'to_ubjson': api/basic_json/to_ubjson.md\n        - 'type': api/basic_json/type.md\n        - 'type_error': api/basic_json/type_error.md\n        - 'type_name': api/basic_json/type_name.md\n        - 'unflatten': api/basic_json/unflatten.md\n        - 'update': api/basic_json/update.md\n        - 'value': api/basic_json/value.md\n        - 'value_t': api/basic_json/value_t.md\n      - byte_container_with_subtype:\n        - 'Overview': api/byte_container_with_subtype/index.md\n        - '(constructor)': api/byte_container_with_subtype/byte_container_with_subtype.md\n        - 'clear_subtype': api/byte_container_with_subtype/clear_subtype.md\n        - 'has_subtype': api/byte_container_with_subtype/has_subtype.md\n        - 'set_subtype': api/byte_container_with_subtype/set_subtype.md\n        - 'subtype': api/byte_container_with_subtype/subtype.md\n      - adl_serializer:\n        - 'Overview': api/adl_serializer/index.md\n        - 'from_json': api/adl_serializer/from_json.md\n        - 'to_json': api/adl_serializer/to_json.md\n      - 'json': api/json.md\n      - json_pointer:\n        - 'Overview': api/json_pointer/index.md\n        - '(Constructor)': api/json_pointer/json_pointer.md\n        - 'back': api/json_pointer/back.md\n        - 'empty': api/json_pointer/empty.md\n        - 'operator std::string': api/json_pointer/operator_string.md\n        - 'operator/': api/json_pointer/operator_slash.md\n        - 'operator/=': api/json_pointer/operator_slasheq.md\n        - 'parent_pointer': api/json_pointer/parent_pointer.md\n        - 'pop_back': api/json_pointer/pop_back.md\n        - 'push_back': api/json_pointer/push_back.md\n        - 'to_string': api/json_pointer/to_string.md\n      - json_sax:\n        - 'Overview': api/json_sax/index.md\n        - 'binary': api/json_sax/binary.md\n        - 'boolean': api/json_sax/boolean.md\n        - 'end_array': api/json_sax/end_array.md\n        - 'end_object': api/json_sax/end_object.md\n        - 'key': api/json_sax/key.md\n        - 'null': api/json_sax/null.md\n        - 'number_float': api/json_sax/number_float.md\n        - 'number_integer': api/json_sax/number_integer.md\n        - 'number_unsigned': api/json_sax/number_unsigned.md\n        - 'parse_error': api/json_sax/parse_error.md\n        - 'start_array': api/json_sax/start_array.md\n        - 'start_object': api/json_sax/start_object.md\n        - 'string': api/json_sax/string.md\n      - 'ordered_json': api/ordered_json.md\n      - 'ordered_map': api/ordered_map.md\n      - macros:\n        - 'Overview': api/macros/index.md\n        - 'JSON_ASSERT(x)': api/macros/json_assert.md\n\n# Extras\nextra:\n  social:\n    - icon: fontawesome/brands/github\n      link: https://github.com/nlohmann\n    - icon: fontawesome/brands/twitter\n      link: https://twitter.com/nlohmann\n    - icon: fontawesome/brands/linkedin\n      link: https://www.linkedin.com/in/nielslohmann/\n    - icon: fontawesome/brands/xing\n      link: https://www.xing.com/profile/Niels_Lohmann\n    - icon: fontawesome/brands/paypal\n      link: https://www.paypal.me/nlohmann\n  generator: false\n\n# Extensions\nmarkdown_extensions:\n  - abbr\n  - admonition\n  - attr_list\n  - def_list\n  - codehilite:\n      guess_lang: false\n  - toc:\n      permalink: true\n  - pymdownx.arithmatex\n  - pymdownx.betterem:\n      smart_enable: all\n  - pymdownx.caret\n  - pymdownx.critic\n  - pymdownx.details\n  - pymdownx.emoji:\n      emoji_index: !!python/name:materialx.emoji.twemoji\n      emoji_generator: !!python/name:materialx.emoji.to_svg\n  - pymdownx.inlinehilite\n  - pymdownx.magiclink\n  - pymdownx.mark\n  #- pymdownx.smartsymbols\n  - pymdownx.superfences\n  - pymdownx.tasklist:\n      custom_checkbox: true\n  - pymdownx.tabbed\n  - pymdownx.tilde\n  - pymdownx.snippets:\n      base_path: docs\n      check_paths: true\n  - plantuml_markdown:\n      format: svg\n\nplugins:\n    - search:\n        separator: '[\\s\\-\\.]'\n        lang: en\n    - minify:\n        minify_html: true\n\nextra_javascript:\n  - https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/requirements.txt",
    "content": "click>=7.1.2\nfuture>=0.18.2\nhtmlmin>=0.1.12\nhttplib2>=0.18.1\nimportlib-metadata>=1.6.0\nJinja2>=2.11.2\njoblib>=0.15.1\njsmin>=2.2.2\nlivereload>=2.6.1\nlunr>=0.5.8\nMarkdown>=3.2.2\nmarkdown-include>=0.5.1\nMarkupSafe>=1.1.1\nmkdocs>=1.1.2\nmkdocs-material>=5.2.1\nmkdocs-material-extensions>=1.0\nmkdocs-minify-plugin>=0.3.0\nmkdocs-simple-hooks>=0.1.1\nnltk>=3.5\nplantuml>=0.3.0\nplantuml-markdown>=3.2.2\nPygments>=2.6.1\npymdown-extensions>=7.1\nPyYAML>=5.3.1\nregex>=2020.5.14\nsix>=1.15.0\ntornado>=6.0.4\ntqdm>=4.46.0\nzipp>=3.1.0\n"
  },
  {
    "path": "subprojects/nlohmann_json/doc/mkdocs/scripts/check_structure.py",
    "content": "#!/usr/bin/env python\n\nimport glob\nimport os.path\n\n\ndef check_structure():\n    expected_headers = [\n        'Template parameters',\n        'Specializations',\n        'Iterator invalidation',\n        'Requirements',\n        'Member types',\n        'Member functions',\n        'Member variables',\n        'Static functions',\n        'Non-member functions',\n        'Literals',\n        'Helper classes',\n        'Parameters',\n        'Return value',\n        'Exception safety',\n        'Exceptions',\n        'Complexity',\n        'Possible implementation',\n        'Notes',\n        'Examples',\n        'See also',\n        'Version history'\n    ]\n\n    required_headers = [\n        'Examples',\n        'Version history'\n    ]\n\n    files = sorted(glob.glob('api/**/*.md', recursive=True))\n    for file in files:\n        with open(file) as file_content:\n            header_idx = -1\n            existing_headers = []\n            in_initial_code_example = False\n            previous_line = None\n            h1sections = 0\n\n            for lineno, line in enumerate(file_content.readlines()):\n                line = line.strip()\n\n                if line.startswith('# '):\n                    h1sections += 1\n\n                # there should only be one top-level title\n                if h1sections > 1:\n                    print(f'{file}:{lineno+1}: Error: unexpected top-level title \"{line}\"!')\n                    h1sections = 1\n\n                # Overview pages should have a better title\n                if line == '# Overview':\n                    print(f'{file}:{lineno+1}: Error: overview pages should have a better title!')\n\n                # lines longer than 160 characters are bad (unless they are tables)\n                if len(line) > 160 and '|' not in line:\n                    print(f'{file}:{lineno+1}: Error: line is too long ({len(line)} vs. 160 chars)!')\n\n                # check if headers are correct\n                if line.startswith('## '):\n                    header = line.strip('## ')\n                    existing_headers.append(header)\n\n                    if header in expected_headers:\n                        idx = expected_headers.index(header)\n                        if idx <= header_idx:\n                            print(f'{file}:{lineno+1}: Error: header \"{header}\" is in an unexpected order (should be before \"{expected_headers[header_idx]}\")!')\n                        header_idx = idx\n                    else:\n                        print(f'{file}:{lineno+1}: Error: header \"{header}\" is not part of the expected headers!')\n\n                # code example\n                if line == '```cpp' and header_idx == -1:\n                    in_initial_code_example = True\n\n                if in_initial_code_example and line.startswith('//'):\n                    if any(map(str.isdigit, line)) and '(' not in line:\n                        print(f'{file}:{lineno+1}: Number should be in parentheses: {line}')\n\n                if line == '```' and in_initial_code_example:\n                    in_initial_code_example = False\n\n                # consecutive blank lines are bad\n                if line == '' and previous_line == '':\n                    print(f'{file}:{lineno}-{lineno+1}: Error: Consecutive blank lines!')\n\n                previous_line = line\n\n            for required_header in required_headers:\n                if required_header not in existing_headers:\n                    print(f'{file}:{lineno+1}: Error: required header \"{required_header}\" was not found!')\n\n\ndef check_examples():\n    example_files = sorted(glob.glob('../../examples/*.cpp'))\n    markdown_files = sorted(glob.glob('**/*.md', recursive=True))\n\n    # check if every example file is used in at least one markdown file\n    for example_file in example_files:\n        example_file = os.path.join('examples', os.path.basename(example_file))\n\n        found = False\n        for markdown_file in markdown_files:\n            content = ' '.join(open(markdown_file).readlines())\n            if example_file in content:\n                found = True\n                break\n\n        if not found:\n            print(f'{example_file}: Error: example file is not used in any documentation file!')\n\n\nif __name__ == '__main__':\n    check_structure()\n    check_examples()\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/adl_serializer.hpp",
    "content": "#pragma once\n\n#include <type_traits>\n#include <utility>\n\n#include <nlohmann/detail/conversions/from_json.hpp>\n#include <nlohmann/detail/conversions/to_json.hpp>\n#include <nlohmann/detail/meta/identity_tag.hpp>\n#include <nlohmann/detail/meta/type_traits.hpp>\n\nnamespace nlohmann\n{\n\n/// @sa https://json.nlohmann.me/api/adl_serializer/\ntemplate<typename ValueType, typename>\nstruct adl_serializer\n{\n    /// @brief convert a JSON value to any value type\n    /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/\n    template<typename BasicJsonType, typename TargetType = ValueType>\n    static auto from_json(BasicJsonType && j, TargetType& val) noexcept(\n        noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))\n    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())\n    {\n        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);\n    }\n\n    /// @brief convert a JSON value to any value type\n    /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/\n    template<typename BasicJsonType, typename TargetType = ValueType>\n    static auto from_json(BasicJsonType && j) noexcept(\n    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))\n    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))\n    {\n        return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});\n    }\n\n    /// @brief convert any value type to a JSON value\n    /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/\n    template<typename BasicJsonType, typename TargetType = ValueType>\n    static auto to_json(BasicJsonType& j, TargetType && val) noexcept(\n        noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))\n    -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())\n    {\n        ::nlohmann::to_json(j, std::forward<TargetType>(val));\n    }\n};\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/byte_container_with_subtype.hpp",
    "content": "#pragma once\n\n#include <cstdint> // uint8_t, uint64_t\n#include <tuple> // tie\n#include <utility> // move\n\nnamespace nlohmann\n{\n\n/// @brief an internal type for a backed binary type\n/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/\ntemplate<typename BinaryType>\nclass byte_container_with_subtype : public BinaryType\n{\n  public:\n    using container_type = BinaryType;\n    using subtype_type = std::uint64_t;\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype() noexcept(noexcept(container_type()))\n        : container_type()\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))\n        : container_type(b)\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))\n        : container_type(std::move(b))\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))\n        : container_type(b)\n        , m_subtype(subtype_)\n        , m_has_subtype(true)\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))\n        : container_type(std::move(b))\n        , m_subtype(subtype_)\n        , m_has_subtype(true)\n    {}\n\n    bool operator==(const byte_container_with_subtype& rhs) const\n    {\n        return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==\n               std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);\n    }\n\n    bool operator!=(const byte_container_with_subtype& rhs) const\n    {\n        return !(rhs == *this);\n    }\n\n    /// @brief sets the binary subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/\n    void set_subtype(subtype_type subtype_) noexcept\n    {\n        m_subtype = subtype_;\n        m_has_subtype = true;\n    }\n\n    /// @brief return the binary subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/\n    constexpr subtype_type subtype() const noexcept\n    {\n        return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);\n    }\n\n    /// @brief return whether the value has a subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/\n    constexpr bool has_subtype() const noexcept\n    {\n        return m_has_subtype;\n    }\n\n    /// @brief clears the binary subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/\n    void clear_subtype() noexcept\n    {\n        m_subtype = 0;\n        m_has_subtype = false;\n    }\n\n  private:\n    subtype_type m_subtype = 0;\n    bool m_has_subtype = false;\n};\n\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/conversions/from_json.hpp",
    "content": "#pragma once\n\n#include <algorithm> // transform\n#include <array> // array\n#include <forward_list> // forward_list\n#include <iterator> // inserter, front_inserter, end\n#include <map> // map\n#include <string> // string\n#include <tuple> // tuple, make_tuple\n#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible\n#include <unordered_map> // unordered_map\n#include <utility> // pair, declval\n#include <valarray> // valarray\n\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/meta/cpp_future.hpp>\n#include <nlohmann/detail/meta/identity_tag.hpp>\n#include <nlohmann/detail/meta/type_traits.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\n#if JSON_HAS_EXPERIMENTAL_FILESYSTEM\n#include <experimental/filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::experimental::filesystem;\n} // namespace nlohmann::detail\n#elif JSON_HAS_FILESYSTEM\n#include <filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::filesystem;\n} // namespace nlohmann::detail\n#endif\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename std::nullptr_t& n)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_null()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be null, but is \" + std::string(j.type_name()), j));\n    }\n    n = nullptr;\n}\n\n// overloads for basic_json template parameters\ntemplate < typename BasicJsonType, typename ArithmeticType,\n           enable_if_t < std::is_arithmetic<ArithmeticType>::value&&\n                         !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,\n                         int > = 0 >\nvoid get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)\n{\n    switch (static_cast<value_t>(j))\n    {\n        case value_t::number_unsigned:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());\n            break;\n        }\n        case value_t::number_integer:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());\n            break;\n        }\n        case value_t::number_float:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());\n            break;\n        }\n\n        case value_t::null:\n        case value_t::object:\n        case value_t::array:\n        case value_t::string:\n        case value_t::boolean:\n        case value_t::binary:\n        case value_t::discarded:\n        default:\n            JSON_THROW(type_error::create(302, \"type must be number, but is \" + std::string(j.type_name()), j));\n    }\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be boolean, but is \" + std::string(j.type_name()), j));\n    }\n    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be string, but is \" + std::string(j.type_name()), j));\n    }\n    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();\n}\n\ntemplate <\n    typename BasicJsonType, typename ConstructibleStringType,\n    enable_if_t <\n        is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&\n        !std::is_same<typename BasicJsonType::string_t,\n                      ConstructibleStringType>::value,\n        int > = 0 >\nvoid from_json(const BasicJsonType& j, ConstructibleStringType& s)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be string, but is \" + std::string(j.type_name()), j));\n    }\n\n    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)\n{\n    get_arithmetic_value(j, val);\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)\n{\n    get_arithmetic_value(j, val);\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)\n{\n    get_arithmetic_value(j, val);\n}\n\ntemplate<typename BasicJsonType, typename EnumType,\n         enable_if_t<std::is_enum<EnumType>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, EnumType& e)\n{\n    typename std::underlying_type<EnumType>::type val;\n    get_arithmetic_value(j, val);\n    e = static_cast<EnumType>(val);\n}\n\n// forward_list doesn't have an insert method\ntemplate<typename BasicJsonType, typename T, typename Allocator,\n         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    l.clear();\n    std::transform(j.rbegin(), j.rend(),\n                   std::front_inserter(l), [](const BasicJsonType & i)\n    {\n        return i.template get<T>();\n    });\n}\n\n// valarray doesn't have an insert method\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, std::valarray<T>& l)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    l.resize(j.size());\n    std::transform(j.begin(), j.end(), std::begin(l),\n                   [](const BasicJsonType & elem)\n    {\n        return elem.template get<T>();\n    });\n}\n\ntemplate<typename BasicJsonType, typename T, std::size_t N>\nauto from_json(const BasicJsonType& j, T (&arr)[N])  // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n-> decltype(j.template get<T>(), void())\n{\n    for (std::size_t i = 0; i < N; ++i)\n    {\n        arr[i] = j.at(i).template get<T>();\n    }\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)\n{\n    arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();\n}\n\ntemplate<typename BasicJsonType, typename T, std::size_t N>\nauto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,\n                          priority_tag<2> /*unused*/)\n-> decltype(j.template get<T>(), void())\n{\n    for (std::size_t i = 0; i < N; ++i)\n    {\n        arr[i] = j.at(i).template get<T>();\n    }\n}\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType,\n         enable_if_t<\n             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,\n             int> = 0>\nauto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)\n-> decltype(\n    arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),\n    j.template get<typename ConstructibleArrayType::value_type>(),\n    void())\n{\n    using std::end;\n\n    ConstructibleArrayType ret;\n    ret.reserve(j.size());\n    std::transform(j.begin(), j.end(),\n                   std::inserter(ret, end(ret)), [](const BasicJsonType & i)\n    {\n        // get<BasicJsonType>() returns *this, this won't call a from_json\n        // method when value_type is BasicJsonType\n        return i.template get<typename ConstructibleArrayType::value_type>();\n    });\n    arr = std::move(ret);\n}\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType,\n         enable_if_t<\n             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,\n             int> = 0>\nvoid from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,\n                          priority_tag<0> /*unused*/)\n{\n    using std::end;\n\n    ConstructibleArrayType ret;\n    std::transform(\n        j.begin(), j.end(), std::inserter(ret, end(ret)),\n        [](const BasicJsonType & i)\n    {\n        // get<BasicJsonType>() returns *this, this won't call a from_json\n        // method when value_type is BasicJsonType\n        return i.template get<typename ConstructibleArrayType::value_type>();\n    });\n    arr = std::move(ret);\n}\n\ntemplate < typename BasicJsonType, typename ConstructibleArrayType,\n           enable_if_t <\n               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&\n               !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&\n               !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&\n               !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&\n               !is_basic_json<ConstructibleArrayType>::value,\n               int > = 0 >\nauto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)\n-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),\nj.template get<typename ConstructibleArrayType::value_type>(),\nvoid())\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n\n    from_json_array_impl(j, arr, priority_tag<3> {});\n}\n\ntemplate < typename BasicJsonType, typename T, std::size_t... Idx >\nstd::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,\n        identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)\n{\n    return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };\n}\n\ntemplate < typename BasicJsonType, typename T, std::size_t N >\nauto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)\n-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n\n    return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be binary, but is \" + std::string(j.type_name()), j));\n    }\n\n    bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();\n}\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType,\n         enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, ConstructibleObjectType& obj)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_object()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be object, but is \" + std::string(j.type_name()), j));\n    }\n\n    ConstructibleObjectType ret;\n    const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();\n    using value_type = typename ConstructibleObjectType::value_type;\n    std::transform(\n        inner_object->begin(), inner_object->end(),\n        std::inserter(ret, ret.begin()),\n        [](typename BasicJsonType::object_t::value_type const & p)\n    {\n        return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());\n    });\n    obj = std::move(ret);\n}\n\n// overload for arithmetic types, not chosen for basic_json template arguments\n// (BooleanType, etc..); note: Is it really necessary to provide explicit\n// overloads for boolean_t etc. in case of a custom BooleanType which is not\n// an arithmetic type?\ntemplate < typename BasicJsonType, typename ArithmeticType,\n           enable_if_t <\n               std::is_arithmetic<ArithmeticType>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,\n               int > = 0 >\nvoid from_json(const BasicJsonType& j, ArithmeticType& val)\n{\n    switch (static_cast<value_t>(j))\n    {\n        case value_t::number_unsigned:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());\n            break;\n        }\n        case value_t::number_integer:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());\n            break;\n        }\n        case value_t::number_float:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());\n            break;\n        }\n        case value_t::boolean:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());\n            break;\n        }\n\n        case value_t::null:\n        case value_t::object:\n        case value_t::array:\n        case value_t::string:\n        case value_t::binary:\n        case value_t::discarded:\n        default:\n            JSON_THROW(type_error::create(302, \"type must be number, but is \" + std::string(j.type_name()), j));\n    }\n}\n\ntemplate<typename BasicJsonType, typename... Args, std::size_t... Idx>\nstd::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)\n{\n    return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);\n}\n\ntemplate < typename BasicJsonType, class A1, class A2 >\nstd::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)\n{\n    return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),\n            std::forward<BasicJsonType>(j).at(1).template get<A2>()};\n}\n\ntemplate<typename BasicJsonType, typename A1, typename A2>\nvoid from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)\n{\n    p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});\n}\n\ntemplate<typename BasicJsonType, typename... Args>\nstd::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)\n{\n    return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});\n}\n\ntemplate<typename BasicJsonType, typename... Args>\nvoid from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)\n{\n    t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});\n}\n\ntemplate<typename BasicJsonType, typename TupleRelated>\nauto from_json(BasicJsonType&& j, TupleRelated&& t)\n-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n\n    return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});\n}\n\ntemplate < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,\n           typename = enable_if_t < !std::is_constructible <\n                                        typename BasicJsonType::string_t, Key >::value >>\nvoid from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    m.clear();\n    for (const auto& p : j)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))\n        {\n            JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(p.type_name()), j));\n        }\n        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());\n    }\n}\n\ntemplate < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,\n           typename = enable_if_t < !std::is_constructible <\n                                        typename BasicJsonType::string_t, Key >::value >>\nvoid from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    m.clear();\n    for (const auto& p : j)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))\n        {\n            JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(p.type_name()), j));\n        }\n        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());\n    }\n}\n\n#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, std_fs::path& p)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be string, but is \" + std::string(j.type_name()), j));\n    }\n    p = *j.template get_ptr<const typename BasicJsonType::string_t*>();\n}\n#endif\n\nstruct from_json_fn\n{\n    template<typename BasicJsonType, typename T>\n    auto operator()(const BasicJsonType& j, T&& val) const\n    noexcept(noexcept(from_json(j, std::forward<T>(val))))\n    -> decltype(from_json(j, std::forward<T>(val)))\n    {\n        return from_json(j, std::forward<T>(val));\n    }\n};\n}  // namespace detail\n\n/// namespace to hold default `from_json` function\n/// to see why this is required:\n/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html\nnamespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)\n{\nconstexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)\n} // namespace\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/conversions/to_chars.hpp",
    "content": "#pragma once\n\n#include <array> // array\n#include <cmath>   // signbit, isfinite\n#include <cstdint> // intN_t, uintN_t\n#include <cstring> // memcpy, memmove\n#include <limits> // numeric_limits\n#include <type_traits> // conditional\n\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n/*!\n@brief implements the Grisu2 algorithm for binary to decimal floating-point\nconversion.\n\nThis implementation is a slightly modified version of the reference\nimplementation which may be obtained from\nhttp://florian.loitsch.com/publications (bench.tar.gz).\n\nThe code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.\n\nFor a detailed description of the algorithm see:\n\n[1] Loitsch, \"Printing Floating-Point Numbers Quickly and Accurately with\n    Integers\", Proceedings of the ACM SIGPLAN 2010 Conference on Programming\n    Language Design and Implementation, PLDI 2010\n[2] Burger, Dybvig, \"Printing Floating-Point Numbers Quickly and Accurately\",\n    Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language\n    Design and Implementation, PLDI 1996\n*/\nnamespace dtoa_impl\n{\n\ntemplate<typename Target, typename Source>\nTarget reinterpret_bits(const Source source)\n{\n    static_assert(sizeof(Target) == sizeof(Source), \"size mismatch\");\n\n    Target target;\n    std::memcpy(&target, &source, sizeof(Source));\n    return target;\n}\n\nstruct diyfp // f * 2^e\n{\n    static constexpr int kPrecision = 64; // = q\n\n    std::uint64_t f = 0;\n    int e = 0;\n\n    constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}\n\n    /*!\n    @brief returns x - y\n    @pre x.e == y.e and x.f >= y.f\n    */\n    static diyfp sub(const diyfp& x, const diyfp& y) noexcept\n    {\n        JSON_ASSERT(x.e == y.e);\n        JSON_ASSERT(x.f >= y.f);\n\n        return {x.f - y.f, x.e};\n    }\n\n    /*!\n    @brief returns x * y\n    @note The result is rounded. (Only the upper q bits are returned.)\n    */\n    static diyfp mul(const diyfp& x, const diyfp& y) noexcept\n    {\n        static_assert(kPrecision == 64, \"internal error\");\n\n        // Computes:\n        //  f = round((x.f * y.f) / 2^q)\n        //  e = x.e + y.e + q\n\n        // Emulate the 64-bit * 64-bit multiplication:\n        //\n        // p = u * v\n        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)\n        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )\n        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )\n        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )\n        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)\n        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )\n        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )\n        //\n        // (Since Q might be larger than 2^32 - 1)\n        //\n        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)\n        //\n        // (Q_hi + H does not overflow a 64-bit int)\n        //\n        //   = p_lo + 2^64 p_hi\n\n        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;\n        const std::uint64_t u_hi = x.f >> 32u;\n        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;\n        const std::uint64_t v_hi = y.f >> 32u;\n\n        const std::uint64_t p0 = u_lo * v_lo;\n        const std::uint64_t p1 = u_lo * v_hi;\n        const std::uint64_t p2 = u_hi * v_lo;\n        const std::uint64_t p3 = u_hi * v_hi;\n\n        const std::uint64_t p0_hi = p0 >> 32u;\n        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;\n        const std::uint64_t p1_hi = p1 >> 32u;\n        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;\n        const std::uint64_t p2_hi = p2 >> 32u;\n\n        std::uint64_t Q = p0_hi + p1_lo + p2_lo;\n\n        // The full product might now be computed as\n        //\n        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)\n        // p_lo = p0_lo + (Q << 32)\n        //\n        // But in this particular case here, the full p_lo is not required.\n        // Effectively we only need to add the highest bit in p_lo to p_hi (and\n        // Q_hi + 1 does not overflow).\n\n        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up\n\n        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);\n\n        return {h, x.e + y.e + 64};\n    }\n\n    /*!\n    @brief normalize x such that the significand is >= 2^(q-1)\n    @pre x.f != 0\n    */\n    static diyfp normalize(diyfp x) noexcept\n    {\n        JSON_ASSERT(x.f != 0);\n\n        while ((x.f >> 63u) == 0)\n        {\n            x.f <<= 1u;\n            x.e--;\n        }\n\n        return x;\n    }\n\n    /*!\n    @brief normalize x such that the result has the exponent E\n    @pre e >= x.e and the upper e - x.e bits of x.f must be zero.\n    */\n    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept\n    {\n        const int delta = x.e - target_exponent;\n\n        JSON_ASSERT(delta >= 0);\n        JSON_ASSERT(((x.f << delta) >> delta) == x.f);\n\n        return {x.f << delta, target_exponent};\n    }\n};\n\nstruct boundaries\n{\n    diyfp w;\n    diyfp minus;\n    diyfp plus;\n};\n\n/*!\nCompute the (normalized) diyfp representing the input number 'value' and its\nboundaries.\n\n@pre value must be finite and positive\n*/\ntemplate<typename FloatType>\nboundaries compute_boundaries(FloatType value)\n{\n    JSON_ASSERT(std::isfinite(value));\n    JSON_ASSERT(value > 0);\n\n    // Convert the IEEE representation into a diyfp.\n    //\n    // If v is denormal:\n    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))\n    // If v is normalized:\n    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))\n\n    static_assert(std::numeric_limits<FloatType>::is_iec559,\n                  \"internal error: dtoa_short requires an IEEE-754 floating-point implementation\");\n\n    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)\n    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);\n    constexpr int      kMinExp    = 1 - kBias;\n    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)\n\n    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;\n\n    const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));\n    const std::uint64_t E = bits >> (kPrecision - 1);\n    const std::uint64_t F = bits & (kHiddenBit - 1);\n\n    const bool is_denormal = E == 0;\n    const diyfp v = is_denormal\n                    ? diyfp(F, kMinExp)\n                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);\n\n    // Compute the boundaries m- and m+ of the floating-point value\n    // v = f * 2^e.\n    //\n    // Determine v- and v+, the floating-point predecessor and successor if v,\n    // respectively.\n    //\n    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)\n    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)\n    //\n    //      v+ = v + 2^e\n    //\n    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_\n    // between m- and m+ round to v, regardless of how the input rounding\n    // algorithm breaks ties.\n    //\n    //      ---+-------------+-------------+-------------+-------------+---  (A)\n    //         v-            m-            v             m+            v+\n    //\n    //      -----------------+------+------+-------------+-------------+---  (B)\n    //                       v-     m-     v             m+            v+\n\n    const bool lower_boundary_is_closer = F == 0 && E > 1;\n    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);\n    const diyfp m_minus = lower_boundary_is_closer\n                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)\n                          : diyfp(2 * v.f - 1, v.e - 1); // (A)\n\n    // Determine the normalized w+ = m+.\n    const diyfp w_plus = diyfp::normalize(m_plus);\n\n    // Determine w- = m- such that e_(w-) = e_(w+).\n    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);\n\n    return {diyfp::normalize(v), w_minus, w_plus};\n}\n\n// Given normalized diyfp w, Grisu needs to find a (normalized) cached\n// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies\n// within a certain range [alpha, gamma] (Definition 3.2 from [1])\n//\n//      alpha <= e = e_c + e_w + q <= gamma\n//\n// or\n//\n//      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q\n//                          <= f_c * f_w * 2^gamma\n//\n// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies\n//\n//      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma\n//\n// or\n//\n//      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)\n//\n// The choice of (alpha,gamma) determines the size of the table and the form of\n// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well\n// in practice:\n//\n// The idea is to cut the number c * w = f * 2^e into two parts, which can be\n// processed independently: An integral part p1, and a fractional part p2:\n//\n//      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e\n//              = (f div 2^-e) + (f mod 2^-e) * 2^e\n//              = p1 + p2 * 2^e\n//\n// The conversion of p1 into decimal form requires a series of divisions and\n// modulos by (a power of) 10. These operations are faster for 32-bit than for\n// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be\n// achieved by choosing\n//\n//      -e >= 32   or   e <= -32 := gamma\n//\n// In order to convert the fractional part\n//\n//      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...\n//\n// into decimal form, the fraction is repeatedly multiplied by 10 and the digits\n// d[-i] are extracted in order:\n//\n//      (10 * p2) div 2^-e = d[-1]\n//      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...\n//\n// The multiplication by 10 must not overflow. It is sufficient to choose\n//\n//      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.\n//\n// Since p2 = f mod 2^-e < 2^-e,\n//\n//      -e <= 60   or   e >= -60 := alpha\n\nconstexpr int kAlpha = -60;\nconstexpr int kGamma = -32;\n\nstruct cached_power // c = f * 2^e ~= 10^k\n{\n    std::uint64_t f;\n    int e;\n    int k;\n};\n\n/*!\nFor a normalized diyfp w = f * 2^e, this function returns a (normalized) cached\npower-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c\nsatisfies (Definition 3.2 from [1])\n\n     alpha <= e_c + e + q <= gamma.\n*/\ninline cached_power get_cached_power_for_binary_exponent(int e)\n{\n    // Now\n    //\n    //      alpha <= e_c + e + q <= gamma                                    (1)\n    //      ==> f_c * 2^alpha <= c * 2^e * 2^q\n    //\n    // and since the c's are normalized, 2^(q-1) <= f_c,\n    //\n    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)\n    //      ==> 2^(alpha - e - 1) <= c\n    //\n    // If c were an exact power of ten, i.e. c = 10^k, one may determine k as\n    //\n    //      k = ceil( log_10( 2^(alpha - e - 1) ) )\n    //        = ceil( (alpha - e - 1) * log_10(2) )\n    //\n    // From the paper:\n    // \"In theory the result of the procedure could be wrong since c is rounded,\n    //  and the computation itself is approximated [...]. In practice, however,\n    //  this simple function is sufficient.\"\n    //\n    // For IEEE double precision floating-point numbers converted into\n    // normalized diyfp's w = f * 2^e, with q = 64,\n    //\n    //      e >= -1022      (min IEEE exponent)\n    //           -52        (p - 1)\n    //           -52        (p - 1, possibly normalize denormal IEEE numbers)\n    //           -11        (normalize the diyfp)\n    //         = -1137\n    //\n    // and\n    //\n    //      e <= +1023      (max IEEE exponent)\n    //           -52        (p - 1)\n    //           -11        (normalize the diyfp)\n    //         = 960\n    //\n    // This binary exponent range [-1137,960] results in a decimal exponent\n    // range [-307,324]. One does not need to store a cached power for each\n    // k in this range. For each such k it suffices to find a cached power\n    // such that the exponent of the product lies in [alpha,gamma].\n    // This implies that the difference of the decimal exponents of adjacent\n    // table entries must be less than or equal to\n    //\n    //      floor( (gamma - alpha) * log_10(2) ) = 8.\n    //\n    // (A smaller distance gamma-alpha would require a larger table.)\n\n    // NB:\n    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.\n\n    constexpr int kCachedPowersMinDecExp = -300;\n    constexpr int kCachedPowersDecStep = 8;\n\n    static constexpr std::array<cached_power, 79> kCachedPowers =\n    {\n        {\n            { 0xAB70FE17C79AC6CA, -1060, -300 },\n            { 0xFF77B1FCBEBCDC4F, -1034, -292 },\n            { 0xBE5691EF416BD60C, -1007, -284 },\n            { 0x8DD01FAD907FFC3C,  -980, -276 },\n            { 0xD3515C2831559A83,  -954, -268 },\n            { 0x9D71AC8FADA6C9B5,  -927, -260 },\n            { 0xEA9C227723EE8BCB,  -901, -252 },\n            { 0xAECC49914078536D,  -874, -244 },\n            { 0x823C12795DB6CE57,  -847, -236 },\n            { 0xC21094364DFB5637,  -821, -228 },\n            { 0x9096EA6F3848984F,  -794, -220 },\n            { 0xD77485CB25823AC7,  -768, -212 },\n            { 0xA086CFCD97BF97F4,  -741, -204 },\n            { 0xEF340A98172AACE5,  -715, -196 },\n            { 0xB23867FB2A35B28E,  -688, -188 },\n            { 0x84C8D4DFD2C63F3B,  -661, -180 },\n            { 0xC5DD44271AD3CDBA,  -635, -172 },\n            { 0x936B9FCEBB25C996,  -608, -164 },\n            { 0xDBAC6C247D62A584,  -582, -156 },\n            { 0xA3AB66580D5FDAF6,  -555, -148 },\n            { 0xF3E2F893DEC3F126,  -529, -140 },\n            { 0xB5B5ADA8AAFF80B8,  -502, -132 },\n            { 0x87625F056C7C4A8B,  -475, -124 },\n            { 0xC9BCFF6034C13053,  -449, -116 },\n            { 0x964E858C91BA2655,  -422, -108 },\n            { 0xDFF9772470297EBD,  -396, -100 },\n            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },\n            { 0xF8A95FCF88747D94,  -343,  -84 },\n            { 0xB94470938FA89BCF,  -316,  -76 },\n            { 0x8A08F0F8BF0F156B,  -289,  -68 },\n            { 0xCDB02555653131B6,  -263,  -60 },\n            { 0x993FE2C6D07B7FAC,  -236,  -52 },\n            { 0xE45C10C42A2B3B06,  -210,  -44 },\n            { 0xAA242499697392D3,  -183,  -36 },\n            { 0xFD87B5F28300CA0E,  -157,  -28 },\n            { 0xBCE5086492111AEB,  -130,  -20 },\n            { 0x8CBCCC096F5088CC,  -103,  -12 },\n            { 0xD1B71758E219652C,   -77,   -4 },\n            { 0x9C40000000000000,   -50,    4 },\n            { 0xE8D4A51000000000,   -24,   12 },\n            { 0xAD78EBC5AC620000,     3,   20 },\n            { 0x813F3978F8940984,    30,   28 },\n            { 0xC097CE7BC90715B3,    56,   36 },\n            { 0x8F7E32CE7BEA5C70,    83,   44 },\n            { 0xD5D238A4ABE98068,   109,   52 },\n            { 0x9F4F2726179A2245,   136,   60 },\n            { 0xED63A231D4C4FB27,   162,   68 },\n            { 0xB0DE65388CC8ADA8,   189,   76 },\n            { 0x83C7088E1AAB65DB,   216,   84 },\n            { 0xC45D1DF942711D9A,   242,   92 },\n            { 0x924D692CA61BE758,   269,  100 },\n            { 0xDA01EE641A708DEA,   295,  108 },\n            { 0xA26DA3999AEF774A,   322,  116 },\n            { 0xF209787BB47D6B85,   348,  124 },\n            { 0xB454E4A179DD1877,   375,  132 },\n            { 0x865B86925B9BC5C2,   402,  140 },\n            { 0xC83553C5C8965D3D,   428,  148 },\n            { 0x952AB45CFA97A0B3,   455,  156 },\n            { 0xDE469FBD99A05FE3,   481,  164 },\n            { 0xA59BC234DB398C25,   508,  172 },\n            { 0xF6C69A72A3989F5C,   534,  180 },\n            { 0xB7DCBF5354E9BECE,   561,  188 },\n            { 0x88FCF317F22241E2,   588,  196 },\n            { 0xCC20CE9BD35C78A5,   614,  204 },\n            { 0x98165AF37B2153DF,   641,  212 },\n            { 0xE2A0B5DC971F303A,   667,  220 },\n            { 0xA8D9D1535CE3B396,   694,  228 },\n            { 0xFB9B7CD9A4A7443C,   720,  236 },\n            { 0xBB764C4CA7A44410,   747,  244 },\n            { 0x8BAB8EEFB6409C1A,   774,  252 },\n            { 0xD01FEF10A657842C,   800,  260 },\n            { 0x9B10A4E5E9913129,   827,  268 },\n            { 0xE7109BFBA19C0C9D,   853,  276 },\n            { 0xAC2820D9623BF429,   880,  284 },\n            { 0x80444B5E7AA7CF85,   907,  292 },\n            { 0xBF21E44003ACDD2D,   933,  300 },\n            { 0x8E679C2F5E44FF8F,   960,  308 },\n            { 0xD433179D9C8CB841,   986,  316 },\n            { 0x9E19DB92B4E31BA9,  1013,  324 },\n        }\n    };\n\n    // This computation gives exactly the same results for k as\n    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)\n    // for |e| <= 1500, but doesn't require floating-point operations.\n    // NB: log_10(2) ~= 78913 / 2^18\n    JSON_ASSERT(e >= -1500);\n    JSON_ASSERT(e <=  1500);\n    const int f = kAlpha - e - 1;\n    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);\n\n    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;\n    JSON_ASSERT(index >= 0);\n    JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());\n\n    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];\n    JSON_ASSERT(kAlpha <= cached.e + e + 64);\n    JSON_ASSERT(kGamma >= cached.e + e + 64);\n\n    return cached;\n}\n\n/*!\nFor n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.\nFor n == 0, returns 1 and sets pow10 := 1.\n*/\ninline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)\n{\n    // LCOV_EXCL_START\n    if (n >= 1000000000)\n    {\n        pow10 = 1000000000;\n        return 10;\n    }\n    // LCOV_EXCL_STOP\n    if (n >= 100000000)\n    {\n        pow10 = 100000000;\n        return  9;\n    }\n    if (n >= 10000000)\n    {\n        pow10 = 10000000;\n        return  8;\n    }\n    if (n >= 1000000)\n    {\n        pow10 = 1000000;\n        return  7;\n    }\n    if (n >= 100000)\n    {\n        pow10 = 100000;\n        return  6;\n    }\n    if (n >= 10000)\n    {\n        pow10 = 10000;\n        return  5;\n    }\n    if (n >= 1000)\n    {\n        pow10 = 1000;\n        return  4;\n    }\n    if (n >= 100)\n    {\n        pow10 = 100;\n        return  3;\n    }\n    if (n >= 10)\n    {\n        pow10 = 10;\n        return  2;\n    }\n\n    pow10 = 1;\n    return 1;\n}\n\ninline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,\n                         std::uint64_t rest, std::uint64_t ten_k)\n{\n    JSON_ASSERT(len >= 1);\n    JSON_ASSERT(dist <= delta);\n    JSON_ASSERT(rest <= delta);\n    JSON_ASSERT(ten_k > 0);\n\n    //               <--------------------------- delta ---->\n    //                                  <---- dist --------->\n    // --------------[------------------+-------------------]--------------\n    //               M-                 w                   M+\n    //\n    //                                  ten_k\n    //                                <------>\n    //                                       <---- rest ---->\n    // --------------[------------------+----+--------------]--------------\n    //                                  w    V\n    //                                       = buf * 10^k\n    //\n    // ten_k represents a unit-in-the-last-place in the decimal representation\n    // stored in buf.\n    // Decrement buf by ten_k while this takes buf closer to w.\n\n    // The tests are written in this order to avoid overflow in unsigned\n    // integer arithmetic.\n\n    while (rest < dist\n            && delta - rest >= ten_k\n            && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))\n    {\n        JSON_ASSERT(buf[len - 1] != '0');\n        buf[len - 1]--;\n        rest += ten_k;\n    }\n}\n\n/*!\nGenerates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.\nM- and M+ must be normalized and share the same exponent -60 <= e <= -32.\n*/\ninline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,\n                             diyfp M_minus, diyfp w, diyfp M_plus)\n{\n    static_assert(kAlpha >= -60, \"internal error\");\n    static_assert(kGamma <= -32, \"internal error\");\n\n    // Generates the digits (and the exponent) of a decimal floating-point\n    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's\n    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.\n    //\n    //               <--------------------------- delta ---->\n    //                                  <---- dist --------->\n    // --------------[------------------+-------------------]--------------\n    //               M-                 w                   M+\n    //\n    // Grisu2 generates the digits of M+ from left to right and stops as soon as\n    // V is in [M-,M+].\n\n    JSON_ASSERT(M_plus.e >= kAlpha);\n    JSON_ASSERT(M_plus.e <= kGamma);\n\n    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)\n    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)\n\n    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):\n    //\n    //      M+ = f * 2^e\n    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e\n    //         = ((p1        ) * 2^-e + (p2        )) * 2^e\n    //         = p1 + p2 * 2^e\n\n    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);\n\n    auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)\n    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e\n\n    // 1)\n    //\n    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]\n\n    JSON_ASSERT(p1 > 0);\n\n    std::uint32_t pow10{};\n    const int k = find_largest_pow10(p1, pow10);\n\n    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)\n    //\n    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))\n    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))\n    //\n    //      M+ = p1                                             + p2 * 2^e\n    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e\n    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e\n    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e\n    //\n    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)\n    //\n    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]\n    //\n    // but stop as soon as\n    //\n    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e\n\n    int n = k;\n    while (n > 0)\n    {\n        // Invariants:\n        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)\n        //      pow10 = 10^(n-1) <= p1 < 10^n\n        //\n        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)\n        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)\n        //\n        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e\n        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)\n        //\n        JSON_ASSERT(d <= 9);\n        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d\n        //\n        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)\n        //\n        p1 = r;\n        n--;\n        //\n        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)\n        //      pow10 = 10^n\n        //\n\n        // Now check if enough digits have been generated.\n        // Compute\n        //\n        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e\n        //\n        // Note:\n        // Since rest and delta share the same exponent e, it suffices to\n        // compare the significands.\n        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;\n        if (rest <= delta)\n        {\n            // V = buffer * 10^n, with M- <= V <= M+.\n\n            decimal_exponent += n;\n\n            // We may now just stop. But instead look if the buffer could be\n            // decremented to bring V closer to w.\n            //\n            // pow10 = 10^n is now 1 ulp in the decimal representation V.\n            // The rounding procedure works with diyfp's with an implicit\n            // exponent of e.\n            //\n            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e\n            //\n            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;\n            grisu2_round(buffer, length, dist, delta, rest, ten_n);\n\n            return;\n        }\n\n        pow10 /= 10;\n        //\n        //      pow10 = 10^(n-1) <= p1 < 10^n\n        // Invariants restored.\n    }\n\n    // 2)\n    //\n    // The digits of the integral part have been generated:\n    //\n    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e\n    //         = buffer            + p2 * 2^e\n    //\n    // Now generate the digits of the fractional part p2 * 2^e.\n    //\n    // Note:\n    // No decimal point is generated: the exponent is adjusted instead.\n    //\n    // p2 actually represents the fraction\n    //\n    //      p2 * 2^e\n    //          = p2 / 2^-e\n    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...\n    //\n    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)\n    //\n    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m\n    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)\n    //\n    // using\n    //\n    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)\n    //                = (                   d) * 2^-e + (                   r)\n    //\n    // or\n    //      10^m * p2 * 2^e = d + r * 2^e\n    //\n    // i.e.\n    //\n    //      M+ = buffer + p2 * 2^e\n    //         = buffer + 10^-m * (d + r * 2^e)\n    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e\n    //\n    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e\n\n    JSON_ASSERT(p2 > delta);\n\n    int m = 0;\n    for (;;)\n    {\n        // Invariant:\n        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e\n        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e\n        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e\n        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e\n        //\n        JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);\n        p2 *= 10;\n        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e\n        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e\n        //\n        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e\n        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))\n        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e\n        //\n        JSON_ASSERT(d <= 9);\n        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d\n        //\n        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e\n        //\n        p2 = r;\n        m++;\n        //\n        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e\n        // Invariant restored.\n\n        // Check if enough digits have been generated.\n        //\n        //      10^-m * p2 * 2^e <= delta * 2^e\n        //              p2 * 2^e <= 10^m * delta * 2^e\n        //                    p2 <= 10^m * delta\n        delta *= 10;\n        dist  *= 10;\n        if (p2 <= delta)\n        {\n            break;\n        }\n    }\n\n    // V = buffer * 10^-m, with M- <= V <= M+.\n\n    decimal_exponent -= m;\n\n    // 1 ulp in the decimal representation is now 10^-m.\n    // Since delta and dist are now scaled by 10^m, we need to do the\n    // same with ulp in order to keep the units in sync.\n    //\n    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e\n    //\n    const std::uint64_t ten_m = one.f;\n    grisu2_round(buffer, length, dist, delta, p2, ten_m);\n\n    // By construction this algorithm generates the shortest possible decimal\n    // number (Loitsch, Theorem 6.2) which rounds back to w.\n    // For an input number of precision p, at least\n    //\n    //      N = 1 + ceil(p * log_10(2))\n    //\n    // decimal digits are sufficient to identify all binary floating-point\n    // numbers (Matula, \"In-and-Out conversions\").\n    // This implies that the algorithm does not produce more than N decimal\n    // digits.\n    //\n    //      N = 17 for p = 53 (IEEE double precision)\n    //      N = 9  for p = 24 (IEEE single precision)\n}\n\n/*!\nv = buf * 10^decimal_exponent\nlen is the length of the buffer (number of decimal digits)\nThe buffer must be large enough, i.e. >= max_digits10.\n*/\nJSON_HEDLEY_NON_NULL(1)\ninline void grisu2(char* buf, int& len, int& decimal_exponent,\n                   diyfp m_minus, diyfp v, diyfp m_plus)\n{\n    JSON_ASSERT(m_plus.e == m_minus.e);\n    JSON_ASSERT(m_plus.e == v.e);\n\n    //  --------(-----------------------+-----------------------)--------    (A)\n    //          m-                      v                       m+\n    //\n    //  --------------------(-----------+-----------------------)--------    (B)\n    //                      m-          v                       m+\n    //\n    // First scale v (and m- and m+) such that the exponent is in the range\n    // [alpha, gamma].\n\n    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);\n\n    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k\n\n    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]\n    const diyfp w       = diyfp::mul(v,       c_minus_k);\n    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);\n    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);\n\n    //  ----(---+---)---------------(---+---)---------------(---+---)----\n    //          w-                      w                       w+\n    //          = c*m-                  = c*v                   = c*m+\n    //\n    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and\n    // w+ are now off by a small amount.\n    // In fact:\n    //\n    //      w - v * 10^k < 1 ulp\n    //\n    // To account for this inaccuracy, add resp. subtract 1 ulp.\n    //\n    //  --------+---[---------------(---+---)---------------]---+--------\n    //          w-  M-                  w                   M+  w+\n    //\n    // Now any number in [M-, M+] (bounds included) will round to w when input,\n    // regardless of how the input rounding algorithm breaks ties.\n    //\n    // And digit_gen generates the shortest possible such number in [M-, M+].\n    // Note that this does not mean that Grisu2 always generates the shortest\n    // possible number in the interval (m-, m+).\n    const diyfp M_minus(w_minus.f + 1, w_minus.e);\n    const diyfp M_plus (w_plus.f  - 1, w_plus.e );\n\n    decimal_exponent = -cached.k; // = -(-k) = k\n\n    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);\n}\n\n/*!\nv = buf * 10^decimal_exponent\nlen is the length of the buffer (number of decimal digits)\nThe buffer must be large enough, i.e. >= max_digits10.\n*/\ntemplate<typename FloatType>\nJSON_HEDLEY_NON_NULL(1)\nvoid grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)\n{\n    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,\n                  \"internal error: not enough precision\");\n\n    JSON_ASSERT(std::isfinite(value));\n    JSON_ASSERT(value > 0);\n\n    // If the neighbors (and boundaries) of 'value' are always computed for double-precision\n    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting\n    // decimal representations are not exactly \"short\".\n    //\n    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)\n    // says \"value is converted to a string as if by std::sprintf in the default (\"C\") locale\"\n    // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'\n    // does.\n    // On the other hand, the documentation for 'std::to_chars' requires that \"parsing the\n    // representation using the corresponding std::from_chars function recovers value exactly\". That\n    // indicates that single precision floating-point numbers should be recovered using\n    // 'std::strtof'.\n    //\n    // NB: If the neighbors are computed for single-precision numbers, there is a single float\n    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision\n    //     value is off by 1 ulp.\n#if 0\n    const boundaries w = compute_boundaries(static_cast<double>(value));\n#else\n    const boundaries w = compute_boundaries(value);\n#endif\n\n    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);\n}\n\n/*!\n@brief appends a decimal representation of e to buf\n@return a pointer to the element following the exponent.\n@pre -1000 < e < 1000\n*/\nJSON_HEDLEY_NON_NULL(1)\nJSON_HEDLEY_RETURNS_NON_NULL\ninline char* append_exponent(char* buf, int e)\n{\n    JSON_ASSERT(e > -1000);\n    JSON_ASSERT(e <  1000);\n\n    if (e < 0)\n    {\n        e = -e;\n        *buf++ = '-';\n    }\n    else\n    {\n        *buf++ = '+';\n    }\n\n    auto k = static_cast<std::uint32_t>(e);\n    if (k < 10)\n    {\n        // Always print at least two digits in the exponent.\n        // This is for compatibility with printf(\"%g\").\n        *buf++ = '0';\n        *buf++ = static_cast<char>('0' + k);\n    }\n    else if (k < 100)\n    {\n        *buf++ = static_cast<char>('0' + k / 10);\n        k %= 10;\n        *buf++ = static_cast<char>('0' + k);\n    }\n    else\n    {\n        *buf++ = static_cast<char>('0' + k / 100);\n        k %= 100;\n        *buf++ = static_cast<char>('0' + k / 10);\n        k %= 10;\n        *buf++ = static_cast<char>('0' + k);\n    }\n\n    return buf;\n}\n\n/*!\n@brief prettify v = buf * 10^decimal_exponent\n\nIf v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point\nnotation. Otherwise it will be printed in exponential notation.\n\n@pre min_exp < 0\n@pre max_exp > 0\n*/\nJSON_HEDLEY_NON_NULL(1)\nJSON_HEDLEY_RETURNS_NON_NULL\ninline char* format_buffer(char* buf, int len, int decimal_exponent,\n                           int min_exp, int max_exp)\n{\n    JSON_ASSERT(min_exp < 0);\n    JSON_ASSERT(max_exp > 0);\n\n    const int k = len;\n    const int n = len + decimal_exponent;\n\n    // v = buf * 10^(n-k)\n    // k is the length of the buffer (number of decimal digits)\n    // n is the position of the decimal point relative to the start of the buffer.\n\n    if (k <= n && n <= max_exp)\n    {\n        // digits[000]\n        // len <= max_exp + 2\n\n        std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));\n        // Make it look like a floating-point number (#362, #378)\n        buf[n + 0] = '.';\n        buf[n + 1] = '0';\n        return buf + (static_cast<size_t>(n) + 2);\n    }\n\n    if (0 < n && n <= max_exp)\n    {\n        // dig.its\n        // len <= max_digits10 + 1\n\n        JSON_ASSERT(k > n);\n\n        std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));\n        buf[n] = '.';\n        return buf + (static_cast<size_t>(k) + 1U);\n    }\n\n    if (min_exp < n && n <= 0)\n    {\n        // 0.[000]digits\n        // len <= 2 + (-min_exp - 1) + max_digits10\n\n        std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));\n        buf[0] = '0';\n        buf[1] = '.';\n        std::memset(buf + 2, '0', static_cast<size_t>(-n));\n        return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));\n    }\n\n    if (k == 1)\n    {\n        // dE+123\n        // len <= 1 + 5\n\n        buf += 1;\n    }\n    else\n    {\n        // d.igitsE+123\n        // len <= max_digits10 + 1 + 5\n\n        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);\n        buf[1] = '.';\n        buf += 1 + static_cast<size_t>(k);\n    }\n\n    *buf++ = 'e';\n    return append_exponent(buf, n - 1);\n}\n\n} // namespace dtoa_impl\n\n/*!\n@brief generates a decimal representation of the floating-point number value in [first, last).\n\nThe format of the resulting decimal representation is similar to printf's %g\nformat. Returns an iterator pointing past-the-end of the decimal representation.\n\n@note The input number must be finite, i.e. NaN's and Inf's are not supported.\n@note The buffer must be large enough.\n@note The result is NOT null-terminated.\n*/\ntemplate<typename FloatType>\nJSON_HEDLEY_NON_NULL(1, 2)\nJSON_HEDLEY_RETURNS_NON_NULL\nchar* to_chars(char* first, const char* last, FloatType value)\n{\n    static_cast<void>(last); // maybe unused - fix warning\n    JSON_ASSERT(std::isfinite(value));\n\n    // Use signbit(value) instead of (value < 0) since signbit works for -0.\n    if (std::signbit(value))\n    {\n        value = -value;\n        *first++ = '-';\n    }\n\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n    if (value == 0) // +-0\n    {\n        *first++ = '0';\n        // Make it look like a floating-point number (#362, #378)\n        *first++ = '.';\n        *first++ = '0';\n        return first;\n    }\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n\n    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);\n\n    // Compute v = buffer * 10^decimal_exponent.\n    // The decimal digits are stored in the buffer, which needs to be interpreted\n    // as an unsigned decimal integer.\n    // len is the length of the buffer, i.e. the number of decimal digits.\n    int len = 0;\n    int decimal_exponent = 0;\n    dtoa_impl::grisu2(first, len, decimal_exponent, value);\n\n    JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);\n\n    // Format the buffer like printf(\"%.*g\", prec, value)\n    constexpr int kMinExp = -4;\n    // Use digits10 here to increase compatibility with version 2.\n    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;\n\n    JSON_ASSERT(last - first >= kMaxExp + 2);\n    JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);\n    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);\n\n    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);\n}\n\n} // namespace detail\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/conversions/to_json.hpp",
    "content": "#pragma once\n\n#include <algorithm> // copy\n#include <iterator> // begin, end\n#include <string> // string\n#include <tuple> // tuple, get\n#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type\n#include <utility> // move, forward, declval, pair\n#include <valarray> // valarray\n#include <vector> // vector\n\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/iterators/iteration_proxy.hpp>\n#include <nlohmann/detail/meta/cpp_future.hpp>\n#include <nlohmann/detail/meta/type_traits.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\n#if JSON_HAS_EXPERIMENTAL_FILESYSTEM\n#include <experimental/filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::experimental::filesystem;\n} // namespace nlohmann::detail\n#elif JSON_HAS_FILESYSTEM\n#include <filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::filesystem;\n} // namespace nlohmann::detail\n#endif\n\nnamespace nlohmann\n{\nnamespace detail\n{\n//////////////////\n// constructors //\n//////////////////\n\n/*\n * Note all external_constructor<>::construct functions need to call\n * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an\n * allocated value (e.g., a string). See bug issue\n * https://github.com/nlohmann/json/issues/2865 for more information.\n */\n\ntemplate<value_t> struct external_constructor;\n\ntemplate<>\nstruct external_constructor<value_t::boolean>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::boolean;\n        j.m_value = b;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::string>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::string;\n        j.m_value = s;\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::string;\n        j.m_value = std::move(s);\n        j.assert_invariant();\n    }\n\n    template < typename BasicJsonType, typename CompatibleStringType,\n               enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,\n                             int > = 0 >\n    static void construct(BasicJsonType& j, const CompatibleStringType& str)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::string;\n        j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::binary>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::binary;\n        j.m_value = typename BasicJsonType::binary_t(b);\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::binary;\n        j.m_value = typename BasicJsonType::binary_t(std::move(b));\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::number_float>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::number_float;\n        j.m_value = val;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::number_unsigned>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::number_unsigned;\n        j.m_value = val;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::number_integer>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::number_integer;\n        j.m_value = val;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::array>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = arr;\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = std::move(arr);\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template < typename BasicJsonType, typename CompatibleArrayType,\n               enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,\n                             int > = 0 >\n    static void construct(BasicJsonType& j, const CompatibleArrayType& arr)\n    {\n        using std::begin;\n        using std::end;\n\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const std::vector<bool>& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = value_t::array;\n        j.m_value.array->reserve(arr.size());\n        for (const bool x : arr)\n        {\n            j.m_value.array->push_back(x);\n            j.set_parent(j.m_value.array->back());\n        }\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType, typename T,\n             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>\n    static void construct(BasicJsonType& j, const std::valarray<T>& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = value_t::array;\n        j.m_value.array->resize(arr.size());\n        if (arr.size() > 0)\n        {\n            std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());\n        }\n        j.set_parents();\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::object>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::object;\n        j.m_value = obj;\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::object;\n        j.m_value = std::move(obj);\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template < typename BasicJsonType, typename CompatibleObjectType,\n               enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >\n    static void construct(BasicJsonType& j, const CompatibleObjectType& obj)\n    {\n        using std::begin;\n        using std::end;\n\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::object;\n        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));\n        j.set_parents();\n        j.assert_invariant();\n    }\n};\n\n/////////////\n// to_json //\n/////////////\n\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>\nvoid to_json(BasicJsonType& j, T b) noexcept\n{\n    external_constructor<value_t::boolean>::construct(j, b);\n}\n\ntemplate<typename BasicJsonType, typename CompatibleString,\n         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>\nvoid to_json(BasicJsonType& j, const CompatibleString& s)\n{\n    external_constructor<value_t::string>::construct(j, s);\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)\n{\n    external_constructor<value_t::string>::construct(j, std::move(s));\n}\n\ntemplate<typename BasicJsonType, typename FloatType,\n         enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, FloatType val) noexcept\n{\n    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));\n}\n\ntemplate<typename BasicJsonType, typename CompatibleNumberUnsignedType,\n         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept\n{\n    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));\n}\n\ntemplate<typename BasicJsonType, typename CompatibleNumberIntegerType,\n         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept\n{\n    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));\n}\n\ntemplate<typename BasicJsonType, typename EnumType,\n         enable_if_t<std::is_enum<EnumType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, EnumType e) noexcept\n{\n    using underlying_type = typename std::underlying_type<EnumType>::type;\n    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const std::vector<bool>& e)\n{\n    external_constructor<value_t::array>::construct(j, e);\n}\n\ntemplate < typename BasicJsonType, typename CompatibleArrayType,\n           enable_if_t < is_compatible_array_type<BasicJsonType,\n                         CompatibleArrayType>::value&&\n                         !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&\n                         !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&\n                         !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&\n                         !is_basic_json<CompatibleArrayType>::value,\n                         int > = 0 >\nvoid to_json(BasicJsonType& j, const CompatibleArrayType& arr)\n{\n    external_constructor<value_t::array>::construct(j, arr);\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)\n{\n    external_constructor<value_t::binary>::construct(j, bin);\n}\n\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, const std::valarray<T>& arr)\n{\n    external_constructor<value_t::array>::construct(j, std::move(arr));\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)\n{\n    external_constructor<value_t::array>::construct(j, std::move(arr));\n}\n\ntemplate < typename BasicJsonType, typename CompatibleObjectType,\n           enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >\nvoid to_json(BasicJsonType& j, const CompatibleObjectType& obj)\n{\n    external_constructor<value_t::object>::construct(j, obj);\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)\n{\n    external_constructor<value_t::object>::construct(j, std::move(obj));\n}\n\ntemplate <\n    typename BasicJsonType, typename T, std::size_t N,\n    enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,\n                  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n                  int > = 0 >\nvoid to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n{\n    external_constructor<value_t::array>::construct(j, arr);\n}\n\ntemplate < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >\nvoid to_json(BasicJsonType& j, const std::pair<T1, T2>& p)\n{\n    j = { p.first, p.second };\n}\n\n// for https://github.com/nlohmann/json/pull/1134\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>\nvoid to_json(BasicJsonType& j, const T& b)\n{\n    j = { {b.key(), b.value()} };\n}\n\ntemplate<typename BasicJsonType, typename Tuple, std::size_t... Idx>\nvoid to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)\n{\n    j = { std::get<Idx>(t)... };\n}\n\ntemplate<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>\nvoid to_json(BasicJsonType& j, const T& t)\n{\n    to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});\n}\n\n#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const std_fs::path& p)\n{\n    j = p.string();\n}\n#endif\n\nstruct to_json_fn\n{\n    template<typename BasicJsonType, typename T>\n    auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))\n    -> decltype(to_json(j, std::forward<T>(val)), void())\n    {\n        return to_json(j, std::forward<T>(val));\n    }\n};\n}  // namespace detail\n\n/// namespace to hold default `to_json` function\n/// to see why this is required:\n/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html\nnamespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)\n{\nconstexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)\n} // namespace\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/exceptions.hpp",
    "content": "#pragma once\n\n#include <exception> // exception\n#include <stdexcept> // runtime_error\n#include <string> // to_string\n#include <vector> // vector\n\n#include <nlohmann/detail/value_t.hpp>\n#include <nlohmann/detail/string_escape.hpp>\n#include <nlohmann/detail/input/position_t.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n////////////////\n// exceptions //\n////////////////\n\n/// @brief general exception of the @ref basic_json class\n/// @sa https://json.nlohmann.me/api/basic_json/exception/\nclass exception : public std::exception\n{\n  public:\n    /// returns the explanatory string\n    const char* what() const noexcept override\n    {\n        return m.what();\n    }\n\n    /// the id of the exception\n    const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)\n\n  protected:\n    JSON_HEDLEY_NON_NULL(3)\n    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)\n\n    static std::string name(const std::string& ename, int id_)\n    {\n        return \"[json.exception.\" + ename + \".\" + std::to_string(id_) + \"] \";\n    }\n\n    template<typename BasicJsonType>\n    static std::string diagnostics(const BasicJsonType& leaf_element)\n    {\n#if JSON_DIAGNOSTICS\n        std::vector<std::string> tokens;\n        for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)\n        {\n            switch (current->m_parent->type())\n            {\n                case value_t::array:\n                {\n                    for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)\n                    {\n                        if (&current->m_parent->m_value.array->operator[](i) == current)\n                        {\n                            tokens.emplace_back(std::to_string(i));\n                            break;\n                        }\n                    }\n                    break;\n                }\n\n                case value_t::object:\n                {\n                    for (const auto& element : *current->m_parent->m_value.object)\n                    {\n                        if (&element.second == current)\n                        {\n                            tokens.emplace_back(element.first.c_str());\n                            break;\n                        }\n                    }\n                    break;\n                }\n\n                case value_t::null: // LCOV_EXCL_LINE\n                case value_t::string: // LCOV_EXCL_LINE\n                case value_t::boolean: // LCOV_EXCL_LINE\n                case value_t::number_integer: // LCOV_EXCL_LINE\n                case value_t::number_unsigned: // LCOV_EXCL_LINE\n                case value_t::number_float: // LCOV_EXCL_LINE\n                case value_t::binary: // LCOV_EXCL_LINE\n                case value_t::discarded: // LCOV_EXCL_LINE\n                default:   // LCOV_EXCL_LINE\n                    break; // LCOV_EXCL_LINE\n            }\n        }\n\n        if (tokens.empty())\n        {\n            return \"\";\n        }\n\n        return \"(\" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},\n                                     [](const std::string & a, const std::string & b)\n        {\n            return a + \"/\" + detail::escape(b);\n        }) + \") \";\n#else\n        static_cast<void>(leaf_element);\n        return \"\";\n#endif\n    }\n\n  private:\n    /// an exception object as storage for error messages\n    std::runtime_error m;\n};\n\n/// @brief exception indicating a parse error\n/// @sa https://json.nlohmann.me/api/basic_json/parse_error/\nclass parse_error : public exception\n{\n  public:\n    /*!\n    @brief create a parse error exception\n    @param[in] id_       the id of the exception\n    @param[in] pos       the position where the error occurred (or with\n                         chars_read_total=0 if the position cannot be\n                         determined)\n    @param[in] what_arg  the explanatory string\n    @return parse_error object\n    */\n    template<typename BasicJsonType>\n    static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"parse_error\", id_) + \"parse error\" +\n                        position_string(pos) + \": \" + exception::diagnostics(context) + what_arg;\n        return {id_, pos.chars_read_total, w.c_str()};\n    }\n\n    template<typename BasicJsonType>\n    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"parse_error\", id_) + \"parse error\" +\n                        (byte_ != 0 ? (\" at byte \" + std::to_string(byte_)) : \"\") +\n                        \": \" + exception::diagnostics(context) + what_arg;\n        return {id_, byte_, w.c_str()};\n    }\n\n    /*!\n    @brief byte index of the parse error\n\n    The byte index of the last read character in the input file.\n\n    @note For an input with n bytes, 1 is the index of the first character and\n          n+1 is the index of the terminating null byte or the end of file.\n          This also holds true when reading a byte vector (CBOR or MessagePack).\n    */\n    const std::size_t byte;\n\n  private:\n    parse_error(int id_, std::size_t byte_, const char* what_arg)\n        : exception(id_, what_arg), byte(byte_) {}\n\n    static std::string position_string(const position_t& pos)\n    {\n        return \" at line \" + std::to_string(pos.lines_read + 1) +\n               \", column \" + std::to_string(pos.chars_read_current_line);\n    }\n};\n\n/// @brief exception indicating errors with iterators\n/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/\nclass invalid_iterator : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"invalid_iterator\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    invalid_iterator(int id_, const char* what_arg)\n        : exception(id_, what_arg) {}\n};\n\n/// @brief exception indicating executing a member function with a wrong type\n/// @sa https://json.nlohmann.me/api/basic_json/type_error/\nclass type_error : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"type_error\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}\n};\n\n/// @brief exception indicating access out of the defined range\n/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/\nclass out_of_range : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"out_of_range\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}\n};\n\n/// @brief exception indicating other library errors\n/// @sa https://json.nlohmann.me/api/basic_json/other_error/\nclass other_error : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"other_error\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}\n};\n\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/hash.hpp",
    "content": "#pragma once\n\n#include <cstdint> // uint8_t\n#include <cstddef> // size_t\n#include <functional> // hash\n\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n// boost::hash_combine\ninline std::size_t combine(std::size_t seed, std::size_t h) noexcept\n{\n    seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);\n    return seed;\n}\n\n/*!\n@brief hash a JSON value\n\nThe hash function tries to rely on std::hash where possible. Furthermore, the\ntype of the JSON value is taken into account to have different hash values for\nnull, 0, 0U, and false, etc.\n\n@tparam BasicJsonType basic_json specialization\n@param j JSON value to hash\n@return hash value of j\n*/\ntemplate<typename BasicJsonType>\nstd::size_t hash(const BasicJsonType& j)\n{\n    using string_t = typename BasicJsonType::string_t;\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n\n    const auto type = static_cast<std::size_t>(j.type());\n    switch (j.type())\n    {\n        case BasicJsonType::value_t::null:\n        case BasicJsonType::value_t::discarded:\n        {\n            return combine(type, 0);\n        }\n\n        case BasicJsonType::value_t::object:\n        {\n            auto seed = combine(type, j.size());\n            for (const auto& element : j.items())\n            {\n                const auto h = std::hash<string_t> {}(element.key());\n                seed = combine(seed, h);\n                seed = combine(seed, hash(element.value()));\n            }\n            return seed;\n        }\n\n        case BasicJsonType::value_t::array:\n        {\n            auto seed = combine(type, j.size());\n            for (const auto& element : j)\n            {\n                seed = combine(seed, hash(element));\n            }\n            return seed;\n        }\n\n        case BasicJsonType::value_t::string:\n        {\n            const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::boolean:\n        {\n            const auto h = std::hash<bool> {}(j.template get<bool>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::number_integer:\n        {\n            const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::number_unsigned:\n        {\n            const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::number_float:\n        {\n            const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::binary:\n        {\n            auto seed = combine(type, j.get_binary().size());\n            const auto h = std::hash<bool> {}(j.get_binary().has_subtype());\n            seed = combine(seed, h);\n            seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));\n            for (const auto byte : j.get_binary())\n            {\n                seed = combine(seed, std::hash<std::uint8_t> {}(byte));\n            }\n            return seed;\n        }\n\n        default:                   // LCOV_EXCL_LINE\n            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n            return 0;              // LCOV_EXCL_LINE\n    }\n}\n\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/input/binary_reader.hpp",
    "content": "#pragma once\n\n#include <algorithm> // generate_n\n#include <array> // array\n#include <cmath> // ldexp\n#include <cstddef> // size_t\n#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t\n#include <cstdio> // snprintf\n#include <cstring> // memcpy\n#include <iterator> // back_inserter\n#include <limits> // numeric_limits\n#include <string> // char_traits, string\n#include <utility> // make_pair, move\n#include <vector> // vector\n\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/input/input_adapters.hpp>\n#include <nlohmann/detail/input/json_sax.hpp>\n#include <nlohmann/detail/input/lexer.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/meta/is_sax.hpp>\n#include <nlohmann/detail/meta/type_traits.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n/// how to treat CBOR tags\nenum class cbor_tag_handler_t\n{\n    error,   ///< throw a parse_error exception in case of a tag\n    ignore,  ///< ignore tags\n    store    ///< store tags as binary type\n};\n\n/*!\n@brief determine system byte order\n\n@return true if and only if system's byte order is little endian\n\n@note from https://stackoverflow.com/a/1001328/266378\n*/\nstatic inline bool little_endianness(int num = 1) noexcept\n{\n    return *reinterpret_cast<char*>(&num) == 1;\n}\n\n\n///////////////////\n// binary reader //\n///////////////////\n\n/*!\n@brief deserialization of CBOR, MessagePack, and UBJSON values\n*/\ntemplate<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>\nclass binary_reader\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using json_sax_t = SAX;\n    using char_type = typename InputAdapterType::char_type;\n    using char_int_type = typename std::char_traits<char_type>::int_type;\n\n  public:\n    /*!\n    @brief create a binary reader\n\n    @param[in] adapter  input adapter to read from\n    */\n    explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))\n    {\n        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};\n    }\n\n    // make class move-only\n    binary_reader(const binary_reader&) = delete;\n    binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    binary_reader& operator=(const binary_reader&) = delete;\n    binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~binary_reader() = default;\n\n    /*!\n    @param[in] format  the binary format to parse\n    @param[in] sax_    a SAX event processor\n    @param[in] strict  whether to expect the input to be consumed completed\n    @param[in] tag_handler  how to treat CBOR tags\n\n    @return whether parsing was successful\n    */\n    JSON_HEDLEY_NON_NULL(3)\n    bool sax_parse(const input_format_t format,\n                   json_sax_t* sax_,\n                   const bool strict = true,\n                   const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        sax = sax_;\n        bool result = false;\n\n        switch (format)\n        {\n            case input_format_t::bson:\n                result = parse_bson_internal();\n                break;\n\n            case input_format_t::cbor:\n                result = parse_cbor_internal(true, tag_handler);\n                break;\n\n            case input_format_t::msgpack:\n                result = parse_msgpack_internal();\n                break;\n\n            case input_format_t::ubjson:\n                result = parse_ubjson_internal();\n                break;\n\n            case input_format_t::json: // LCOV_EXCL_LINE\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n\n        // strict mode: next byte must be EOF\n        if (result && strict)\n        {\n            if (format == input_format_t::ubjson)\n            {\n                get_ignore_noop();\n            }\n            else\n            {\n                get();\n            }\n\n            if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))\n            {\n                return sax->parse_error(chars_read, get_token_string(),\n                                        parse_error::create(110, chars_read, exception_message(format, \"expected end of input; last byte: 0x\" + get_token_string(), \"value\"), BasicJsonType()));\n            }\n        }\n\n        return result;\n    }\n\n  private:\n    //////////\n    // BSON //\n    //////////\n\n    /*!\n    @brief Reads in a BSON-object and passes it to the SAX-parser.\n    @return whether a valid BSON-value was passed to the SAX parser\n    */\n    bool parse_bson_internal()\n    {\n        std::int32_t document_size{};\n        get_number<std::int32_t, true>(input_format_t::bson, document_size);\n\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))\n        {\n            return false;\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))\n        {\n            return false;\n        }\n\n        return sax->end_object();\n    }\n\n    /*!\n    @brief Parses a C-style string from the BSON input.\n    @param[in,out] result  A reference to the string variable where the read\n                            string is to be stored.\n    @return `true` if the \\x00-byte indicating the end of the string was\n             encountered before the EOF; false` indicates an unexpected EOF.\n    */\n    bool get_bson_cstr(string_t& result)\n    {\n        auto out = std::back_inserter(result);\n        while (true)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, \"cstring\")))\n            {\n                return false;\n            }\n            if (current == 0x00)\n            {\n                return true;\n            }\n            *out++ = static_cast<typename string_t::value_type>(current);\n        }\n    }\n\n    /*!\n    @brief Parses a zero-terminated string of length @a len from the BSON\n           input.\n    @param[in] len  The length (including the zero-byte at the end) of the\n                    string to be read.\n    @param[in,out] result  A reference to the string variable where the read\n                            string is to be stored.\n    @tparam NumberType The type of the length @a len\n    @pre len >= 1\n    @return `true` if the string was successfully parsed\n    */\n    template<typename NumberType>\n    bool get_bson_string(const NumberType len, string_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(len < 1))\n        {\n            auto last_token = get_token_string();\n            return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, \"string length must be at least 1, is \" + std::to_string(len), \"string\"), BasicJsonType()));\n        }\n\n        return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();\n    }\n\n    /*!\n    @brief Parses a byte array input of length @a len from the BSON input.\n    @param[in] len  The length of the byte array to be read.\n    @param[in,out] result  A reference to the binary variable where the read\n                            array is to be stored.\n    @tparam NumberType The type of the length @a len\n    @pre len >= 0\n    @return `true` if the byte array was successfully parsed\n    */\n    template<typename NumberType>\n    bool get_bson_binary(const NumberType len, binary_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(len < 0))\n        {\n            auto last_token = get_token_string();\n            return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, \"byte array length cannot be negative, is \" + std::to_string(len), \"binary\"), BasicJsonType()));\n        }\n\n        // All BSON binary values have a subtype\n        std::uint8_t subtype{};\n        get_number<std::uint8_t>(input_format_t::bson, subtype);\n        result.set_subtype(subtype);\n\n        return get_binary(input_format_t::bson, len, result);\n    }\n\n    /*!\n    @brief Read a BSON document element of the given @a element_type.\n    @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html\n    @param[in] element_type_parse_position The position in the input stream,\n               where the `element_type` was read.\n    @warning Not all BSON element types are supported yet. An unsupported\n             @a element_type will give rise to a parse_error.114:\n             Unsupported BSON record type 0x...\n    @return whether a valid BSON-object/array was passed to the SAX parser\n    */\n    bool parse_bson_element_internal(const char_int_type element_type,\n                                     const std::size_t element_type_parse_position)\n    {\n        switch (element_type)\n        {\n            case 0x01: // double\n            {\n                double number{};\n                return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0x02: // string\n            {\n                std::int32_t len{};\n                string_t value;\n                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);\n            }\n\n            case 0x03: // object\n            {\n                return parse_bson_internal();\n            }\n\n            case 0x04: // array\n            {\n                return parse_bson_array();\n            }\n\n            case 0x05: // binary\n            {\n                std::int32_t len{};\n                binary_t value;\n                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);\n            }\n\n            case 0x08: // boolean\n            {\n                return sax->boolean(get() != 0);\n            }\n\n            case 0x0A: // null\n            {\n                return sax->null();\n            }\n\n            case 0x10: // int32\n            {\n                std::int32_t value{};\n                return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);\n            }\n\n            case 0x12: // int64\n            {\n                std::int64_t value{};\n                return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);\n            }\n\n            default: // anything else not supported (yet)\n            {\n                std::array<char, 3> cr{{}};\n                static_cast<void>((std::snprintf)(cr.data(), cr.size(), \"%.2hhX\", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, \"Unsupported BSON record type 0x\" + std::string(cr.data()), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief Read a BSON element list (as specified in the BSON-spec)\n\n    The same binary layout is used for objects and arrays, hence it must be\n    indicated with the argument @a is_array which one is expected\n    (true --> array, false --> object).\n\n    @param[in] is_array Determines if the element list being read is to be\n                        treated as an object (@a is_array == false), or as an\n                        array (@a is_array == true).\n    @return whether a valid BSON-object/array was passed to the SAX parser\n    */\n    bool parse_bson_element_list(const bool is_array)\n    {\n        string_t key;\n\n        while (auto element_type = get())\n        {\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, \"element list\")))\n            {\n                return false;\n            }\n\n            const std::size_t element_type_parse_position = chars_read;\n            if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))\n            {\n                return false;\n            }\n\n            if (!is_array && !sax->key(key))\n            {\n                return false;\n            }\n\n            if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))\n            {\n                return false;\n            }\n\n            // get_bson_cstr only appends\n            key.clear();\n        }\n\n        return true;\n    }\n\n    /*!\n    @brief Reads an array from the BSON input and passes it to the SAX-parser.\n    @return whether a valid BSON-array was passed to the SAX parser\n    */\n    bool parse_bson_array()\n    {\n        std::int32_t document_size{};\n        get_number<std::int32_t, true>(input_format_t::bson, document_size);\n\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))\n        {\n            return false;\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))\n        {\n            return false;\n        }\n\n        return sax->end_array();\n    }\n\n    //////////\n    // CBOR //\n    //////////\n\n    /*!\n    @param[in] get_char  whether a new character should be retrieved from the\n                         input (true) or whether the last read character should\n                         be considered instead (false)\n    @param[in] tag_handler how CBOR tags should be treated\n\n    @return whether a valid CBOR value was passed to the SAX parser\n    */\n    bool parse_cbor_internal(const bool get_char,\n                             const cbor_tag_handler_t tag_handler)\n    {\n        switch (get_char ? get() : current)\n        {\n            // EOF\n            case std::char_traits<char_type>::eof():\n                return unexpect_eof(input_format_t::cbor, \"value\");\n\n            // Integer 0x00..0x17 (0..23)\n            case 0x00:\n            case 0x01:\n            case 0x02:\n            case 0x03:\n            case 0x04:\n            case 0x05:\n            case 0x06:\n            case 0x07:\n            case 0x08:\n            case 0x09:\n            case 0x0A:\n            case 0x0B:\n            case 0x0C:\n            case 0x0D:\n            case 0x0E:\n            case 0x0F:\n            case 0x10:\n            case 0x11:\n            case 0x12:\n            case 0x13:\n            case 0x14:\n            case 0x15:\n            case 0x16:\n            case 0x17:\n                return sax->number_unsigned(static_cast<number_unsigned_t>(current));\n\n            case 0x18: // Unsigned integer (one-byte uint8_t follows)\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            case 0x19: // Unsigned integer (two-byte uint16_t follows)\n            {\n                std::uint16_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            case 0x1A: // Unsigned integer (four-byte uint32_t follows)\n            {\n                std::uint32_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            case 0x1B: // Unsigned integer (eight-byte uint64_t follows)\n            {\n                std::uint64_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            // Negative integer -1-0x00..-1-0x17 (-1..-24)\n            case 0x20:\n            case 0x21:\n            case 0x22:\n            case 0x23:\n            case 0x24:\n            case 0x25:\n            case 0x26:\n            case 0x27:\n            case 0x28:\n            case 0x29:\n            case 0x2A:\n            case 0x2B:\n            case 0x2C:\n            case 0x2D:\n            case 0x2E:\n            case 0x2F:\n            case 0x30:\n            case 0x31:\n            case 0x32:\n            case 0x33:\n            case 0x34:\n            case 0x35:\n            case 0x36:\n            case 0x37:\n                return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));\n\n            case 0x38: // Negative integer (one-byte uint8_t follows)\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);\n            }\n\n            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)\n            {\n                std::uint16_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);\n            }\n\n            case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)\n            {\n                std::uint32_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);\n            }\n\n            case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)\n            {\n                std::uint64_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)\n                        - static_cast<number_integer_t>(number));\n            }\n\n            // Binary data (0x00..0x17 bytes follow)\n            case 0x40:\n            case 0x41:\n            case 0x42:\n            case 0x43:\n            case 0x44:\n            case 0x45:\n            case 0x46:\n            case 0x47:\n            case 0x48:\n            case 0x49:\n            case 0x4A:\n            case 0x4B:\n            case 0x4C:\n            case 0x4D:\n            case 0x4E:\n            case 0x4F:\n            case 0x50:\n            case 0x51:\n            case 0x52:\n            case 0x53:\n            case 0x54:\n            case 0x55:\n            case 0x56:\n            case 0x57:\n            case 0x58: // Binary data (one-byte uint8_t for n follows)\n            case 0x59: // Binary data (two-byte uint16_t for n follow)\n            case 0x5A: // Binary data (four-byte uint32_t for n follow)\n            case 0x5B: // Binary data (eight-byte uint64_t for n follow)\n            case 0x5F: // Binary data (indefinite length)\n            {\n                binary_t b;\n                return get_cbor_binary(b) && sax->binary(b);\n            }\n\n            // UTF-8 string (0x00..0x17 bytes follow)\n            case 0x60:\n            case 0x61:\n            case 0x62:\n            case 0x63:\n            case 0x64:\n            case 0x65:\n            case 0x66:\n            case 0x67:\n            case 0x68:\n            case 0x69:\n            case 0x6A:\n            case 0x6B:\n            case 0x6C:\n            case 0x6D:\n            case 0x6E:\n            case 0x6F:\n            case 0x70:\n            case 0x71:\n            case 0x72:\n            case 0x73:\n            case 0x74:\n            case 0x75:\n            case 0x76:\n            case 0x77:\n            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)\n            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)\n            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)\n            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)\n            case 0x7F: // UTF-8 string (indefinite length)\n            {\n                string_t s;\n                return get_cbor_string(s) && sax->string(s);\n            }\n\n            // array (0x00..0x17 data items follow)\n            case 0x80:\n            case 0x81:\n            case 0x82:\n            case 0x83:\n            case 0x84:\n            case 0x85:\n            case 0x86:\n            case 0x87:\n            case 0x88:\n            case 0x89:\n            case 0x8A:\n            case 0x8B:\n            case 0x8C:\n            case 0x8D:\n            case 0x8E:\n            case 0x8F:\n            case 0x90:\n            case 0x91:\n            case 0x92:\n            case 0x93:\n            case 0x94:\n            case 0x95:\n            case 0x96:\n            case 0x97:\n                return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);\n\n            case 0x98: // array (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x99: // array (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x9A: // array (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x9B: // array (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x9F: // array (indefinite length)\n                return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);\n\n            // map (0x00..0x17 pairs of data items follow)\n            case 0xA0:\n            case 0xA1:\n            case 0xA2:\n            case 0xA3:\n            case 0xA4:\n            case 0xA5:\n            case 0xA6:\n            case 0xA7:\n            case 0xA8:\n            case 0xA9:\n            case 0xAA:\n            case 0xAB:\n            case 0xAC:\n            case 0xAD:\n            case 0xAE:\n            case 0xAF:\n            case 0xB0:\n            case 0xB1:\n            case 0xB2:\n            case 0xB3:\n            case 0xB4:\n            case 0xB5:\n            case 0xB6:\n            case 0xB7:\n                return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);\n\n            case 0xB8: // map (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xB9: // map (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xBA: // map (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xBB: // map (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xBF: // map (indefinite length)\n                return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);\n\n            case 0xC6: // tagged item\n            case 0xC7:\n            case 0xC8:\n            case 0xC9:\n            case 0xCA:\n            case 0xCB:\n            case 0xCC:\n            case 0xCD:\n            case 0xCE:\n            case 0xCF:\n            case 0xD0:\n            case 0xD1:\n            case 0xD2:\n            case 0xD3:\n            case 0xD4:\n            case 0xD8: // tagged item (1 bytes follow)\n            case 0xD9: // tagged item (2 bytes follow)\n            case 0xDA: // tagged item (4 bytes follow)\n            case 0xDB: // tagged item (8 bytes follow)\n            {\n                switch (tag_handler)\n                {\n                    case cbor_tag_handler_t::error:\n                    {\n                        auto last_token = get_token_string();\n                        return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n                    }\n\n                    case cbor_tag_handler_t::ignore:\n                    {\n                        // ignore binary subtype\n                        switch (current)\n                        {\n                            case 0xD8:\n                            {\n                                std::uint8_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            case 0xD9:\n                            {\n                                std::uint16_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            case 0xDA:\n                            {\n                                std::uint32_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            case 0xDB:\n                            {\n                                std::uint64_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            default:\n                                break;\n                        }\n                        return parse_cbor_internal(true, tag_handler);\n                    }\n\n                    case cbor_tag_handler_t::store:\n                    {\n                        binary_t b;\n                        // use binary subtype and store in binary container\n                        switch (current)\n                        {\n                            case 0xD8:\n                            {\n                                std::uint8_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            case 0xD9:\n                            {\n                                std::uint16_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            case 0xDA:\n                            {\n                                std::uint32_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            case 0xDB:\n                            {\n                                std::uint64_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            default:\n                                return parse_cbor_internal(true, tag_handler);\n                        }\n                        get();\n                        return get_cbor_binary(b) && sax->binary(b);\n                    }\n\n                    default:                 // LCOV_EXCL_LINE\n                        JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n                        return false;        // LCOV_EXCL_LINE\n                }\n            }\n\n            case 0xF4: // false\n                return sax->boolean(false);\n\n            case 0xF5: // true\n                return sax->boolean(true);\n\n            case 0xF6: // null\n                return sax->null();\n\n            case 0xF9: // Half-Precision Float (two-byte IEEE 754)\n            {\n                const auto byte1_raw = get();\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"number\")))\n                {\n                    return false;\n                }\n                const auto byte2_raw = get();\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"number\")))\n                {\n                    return false;\n                }\n\n                const auto byte1 = static_cast<unsigned char>(byte1_raw);\n                const auto byte2 = static_cast<unsigned char>(byte2_raw);\n\n                // code from RFC 7049, Appendix D, Figure 3:\n                // As half-precision floating-point numbers were only added\n                // to IEEE 754 in 2008, today's programming platforms often\n                // still only have limited support for them. It is very\n                // easy to include at least decoding support for them even\n                // without such support. An example of a small decoder for\n                // half-precision floating-point numbers in the C language\n                // is shown in Fig. 3.\n                const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);\n                const double val = [&half]\n                {\n                    const int exp = (half >> 10u) & 0x1Fu;\n                    const unsigned int mant = half & 0x3FFu;\n                    JSON_ASSERT(0 <= exp&& exp <= 32);\n                    JSON_ASSERT(mant <= 1024);\n                    switch (exp)\n                    {\n                        case 0:\n                            return std::ldexp(mant, -24);\n                        case 31:\n                            return (mant == 0)\n                            ? std::numeric_limits<double>::infinity()\n                            : std::numeric_limits<double>::quiet_NaN();\n                        default:\n                            return std::ldexp(mant + 1024, exp - 25);\n                    }\n                }();\n                return sax->number_float((half & 0x8000u) != 0\n                                         ? static_cast<number_float_t>(-val)\n                                         : static_cast<number_float_t>(val), \"\");\n            }\n\n            case 0xFA: // Single-Precision Float (four-byte IEEE 754)\n            {\n                float number{};\n                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0xFB: // Double-Precision Float (eight-byte IEEE 754)\n            {\n                double number{};\n                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            default: // anything else (0xFF is handled inside the other types)\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a CBOR string\n\n    This function first reads starting bytes to determine the expected\n    string length and then copies this number of bytes into a string.\n    Additionally, CBOR's strings with indefinite lengths are supported.\n\n    @param[out] result  created string\n\n    @return whether string creation completed\n    */\n    bool get_cbor_string(string_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"string\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            // UTF-8 string (0x00..0x17 bytes follow)\n            case 0x60:\n            case 0x61:\n            case 0x62:\n            case 0x63:\n            case 0x64:\n            case 0x65:\n            case 0x66:\n            case 0x67:\n            case 0x68:\n            case 0x69:\n            case 0x6A:\n            case 0x6B:\n            case 0x6C:\n            case 0x6D:\n            case 0x6E:\n            case 0x6F:\n            case 0x70:\n            case 0x71:\n            case 0x72:\n            case 0x73:\n            case 0x74:\n            case 0x75:\n            case 0x76:\n            case 0x77:\n            {\n                return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);\n            }\n\n            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x7F: // UTF-8 string (indefinite length)\n            {\n                while (get() != 0xFF)\n                {\n                    string_t chunk;\n                    if (!get_cbor_string(chunk))\n                    {\n                        return false;\n                    }\n                    result.append(chunk);\n                }\n                return true;\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, \"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x\" + last_token, \"string\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a CBOR byte array\n\n    This function first reads starting bytes to determine the expected\n    byte array length and then copies this number of bytes into the byte array.\n    Additionally, CBOR's byte arrays with indefinite lengths are supported.\n\n    @param[out] result  created byte array\n\n    @return whether byte array creation completed\n    */\n    bool get_cbor_binary(binary_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"binary\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            // Binary data (0x00..0x17 bytes follow)\n            case 0x40:\n            case 0x41:\n            case 0x42:\n            case 0x43:\n            case 0x44:\n            case 0x45:\n            case 0x46:\n            case 0x47:\n            case 0x48:\n            case 0x49:\n            case 0x4A:\n            case 0x4B:\n            case 0x4C:\n            case 0x4D:\n            case 0x4E:\n            case 0x4F:\n            case 0x50:\n            case 0x51:\n            case 0x52:\n            case 0x53:\n            case 0x54:\n            case 0x55:\n            case 0x56:\n            case 0x57:\n            {\n                return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);\n            }\n\n            case 0x58: // Binary data (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x59: // Binary data (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x5A: // Binary data (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x5B: // Binary data (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x5F: // Binary data (indefinite length)\n            {\n                while (get() != 0xFF)\n                {\n                    binary_t chunk;\n                    if (!get_cbor_binary(chunk))\n                    {\n                        return false;\n                    }\n                    result.insert(result.end(), chunk.begin(), chunk.end());\n                }\n                return true;\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, \"expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x\" + last_token, \"binary\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @param[in] len  the length of the array or static_cast<std::size_t>(-1) for an\n                    array of indefinite size\n    @param[in] tag_handler how CBOR tags should be treated\n    @return whether array creation completed\n    */\n    bool get_cbor_array(const std::size_t len,\n                        const cbor_tag_handler_t tag_handler)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))\n        {\n            return false;\n        }\n\n        if (len != static_cast<std::size_t>(-1))\n        {\n            for (std::size_t i = 0; i < len; ++i)\n            {\n                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))\n                {\n                    return false;\n                }\n            }\n        }\n        else\n        {\n            while (get() != 0xFF)\n            {\n                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))\n                {\n                    return false;\n                }\n            }\n        }\n\n        return sax->end_array();\n    }\n\n    /*!\n    @param[in] len  the length of the object or static_cast<std::size_t>(-1) for an\n                    object of indefinite size\n    @param[in] tag_handler how CBOR tags should be treated\n    @return whether object creation completed\n    */\n    bool get_cbor_object(const std::size_t len,\n                         const cbor_tag_handler_t tag_handler)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))\n        {\n            return false;\n        }\n\n        if (len != 0)\n        {\n            string_t key;\n            if (len != static_cast<std::size_t>(-1))\n            {\n                for (std::size_t i = 0; i < len; ++i)\n                {\n                    get();\n                    if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n\n                    if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n            else\n            {\n                while (get() != 0xFF)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n\n                    if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n        }\n\n        return sax->end_object();\n    }\n\n    /////////////\n    // MsgPack //\n    /////////////\n\n    /*!\n    @return whether a valid MessagePack value was passed to the SAX parser\n    */\n    bool parse_msgpack_internal()\n    {\n        switch (get())\n        {\n            // EOF\n            case std::char_traits<char_type>::eof():\n                return unexpect_eof(input_format_t::msgpack, \"value\");\n\n            // positive fixint\n            case 0x00:\n            case 0x01:\n            case 0x02:\n            case 0x03:\n            case 0x04:\n            case 0x05:\n            case 0x06:\n            case 0x07:\n            case 0x08:\n            case 0x09:\n            case 0x0A:\n            case 0x0B:\n            case 0x0C:\n            case 0x0D:\n            case 0x0E:\n            case 0x0F:\n            case 0x10:\n            case 0x11:\n            case 0x12:\n            case 0x13:\n            case 0x14:\n            case 0x15:\n            case 0x16:\n            case 0x17:\n            case 0x18:\n            case 0x19:\n            case 0x1A:\n            case 0x1B:\n            case 0x1C:\n            case 0x1D:\n            case 0x1E:\n            case 0x1F:\n            case 0x20:\n            case 0x21:\n            case 0x22:\n            case 0x23:\n            case 0x24:\n            case 0x25:\n            case 0x26:\n            case 0x27:\n            case 0x28:\n            case 0x29:\n            case 0x2A:\n            case 0x2B:\n            case 0x2C:\n            case 0x2D:\n            case 0x2E:\n            case 0x2F:\n            case 0x30:\n            case 0x31:\n            case 0x32:\n            case 0x33:\n            case 0x34:\n            case 0x35:\n            case 0x36:\n            case 0x37:\n            case 0x38:\n            case 0x39:\n            case 0x3A:\n            case 0x3B:\n            case 0x3C:\n            case 0x3D:\n            case 0x3E:\n            case 0x3F:\n            case 0x40:\n            case 0x41:\n            case 0x42:\n            case 0x43:\n            case 0x44:\n            case 0x45:\n            case 0x46:\n            case 0x47:\n            case 0x48:\n            case 0x49:\n            case 0x4A:\n            case 0x4B:\n            case 0x4C:\n            case 0x4D:\n            case 0x4E:\n            case 0x4F:\n            case 0x50:\n            case 0x51:\n            case 0x52:\n            case 0x53:\n            case 0x54:\n            case 0x55:\n            case 0x56:\n            case 0x57:\n            case 0x58:\n            case 0x59:\n            case 0x5A:\n            case 0x5B:\n            case 0x5C:\n            case 0x5D:\n            case 0x5E:\n            case 0x5F:\n            case 0x60:\n            case 0x61:\n            case 0x62:\n            case 0x63:\n            case 0x64:\n            case 0x65:\n            case 0x66:\n            case 0x67:\n            case 0x68:\n            case 0x69:\n            case 0x6A:\n            case 0x6B:\n            case 0x6C:\n            case 0x6D:\n            case 0x6E:\n            case 0x6F:\n            case 0x70:\n            case 0x71:\n            case 0x72:\n            case 0x73:\n            case 0x74:\n            case 0x75:\n            case 0x76:\n            case 0x77:\n            case 0x78:\n            case 0x79:\n            case 0x7A:\n            case 0x7B:\n            case 0x7C:\n            case 0x7D:\n            case 0x7E:\n            case 0x7F:\n                return sax->number_unsigned(static_cast<number_unsigned_t>(current));\n\n            // fixmap\n            case 0x80:\n            case 0x81:\n            case 0x82:\n            case 0x83:\n            case 0x84:\n            case 0x85:\n            case 0x86:\n            case 0x87:\n            case 0x88:\n            case 0x89:\n            case 0x8A:\n            case 0x8B:\n            case 0x8C:\n            case 0x8D:\n            case 0x8E:\n            case 0x8F:\n                return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));\n\n            // fixarray\n            case 0x90:\n            case 0x91:\n            case 0x92:\n            case 0x93:\n            case 0x94:\n            case 0x95:\n            case 0x96:\n            case 0x97:\n            case 0x98:\n            case 0x99:\n            case 0x9A:\n            case 0x9B:\n            case 0x9C:\n            case 0x9D:\n            case 0x9E:\n            case 0x9F:\n                return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));\n\n            // fixstr\n            case 0xA0:\n            case 0xA1:\n            case 0xA2:\n            case 0xA3:\n            case 0xA4:\n            case 0xA5:\n            case 0xA6:\n            case 0xA7:\n            case 0xA8:\n            case 0xA9:\n            case 0xAA:\n            case 0xAB:\n            case 0xAC:\n            case 0xAD:\n            case 0xAE:\n            case 0xAF:\n            case 0xB0:\n            case 0xB1:\n            case 0xB2:\n            case 0xB3:\n            case 0xB4:\n            case 0xB5:\n            case 0xB6:\n            case 0xB7:\n            case 0xB8:\n            case 0xB9:\n            case 0xBA:\n            case 0xBB:\n            case 0xBC:\n            case 0xBD:\n            case 0xBE:\n            case 0xBF:\n            case 0xD9: // str 8\n            case 0xDA: // str 16\n            case 0xDB: // str 32\n            {\n                string_t s;\n                return get_msgpack_string(s) && sax->string(s);\n            }\n\n            case 0xC0: // nil\n                return sax->null();\n\n            case 0xC2: // false\n                return sax->boolean(false);\n\n            case 0xC3: // true\n                return sax->boolean(true);\n\n            case 0xC4: // bin 8\n            case 0xC5: // bin 16\n            case 0xC6: // bin 32\n            case 0xC7: // ext 8\n            case 0xC8: // ext 16\n            case 0xC9: // ext 32\n            case 0xD4: // fixext 1\n            case 0xD5: // fixext 2\n            case 0xD6: // fixext 4\n            case 0xD7: // fixext 8\n            case 0xD8: // fixext 16\n            {\n                binary_t b;\n                return get_msgpack_binary(b) && sax->binary(b);\n            }\n\n            case 0xCA: // float 32\n            {\n                float number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0xCB: // float 64\n            {\n                double number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0xCC: // uint 8\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xCD: // uint 16\n            {\n                std::uint16_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xCE: // uint 32\n            {\n                std::uint32_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xCF: // uint 64\n            {\n                std::uint64_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xD0: // int 8\n            {\n                std::int8_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xD1: // int 16\n            {\n                std::int16_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xD2: // int 32\n            {\n                std::int32_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xD3: // int 64\n            {\n                std::int64_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xDC: // array 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));\n            }\n\n            case 0xDD: // array 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));\n            }\n\n            case 0xDE: // map 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));\n            }\n\n            case 0xDF: // map 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));\n            }\n\n            // negative fixint\n            case 0xE0:\n            case 0xE1:\n            case 0xE2:\n            case 0xE3:\n            case 0xE4:\n            case 0xE5:\n            case 0xE6:\n            case 0xE7:\n            case 0xE8:\n            case 0xE9:\n            case 0xEA:\n            case 0xEB:\n            case 0xEC:\n            case 0xED:\n            case 0xEE:\n            case 0xEF:\n            case 0xF0:\n            case 0xF1:\n            case 0xF2:\n            case 0xF3:\n            case 0xF4:\n            case 0xF5:\n            case 0xF6:\n            case 0xF7:\n            case 0xF8:\n            case 0xF9:\n            case 0xFA:\n            case 0xFB:\n            case 0xFC:\n            case 0xFD:\n            case 0xFE:\n            case 0xFF:\n                return sax->number_integer(static_cast<std::int8_t>(current));\n\n            default: // anything else\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a MessagePack string\n\n    This function first reads starting bytes to determine the expected\n    string length and then copies this number of bytes into a string.\n\n    @param[out] result  created string\n\n    @return whether string creation completed\n    */\n    bool get_msgpack_string(string_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, \"string\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            // fixstr\n            case 0xA0:\n            case 0xA1:\n            case 0xA2:\n            case 0xA3:\n            case 0xA4:\n            case 0xA5:\n            case 0xA6:\n            case 0xA7:\n            case 0xA8:\n            case 0xA9:\n            case 0xAA:\n            case 0xAB:\n            case 0xAC:\n            case 0xAD:\n            case 0xAE:\n            case 0xAF:\n            case 0xB0:\n            case 0xB1:\n            case 0xB2:\n            case 0xB3:\n            case 0xB4:\n            case 0xB5:\n            case 0xB6:\n            case 0xB7:\n            case 0xB8:\n            case 0xB9:\n            case 0xBA:\n            case 0xBB:\n            case 0xBC:\n            case 0xBD:\n            case 0xBE:\n            case 0xBF:\n            {\n                return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);\n            }\n\n            case 0xD9: // str 8\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);\n            }\n\n            case 0xDA: // str 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);\n            }\n\n            case 0xDB: // str 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, \"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x\" + last_token, \"string\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a MessagePack byte array\n\n    This function first reads starting bytes to determine the expected\n    byte array length and then copies this number of bytes into a byte array.\n\n    @param[out] result  created byte array\n\n    @return whether byte array creation completed\n    */\n    bool get_msgpack_binary(binary_t& result)\n    {\n        // helper function to set the subtype\n        auto assign_and_return_true = [&result](std::int8_t subtype)\n        {\n            result.set_subtype(static_cast<std::uint8_t>(subtype));\n            return true;\n        };\n\n        switch (current)\n        {\n            case 0xC4: // bin 8\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_binary(input_format_t::msgpack, len, result);\n            }\n\n            case 0xC5: // bin 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_binary(input_format_t::msgpack, len, result);\n            }\n\n            case 0xC6: // bin 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_binary(input_format_t::msgpack, len, result);\n            }\n\n            case 0xC7: // ext 8\n            {\n                std::uint8_t len{};\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, len, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xC8: // ext 16\n            {\n                std::uint16_t len{};\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, len, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xC9: // ext 32\n            {\n                std::uint32_t len{};\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, len, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD4: // fixext 1\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 1, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD5: // fixext 2\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 2, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD6: // fixext 4\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 4, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD7: // fixext 8\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 8, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD8: // fixext 16\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 16, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            default:           // LCOV_EXCL_LINE\n                return false;  // LCOV_EXCL_LINE\n        }\n    }\n\n    /*!\n    @param[in] len  the length of the array\n    @return whether array creation completed\n    */\n    bool get_msgpack_array(const std::size_t len)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))\n        {\n            return false;\n        }\n\n        for (std::size_t i = 0; i < len; ++i)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))\n            {\n                return false;\n            }\n        }\n\n        return sax->end_array();\n    }\n\n    /*!\n    @param[in] len  the length of the object\n    @return whether object creation completed\n    */\n    bool get_msgpack_object(const std::size_t len)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))\n        {\n            return false;\n        }\n\n        string_t key;\n        for (std::size_t i = 0; i < len; ++i)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))\n            {\n                return false;\n            }\n\n            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))\n            {\n                return false;\n            }\n            key.clear();\n        }\n\n        return sax->end_object();\n    }\n\n    ////////////\n    // UBJSON //\n    ////////////\n\n    /*!\n    @param[in] get_char  whether a new character should be retrieved from the\n                         input (true, default) or whether the last read\n                         character should be considered instead\n\n    @return whether a valid UBJSON value was passed to the SAX parser\n    */\n    bool parse_ubjson_internal(const bool get_char = true)\n    {\n        return get_ubjson_value(get_char ? get_ignore_noop() : current);\n    }\n\n    /*!\n    @brief reads a UBJSON string\n\n    This function is either called after reading the 'S' byte explicitly\n    indicating a string, or in case of an object key where the 'S' byte can be\n    left out.\n\n    @param[out] result   created string\n    @param[in] get_char  whether a new character should be retrieved from the\n                         input (true, default) or whether the last read\n                         character should be considered instead\n\n    @return whether string creation completed\n    */\n    bool get_ubjson_string(string_t& result, const bool get_char = true)\n    {\n        if (get_char)\n        {\n            get();  // TODO(niels): may we ignore N here?\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"value\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            case 'U':\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'i':\n            {\n                std::int8_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'I':\n            {\n                std::int16_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'l':\n            {\n                std::int32_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'L':\n            {\n                std::int64_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            default:\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, \"expected length type specification (U, i, I, l, L); last byte: 0x\" + last_token, \"string\"), BasicJsonType()));\n        }\n    }\n\n    /*!\n    @param[out] result  determined size\n    @return whether size determination completed\n    */\n    bool get_ubjson_size_value(std::size_t& result)\n    {\n        switch (get_ignore_noop())\n        {\n            case 'U':\n            {\n                std::uint8_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            case 'i':\n            {\n                std::int8_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char\n                return true;\n            }\n\n            case 'I':\n            {\n                std::int16_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            case 'l':\n            {\n                std::int32_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            case 'L':\n            {\n                std::int64_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, \"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x\" + last_token, \"size\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief determine the type and size for a container\n\n    In the optimized UBJSON format, a type and a size can be provided to allow\n    for a more compact representation.\n\n    @param[out] result  pair of the size and the type\n\n    @return whether pair creation completed\n    */\n    bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)\n    {\n        result.first = string_t::npos; // size\n        result.second = 0; // type\n\n        get_ignore_noop();\n\n        if (current == '$')\n        {\n            result.second = get();  // must not ignore 'N', because 'N' maybe the type\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"type\")))\n            {\n                return false;\n            }\n\n            get_ignore_noop();\n            if (JSON_HEDLEY_UNLIKELY(current != '#'))\n            {\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"value\")))\n                {\n                    return false;\n                }\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, \"expected '#' after type information; last byte: 0x\" + last_token, \"size\"), BasicJsonType()));\n            }\n\n            return get_ubjson_size_value(result.first);\n        }\n\n        if (current == '#')\n        {\n            return get_ubjson_size_value(result.first);\n        }\n\n        return true;\n    }\n\n    /*!\n    @param prefix  the previously read or set type prefix\n    @return whether value creation completed\n    */\n    bool get_ubjson_value(const char_int_type prefix)\n    {\n        switch (prefix)\n        {\n            case std::char_traits<char_type>::eof():  // EOF\n                return unexpect_eof(input_format_t::ubjson, \"value\");\n\n            case 'T':  // true\n                return sax->boolean(true);\n            case 'F':  // false\n                return sax->boolean(false);\n\n            case 'Z':  // null\n                return sax->null();\n\n            case 'U':\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);\n            }\n\n            case 'i':\n            {\n                std::int8_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'I':\n            {\n                std::int16_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'l':\n            {\n                std::int32_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'L':\n            {\n                std::int64_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'd':\n            {\n                float number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 'D':\n            {\n                double number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 'H':\n            {\n                return get_ubjson_high_precision_number();\n            }\n\n            case 'C':  // char\n            {\n                get();\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"char\")))\n                {\n                    return false;\n                }\n                if (JSON_HEDLEY_UNLIKELY(current > 127))\n                {\n                    auto last_token = get_token_string();\n                    return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, \"byte after 'C' must be in range 0x00..0x7F; last byte: 0x\" + last_token, \"char\"), BasicJsonType()));\n                }\n                string_t s(1, static_cast<typename string_t::value_type>(current));\n                return sax->string(s);\n            }\n\n            case 'S':  // string\n            {\n                string_t s;\n                return get_ubjson_string(s) && sax->string(s);\n            }\n\n            case '[':  // array\n                return get_ubjson_array();\n\n            case '{':  // object\n                return get_ubjson_object();\n\n            default: // anything else\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @return whether array creation completed\n    */\n    bool get_ubjson_array()\n    {\n        std::pair<std::size_t, char_int_type> size_and_type;\n        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))\n        {\n            return false;\n        }\n\n        if (size_and_type.first != string_t::npos)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))\n            {\n                return false;\n            }\n\n            if (size_and_type.second != 0)\n            {\n                if (size_and_type.second != 'N')\n                {\n                    for (std::size_t i = 0; i < size_and_type.first; ++i)\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))\n                        {\n                            return false;\n                        }\n                    }\n                }\n            }\n            else\n            {\n                for (std::size_t i = 0; i < size_and_type.first; ++i)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))\n                    {\n                        return false;\n                    }\n                }\n            }\n        }\n        else\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))\n            {\n                return false;\n            }\n\n            while (current != ']')\n            {\n                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))\n                {\n                    return false;\n                }\n                get_ignore_noop();\n            }\n        }\n\n        return sax->end_array();\n    }\n\n    /*!\n    @return whether object creation completed\n    */\n    bool get_ubjson_object()\n    {\n        std::pair<std::size_t, char_int_type> size_and_type;\n        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))\n        {\n            return false;\n        }\n\n        string_t key;\n        if (size_and_type.first != string_t::npos)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))\n            {\n                return false;\n            }\n\n            if (size_and_type.second != 0)\n            {\n                for (std::size_t i = 0; i < size_and_type.first; ++i)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n            else\n            {\n                for (std::size_t i = 0; i < size_and_type.first; ++i)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n        }\n        else\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))\n            {\n                return false;\n            }\n\n            while (current != '}')\n            {\n                if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))\n                {\n                    return false;\n                }\n                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))\n                {\n                    return false;\n                }\n                get_ignore_noop();\n                key.clear();\n            }\n        }\n\n        return sax->end_object();\n    }\n\n    // Note, no reader for UBJSON binary types is implemented because they do\n    // not exist\n\n    bool get_ubjson_high_precision_number()\n    {\n        // get size of following number string\n        std::size_t size{};\n        auto res = get_ubjson_size_value(size);\n        if (JSON_HEDLEY_UNLIKELY(!res))\n        {\n            return res;\n        }\n\n        // get number string\n        std::vector<char> number_vector;\n        for (std::size_t i = 0; i < size; ++i)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"number\")))\n            {\n                return false;\n            }\n            number_vector.push_back(static_cast<char>(current));\n        }\n\n        // parse number string\n        using ia_type = decltype(detail::input_adapter(number_vector));\n        auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);\n        const auto result_number = number_lexer.scan();\n        const auto number_string = number_lexer.get_token_string();\n        const auto result_remainder = number_lexer.scan();\n\n        using token_type = typename detail::lexer_base<BasicJsonType>::token_type;\n\n        if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))\n        {\n            return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, \"invalid number text: \" + number_lexer.get_token_string(), \"high-precision number\"), BasicJsonType()));\n        }\n\n        switch (result_number)\n        {\n            case token_type::value_integer:\n                return sax->number_integer(number_lexer.get_number_integer());\n            case token_type::value_unsigned:\n                return sax->number_unsigned(number_lexer.get_number_unsigned());\n            case token_type::value_float:\n                return sax->number_float(number_lexer.get_number_float(), std::move(number_string));\n            case token_type::uninitialized:\n            case token_type::literal_true:\n            case token_type::literal_false:\n            case token_type::literal_null:\n            case token_type::value_string:\n            case token_type::begin_array:\n            case token_type::begin_object:\n            case token_type::end_array:\n            case token_type::end_object:\n            case token_type::name_separator:\n            case token_type::value_separator:\n            case token_type::parse_error:\n            case token_type::end_of_input:\n            case token_type::literal_or_value:\n            default:\n                return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, \"invalid number text: \" + number_lexer.get_token_string(), \"high-precision number\"), BasicJsonType()));\n        }\n    }\n\n    ///////////////////////\n    // Utility functions //\n    ///////////////////////\n\n    /*!\n    @brief get next character from the input\n\n    This function provides the interface to the used input adapter. It does\n    not throw in case the input reached EOF, but returns a -'ve valued\n    `std::char_traits<char_type>::eof()` in that case.\n\n    @return character read from the input\n    */\n    char_int_type get()\n    {\n        ++chars_read;\n        return current = ia.get_character();\n    }\n\n    /*!\n    @return character read from the input after ignoring all 'N' entries\n    */\n    char_int_type get_ignore_noop()\n    {\n        do\n        {\n            get();\n        }\n        while (current == 'N');\n\n        return current;\n    }\n\n    /*\n    @brief read a number from the input\n\n    @tparam NumberType the type of the number\n    @param[in] format   the current format (for diagnostics)\n    @param[out] result  number of type @a NumberType\n\n    @return whether conversion completed\n\n    @note This function needs to respect the system's endianness, because\n          bytes in CBOR, MessagePack, and UBJSON are stored in network order\n          (big endian) and therefore need reordering on little endian systems.\n    */\n    template<typename NumberType, bool InputIsLittleEndian = false>\n    bool get_number(const input_format_t format, NumberType& result)\n    {\n        // step 1: read input into array with system's byte order\n        std::array<std::uint8_t, sizeof(NumberType)> vec{};\n        for (std::size_t i = 0; i < sizeof(NumberType); ++i)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, \"number\")))\n            {\n                return false;\n            }\n\n            // reverse byte order prior to conversion if necessary\n            if (is_little_endian != InputIsLittleEndian)\n            {\n                vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);\n            }\n            else\n            {\n                vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE\n            }\n        }\n\n        // step 2: convert array into number of type T and return\n        std::memcpy(&result, vec.data(), sizeof(NumberType));\n        return true;\n    }\n\n    /*!\n    @brief create a string by reading characters from the input\n\n    @tparam NumberType the type of the number\n    @param[in] format the current format (for diagnostics)\n    @param[in] len number of characters to read\n    @param[out] result string created by reading @a len bytes\n\n    @return whether string creation completed\n\n    @note We can not reserve @a len bytes for the result, because @a len\n          may be too large. Usually, @ref unexpect_eof() detects the end of\n          the input before we run out of string memory.\n    */\n    template<typename NumberType>\n    bool get_string(const input_format_t format,\n                    const NumberType len,\n                    string_t& result)\n    {\n        bool success = true;\n        for (NumberType i = 0; i < len; i++)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, \"string\")))\n            {\n                success = false;\n                break;\n            }\n            result.push_back(static_cast<typename string_t::value_type>(current));\n        }\n        return success;\n    }\n\n    /*!\n    @brief create a byte array by reading bytes from the input\n\n    @tparam NumberType the type of the number\n    @param[in] format the current format (for diagnostics)\n    @param[in] len number of bytes to read\n    @param[out] result byte array created by reading @a len bytes\n\n    @return whether byte array creation completed\n\n    @note We can not reserve @a len bytes for the result, because @a len\n          may be too large. Usually, @ref unexpect_eof() detects the end of\n          the input before we run out of memory.\n    */\n    template<typename NumberType>\n    bool get_binary(const input_format_t format,\n                    const NumberType len,\n                    binary_t& result)\n    {\n        bool success = true;\n        for (NumberType i = 0; i < len; i++)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, \"binary\")))\n            {\n                success = false;\n                break;\n            }\n            result.push_back(static_cast<std::uint8_t>(current));\n        }\n        return success;\n    }\n\n    /*!\n    @param[in] format   the current format (for diagnostics)\n    @param[in] context  further context information (for diagnostics)\n    @return whether the last read character is not EOF\n    */\n    JSON_HEDLEY_NON_NULL(3)\n    bool unexpect_eof(const input_format_t format, const char* context) const\n    {\n        if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))\n        {\n            return sax->parse_error(chars_read, \"<end of file>\",\n                                    parse_error::create(110, chars_read, exception_message(format, \"unexpected end of input\", context), BasicJsonType()));\n        }\n        return true;\n    }\n\n    /*!\n    @return a string representation of the last read byte\n    */\n    std::string get_token_string() const\n    {\n        std::array<char, 3> cr{{}};\n        static_cast<void>((std::snprintf)(cr.data(), cr.size(), \"%.2hhX\", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n        return std::string{cr.data()};\n    }\n\n    /*!\n    @param[in] format   the current format\n    @param[in] detail   a detailed error message\n    @param[in] context  further context information\n    @return a message string to use in the parse_error exceptions\n    */\n    std::string exception_message(const input_format_t format,\n                                  const std::string& detail,\n                                  const std::string& context) const\n    {\n        std::string error_msg = \"syntax error while parsing \";\n\n        switch (format)\n        {\n            case input_format_t::cbor:\n                error_msg += \"CBOR\";\n                break;\n\n            case input_format_t::msgpack:\n                error_msg += \"MessagePack\";\n                break;\n\n            case input_format_t::ubjson:\n                error_msg += \"UBJSON\";\n                break;\n\n            case input_format_t::bson:\n                error_msg += \"BSON\";\n                break;\n\n            case input_format_t::json: // LCOV_EXCL_LINE\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n\n        return error_msg + \" \" + context + \": \" + detail;\n    }\n\n  private:\n    /// input adapter\n    InputAdapterType ia;\n\n    /// the current character\n    char_int_type current = std::char_traits<char_type>::eof();\n\n    /// the number of characters read\n    std::size_t chars_read = 0;\n\n    /// whether we can assume little endianness\n    const bool is_little_endian = little_endianness();\n\n    /// the SAX parser\n    json_sax_t* sax = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/input/input_adapters.hpp",
    "content": "#pragma once\n\n#include <array> // array\n#include <cstddef> // size_t\n#include <cstring> // strlen\n#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next\n#include <memory> // shared_ptr, make_shared, addressof\n#include <numeric> // accumulate\n#include <string> // string, char_traits\n#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer\n#include <utility> // pair, declval\n\n#ifndef JSON_NO_IO\n    #include <cstdio>   // FILE *\n    #include <istream>  // istream\n#endif                  // JSON_NO_IO\n\n#include <nlohmann/detail/iterators/iterator_traits.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/// the supported input formats\nenum class input_format_t { json, cbor, msgpack, ubjson, bson };\n\n////////////////////\n// input adapters //\n////////////////////\n\n#ifndef JSON_NO_IO\n/*!\nInput adapter for stdio file access. This adapter read only 1 byte and do not use any\n buffer. This adapter is a very low level adapter.\n*/\nclass file_input_adapter\n{\n  public:\n    using char_type = char;\n\n    JSON_HEDLEY_NON_NULL(2)\n    explicit file_input_adapter(std::FILE* f) noexcept\n        : m_file(f)\n    {}\n\n    // make class move-only\n    file_input_adapter(const file_input_adapter&) = delete;\n    file_input_adapter(file_input_adapter&&) noexcept = default;\n    file_input_adapter& operator=(const file_input_adapter&) = delete;\n    file_input_adapter& operator=(file_input_adapter&&) = delete;\n    ~file_input_adapter() = default;\n\n    std::char_traits<char>::int_type get_character() noexcept\n    {\n        return std::fgetc(m_file);\n    }\n\n  private:\n    /// the file pointer to read from\n    std::FILE* m_file;\n};\n\n\n/*!\nInput adapter for a (caching) istream. Ignores a UFT Byte Order Mark at\nbeginning of input. Does not support changing the underlying std::streambuf\nin mid-input. Maintains underlying std::istream and std::streambuf to support\nsubsequent use of standard std::istream operations to process any input\ncharacters following those used in parsing the JSON input.  Clears the\nstd::istream flags; any input errors (e.g., EOF) will be detected by the first\nsubsequent call for input from the std::istream.\n*/\nclass input_stream_adapter\n{\n  public:\n    using char_type = char;\n\n    ~input_stream_adapter()\n    {\n        // clear stream flags; we use underlying streambuf I/O, do not\n        // maintain ifstream flags, except eof\n        if (is != nullptr)\n        {\n            is->clear(is->rdstate() & std::ios::eofbit);\n        }\n    }\n\n    explicit input_stream_adapter(std::istream& i)\n        : is(&i), sb(i.rdbuf())\n    {}\n\n    // delete because of pointer members\n    input_stream_adapter(const input_stream_adapter&) = delete;\n    input_stream_adapter& operator=(input_stream_adapter&) = delete;\n    input_stream_adapter& operator=(input_stream_adapter&&) = delete;\n\n    input_stream_adapter(input_stream_adapter&& rhs) noexcept\n        : is(rhs.is), sb(rhs.sb)\n    {\n        rhs.is = nullptr;\n        rhs.sb = nullptr;\n    }\n\n    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to\n    // ensure that std::char_traits<char>::eof() and the character 0xFF do not\n    // end up as the same value, e.g. 0xFFFFFFFF.\n    std::char_traits<char>::int_type get_character()\n    {\n        auto res = sb->sbumpc();\n        // set eof manually, as we don't use the istream interface.\n        if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))\n        {\n            is->clear(is->rdstate() | std::ios::eofbit);\n        }\n        return res;\n    }\n\n  private:\n    /// the associated input stream\n    std::istream* is = nullptr;\n    std::streambuf* sb = nullptr;\n};\n#endif  // JSON_NO_IO\n\n// General-purpose iterator-based adapter. It might not be as fast as\n// theoretically possible for some containers, but it is extremely versatile.\ntemplate<typename IteratorType>\nclass iterator_input_adapter\n{\n  public:\n    using char_type = typename std::iterator_traits<IteratorType>::value_type;\n\n    iterator_input_adapter(IteratorType first, IteratorType last)\n        : current(std::move(first)), end(std::move(last))\n    {}\n\n    typename std::char_traits<char_type>::int_type get_character()\n    {\n        if (JSON_HEDLEY_LIKELY(current != end))\n        {\n            auto result = std::char_traits<char_type>::to_int_type(*current);\n            std::advance(current, 1);\n            return result;\n        }\n\n        return std::char_traits<char_type>::eof();\n    }\n\n  private:\n    IteratorType current;\n    IteratorType end;\n\n    template<typename BaseInputAdapter, size_t T>\n    friend struct wide_string_input_helper;\n\n    bool empty() const\n    {\n        return current == end;\n    }\n};\n\n\ntemplate<typename BaseInputAdapter, size_t T>\nstruct wide_string_input_helper;\n\ntemplate<typename BaseInputAdapter>\nstruct wide_string_input_helper<BaseInputAdapter, 4>\n{\n    // UTF-32\n    static void fill_buffer(BaseInputAdapter& input,\n                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,\n                            size_t& utf8_bytes_index,\n                            size_t& utf8_bytes_filled)\n    {\n        utf8_bytes_index = 0;\n\n        if (JSON_HEDLEY_UNLIKELY(input.empty()))\n        {\n            utf8_bytes[0] = std::char_traits<char>::eof();\n            utf8_bytes_filled = 1;\n        }\n        else\n        {\n            // get the current character\n            const auto wc = input.get_character();\n\n            // UTF-32 to UTF-8 encoding\n            if (wc < 0x80)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                utf8_bytes_filled = 1;\n            }\n            else if (wc <= 0x7FF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 2;\n            }\n            else if (wc <= 0xFFFF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));\n                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 3;\n            }\n            else if (wc <= 0x10FFFF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));\n                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));\n                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 4;\n            }\n            else\n            {\n                // unknown character\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                utf8_bytes_filled = 1;\n            }\n        }\n    }\n};\n\ntemplate<typename BaseInputAdapter>\nstruct wide_string_input_helper<BaseInputAdapter, 2>\n{\n    // UTF-16\n    static void fill_buffer(BaseInputAdapter& input,\n                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,\n                            size_t& utf8_bytes_index,\n                            size_t& utf8_bytes_filled)\n    {\n        utf8_bytes_index = 0;\n\n        if (JSON_HEDLEY_UNLIKELY(input.empty()))\n        {\n            utf8_bytes[0] = std::char_traits<char>::eof();\n            utf8_bytes_filled = 1;\n        }\n        else\n        {\n            // get the current character\n            const auto wc = input.get_character();\n\n            // UTF-16 to UTF-8 encoding\n            if (wc < 0x80)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                utf8_bytes_filled = 1;\n            }\n            else if (wc <= 0x7FF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 2;\n            }\n            else if (0xD800 > wc || wc >= 0xE000)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));\n                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 3;\n            }\n            else\n            {\n                if (JSON_HEDLEY_UNLIKELY(!input.empty()))\n                {\n                    const auto wc2 = static_cast<unsigned int>(input.get_character());\n                    const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));\n                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));\n                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));\n                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));\n                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));\n                    utf8_bytes_filled = 4;\n                }\n                else\n                {\n                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                    utf8_bytes_filled = 1;\n                }\n            }\n        }\n    }\n};\n\n// Wraps another input apdater to convert wide character types into individual bytes.\ntemplate<typename BaseInputAdapter, typename WideCharType>\nclass wide_string_input_adapter\n{\n  public:\n    using char_type = char;\n\n    wide_string_input_adapter(BaseInputAdapter base)\n        : base_adapter(base) {}\n\n    typename std::char_traits<char>::int_type get_character() noexcept\n    {\n        // check if buffer needs to be filled\n        if (utf8_bytes_index == utf8_bytes_filled)\n        {\n            fill_buffer<sizeof(WideCharType)>();\n\n            JSON_ASSERT(utf8_bytes_filled > 0);\n            JSON_ASSERT(utf8_bytes_index == 0);\n        }\n\n        // use buffer\n        JSON_ASSERT(utf8_bytes_filled > 0);\n        JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);\n        return utf8_bytes[utf8_bytes_index++];\n    }\n\n  private:\n    BaseInputAdapter base_adapter;\n\n    template<size_t T>\n    void fill_buffer()\n    {\n        wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);\n    }\n\n    /// a buffer for UTF-8 bytes\n    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};\n\n    /// index to the utf8_codes array for the next valid byte\n    std::size_t utf8_bytes_index = 0;\n    /// number of valid bytes in the utf8_codes array\n    std::size_t utf8_bytes_filled = 0;\n};\n\n\ntemplate<typename IteratorType, typename Enable = void>\nstruct iterator_input_adapter_factory\n{\n    using iterator_type = IteratorType;\n    using char_type = typename std::iterator_traits<iterator_type>::value_type;\n    using adapter_type = iterator_input_adapter<iterator_type>;\n\n    static adapter_type create(IteratorType first, IteratorType last)\n    {\n        return adapter_type(std::move(first), std::move(last));\n    }\n};\n\ntemplate<typename T>\nstruct is_iterator_of_multibyte\n{\n    using value_type = typename std::iterator_traits<T>::value_type;\n    enum\n    {\n        value = sizeof(value_type) > 1\n    };\n};\n\ntemplate<typename IteratorType>\nstruct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>\n{\n    using iterator_type = IteratorType;\n    using char_type = typename std::iterator_traits<iterator_type>::value_type;\n    using base_adapter_type = iterator_input_adapter<iterator_type>;\n    using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;\n\n    static adapter_type create(IteratorType first, IteratorType last)\n    {\n        return adapter_type(base_adapter_type(std::move(first), std::move(last)));\n    }\n};\n\n// General purpose iterator-based input\ntemplate<typename IteratorType>\ntypename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)\n{\n    using factory_type = iterator_input_adapter_factory<IteratorType>;\n    return factory_type::create(first, last);\n}\n\n// Convenience shorthand from container to iterator\n// Enables ADL on begin(container) and end(container)\n// Encloses the using declarations in namespace for not to leak them to outside scope\n\nnamespace container_input_adapter_factory_impl\n{\n\nusing std::begin;\nusing std::end;\n\ntemplate<typename ContainerType, typename Enable = void>\nstruct container_input_adapter_factory {};\n\ntemplate<typename ContainerType>\nstruct container_input_adapter_factory< ContainerType,\n       void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>\n       {\n           using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));\n\n           static adapter_type create(const ContainerType& container)\n{\n    return input_adapter(begin(container), end(container));\n}\n       };\n\n} // namespace container_input_adapter_factory_impl\n\ntemplate<typename ContainerType>\ntypename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)\n{\n    return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);\n}\n\n#ifndef JSON_NO_IO\n// Special cases with fast paths\ninline file_input_adapter input_adapter(std::FILE* file)\n{\n    return file_input_adapter(file);\n}\n\ninline input_stream_adapter input_adapter(std::istream& stream)\n{\n    return input_stream_adapter(stream);\n}\n\ninline input_stream_adapter input_adapter(std::istream&& stream)\n{\n    return input_stream_adapter(stream);\n}\n#endif  // JSON_NO_IO\n\nusing contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));\n\n// Null-delimited strings, and the like.\ntemplate < typename CharT,\n           typename std::enable_if <\n               std::is_pointer<CharT>::value&&\n               !std::is_array<CharT>::value&&\n               std::is_integral<typename std::remove_pointer<CharT>::type>::value&&\n               sizeof(typename std::remove_pointer<CharT>::type) == 1,\n               int >::type = 0 >\ncontiguous_bytes_input_adapter input_adapter(CharT b)\n{\n    auto length = std::strlen(reinterpret_cast<const char*>(b));\n    const auto* ptr = reinterpret_cast<const char*>(b);\n    return input_adapter(ptr, ptr + length);\n}\n\ntemplate<typename T, std::size_t N>\nauto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n{\n    return input_adapter(array, array + N);\n}\n\n// This class only handles inputs of input_buffer_adapter type.\n// It's required so that expressions like {ptr, len} can be implicitly cast\n// to the correct adapter.\nclass span_input_adapter\n{\n  public:\n    template < typename CharT,\n               typename std::enable_if <\n                   std::is_pointer<CharT>::value&&\n                   std::is_integral<typename std::remove_pointer<CharT>::type>::value&&\n                   sizeof(typename std::remove_pointer<CharT>::type) == 1,\n                   int >::type = 0 >\n    span_input_adapter(CharT b, std::size_t l)\n        : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}\n\n    template<class IteratorType,\n             typename std::enable_if<\n                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,\n                 int>::type = 0>\n    span_input_adapter(IteratorType first, IteratorType last)\n        : ia(input_adapter(first, last)) {}\n\n    contiguous_bytes_input_adapter&& get()\n    {\n        return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)\n    }\n\n  private:\n    contiguous_bytes_input_adapter ia;\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/input/json_sax.hpp",
    "content": "#pragma once\n\n#include <cstddef>\n#include <string> // string\n#include <utility> // move\n#include <vector> // vector\n\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\n\n/*!\n@brief SAX interface\n\nThis class describes the SAX interface used by @ref nlohmann::json::sax_parse.\nEach function is called in different situations while the input is parsed. The\nboolean return value informs the parser whether to continue processing the\ninput.\n*/\ntemplate<typename BasicJsonType>\nstruct json_sax\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n\n    /*!\n    @brief a null value was read\n    @return whether parsing should proceed\n    */\n    virtual bool null() = 0;\n\n    /*!\n    @brief a boolean value was read\n    @param[in] val  boolean value\n    @return whether parsing should proceed\n    */\n    virtual bool boolean(bool val) = 0;\n\n    /*!\n    @brief an integer number was read\n    @param[in] val  integer value\n    @return whether parsing should proceed\n    */\n    virtual bool number_integer(number_integer_t val) = 0;\n\n    /*!\n    @brief an unsigned integer number was read\n    @param[in] val  unsigned integer value\n    @return whether parsing should proceed\n    */\n    virtual bool number_unsigned(number_unsigned_t val) = 0;\n\n    /*!\n    @brief a floating-point number was read\n    @param[in] val  floating-point value\n    @param[in] s    raw token value\n    @return whether parsing should proceed\n    */\n    virtual bool number_float(number_float_t val, const string_t& s) = 0;\n\n    /*!\n    @brief a string value was read\n    @param[in] val  string value\n    @return whether parsing should proceed\n    @note It is safe to move the passed string value.\n    */\n    virtual bool string(string_t& val) = 0;\n\n    /*!\n    @brief a binary value was read\n    @param[in] val  binary value\n    @return whether parsing should proceed\n    @note It is safe to move the passed binary value.\n    */\n    virtual bool binary(binary_t& val) = 0;\n\n    /*!\n    @brief the beginning of an object was read\n    @param[in] elements  number of object elements or -1 if unknown\n    @return whether parsing should proceed\n    @note binary formats may report the number of elements\n    */\n    virtual bool start_object(std::size_t elements) = 0;\n\n    /*!\n    @brief an object key was read\n    @param[in] val  object key\n    @return whether parsing should proceed\n    @note It is safe to move the passed string.\n    */\n    virtual bool key(string_t& val) = 0;\n\n    /*!\n    @brief the end of an object was read\n    @return whether parsing should proceed\n    */\n    virtual bool end_object() = 0;\n\n    /*!\n    @brief the beginning of an array was read\n    @param[in] elements  number of array elements or -1 if unknown\n    @return whether parsing should proceed\n    @note binary formats may report the number of elements\n    */\n    virtual bool start_array(std::size_t elements) = 0;\n\n    /*!\n    @brief the end of an array was read\n    @return whether parsing should proceed\n    */\n    virtual bool end_array() = 0;\n\n    /*!\n    @brief a parse error occurred\n    @param[in] position    the position in the input where the error occurs\n    @param[in] last_token  the last read token\n    @param[in] ex          an exception object describing the error\n    @return whether parsing should proceed (must return false)\n    */\n    virtual bool parse_error(std::size_t position,\n                             const std::string& last_token,\n                             const detail::exception& ex) = 0;\n\n    json_sax() = default;\n    json_sax(const json_sax&) = default;\n    json_sax(json_sax&&) noexcept = default;\n    json_sax& operator=(const json_sax&) = default;\n    json_sax& operator=(json_sax&&) noexcept = default;\n    virtual ~json_sax() = default;\n};\n\n\nnamespace detail\n{\n/*!\n@brief SAX implementation to create a JSON value from SAX events\n\nThis class implements the @ref json_sax interface and processes the SAX events\nto create a JSON value which makes it basically a DOM parser. The structure or\nhierarchy of the JSON value is managed by the stack `ref_stack` which contains\na pointer to the respective array or object for each recursion depth.\n\nAfter successful parsing, the value that is passed by reference to the\nconstructor contains the parsed value.\n\n@tparam BasicJsonType  the JSON type\n*/\ntemplate<typename BasicJsonType>\nclass json_sax_dom_parser\n{\n  public:\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n\n    /*!\n    @param[in,out] r  reference to a JSON value that is manipulated while\n                       parsing\n    @param[in] allow_exceptions_  whether parse errors yield exceptions\n    */\n    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)\n        : root(r), allow_exceptions(allow_exceptions_)\n    {}\n\n    // make class move-only\n    json_sax_dom_parser(const json_sax_dom_parser&) = delete;\n    json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;\n    json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~json_sax_dom_parser() = default;\n\n    bool null()\n    {\n        handle_value(nullptr);\n        return true;\n    }\n\n    bool boolean(bool val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_integer(number_integer_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& /*unused*/)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool string(string_t& val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool binary(binary_t& val)\n    {\n        handle_value(std::move(val));\n        return true;\n    }\n\n    bool start_object(std::size_t len)\n    {\n        ref_stack.push_back(handle_value(BasicJsonType::value_t::object));\n\n        if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive object size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool key(string_t& val)\n    {\n        // add null at given key and store the reference for later\n        object_element = &(ref_stack.back()->m_value.object->operator[](val));\n        return true;\n    }\n\n    bool end_object()\n    {\n        ref_stack.back()->set_parents();\n        ref_stack.pop_back();\n        return true;\n    }\n\n    bool start_array(std::size_t len)\n    {\n        ref_stack.push_back(handle_value(BasicJsonType::value_t::array));\n\n        if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive array size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool end_array()\n    {\n        ref_stack.back()->set_parents();\n        ref_stack.pop_back();\n        return true;\n    }\n\n    template<class Exception>\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,\n                     const Exception& ex)\n    {\n        errored = true;\n        static_cast<void>(ex);\n        if (allow_exceptions)\n        {\n            JSON_THROW(ex);\n        }\n        return false;\n    }\n\n    constexpr bool is_errored() const\n    {\n        return errored;\n    }\n\n  private:\n    /*!\n    @invariant If the ref stack is empty, then the passed value will be the new\n               root.\n    @invariant If the ref stack contains a value, then it is an array or an\n               object to which we can add elements\n    */\n    template<typename Value>\n    JSON_HEDLEY_RETURNS_NON_NULL\n    BasicJsonType* handle_value(Value&& v)\n    {\n        if (ref_stack.empty())\n        {\n            root = BasicJsonType(std::forward<Value>(v));\n            return &root;\n        }\n\n        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());\n\n        if (ref_stack.back()->is_array())\n        {\n            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));\n            return &(ref_stack.back()->m_value.array->back());\n        }\n\n        JSON_ASSERT(ref_stack.back()->is_object());\n        JSON_ASSERT(object_element);\n        *object_element = BasicJsonType(std::forward<Value>(v));\n        return object_element;\n    }\n\n    /// the parsed JSON value\n    BasicJsonType& root;\n    /// stack to model hierarchy of values\n    std::vector<BasicJsonType*> ref_stack {};\n    /// helper to hold the reference for the next object element\n    BasicJsonType* object_element = nullptr;\n    /// whether a syntax error occurred\n    bool errored = false;\n    /// whether to throw exceptions in case of errors\n    const bool allow_exceptions = true;\n};\n\ntemplate<typename BasicJsonType>\nclass json_sax_dom_callback_parser\n{\n  public:\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using parser_callback_t = typename BasicJsonType::parser_callback_t;\n    using parse_event_t = typename BasicJsonType::parse_event_t;\n\n    json_sax_dom_callback_parser(BasicJsonType& r,\n                                 const parser_callback_t cb,\n                                 const bool allow_exceptions_ = true)\n        : root(r), callback(cb), allow_exceptions(allow_exceptions_)\n    {\n        keep_stack.push_back(true);\n    }\n\n    // make class move-only\n    json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;\n    json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;\n    json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~json_sax_dom_callback_parser() = default;\n\n    bool null()\n    {\n        handle_value(nullptr);\n        return true;\n    }\n\n    bool boolean(bool val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_integer(number_integer_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& /*unused*/)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool string(string_t& val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool binary(binary_t& val)\n    {\n        handle_value(std::move(val));\n        return true;\n    }\n\n    bool start_object(std::size_t len)\n    {\n        // check callback for object start\n        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);\n        keep_stack.push_back(keep);\n\n        auto val = handle_value(BasicJsonType::value_t::object, true);\n        ref_stack.push_back(val.second);\n\n        // check object limit\n        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive object size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool key(string_t& val)\n    {\n        BasicJsonType k = BasicJsonType(val);\n\n        // check callback for key\n        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);\n        key_keep_stack.push_back(keep);\n\n        // add discarded value at given key and store the reference for later\n        if (keep && ref_stack.back())\n        {\n            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);\n        }\n\n        return true;\n    }\n\n    bool end_object()\n    {\n        if (ref_stack.back())\n        {\n            if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))\n            {\n                // discard object\n                *ref_stack.back() = discarded;\n            }\n            else\n            {\n                ref_stack.back()->set_parents();\n            }\n        }\n\n        JSON_ASSERT(!ref_stack.empty());\n        JSON_ASSERT(!keep_stack.empty());\n        ref_stack.pop_back();\n        keep_stack.pop_back();\n\n        if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())\n        {\n            // remove discarded value\n            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)\n            {\n                if (it->is_discarded())\n                {\n                    ref_stack.back()->erase(it);\n                    break;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    bool start_array(std::size_t len)\n    {\n        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);\n        keep_stack.push_back(keep);\n\n        auto val = handle_value(BasicJsonType::value_t::array, true);\n        ref_stack.push_back(val.second);\n\n        // check array limit\n        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive array size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool end_array()\n    {\n        bool keep = true;\n\n        if (ref_stack.back())\n        {\n            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());\n            if (keep)\n            {\n                ref_stack.back()->set_parents();\n            }\n            else\n            {\n                // discard array\n                *ref_stack.back() = discarded;\n            }\n        }\n\n        JSON_ASSERT(!ref_stack.empty());\n        JSON_ASSERT(!keep_stack.empty());\n        ref_stack.pop_back();\n        keep_stack.pop_back();\n\n        // remove discarded value\n        if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())\n        {\n            ref_stack.back()->m_value.array->pop_back();\n        }\n\n        return true;\n    }\n\n    template<class Exception>\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,\n                     const Exception& ex)\n    {\n        errored = true;\n        static_cast<void>(ex);\n        if (allow_exceptions)\n        {\n            JSON_THROW(ex);\n        }\n        return false;\n    }\n\n    constexpr bool is_errored() const\n    {\n        return errored;\n    }\n\n  private:\n    /*!\n    @param[in] v  value to add to the JSON value we build during parsing\n    @param[in] skip_callback  whether we should skip calling the callback\n               function; this is required after start_array() and\n               start_object() SAX events, because otherwise we would call the\n               callback function with an empty array or object, respectively.\n\n    @invariant If the ref stack is empty, then the passed value will be the new\n               root.\n    @invariant If the ref stack contains a value, then it is an array or an\n               object to which we can add elements\n\n    @return pair of boolean (whether value should be kept) and pointer (to the\n            passed value in the ref_stack hierarchy; nullptr if not kept)\n    */\n    template<typename Value>\n    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)\n    {\n        JSON_ASSERT(!keep_stack.empty());\n\n        // do not handle this value if we know it would be added to a discarded\n        // container\n        if (!keep_stack.back())\n        {\n            return {false, nullptr};\n        }\n\n        // create value\n        auto value = BasicJsonType(std::forward<Value>(v));\n\n        // check callback\n        const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);\n\n        // do not handle this value if we just learnt it shall be discarded\n        if (!keep)\n        {\n            return {false, nullptr};\n        }\n\n        if (ref_stack.empty())\n        {\n            root = std::move(value);\n            return {true, &root};\n        }\n\n        // skip this value if we already decided to skip the parent\n        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)\n        if (!ref_stack.back())\n        {\n            return {false, nullptr};\n        }\n\n        // we now only expect arrays and objects\n        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());\n\n        // array\n        if (ref_stack.back()->is_array())\n        {\n            ref_stack.back()->m_value.array->emplace_back(std::move(value));\n            return {true, &(ref_stack.back()->m_value.array->back())};\n        }\n\n        // object\n        JSON_ASSERT(ref_stack.back()->is_object());\n        // check if we should store an element for the current key\n        JSON_ASSERT(!key_keep_stack.empty());\n        const bool store_element = key_keep_stack.back();\n        key_keep_stack.pop_back();\n\n        if (!store_element)\n        {\n            return {false, nullptr};\n        }\n\n        JSON_ASSERT(object_element);\n        *object_element = std::move(value);\n        return {true, object_element};\n    }\n\n    /// the parsed JSON value\n    BasicJsonType& root;\n    /// stack to model hierarchy of values\n    std::vector<BasicJsonType*> ref_stack {};\n    /// stack to manage which values to keep\n    std::vector<bool> keep_stack {};\n    /// stack to manage which object keys to keep\n    std::vector<bool> key_keep_stack {};\n    /// helper to hold the reference for the next object element\n    BasicJsonType* object_element = nullptr;\n    /// whether a syntax error occurred\n    bool errored = false;\n    /// callback function\n    const parser_callback_t callback = nullptr;\n    /// whether to throw exceptions in case of errors\n    const bool allow_exceptions = true;\n    /// a discarded value for the callback\n    BasicJsonType discarded = BasicJsonType::value_t::discarded;\n};\n\ntemplate<typename BasicJsonType>\nclass json_sax_acceptor\n{\n  public:\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n\n    bool null()\n    {\n        return true;\n    }\n\n    bool boolean(bool /*unused*/)\n    {\n        return true;\n    }\n\n    bool number_integer(number_integer_t /*unused*/)\n    {\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t /*unused*/)\n    {\n        return true;\n    }\n\n    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool string(string_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool binary(binary_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))\n    {\n        return true;\n    }\n\n    bool key(string_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool end_object()\n    {\n        return true;\n    }\n\n    bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))\n    {\n        return true;\n    }\n\n    bool end_array()\n    {\n        return true;\n    }\n\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)\n    {\n        return false;\n    }\n};\n}  // namespace detail\n\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/input/lexer.hpp",
    "content": "#pragma once\n\n#include <array> // array\n#include <clocale> // localeconv\n#include <cstddef> // size_t\n#include <cstdio> // snprintf\n#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull\n#include <initializer_list> // initializer_list\n#include <string> // char_traits, string\n#include <utility> // move\n#include <vector> // vector\n\n#include <nlohmann/detail/input/input_adapters.hpp>\n#include <nlohmann/detail/input/position_t.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////\n// lexer //\n///////////\n\ntemplate<typename BasicJsonType>\nclass lexer_base\n{\n  public:\n    /// token types for the parser\n    enum class token_type\n    {\n        uninitialized,    ///< indicating the scanner is uninitialized\n        literal_true,     ///< the `true` literal\n        literal_false,    ///< the `false` literal\n        literal_null,     ///< the `null` literal\n        value_string,     ///< a string -- use get_string() for actual value\n        value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value\n        value_integer,    ///< a signed integer -- use get_number_integer() for actual value\n        value_float,      ///< an floating point number -- use get_number_float() for actual value\n        begin_array,      ///< the character for array begin `[`\n        begin_object,     ///< the character for object begin `{`\n        end_array,        ///< the character for array end `]`\n        end_object,       ///< the character for object end `}`\n        name_separator,   ///< the name separator `:`\n        value_separator,  ///< the value separator `,`\n        parse_error,      ///< indicating a parse error\n        end_of_input,     ///< indicating the end of the input buffer\n        literal_or_value  ///< a literal or the begin of a value (only for diagnostics)\n    };\n\n    /// return name of values of type token_type (only used for errors)\n    JSON_HEDLEY_RETURNS_NON_NULL\n    JSON_HEDLEY_CONST\n    static const char* token_type_name(const token_type t) noexcept\n    {\n        switch (t)\n        {\n            case token_type::uninitialized:\n                return \"<uninitialized>\";\n            case token_type::literal_true:\n                return \"true literal\";\n            case token_type::literal_false:\n                return \"false literal\";\n            case token_type::literal_null:\n                return \"null literal\";\n            case token_type::value_string:\n                return \"string literal\";\n            case token_type::value_unsigned:\n            case token_type::value_integer:\n            case token_type::value_float:\n                return \"number literal\";\n            case token_type::begin_array:\n                return \"'['\";\n            case token_type::begin_object:\n                return \"'{'\";\n            case token_type::end_array:\n                return \"']'\";\n            case token_type::end_object:\n                return \"'}'\";\n            case token_type::name_separator:\n                return \"':'\";\n            case token_type::value_separator:\n                return \"','\";\n            case token_type::parse_error:\n                return \"<parse error>\";\n            case token_type::end_of_input:\n                return \"end of input\";\n            case token_type::literal_or_value:\n                return \"'[', '{', or a literal\";\n            // LCOV_EXCL_START\n            default: // catch non-enum values\n                return \"unknown token\";\n                // LCOV_EXCL_STOP\n        }\n    }\n};\n/*!\n@brief lexical analysis\n\nThis class organizes the lexical analysis during JSON deserialization.\n*/\ntemplate<typename BasicJsonType, typename InputAdapterType>\nclass lexer : public lexer_base<BasicJsonType>\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using char_type = typename InputAdapterType::char_type;\n    using char_int_type = typename std::char_traits<char_type>::int_type;\n\n  public:\n    using token_type = typename lexer_base<BasicJsonType>::token_type;\n\n    explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept\n        : ia(std::move(adapter))\n        , ignore_comments(ignore_comments_)\n        , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))\n    {}\n\n    // delete because of pointer members\n    lexer(const lexer&) = delete;\n    lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    lexer& operator=(lexer&) = delete;\n    lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~lexer() = default;\n\n  private:\n    /////////////////////\n    // locales\n    /////////////////////\n\n    /// return the locale-dependent decimal point\n    JSON_HEDLEY_PURE\n    static char get_decimal_point() noexcept\n    {\n        const auto* loc = localeconv();\n        JSON_ASSERT(loc != nullptr);\n        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);\n    }\n\n    /////////////////////\n    // scan functions\n    /////////////////////\n\n    /*!\n    @brief get codepoint from 4 hex characters following `\\u`\n\n    For input \"\\u c1 c2 c3 c4\" the codepoint is:\n      (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4\n    = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)\n\n    Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'\n    must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The\n    conversion is done by subtracting the offset (0x30, 0x37, and 0x57)\n    between the ASCII value of the character and the desired integer value.\n\n    @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or\n            non-hex character)\n    */\n    int get_codepoint()\n    {\n        // this function only makes sense after reading `\\u`\n        JSON_ASSERT(current == 'u');\n        int codepoint = 0;\n\n        const auto factors = { 12u, 8u, 4u, 0u };\n        for (const auto factor : factors)\n        {\n            get();\n\n            if (current >= '0' && current <= '9')\n            {\n                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);\n            }\n            else if (current >= 'A' && current <= 'F')\n            {\n                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);\n            }\n            else if (current >= 'a' && current <= 'f')\n            {\n                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);\n        return codepoint;\n    }\n\n    /*!\n    @brief check if the next byte(s) are inside a given range\n\n    Adds the current byte and, for each passed range, reads a new byte and\n    checks if it is inside the range. If a violation was detected, set up an\n    error message and return false. Otherwise, return true.\n\n    @param[in] ranges  list of integers; interpreted as list of pairs of\n                       inclusive lower and upper bound, respectively\n\n    @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,\n         1, 2, or 3 pairs. This precondition is enforced by an assertion.\n\n    @return true if and only if no range violation was detected\n    */\n    bool next_byte_in_range(std::initializer_list<char_int_type> ranges)\n    {\n        JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);\n        add(current);\n\n        for (auto range = ranges.begin(); range != ranges.end(); ++range)\n        {\n            get();\n            if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))\n            {\n                add(current);\n            }\n            else\n            {\n                error_message = \"invalid string: ill-formed UTF-8 byte\";\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /*!\n    @brief scan a string literal\n\n    This function scans a string according to Sect. 7 of RFC 8259. While\n    scanning, bytes are escaped and copied into buffer token_buffer. Then the\n    function returns successfully, token_buffer is *not* null-terminated (as it\n    may contain \\0 bytes), and token_buffer.size() is the number of bytes in the\n    string.\n\n    @return token_type::value_string if string could be successfully scanned,\n            token_type::parse_error otherwise\n\n    @note In case of errors, variable error_message contains a textual\n          description.\n    */\n    token_type scan_string()\n    {\n        // reset token_buffer (ignore opening quote)\n        reset();\n\n        // we entered the function by reading an open quote\n        JSON_ASSERT(current == '\\\"');\n\n        while (true)\n        {\n            // get next character\n            switch (get())\n            {\n                // end of file while parsing string\n                case std::char_traits<char_type>::eof():\n                {\n                    error_message = \"invalid string: missing closing quote\";\n                    return token_type::parse_error;\n                }\n\n                // closing quote\n                case '\\\"':\n                {\n                    return token_type::value_string;\n                }\n\n                // escapes\n                case '\\\\':\n                {\n                    switch (get())\n                    {\n                        // quotation mark\n                        case '\\\"':\n                            add('\\\"');\n                            break;\n                        // reverse solidus\n                        case '\\\\':\n                            add('\\\\');\n                            break;\n                        // solidus\n                        case '/':\n                            add('/');\n                            break;\n                        // backspace\n                        case 'b':\n                            add('\\b');\n                            break;\n                        // form feed\n                        case 'f':\n                            add('\\f');\n                            break;\n                        // line feed\n                        case 'n':\n                            add('\\n');\n                            break;\n                        // carriage return\n                        case 'r':\n                            add('\\r');\n                            break;\n                        // tab\n                        case 't':\n                            add('\\t');\n                            break;\n\n                        // unicode escapes\n                        case 'u':\n                        {\n                            const int codepoint1 = get_codepoint();\n                            int codepoint = codepoint1; // start with codepoint1\n\n                            if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))\n                            {\n                                error_message = \"invalid string: '\\\\u' must be followed by 4 hex digits\";\n                                return token_type::parse_error;\n                            }\n\n                            // check if code point is a high surrogate\n                            if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)\n                            {\n                                // expect next \\uxxxx entry\n                                if (JSON_HEDLEY_LIKELY(get() == '\\\\' && get() == 'u'))\n                                {\n                                    const int codepoint2 = get_codepoint();\n\n                                    if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))\n                                    {\n                                        error_message = \"invalid string: '\\\\u' must be followed by 4 hex digits\";\n                                        return token_type::parse_error;\n                                    }\n\n                                    // check if codepoint2 is a low surrogate\n                                    if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))\n                                    {\n                                        // overwrite codepoint\n                                        codepoint = static_cast<int>(\n                                                        // high surrogate occupies the most significant 22 bits\n                                                        (static_cast<unsigned int>(codepoint1) << 10u)\n                                                        // low surrogate occupies the least significant 15 bits\n                                                        + static_cast<unsigned int>(codepoint2)\n                                                        // there is still the 0xD800, 0xDC00 and 0x10000 noise\n                                                        // in the result, so we have to subtract with:\n                                                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00\n                                                        - 0x35FDC00u);\n                                    }\n                                    else\n                                    {\n                                        error_message = \"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF\";\n                                        return token_type::parse_error;\n                                    }\n                                }\n                                else\n                                {\n                                    error_message = \"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF\";\n                                    return token_type::parse_error;\n                                }\n                            }\n                            else\n                            {\n                                if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))\n                                {\n                                    error_message = \"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF\";\n                                    return token_type::parse_error;\n                                }\n                            }\n\n                            // result of the above calculation yields a proper codepoint\n                            JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);\n\n                            // translate codepoint into bytes\n                            if (codepoint < 0x80)\n                            {\n                                // 1-byte characters: 0xxxxxxx (ASCII)\n                                add(static_cast<char_int_type>(codepoint));\n                            }\n                            else if (codepoint <= 0x7FF)\n                            {\n                                // 2-byte characters: 110xxxxx 10xxxxxx\n                                add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));\n                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));\n                            }\n                            else if (codepoint <= 0xFFFF)\n                            {\n                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx\n                                add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));\n                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));\n                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));\n                            }\n                            else\n                            {\n                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n                                add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));\n                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));\n                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));\n                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));\n                            }\n\n                            break;\n                        }\n\n                        // other characters after escape\n                        default:\n                            error_message = \"invalid string: forbidden character after backslash\";\n                            return token_type::parse_error;\n                    }\n\n                    break;\n                }\n\n                // invalid control characters\n                case 0x00:\n                {\n                    error_message = \"invalid string: control character U+0000 (NUL) must be escaped to \\\\u0000\";\n                    return token_type::parse_error;\n                }\n\n                case 0x01:\n                {\n                    error_message = \"invalid string: control character U+0001 (SOH) must be escaped to \\\\u0001\";\n                    return token_type::parse_error;\n                }\n\n                case 0x02:\n                {\n                    error_message = \"invalid string: control character U+0002 (STX) must be escaped to \\\\u0002\";\n                    return token_type::parse_error;\n                }\n\n                case 0x03:\n                {\n                    error_message = \"invalid string: control character U+0003 (ETX) must be escaped to \\\\u0003\";\n                    return token_type::parse_error;\n                }\n\n                case 0x04:\n                {\n                    error_message = \"invalid string: control character U+0004 (EOT) must be escaped to \\\\u0004\";\n                    return token_type::parse_error;\n                }\n\n                case 0x05:\n                {\n                    error_message = \"invalid string: control character U+0005 (ENQ) must be escaped to \\\\u0005\";\n                    return token_type::parse_error;\n                }\n\n                case 0x06:\n                {\n                    error_message = \"invalid string: control character U+0006 (ACK) must be escaped to \\\\u0006\";\n                    return token_type::parse_error;\n                }\n\n                case 0x07:\n                {\n                    error_message = \"invalid string: control character U+0007 (BEL) must be escaped to \\\\u0007\";\n                    return token_type::parse_error;\n                }\n\n                case 0x08:\n                {\n                    error_message = \"invalid string: control character U+0008 (BS) must be escaped to \\\\u0008 or \\\\b\";\n                    return token_type::parse_error;\n                }\n\n                case 0x09:\n                {\n                    error_message = \"invalid string: control character U+0009 (HT) must be escaped to \\\\u0009 or \\\\t\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0A:\n                {\n                    error_message = \"invalid string: control character U+000A (LF) must be escaped to \\\\u000A or \\\\n\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0B:\n                {\n                    error_message = \"invalid string: control character U+000B (VT) must be escaped to \\\\u000B\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0C:\n                {\n                    error_message = \"invalid string: control character U+000C (FF) must be escaped to \\\\u000C or \\\\f\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0D:\n                {\n                    error_message = \"invalid string: control character U+000D (CR) must be escaped to \\\\u000D or \\\\r\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0E:\n                {\n                    error_message = \"invalid string: control character U+000E (SO) must be escaped to \\\\u000E\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0F:\n                {\n                    error_message = \"invalid string: control character U+000F (SI) must be escaped to \\\\u000F\";\n                    return token_type::parse_error;\n                }\n\n                case 0x10:\n                {\n                    error_message = \"invalid string: control character U+0010 (DLE) must be escaped to \\\\u0010\";\n                    return token_type::parse_error;\n                }\n\n                case 0x11:\n                {\n                    error_message = \"invalid string: control character U+0011 (DC1) must be escaped to \\\\u0011\";\n                    return token_type::parse_error;\n                }\n\n                case 0x12:\n                {\n                    error_message = \"invalid string: control character U+0012 (DC2) must be escaped to \\\\u0012\";\n                    return token_type::parse_error;\n                }\n\n                case 0x13:\n                {\n                    error_message = \"invalid string: control character U+0013 (DC3) must be escaped to \\\\u0013\";\n                    return token_type::parse_error;\n                }\n\n                case 0x14:\n                {\n                    error_message = \"invalid string: control character U+0014 (DC4) must be escaped to \\\\u0014\";\n                    return token_type::parse_error;\n                }\n\n                case 0x15:\n                {\n                    error_message = \"invalid string: control character U+0015 (NAK) must be escaped to \\\\u0015\";\n                    return token_type::parse_error;\n                }\n\n                case 0x16:\n                {\n                    error_message = \"invalid string: control character U+0016 (SYN) must be escaped to \\\\u0016\";\n                    return token_type::parse_error;\n                }\n\n                case 0x17:\n                {\n                    error_message = \"invalid string: control character U+0017 (ETB) must be escaped to \\\\u0017\";\n                    return token_type::parse_error;\n                }\n\n                case 0x18:\n                {\n                    error_message = \"invalid string: control character U+0018 (CAN) must be escaped to \\\\u0018\";\n                    return token_type::parse_error;\n                }\n\n                case 0x19:\n                {\n                    error_message = \"invalid string: control character U+0019 (EM) must be escaped to \\\\u0019\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1A:\n                {\n                    error_message = \"invalid string: control character U+001A (SUB) must be escaped to \\\\u001A\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1B:\n                {\n                    error_message = \"invalid string: control character U+001B (ESC) must be escaped to \\\\u001B\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1C:\n                {\n                    error_message = \"invalid string: control character U+001C (FS) must be escaped to \\\\u001C\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1D:\n                {\n                    error_message = \"invalid string: control character U+001D (GS) must be escaped to \\\\u001D\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1E:\n                {\n                    error_message = \"invalid string: control character U+001E (RS) must be escaped to \\\\u001E\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1F:\n                {\n                    error_message = \"invalid string: control character U+001F (US) must be escaped to \\\\u001F\";\n                    return token_type::parse_error;\n                }\n\n                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))\n                case 0x20:\n                case 0x21:\n                case 0x23:\n                case 0x24:\n                case 0x25:\n                case 0x26:\n                case 0x27:\n                case 0x28:\n                case 0x29:\n                case 0x2A:\n                case 0x2B:\n                case 0x2C:\n                case 0x2D:\n                case 0x2E:\n                case 0x2F:\n                case 0x30:\n                case 0x31:\n                case 0x32:\n                case 0x33:\n                case 0x34:\n                case 0x35:\n                case 0x36:\n                case 0x37:\n                case 0x38:\n                case 0x39:\n                case 0x3A:\n                case 0x3B:\n                case 0x3C:\n                case 0x3D:\n                case 0x3E:\n                case 0x3F:\n                case 0x40:\n                case 0x41:\n                case 0x42:\n                case 0x43:\n                case 0x44:\n                case 0x45:\n                case 0x46:\n                case 0x47:\n                case 0x48:\n                case 0x49:\n                case 0x4A:\n                case 0x4B:\n                case 0x4C:\n                case 0x4D:\n                case 0x4E:\n                case 0x4F:\n                case 0x50:\n                case 0x51:\n                case 0x52:\n                case 0x53:\n                case 0x54:\n                case 0x55:\n                case 0x56:\n                case 0x57:\n                case 0x58:\n                case 0x59:\n                case 0x5A:\n                case 0x5B:\n                case 0x5D:\n                case 0x5E:\n                case 0x5F:\n                case 0x60:\n                case 0x61:\n                case 0x62:\n                case 0x63:\n                case 0x64:\n                case 0x65:\n                case 0x66:\n                case 0x67:\n                case 0x68:\n                case 0x69:\n                case 0x6A:\n                case 0x6B:\n                case 0x6C:\n                case 0x6D:\n                case 0x6E:\n                case 0x6F:\n                case 0x70:\n                case 0x71:\n                case 0x72:\n                case 0x73:\n                case 0x74:\n                case 0x75:\n                case 0x76:\n                case 0x77:\n                case 0x78:\n                case 0x79:\n                case 0x7A:\n                case 0x7B:\n                case 0x7C:\n                case 0x7D:\n                case 0x7E:\n                case 0x7F:\n                {\n                    add(current);\n                    break;\n                }\n\n                // U+0080..U+07FF: bytes C2..DF 80..BF\n                case 0xC2:\n                case 0xC3:\n                case 0xC4:\n                case 0xC5:\n                case 0xC6:\n                case 0xC7:\n                case 0xC8:\n                case 0xC9:\n                case 0xCA:\n                case 0xCB:\n                case 0xCC:\n                case 0xCD:\n                case 0xCE:\n                case 0xCF:\n                case 0xD0:\n                case 0xD1:\n                case 0xD2:\n                case 0xD3:\n                case 0xD4:\n                case 0xD5:\n                case 0xD6:\n                case 0xD7:\n                case 0xD8:\n                case 0xD9:\n                case 0xDA:\n                case 0xDB:\n                case 0xDC:\n                case 0xDD:\n                case 0xDE:\n                case 0xDF:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF\n                case 0xE0:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF\n                // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF\n                case 0xE1:\n                case 0xE2:\n                case 0xE3:\n                case 0xE4:\n                case 0xE5:\n                case 0xE6:\n                case 0xE7:\n                case 0xE8:\n                case 0xE9:\n                case 0xEA:\n                case 0xEB:\n                case 0xEC:\n                case 0xEE:\n                case 0xEF:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+D000..U+D7FF: bytes ED 80..9F 80..BF\n                case 0xED:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF\n                case 0xF0:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF\n                case 0xF1:\n                case 0xF2:\n                case 0xF3:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF\n                case 0xF4:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // remaining bytes (80..C1 and F5..FF) are ill-formed\n                default:\n                {\n                    error_message = \"invalid string: ill-formed UTF-8 byte\";\n                    return token_type::parse_error;\n                }\n            }\n        }\n    }\n\n    /*!\n     * @brief scan a comment\n     * @return whether comment could be scanned successfully\n     */\n    bool scan_comment()\n    {\n        switch (get())\n        {\n            // single-line comments skip input until a newline or EOF is read\n            case '/':\n            {\n                while (true)\n                {\n                    switch (get())\n                    {\n                        case '\\n':\n                        case '\\r':\n                        case std::char_traits<char_type>::eof():\n                        case '\\0':\n                            return true;\n\n                        default:\n                            break;\n                    }\n                }\n            }\n\n            // multi-line comments skip input until */ is read\n            case '*':\n            {\n                while (true)\n                {\n                    switch (get())\n                    {\n                        case std::char_traits<char_type>::eof():\n                        case '\\0':\n                        {\n                            error_message = \"invalid comment; missing closing '*/'\";\n                            return false;\n                        }\n\n                        case '*':\n                        {\n                            switch (get())\n                            {\n                                case '/':\n                                    return true;\n\n                                default:\n                                {\n                                    unget();\n                                    continue;\n                                }\n                            }\n                        }\n\n                        default:\n                            continue;\n                    }\n                }\n            }\n\n            // unexpected character after reading '/'\n            default:\n            {\n                error_message = \"invalid comment; expecting '/' or '*' after '/'\";\n                return false;\n            }\n        }\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    static void strtof(float& f, const char* str, char** endptr) noexcept\n    {\n        f = std::strtof(str, endptr);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    static void strtof(double& f, const char* str, char** endptr) noexcept\n    {\n        f = std::strtod(str, endptr);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    static void strtof(long double& f, const char* str, char** endptr) noexcept\n    {\n        f = std::strtold(str, endptr);\n    }\n\n    /*!\n    @brief scan a number literal\n\n    This function scans a string according to Sect. 6 of RFC 8259.\n\n    The function is realized with a deterministic finite state machine derived\n    from the grammar described in RFC 8259. Starting in state \"init\", the\n    input is read and used to determined the next state. Only state \"done\"\n    accepts the number. State \"error\" is a trap state to model errors. In the\n    table below, \"anything\" means any character but the ones listed before.\n\n    state    | 0        | 1-9      | e E      | +       | -       | .        | anything\n    ---------|----------|----------|----------|---------|---------|----------|-----------\n    init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]\n    minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]\n    zero     | done     | done     | exponent | done    | done    | decimal1 | done\n    any1     | any1     | any1     | exponent | done    | done    | decimal1 | done\n    decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]\n    decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done\n    exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]\n    sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]\n    any2     | any2     | any2     | done     | done    | done    | done     | done\n\n    The state machine is realized with one label per state (prefixed with\n    \"scan_number_\") and `goto` statements between them. The state machine\n    contains cycles, but any cycle can be left when EOF is read. Therefore,\n    the function is guaranteed to terminate.\n\n    During scanning, the read bytes are stored in token_buffer. This string is\n    then converted to a signed integer, an unsigned integer, or a\n    floating-point number.\n\n    @return token_type::value_unsigned, token_type::value_integer, or\n            token_type::value_float if number could be successfully scanned,\n            token_type::parse_error otherwise\n\n    @note The scanner is independent of the current locale. Internally, the\n          locale's decimal point is used instead of `.` to work with the\n          locale-dependent converters.\n    */\n    token_type scan_number()  // lgtm [cpp/use-of-goto]\n    {\n        // reset token_buffer to store the number's bytes\n        reset();\n\n        // the type of the parsed number; initially set to unsigned; will be\n        // changed if minus sign, decimal point or exponent is read\n        token_type number_type = token_type::value_unsigned;\n\n        // state (init): we just found out we need to scan a number\n        switch (current)\n        {\n            case '-':\n            {\n                add(current);\n                goto scan_number_minus;\n            }\n\n            case '0':\n            {\n                add(current);\n                goto scan_number_zero;\n            }\n\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any1;\n            }\n\n            // all other characters are rejected outside scan_number()\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n\nscan_number_minus:\n        // state: we just parsed a leading minus sign\n        number_type = token_type::value_integer;\n        switch (get())\n        {\n            case '0':\n            {\n                add(current);\n                goto scan_number_zero;\n            }\n\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any1;\n            }\n\n            default:\n            {\n                error_message = \"invalid number; expected digit after '-'\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_zero:\n        // state: we just parse a zero (maybe with a leading minus sign)\n        switch (get())\n        {\n            case '.':\n            {\n                add(decimal_point_char);\n                goto scan_number_decimal1;\n            }\n\n            case 'e':\n            case 'E':\n            {\n                add(current);\n                goto scan_number_exponent;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_any1:\n        // state: we just parsed a number 0-9 (maybe with a leading minus sign)\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any1;\n            }\n\n            case '.':\n            {\n                add(decimal_point_char);\n                goto scan_number_decimal1;\n            }\n\n            case 'e':\n            case 'E':\n            {\n                add(current);\n                goto scan_number_exponent;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_decimal1:\n        // state: we just parsed a decimal point\n        number_type = token_type::value_float;\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_decimal2;\n            }\n\n            default:\n            {\n                error_message = \"invalid number; expected digit after '.'\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_decimal2:\n        // we just parsed at least one number after a decimal point\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_decimal2;\n            }\n\n            case 'e':\n            case 'E':\n            {\n                add(current);\n                goto scan_number_exponent;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_exponent:\n        // we just parsed an exponent\n        number_type = token_type::value_float;\n        switch (get())\n        {\n            case '+':\n            case '-':\n            {\n                add(current);\n                goto scan_number_sign;\n            }\n\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any2;\n            }\n\n            default:\n            {\n                error_message =\n                    \"invalid number; expected '+', '-', or digit after exponent\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_sign:\n        // we just parsed an exponent sign\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any2;\n            }\n\n            default:\n            {\n                error_message = \"invalid number; expected digit after exponent sign\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_any2:\n        // we just parsed a number after the exponent or exponent sign\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any2;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_done:\n        // unget the character after the number (we only read it to know that\n        // we are done scanning a number)\n        unget();\n\n        char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n        errno = 0;\n\n        // try to parse integers first and fall back to floats\n        if (number_type == token_type::value_unsigned)\n        {\n            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);\n\n            // we checked the number format before\n            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());\n\n            if (errno == 0)\n            {\n                value_unsigned = static_cast<number_unsigned_t>(x);\n                if (value_unsigned == x)\n                {\n                    return token_type::value_unsigned;\n                }\n            }\n        }\n        else if (number_type == token_type::value_integer)\n        {\n            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);\n\n            // we checked the number format before\n            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());\n\n            if (errno == 0)\n            {\n                value_integer = static_cast<number_integer_t>(x);\n                if (value_integer == x)\n                {\n                    return token_type::value_integer;\n                }\n            }\n        }\n\n        // this code is reached if we parse a floating-point number or if an\n        // integer conversion above failed\n        strtof(value_float, token_buffer.data(), &endptr);\n\n        // we checked the number format before\n        JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());\n\n        return token_type::value_float;\n    }\n\n    /*!\n    @param[in] literal_text  the literal text to expect\n    @param[in] length        the length of the passed literal text\n    @param[in] return_type   the token type to return on success\n    */\n    JSON_HEDLEY_NON_NULL(2)\n    token_type scan_literal(const char_type* literal_text, const std::size_t length,\n                            token_type return_type)\n    {\n        JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);\n        for (std::size_t i = 1; i < length; ++i)\n        {\n            if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))\n            {\n                error_message = \"invalid literal\";\n                return token_type::parse_error;\n            }\n        }\n        return return_type;\n    }\n\n    /////////////////////\n    // input management\n    /////////////////////\n\n    /// reset token_buffer; current character is beginning of token\n    void reset() noexcept\n    {\n        token_buffer.clear();\n        token_string.clear();\n        token_string.push_back(std::char_traits<char_type>::to_char_type(current));\n    }\n\n    /*\n    @brief get next character from the input\n\n    This function provides the interface to the used input adapter. It does\n    not throw in case the input reached EOF, but returns a\n    `std::char_traits<char>::eof()` in that case.  Stores the scanned characters\n    for use in error messages.\n\n    @return character read from the input\n    */\n    char_int_type get()\n    {\n        ++position.chars_read_total;\n        ++position.chars_read_current_line;\n\n        if (next_unget)\n        {\n            // just reset the next_unget variable and work with current\n            next_unget = false;\n        }\n        else\n        {\n            current = ia.get_character();\n        }\n\n        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))\n        {\n            token_string.push_back(std::char_traits<char_type>::to_char_type(current));\n        }\n\n        if (current == '\\n')\n        {\n            ++position.lines_read;\n            position.chars_read_current_line = 0;\n        }\n\n        return current;\n    }\n\n    /*!\n    @brief unget current character (read it again on next get)\n\n    We implement unget by setting variable next_unget to true. The input is not\n    changed - we just simulate ungetting by modifying chars_read_total,\n    chars_read_current_line, and token_string. The next call to get() will\n    behave as if the unget character is read again.\n    */\n    void unget()\n    {\n        next_unget = true;\n\n        --position.chars_read_total;\n\n        // in case we \"unget\" a newline, we have to also decrement the lines_read\n        if (position.chars_read_current_line == 0)\n        {\n            if (position.lines_read > 0)\n            {\n                --position.lines_read;\n            }\n        }\n        else\n        {\n            --position.chars_read_current_line;\n        }\n\n        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))\n        {\n            JSON_ASSERT(!token_string.empty());\n            token_string.pop_back();\n        }\n    }\n\n    /// add a character to token_buffer\n    void add(char_int_type c)\n    {\n        token_buffer.push_back(static_cast<typename string_t::value_type>(c));\n    }\n\n  public:\n    /////////////////////\n    // value getters\n    /////////////////////\n\n    /// return integer value\n    constexpr number_integer_t get_number_integer() const noexcept\n    {\n        return value_integer;\n    }\n\n    /// return unsigned integer value\n    constexpr number_unsigned_t get_number_unsigned() const noexcept\n    {\n        return value_unsigned;\n    }\n\n    /// return floating-point value\n    constexpr number_float_t get_number_float() const noexcept\n    {\n        return value_float;\n    }\n\n    /// return current string value (implicitly resets the token; useful only once)\n    string_t& get_string()\n    {\n        return token_buffer;\n    }\n\n    /////////////////////\n    // diagnostics\n    /////////////////////\n\n    /// return position of last read token\n    constexpr position_t get_position() const noexcept\n    {\n        return position;\n    }\n\n    /// return the last read token (for errors only).  Will never contain EOF\n    /// (an arbitrary value that is not a valid char value, often -1), because\n    /// 255 may legitimately occur.  May contain NUL, which should be escaped.\n    std::string get_token_string() const\n    {\n        // escape control characters\n        std::string result;\n        for (const auto c : token_string)\n        {\n            if (static_cast<unsigned char>(c) <= '\\x1F')\n            {\n                // escape control characters\n                std::array<char, 9> cs{{}};\n                static_cast<void>((std::snprintf)(cs.data(), cs.size(), \"<U+%.4X>\", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                result += cs.data();\n            }\n            else\n            {\n                // add character as is\n                result.push_back(static_cast<std::string::value_type>(c));\n            }\n        }\n\n        return result;\n    }\n\n    /// return syntax error message\n    JSON_HEDLEY_RETURNS_NON_NULL\n    constexpr const char* get_error_message() const noexcept\n    {\n        return error_message;\n    }\n\n    /////////////////////\n    // actual scanner\n    /////////////////////\n\n    /*!\n    @brief skip the UTF-8 byte order mark\n    @return true iff there is no BOM or the correct BOM has been skipped\n    */\n    bool skip_bom()\n    {\n        if (get() == 0xEF)\n        {\n            // check if we completely parse the BOM\n            return get() == 0xBB && get() == 0xBF;\n        }\n\n        // the first character is not the beginning of the BOM; unget it to\n        // process is later\n        unget();\n        return true;\n    }\n\n    void skip_whitespace()\n    {\n        do\n        {\n            get();\n        }\n        while (current == ' ' || current == '\\t' || current == '\\n' || current == '\\r');\n    }\n\n    token_type scan()\n    {\n        // initially, skip the BOM\n        if (position.chars_read_total == 0 && !skip_bom())\n        {\n            error_message = \"invalid BOM; must be 0xEF 0xBB 0xBF if given\";\n            return token_type::parse_error;\n        }\n\n        // read next character and ignore whitespace\n        skip_whitespace();\n\n        // ignore comments\n        while (ignore_comments && current == '/')\n        {\n            if (!scan_comment())\n            {\n                return token_type::parse_error;\n            }\n\n            // skip following whitespace\n            skip_whitespace();\n        }\n\n        switch (current)\n        {\n            // structural characters\n            case '[':\n                return token_type::begin_array;\n            case ']':\n                return token_type::end_array;\n            case '{':\n                return token_type::begin_object;\n            case '}':\n                return token_type::end_object;\n            case ':':\n                return token_type::name_separator;\n            case ',':\n                return token_type::value_separator;\n\n            // literals\n            case 't':\n            {\n                std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};\n                return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);\n            }\n            case 'f':\n            {\n                std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};\n                return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);\n            }\n            case 'n':\n            {\n                std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};\n                return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);\n            }\n\n            // string\n            case '\\\"':\n                return scan_string();\n\n            // number\n            case '-':\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n                return scan_number();\n\n            // end of input (the null byte is needed when parsing from\n            // string literals)\n            case '\\0':\n            case std::char_traits<char_type>::eof():\n                return token_type::end_of_input;\n\n            // error\n            default:\n                error_message = \"invalid literal\";\n                return token_type::parse_error;\n        }\n    }\n\n  private:\n    /// input adapter\n    InputAdapterType ia;\n\n    /// whether comments should be ignored (true) or signaled as errors (false)\n    const bool ignore_comments = false;\n\n    /// the current character\n    char_int_type current = std::char_traits<char_type>::eof();\n\n    /// whether the next get() call should just return current\n    bool next_unget = false;\n\n    /// the start position of the current token\n    position_t position {};\n\n    /// raw input token string (for error messages)\n    std::vector<char_type> token_string {};\n\n    /// buffer for variable-length tokens (numbers, strings)\n    string_t token_buffer {};\n\n    /// a description of occurred lexer errors\n    const char* error_message = \"\";\n\n    // number values\n    number_integer_t value_integer = 0;\n    number_unsigned_t value_unsigned = 0;\n    number_float_t value_float = 0;\n\n    /// the decimal point\n    const char_int_type decimal_point_char = '.';\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/input/parser.hpp",
    "content": "#pragma once\n\n#include <cmath> // isfinite\n#include <cstdint> // uint8_t\n#include <functional> // function\n#include <string> // string\n#include <utility> // move\n#include <vector> // vector\n\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/input/input_adapters.hpp>\n#include <nlohmann/detail/input/json_sax.hpp>\n#include <nlohmann/detail/input/lexer.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/meta/is_sax.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n////////////\n// parser //\n////////////\n\nenum class parse_event_t : std::uint8_t\n{\n    /// the parser read `{` and started to process a JSON object\n    object_start,\n    /// the parser read `}` and finished processing a JSON object\n    object_end,\n    /// the parser read `[` and started to process a JSON array\n    array_start,\n    /// the parser read `]` and finished processing a JSON array\n    array_end,\n    /// the parser read a key of a value in an object\n    key,\n    /// the parser finished reading a JSON value\n    value\n};\n\ntemplate<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;\n\n/*!\n@brief syntax analysis\n\nThis class implements a recursive descent parser.\n*/\ntemplate<typename BasicJsonType, typename InputAdapterType>\nclass parser\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using lexer_t = lexer<BasicJsonType, InputAdapterType>;\n    using token_type = typename lexer_t::token_type;\n\n  public:\n    /// a parser reading from an input adapter\n    explicit parser(InputAdapterType&& adapter,\n                    const parser_callback_t<BasicJsonType> cb = nullptr,\n                    const bool allow_exceptions_ = true,\n                    const bool skip_comments = false)\n        : callback(cb)\n        , m_lexer(std::move(adapter), skip_comments)\n        , allow_exceptions(allow_exceptions_)\n    {\n        // read first token\n        get_token();\n    }\n\n    /*!\n    @brief public parser interface\n\n    @param[in] strict      whether to expect the last token to be EOF\n    @param[in,out] result  parsed JSON value\n\n    @throw parse_error.101 in case of an unexpected token\n    @throw parse_error.102 if to_unicode fails or surrogate error\n    @throw parse_error.103 if to_unicode fails\n    */\n    void parse(const bool strict, BasicJsonType& result)\n    {\n        if (callback)\n        {\n            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);\n            sax_parse_internal(&sdp);\n\n            // in strict mode, input must be completely read\n            if (strict && (get_token() != token_type::end_of_input))\n            {\n                sdp.parse_error(m_lexer.get_position(),\n                                m_lexer.get_token_string(),\n                                parse_error::create(101, m_lexer.get_position(),\n                                                    exception_message(token_type::end_of_input, \"value\"), BasicJsonType()));\n            }\n\n            // in case of an error, return discarded value\n            if (sdp.is_errored())\n            {\n                result = value_t::discarded;\n                return;\n            }\n\n            // set top-level value to null if it was discarded by the callback\n            // function\n            if (result.is_discarded())\n            {\n                result = nullptr;\n            }\n        }\n        else\n        {\n            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);\n            sax_parse_internal(&sdp);\n\n            // in strict mode, input must be completely read\n            if (strict && (get_token() != token_type::end_of_input))\n            {\n                sdp.parse_error(m_lexer.get_position(),\n                                m_lexer.get_token_string(),\n                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, \"value\"), BasicJsonType()));\n            }\n\n            // in case of an error, return discarded value\n            if (sdp.is_errored())\n            {\n                result = value_t::discarded;\n                return;\n            }\n        }\n\n        result.assert_invariant();\n    }\n\n    /*!\n    @brief public accept interface\n\n    @param[in] strict  whether to expect the last token to be EOF\n    @return whether the input is a proper JSON text\n    */\n    bool accept(const bool strict = true)\n    {\n        json_sax_acceptor<BasicJsonType> sax_acceptor;\n        return sax_parse(&sax_acceptor, strict);\n    }\n\n    template<typename SAX>\n    JSON_HEDLEY_NON_NULL(2)\n    bool sax_parse(SAX* sax, const bool strict = true)\n    {\n        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};\n        const bool result = sax_parse_internal(sax);\n\n        // strict mode: next byte must be EOF\n        if (result && strict && (get_token() != token_type::end_of_input))\n        {\n            return sax->parse_error(m_lexer.get_position(),\n                                    m_lexer.get_token_string(),\n                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, \"value\"), BasicJsonType()));\n        }\n\n        return result;\n    }\n\n  private:\n    template<typename SAX>\n    JSON_HEDLEY_NON_NULL(2)\n    bool sax_parse_internal(SAX* sax)\n    {\n        // stack to remember the hierarchy of structured values we are parsing\n        // true = array; false = object\n        std::vector<bool> states;\n        // value to avoid a goto (see comment where set to true)\n        bool skip_to_state_evaluation = false;\n\n        while (true)\n        {\n            if (!skip_to_state_evaluation)\n            {\n                // invariant: get_token() was called before each iteration\n                switch (last_token)\n                {\n                    case token_type::begin_object:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))\n                        {\n                            return false;\n                        }\n\n                        // closing } -> we are done\n                        if (get_token() == token_type::end_object)\n                        {\n                            if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))\n                            {\n                                return false;\n                            }\n                            break;\n                        }\n\n                        // parse key\n                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))\n                        {\n                            return sax->parse_error(m_lexer.get_position(),\n                                                    m_lexer.get_token_string(),\n                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, \"object key\"), BasicJsonType()));\n                        }\n                        if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))\n                        {\n                            return false;\n                        }\n\n                        // parse separator (:)\n                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))\n                        {\n                            return sax->parse_error(m_lexer.get_position(),\n                                                    m_lexer.get_token_string(),\n                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, \"object separator\"), BasicJsonType()));\n                        }\n\n                        // remember we are now inside an object\n                        states.push_back(false);\n\n                        // parse values\n                        get_token();\n                        continue;\n                    }\n\n                    case token_type::begin_array:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))\n                        {\n                            return false;\n                        }\n\n                        // closing ] -> we are done\n                        if (get_token() == token_type::end_array)\n                        {\n                            if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))\n                            {\n                                return false;\n                            }\n                            break;\n                        }\n\n                        // remember we are now inside an array\n                        states.push_back(true);\n\n                        // parse values (no need to call get_token)\n                        continue;\n                    }\n\n                    case token_type::value_float:\n                    {\n                        const auto res = m_lexer.get_number_float();\n\n                        if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))\n                        {\n                            return sax->parse_error(m_lexer.get_position(),\n                                                    m_lexer.get_token_string(),\n                                                    out_of_range::create(406, \"number overflow parsing '\" + m_lexer.get_token_string() + \"'\", BasicJsonType()));\n                        }\n\n                        if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))\n                        {\n                            return false;\n                        }\n\n                        break;\n                    }\n\n                    case token_type::literal_false:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::literal_null:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->null()))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::literal_true:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::value_integer:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::value_string:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::value_unsigned:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::parse_error:\n                    {\n                        // using \"uninitialized\" to avoid \"expected\" message\n                        return sax->parse_error(m_lexer.get_position(),\n                                                m_lexer.get_token_string(),\n                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, \"value\"), BasicJsonType()));\n                    }\n\n                    case token_type::uninitialized:\n                    case token_type::end_array:\n                    case token_type::end_object:\n                    case token_type::name_separator:\n                    case token_type::value_separator:\n                    case token_type::end_of_input:\n                    case token_type::literal_or_value:\n                    default: // the last token was unexpected\n                    {\n                        return sax->parse_error(m_lexer.get_position(),\n                                                m_lexer.get_token_string(),\n                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, \"value\"), BasicJsonType()));\n                    }\n                }\n            }\n            else\n            {\n                skip_to_state_evaluation = false;\n            }\n\n            // we reached this line after we successfully parsed a value\n            if (states.empty())\n            {\n                // empty stack: we reached the end of the hierarchy: done\n                return true;\n            }\n\n            if (states.back())  // array\n            {\n                // comma -> next value\n                if (get_token() == token_type::value_separator)\n                {\n                    // parse a new value\n                    get_token();\n                    continue;\n                }\n\n                // closing ]\n                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))\n                    {\n                        return false;\n                    }\n\n                    // We are done with this array. Before we can parse a\n                    // new value, we need to evaluate the new state first.\n                    // By setting skip_to_state_evaluation to false, we\n                    // are effectively jumping to the beginning of this if.\n                    JSON_ASSERT(!states.empty());\n                    states.pop_back();\n                    skip_to_state_evaluation = true;\n                    continue;\n                }\n\n                return sax->parse_error(m_lexer.get_position(),\n                                        m_lexer.get_token_string(),\n                                        parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, \"array\"), BasicJsonType()));\n            }\n\n            // states.back() is false -> object\n\n            // comma -> next value\n            if (get_token() == token_type::value_separator)\n            {\n                // parse key\n                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))\n                {\n                    return sax->parse_error(m_lexer.get_position(),\n                                            m_lexer.get_token_string(),\n                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, \"object key\"), BasicJsonType()));\n                }\n\n                if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))\n                {\n                    return false;\n                }\n\n                // parse separator (:)\n                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))\n                {\n                    return sax->parse_error(m_lexer.get_position(),\n                                            m_lexer.get_token_string(),\n                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, \"object separator\"), BasicJsonType()));\n                }\n\n                // parse values\n                get_token();\n                continue;\n            }\n\n            // closing }\n            if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))\n            {\n                if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))\n                {\n                    return false;\n                }\n\n                // We are done with this object. Before we can parse a\n                // new value, we need to evaluate the new state first.\n                // By setting skip_to_state_evaluation to false, we\n                // are effectively jumping to the beginning of this if.\n                JSON_ASSERT(!states.empty());\n                states.pop_back();\n                skip_to_state_evaluation = true;\n                continue;\n            }\n\n            return sax->parse_error(m_lexer.get_position(),\n                                    m_lexer.get_token_string(),\n                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, \"object\"), BasicJsonType()));\n        }\n    }\n\n    /// get next token from lexer\n    token_type get_token()\n    {\n        return last_token = m_lexer.scan();\n    }\n\n    std::string exception_message(const token_type expected, const std::string& context)\n    {\n        std::string error_msg = \"syntax error \";\n\n        if (!context.empty())\n        {\n            error_msg += \"while parsing \" + context + \" \";\n        }\n\n        error_msg += \"- \";\n\n        if (last_token == token_type::parse_error)\n        {\n            error_msg += std::string(m_lexer.get_error_message()) + \"; last read: '\" +\n                         m_lexer.get_token_string() + \"'\";\n        }\n        else\n        {\n            error_msg += \"unexpected \" + std::string(lexer_t::token_type_name(last_token));\n        }\n\n        if (expected != token_type::uninitialized)\n        {\n            error_msg += \"; expected \" + std::string(lexer_t::token_type_name(expected));\n        }\n\n        return error_msg;\n    }\n\n  private:\n    /// callback function\n    const parser_callback_t<BasicJsonType> callback = nullptr;\n    /// the type of the last read token\n    token_type last_token = token_type::uninitialized;\n    /// the lexer\n    lexer_t m_lexer;\n    /// whether to throw exceptions in case of errors\n    const bool allow_exceptions = true;\n};\n\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/input/position_t.hpp",
    "content": "#pragma once\n\n#include <cstddef> // size_t\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/// struct to capture the start position of the current token\nstruct position_t\n{\n    /// the total number of characters read\n    std::size_t chars_read_total = 0;\n    /// the number of characters read in the current line\n    std::size_t chars_read_current_line = 0;\n    /// the number of lines read\n    std::size_t lines_read = 0;\n\n    /// conversion to size_t to preserve SAX interface\n    constexpr operator size_t() const\n    {\n        return chars_read_total;\n    }\n};\n\n} // namespace detail\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/iterators/internal_iterator.hpp",
    "content": "#pragma once\n\n#include <nlohmann/detail/iterators/primitive_iterator.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/*!\n@brief an iterator value\n\n@note This structure could easily be a union, but MSVC currently does not allow\nunions members with complex constructors, see https://github.com/nlohmann/json/pull/105.\n*/\ntemplate<typename BasicJsonType> struct internal_iterator\n{\n    /// iterator for JSON objects\n    typename BasicJsonType::object_t::iterator object_iterator {};\n    /// iterator for JSON arrays\n    typename BasicJsonType::array_t::iterator array_iterator {};\n    /// generic iterator for all other types\n    primitive_iterator_t primitive_iterator {};\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/iterators/iter_impl.hpp",
    "content": "#pragma once\n\n#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next\n#include <type_traits> // conditional, is_const, remove_const\n\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/iterators/internal_iterator.hpp>\n#include <nlohmann/detail/iterators/primitive_iterator.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/meta/cpp_future.hpp>\n#include <nlohmann/detail/meta/type_traits.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n// forward declare, to be able to friend it later on\ntemplate<typename IteratorType> class iteration_proxy;\ntemplate<typename IteratorType> class iteration_proxy_value;\n\n/*!\n@brief a template for a bidirectional iterator for the @ref basic_json class\nThis class implements a both iterators (iterator and const_iterator) for the\n@ref basic_json class.\n@note An iterator is called *initialized* when a pointer to a JSON value has\n      been set (e.g., by a constructor or a copy assignment). If the iterator is\n      default-constructed, it is *uninitialized* and most methods are undefined.\n      **The library uses assertions to detect calls on uninitialized iterators.**\n@requirement The class satisfies the following concept requirements:\n-\n[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):\n  The iterator that can be moved can be moved in both directions (i.e.\n  incremented and decremented).\n@since version 1.0.0, simplified in version 2.0.9, change to bidirectional\n       iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)\n*/\ntemplate<typename BasicJsonType>\nclass iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)\n{\n    /// the iterator with BasicJsonType of different const-ness\n    using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;\n    /// allow basic_json to access private members\n    friend other_iter_impl;\n    friend BasicJsonType;\n    friend iteration_proxy<iter_impl>;\n    friend iteration_proxy_value<iter_impl>;\n\n    using object_t = typename BasicJsonType::object_t;\n    using array_t = typename BasicJsonType::array_t;\n    // make sure BasicJsonType is basic_json or const basic_json\n    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,\n                  \"iter_impl only accepts (const) basic_json\");\n\n  public:\n\n    /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.\n    /// The C++ Standard has never required user-defined iterators to derive from std::iterator.\n    /// A user-defined iterator should provide publicly accessible typedefs named\n    /// iterator_category, value_type, difference_type, pointer, and reference.\n    /// Note that value_type is required to be non-const, even for constant iterators.\n    using iterator_category = std::bidirectional_iterator_tag;\n\n    /// the type of the values when the iterator is dereferenced\n    using value_type = typename BasicJsonType::value_type;\n    /// a type to represent differences between iterators\n    using difference_type = typename BasicJsonType::difference_type;\n    /// defines a pointer to the type iterated over (value_type)\n    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,\n          typename BasicJsonType::const_pointer,\n          typename BasicJsonType::pointer>::type;\n    /// defines a reference to the type iterated over (value_type)\n    using reference =\n        typename std::conditional<std::is_const<BasicJsonType>::value,\n        typename BasicJsonType::const_reference,\n        typename BasicJsonType::reference>::type;\n\n    iter_impl() = default;\n    ~iter_impl() = default;\n    iter_impl(iter_impl&&) noexcept = default;\n    iter_impl& operator=(iter_impl&&) noexcept = default;\n\n    /*!\n    @brief constructor for a given JSON instance\n    @param[in] object  pointer to a JSON object for this iterator\n    @pre object != nullptr\n    @post The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    explicit iter_impl(pointer object) noexcept : m_object(object)\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                m_it.object_iterator = typename object_t::iterator();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_it.array_iterator = typename array_t::iterator();\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator = primitive_iterator_t();\n                break;\n            }\n        }\n    }\n\n    /*!\n    @note The conventional copy constructor and copy assignment are implicitly\n          defined. Combined with the following converting constructor and\n          assignment, they support: (1) copy from iterator to iterator, (2)\n          copy from const iterator to const iterator, and (3) conversion from\n          iterator to const iterator. However conversion from const iterator\n          to iterator is not defined.\n    */\n\n    /*!\n    @brief const copy constructor\n    @param[in] other const iterator to copy from\n    @note This copy constructor had to be defined explicitly to circumvent a bug\n          occurring on msvc v19.0 compiler (VS 2015) debug build. For more\n          information refer to: https://github.com/nlohmann/json/issues/1608\n    */\n    iter_impl(const iter_impl<const BasicJsonType>& other) noexcept\n        : m_object(other.m_object), m_it(other.m_it)\n    {}\n\n    /*!\n    @brief converting assignment\n    @param[in] other const iterator to copy from\n    @return const/non-const iterator\n    @note It is not checked whether @a other is initialized.\n    */\n    iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept\n    {\n        if (&other != this)\n        {\n            m_object = other.m_object;\n            m_it = other.m_it;\n        }\n        return *this;\n    }\n\n    /*!\n    @brief converting constructor\n    @param[in] other  non-const iterator to copy from\n    @note It is not checked whether @a other is initialized.\n    */\n    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept\n        : m_object(other.m_object), m_it(other.m_it)\n    {}\n\n    /*!\n    @brief converting assignment\n    @param[in] other  non-const iterator to copy from\n    @return const/non-const iterator\n    @note It is not checked whether @a other is initialized.\n    */\n    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)\n    {\n        m_object = other.m_object;\n        m_it = other.m_it;\n        return *this;\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /*!\n    @brief set the iterator to the first value\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    void set_begin() noexcept\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                m_it.object_iterator = m_object->m_value.object->begin();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_it.array_iterator = m_object->m_value.array->begin();\n                break;\n            }\n\n            case value_t::null:\n            {\n                // set to end so begin()==end() is true: null is empty\n                m_it.primitive_iterator.set_end();\n                break;\n            }\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator.set_begin();\n                break;\n            }\n        }\n    }\n\n    /*!\n    @brief set the iterator past the last value\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    void set_end() noexcept\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                m_it.object_iterator = m_object->m_value.object->end();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_it.array_iterator = m_object->m_value.array->end();\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator.set_end();\n                break;\n            }\n        }\n    }\n\n  public:\n    /*!\n    @brief return a reference to the value pointed to by the iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    reference operator*() const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());\n                return m_it.object_iterator->second;\n            }\n\n            case value_t::array:\n            {\n                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());\n                return *m_it.array_iterator;\n            }\n\n            case value_t::null:\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))\n                {\n                    return *m_object;\n                }\n\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n            }\n        }\n    }\n\n    /*!\n    @brief dereference the iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    pointer operator->() const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());\n                return &(m_it.object_iterator->second);\n            }\n\n            case value_t::array:\n            {\n                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());\n                return &*m_it.array_iterator;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))\n                {\n                    return m_object;\n                }\n\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n            }\n        }\n    }\n\n    /*!\n    @brief post-increment (it++)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl const operator++(int) // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        ++(*this);\n        return result;\n    }\n\n    /*!\n    @brief pre-increment (++it)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator++()\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                std::advance(m_it.object_iterator, 1);\n                break;\n            }\n\n            case value_t::array:\n            {\n                std::advance(m_it.array_iterator, 1);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                ++m_it.primitive_iterator;\n                break;\n            }\n        }\n\n        return *this;\n    }\n\n    /*!\n    @brief post-decrement (it--)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl const operator--(int) // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        --(*this);\n        return result;\n    }\n\n    /*!\n    @brief pre-decrement (--it)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator--()\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                std::advance(m_it.object_iterator, -1);\n                break;\n            }\n\n            case value_t::array:\n            {\n                std::advance(m_it.array_iterator, -1);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                --m_it.primitive_iterator;\n                break;\n            }\n        }\n\n        return *this;\n    }\n\n    /*!\n    @brief comparison: equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >\n    bool operator==(const IterImpl& other) const\n    {\n        // if objects are not the same, the comparison is undefined\n        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(212, \"cannot compare iterators of different containers\", *m_object));\n        }\n\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                return (m_it.object_iterator == other.m_it.object_iterator);\n\n            case value_t::array:\n                return (m_it.array_iterator == other.m_it.array_iterator);\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return (m_it.primitive_iterator == other.m_it.primitive_iterator);\n        }\n    }\n\n    /*!\n    @brief comparison: not equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >\n    bool operator!=(const IterImpl& other) const\n    {\n        return !operator==(other);\n    }\n\n    /*!\n    @brief comparison: smaller\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator<(const iter_impl& other) const\n    {\n        // if objects are not the same, the comparison is undefined\n        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(212, \"cannot compare iterators of different containers\", *m_object));\n        }\n\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(213, \"cannot compare order of object iterators\", *m_object));\n\n            case value_t::array:\n                return (m_it.array_iterator < other.m_it.array_iterator);\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return (m_it.primitive_iterator < other.m_it.primitive_iterator);\n        }\n    }\n\n    /*!\n    @brief comparison: less than or equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator<=(const iter_impl& other) const\n    {\n        return !other.operator < (*this);\n    }\n\n    /*!\n    @brief comparison: greater than\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator>(const iter_impl& other) const\n    {\n        return !operator<=(other);\n    }\n\n    /*!\n    @brief comparison: greater than or equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator>=(const iter_impl& other) const\n    {\n        return !operator<(other);\n    }\n\n    /*!\n    @brief add to iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator+=(difference_type i)\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(209, \"cannot use offsets with object iterators\", *m_object));\n\n            case value_t::array:\n            {\n                std::advance(m_it.array_iterator, i);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator += i;\n                break;\n            }\n        }\n\n        return *this;\n    }\n\n    /*!\n    @brief subtract from iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator-=(difference_type i)\n    {\n        return operator+=(-i);\n    }\n\n    /*!\n    @brief add to iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl operator+(difference_type i) const\n    {\n        auto result = *this;\n        result += i;\n        return result;\n    }\n\n    /*!\n    @brief addition of distance and iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    friend iter_impl operator+(difference_type i, const iter_impl& it)\n    {\n        auto result = it;\n        result += i;\n        return result;\n    }\n\n    /*!\n    @brief subtract from iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl operator-(difference_type i) const\n    {\n        auto result = *this;\n        result -= i;\n        return result;\n    }\n\n    /*!\n    @brief return difference\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    difference_type operator-(const iter_impl& other) const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(209, \"cannot use offsets with object iterators\", *m_object));\n\n            case value_t::array:\n                return m_it.array_iterator - other.m_it.array_iterator;\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return m_it.primitive_iterator - other.m_it.primitive_iterator;\n        }\n    }\n\n    /*!\n    @brief access to successor\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    reference operator[](difference_type n) const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(208, \"cannot use operator[] for object iterators\", *m_object));\n\n            case value_t::array:\n                return *std::next(m_it.array_iterator, n);\n\n            case value_t::null:\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))\n                {\n                    return *m_object;\n                }\n\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n            }\n        }\n    }\n\n    /*!\n    @brief return the key of an object iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    const typename object_t::key_type& key() const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        if (JSON_HEDLEY_LIKELY(m_object->is_object()))\n        {\n            return m_it.object_iterator->first;\n        }\n\n        JSON_THROW(invalid_iterator::create(207, \"cannot use key() for non-object iterators\", *m_object));\n    }\n\n    /*!\n    @brief return the value of an iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    reference value() const\n    {\n        return operator*();\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /// associated JSON instance\n    pointer m_object = nullptr;\n    /// the actual iterator of the associated instance\n    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};\n};\n} // namespace detail\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/iterators/iteration_proxy.hpp",
    "content": "#pragma once\n\n#include <cstddef> // size_t\n#include <iterator> // input_iterator_tag\n#include <string> // string, to_string\n#include <tuple> // tuple_size, get, tuple_element\n#include <utility> // move\n\n#include <nlohmann/detail/meta/type_traits.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename string_type>\nvoid int_to_string( string_type& target, std::size_t value )\n{\n    // For ADL\n    using std::to_string;\n    target = to_string(value);\n}\ntemplate<typename IteratorType> class iteration_proxy_value\n{\n  public:\n    using difference_type = std::ptrdiff_t;\n    using value_type = iteration_proxy_value;\n    using pointer = value_type * ;\n    using reference = value_type & ;\n    using iterator_category = std::input_iterator_tag;\n    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;\n\n  private:\n    /// the iterator\n    IteratorType anchor;\n    /// an index for arrays (used to create key names)\n    std::size_t array_index = 0;\n    /// last stringified array index\n    mutable std::size_t array_index_last = 0;\n    /// a string representation of the array index\n    mutable string_type array_index_str = \"0\";\n    /// an empty string (to return a reference for primitive values)\n    const string_type empty_str{};\n\n  public:\n    explicit iteration_proxy_value(IteratorType it) noexcept\n        : anchor(std::move(it))\n    {}\n\n    /// dereference operator (needed for range-based for)\n    iteration_proxy_value& operator*()\n    {\n        return *this;\n    }\n\n    /// increment operator (needed for range-based for)\n    iteration_proxy_value& operator++()\n    {\n        ++anchor;\n        ++array_index;\n\n        return *this;\n    }\n\n    /// equality operator (needed for InputIterator)\n    bool operator==(const iteration_proxy_value& o) const\n    {\n        return anchor == o.anchor;\n    }\n\n    /// inequality operator (needed for range-based for)\n    bool operator!=(const iteration_proxy_value& o) const\n    {\n        return anchor != o.anchor;\n    }\n\n    /// return key of the iterator\n    const string_type& key() const\n    {\n        JSON_ASSERT(anchor.m_object != nullptr);\n\n        switch (anchor.m_object->type())\n        {\n            // use integer array index as key\n            case value_t::array:\n            {\n                if (array_index != array_index_last)\n                {\n                    int_to_string( array_index_str, array_index );\n                    array_index_last = array_index;\n                }\n                return array_index_str;\n            }\n\n            // use key from the object\n            case value_t::object:\n                return anchor.key();\n\n            // use an empty key for all primitive types\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return empty_str;\n        }\n    }\n\n    /// return value of the iterator\n    typename IteratorType::reference value() const\n    {\n        return anchor.value();\n    }\n};\n\n/// proxy class for the items() function\ntemplate<typename IteratorType> class iteration_proxy\n{\n  private:\n    /// the container to iterate\n    typename IteratorType::reference container;\n\n  public:\n    /// construct iteration proxy from a container\n    explicit iteration_proxy(typename IteratorType::reference cont) noexcept\n        : container(cont) {}\n\n    /// return iterator begin (needed for range-based for)\n    iteration_proxy_value<IteratorType> begin() noexcept\n    {\n        return iteration_proxy_value<IteratorType>(container.begin());\n    }\n\n    /// return iterator end (needed for range-based for)\n    iteration_proxy_value<IteratorType> end() noexcept\n    {\n        return iteration_proxy_value<IteratorType>(container.end());\n    }\n};\n// Structured Bindings Support\n// For further reference see https://blog.tartanllama.xyz/structured-bindings/\n// And see https://github.com/nlohmann/json/pull/1391\ntemplate<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>\nauto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())\n{\n    return i.key();\n}\n// Structured Bindings Support\n// For further reference see https://blog.tartanllama.xyz/structured-bindings/\n// And see https://github.com/nlohmann/json/pull/1391\ntemplate<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>\nauto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())\n{\n    return i.value();\n}\n}  // namespace detail\n}  // namespace nlohmann\n\n// The Addition to the STD Namespace is required to add\n// Structured Bindings Support to the iteration_proxy_value class\n// For further reference see https://blog.tartanllama.xyz/structured-bindings/\n// And see https://github.com/nlohmann/json/pull/1391\nnamespace std\n{\n#if defined(__clang__)\n    // Fix: https://github.com/nlohmann/json/issues/1401\n    #pragma clang diagnostic push\n    #pragma clang diagnostic ignored \"-Wmismatched-tags\"\n#endif\ntemplate<typename IteratorType>\nclass tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>\n            : public std::integral_constant<std::size_t, 2> {};\n\ntemplate<std::size_t N, typename IteratorType>\nclass tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>\n{\n  public:\n    using type = decltype(\n                     get<N>(std::declval <\n                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));\n};\n#if defined(__clang__)\n    #pragma clang diagnostic pop\n#endif\n} // namespace std\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/iterators/iterator_traits.hpp",
    "content": "#pragma once\n\n#include <iterator> // random_access_iterator_tag\n\n#include <nlohmann/detail/meta/void_t.hpp>\n#include <nlohmann/detail/meta/cpp_future.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename It, typename = void>\nstruct iterator_types {};\n\ntemplate<typename It>\nstruct iterator_types <\n    It,\n    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,\n    typename It::reference, typename It::iterator_category >>\n{\n    using difference_type = typename It::difference_type;\n    using value_type = typename It::value_type;\n    using pointer = typename It::pointer;\n    using reference = typename It::reference;\n    using iterator_category = typename It::iterator_category;\n};\n\n// This is required as some compilers implement std::iterator_traits in a way that\n// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.\ntemplate<typename T, typename = void>\nstruct iterator_traits\n{\n};\n\ntemplate<typename T>\nstruct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>\n            : iterator_types<T>\n{\n};\n\ntemplate<typename T>\nstruct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>\n{\n    using iterator_category = std::random_access_iterator_tag;\n    using value_type = T;\n    using difference_type = ptrdiff_t;\n    using pointer = T*;\n    using reference = T&;\n};\n} // namespace detail\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/iterators/json_reverse_iterator.hpp",
    "content": "#pragma once\n\n#include <cstddef> // ptrdiff_t\n#include <iterator> // reverse_iterator\n#include <utility> // declval\n\nnamespace nlohmann\n{\nnamespace detail\n{\n//////////////////////\n// reverse_iterator //\n//////////////////////\n\n/*!\n@brief a template for a reverse iterator class\n\n@tparam Base the base iterator type to reverse. Valid types are @ref\niterator (to create @ref reverse_iterator) and @ref const_iterator (to\ncreate @ref const_reverse_iterator).\n\n@requirement The class satisfies the following concept requirements:\n-\n[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):\n  The iterator that can be moved can be moved in both directions (i.e.\n  incremented and decremented).\n- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):\n  It is possible to write to the pointed-to element (only if @a Base is\n  @ref iterator).\n\n@since version 1.0.0\n*/\ntemplate<typename Base>\nclass json_reverse_iterator : public std::reverse_iterator<Base>\n{\n  public:\n    using difference_type = std::ptrdiff_t;\n    /// shortcut to the reverse iterator adapter\n    using base_iterator = std::reverse_iterator<Base>;\n    /// the reference type for the pointed-to element\n    using reference = typename Base::reference;\n\n    /// create reverse iterator from iterator\n    explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept\n        : base_iterator(it) {}\n\n    /// create reverse iterator from base class\n    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}\n\n    /// post-increment (it++)\n    json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));\n    }\n\n    /// pre-increment (++it)\n    json_reverse_iterator& operator++()\n    {\n        return static_cast<json_reverse_iterator&>(base_iterator::operator++());\n    }\n\n    /// post-decrement (it--)\n    json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));\n    }\n\n    /// pre-decrement (--it)\n    json_reverse_iterator& operator--()\n    {\n        return static_cast<json_reverse_iterator&>(base_iterator::operator--());\n    }\n\n    /// add to iterator\n    json_reverse_iterator& operator+=(difference_type i)\n    {\n        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));\n    }\n\n    /// add to iterator\n    json_reverse_iterator operator+(difference_type i) const\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));\n    }\n\n    /// subtract from iterator\n    json_reverse_iterator operator-(difference_type i) const\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));\n    }\n\n    /// return difference\n    difference_type operator-(const json_reverse_iterator& other) const\n    {\n        return base_iterator(*this) - base_iterator(other);\n    }\n\n    /// access to successor\n    reference operator[](difference_type n) const\n    {\n        return *(this->operator+(n));\n    }\n\n    /// return the key of an object iterator\n    auto key() const -> decltype(std::declval<Base>().key())\n    {\n        auto it = --this->base();\n        return it.key();\n    }\n\n    /// return the value of an iterator\n    reference value() const\n    {\n        auto it = --this->base();\n        return it.operator * ();\n    }\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/iterators/primitive_iterator.hpp",
    "content": "#pragma once\n\n#include <cstddef> // ptrdiff_t\n#include <limits>  // numeric_limits\n\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/*\n@brief an iterator for primitive JSON types\n\nThis class models an iterator for primitive JSON types (boolean, number,\nstring). It's only purpose is to allow the iterator/const_iterator classes\nto \"iterate\" over primitive values. Internally, the iterator is modeled by\na `difference_type` variable. Value begin_value (`0`) models the begin,\nend_value (`1`) models past the end.\n*/\nclass primitive_iterator_t\n{\n  private:\n    using difference_type = std::ptrdiff_t;\n    static constexpr difference_type begin_value = 0;\n    static constexpr difference_type end_value = begin_value + 1;\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /// iterator as signed integer type\n    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();\n\n  public:\n    constexpr difference_type get_value() const noexcept\n    {\n        return m_it;\n    }\n\n    /// set iterator to a defined beginning\n    void set_begin() noexcept\n    {\n        m_it = begin_value;\n    }\n\n    /// set iterator to a defined past the end\n    void set_end() noexcept\n    {\n        m_it = end_value;\n    }\n\n    /// return whether the iterator can be dereferenced\n    constexpr bool is_begin() const noexcept\n    {\n        return m_it == begin_value;\n    }\n\n    /// return whether the iterator is at end\n    constexpr bool is_end() const noexcept\n    {\n        return m_it == end_value;\n    }\n\n    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept\n    {\n        return lhs.m_it == rhs.m_it;\n    }\n\n    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept\n    {\n        return lhs.m_it < rhs.m_it;\n    }\n\n    primitive_iterator_t operator+(difference_type n) noexcept\n    {\n        auto result = *this;\n        result += n;\n        return result;\n    }\n\n    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept\n    {\n        return lhs.m_it - rhs.m_it;\n    }\n\n    primitive_iterator_t& operator++() noexcept\n    {\n        ++m_it;\n        return *this;\n    }\n\n    primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        ++m_it;\n        return result;\n    }\n\n    primitive_iterator_t& operator--() noexcept\n    {\n        --m_it;\n        return *this;\n    }\n\n    primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        --m_it;\n        return result;\n    }\n\n    primitive_iterator_t& operator+=(difference_type n) noexcept\n    {\n        m_it += n;\n        return *this;\n    }\n\n    primitive_iterator_t& operator-=(difference_type n) noexcept\n    {\n        m_it -= n;\n        return *this;\n    }\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/json_pointer.hpp",
    "content": "#pragma once\n\n#include <algorithm> // all_of\n#include <cctype> // isdigit\n#include <limits> // max\n#include <numeric> // accumulate\n#include <string> // string\n#include <utility> // move\n#include <vector> // vector\n\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/string_escape.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\nnamespace nlohmann\n{\n\n/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document\n/// @sa https://json.nlohmann.me/api/json_pointer/\ntemplate<typename BasicJsonType>\nclass json_pointer\n{\n    // allow basic_json to access private members\n    NLOHMANN_BASIC_JSON_TPL_DECLARATION\n    friend class basic_json;\n\n  public:\n    /// @brief create JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/\n    explicit json_pointer(const std::string& s = \"\")\n        : reference_tokens(split(s))\n    {}\n\n    /// @brief return a string representation of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/to_string/\n    std::string to_string() const\n    {\n        return std::accumulate(reference_tokens.begin(), reference_tokens.end(),\n                               std::string{},\n                               [](const std::string & a, const std::string & b)\n        {\n            return a + \"/\" + detail::escape(b);\n        });\n    }\n\n    /// @brief return a string representation of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/\n    operator std::string() const\n    {\n        return to_string();\n    }\n\n    /// @brief append another JSON pointer at the end of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/\n    json_pointer& operator/=(const json_pointer& ptr)\n    {\n        reference_tokens.insert(reference_tokens.end(),\n                                ptr.reference_tokens.begin(),\n                                ptr.reference_tokens.end());\n        return *this;\n    }\n\n    /// @brief append an unescaped reference token at the end of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/\n    json_pointer& operator/=(std::string token)\n    {\n        push_back(std::move(token));\n        return *this;\n    }\n\n    /// @brief append an array index at the end of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/\n    json_pointer& operator/=(std::size_t array_idx)\n    {\n        return *this /= std::to_string(array_idx);\n    }\n\n    /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/\n    friend json_pointer operator/(const json_pointer& lhs,\n                                  const json_pointer& rhs)\n    {\n        return json_pointer(lhs) /= rhs;\n    }\n\n    /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/\n    friend json_pointer operator/(const json_pointer& lhs, std::string token) // NOLINT(performance-unnecessary-value-param)\n    {\n        return json_pointer(lhs) /= std::move(token);\n    }\n\n    /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/\n    friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)\n    {\n        return json_pointer(lhs) /= array_idx;\n    }\n\n    /// @brief returns the parent of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/\n    json_pointer parent_pointer() const\n    {\n        if (empty())\n        {\n            return *this;\n        }\n\n        json_pointer res = *this;\n        res.pop_back();\n        return res;\n    }\n\n    /// @brief remove last reference token\n    /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/\n    void pop_back()\n    {\n        if (JSON_HEDLEY_UNLIKELY(empty()))\n        {\n            JSON_THROW(detail::out_of_range::create(405, \"JSON pointer has no parent\", BasicJsonType()));\n        }\n\n        reference_tokens.pop_back();\n    }\n\n    /// @brief return last reference token\n    /// @sa https://json.nlohmann.me/api/json_pointer/back/\n    const std::string& back() const\n    {\n        if (JSON_HEDLEY_UNLIKELY(empty()))\n        {\n            JSON_THROW(detail::out_of_range::create(405, \"JSON pointer has no parent\", BasicJsonType()));\n        }\n\n        return reference_tokens.back();\n    }\n\n    /// @brief append an unescaped token at the end of the reference pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/push_back/\n    void push_back(const std::string& token)\n    {\n        reference_tokens.push_back(token);\n    }\n\n    /// @brief append an unescaped token at the end of the reference pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/push_back/\n    void push_back(std::string&& token)\n    {\n        reference_tokens.push_back(std::move(token));\n    }\n\n    /// @brief return whether pointer points to the root document\n    /// @sa https://json.nlohmann.me/api/json_pointer/empty/\n    bool empty() const noexcept\n    {\n        return reference_tokens.empty();\n    }\n\n  private:\n    /*!\n    @param[in] s  reference token to be converted into an array index\n\n    @return integer representation of @a s\n\n    @throw parse_error.106  if an array index begins with '0'\n    @throw parse_error.109  if an array index begins not with a digit\n    @throw out_of_range.404 if string @a s could not be converted to an integer\n    @throw out_of_range.410 if an array index exceeds size_type\n    */\n    static typename BasicJsonType::size_type array_index(const std::string& s)\n    {\n        using size_type = typename BasicJsonType::size_type;\n\n        // error condition (cf. RFC 6901, Sect. 4)\n        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))\n        {\n            JSON_THROW(detail::parse_error::create(106, 0, \"array index '\" + s + \"' must not begin with '0'\", BasicJsonType()));\n        }\n\n        // error condition (cf. RFC 6901, Sect. 4)\n        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))\n        {\n            JSON_THROW(detail::parse_error::create(109, 0, \"array index '\" + s + \"' is not a number\", BasicJsonType()));\n        }\n\n        std::size_t processed_chars = 0;\n        unsigned long long res = 0;  // NOLINT(runtime/int)\n        JSON_TRY\n        {\n            res = std::stoull(s, &processed_chars);\n        }\n        JSON_CATCH(std::out_of_range&)\n        {\n            JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + s + \"'\", BasicJsonType()));\n        }\n\n        // check if the string was completely read\n        if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))\n        {\n            JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + s + \"'\", BasicJsonType()));\n        }\n\n        // only triggered on special platforms (like 32bit), see also\n        // https://github.com/nlohmann/json/pull/2203\n        if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))  // NOLINT(runtime/int)\n        {\n            JSON_THROW(detail::out_of_range::create(410, \"array index \" + s + \" exceeds size_type\", BasicJsonType())); // LCOV_EXCL_LINE\n        }\n\n        return static_cast<size_type>(res);\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    json_pointer top() const\n    {\n        if (JSON_HEDLEY_UNLIKELY(empty()))\n        {\n            JSON_THROW(detail::out_of_range::create(405, \"JSON pointer has no parent\", BasicJsonType()));\n        }\n\n        json_pointer result = *this;\n        result.reference_tokens = {reference_tokens[0]};\n        return result;\n    }\n\n  private:\n    /*!\n    @brief create and return a reference to the pointed to value\n\n    @complexity Linear in the number of reference tokens.\n\n    @throw parse_error.109 if array index is not a number\n    @throw type_error.313 if value cannot be unflattened\n    */\n    BasicJsonType& get_and_create(BasicJsonType& j) const\n    {\n        auto* result = &j;\n\n        // in case no reference tokens exist, return a reference to the JSON value\n        // j which will be overwritten by a primitive value\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (result->type())\n            {\n                case detail::value_t::null:\n                {\n                    if (reference_token == \"0\")\n                    {\n                        // start a new array if reference token is 0\n                        result = &result->operator[](0);\n                    }\n                    else\n                    {\n                        // start a new object otherwise\n                        result = &result->operator[](reference_token);\n                    }\n                    break;\n                }\n\n                case detail::value_t::object:\n                {\n                    // create an entry in the object\n                    result = &result->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    // create an entry in the array\n                    result = &result->operator[](array_index(reference_token));\n                    break;\n                }\n\n                /*\n                The following code is only reached if there exists a reference\n                token _and_ the current value is primitive. In this case, we have\n                an error situation, because primitive values may only occur as\n                single value; that is, with an empty list of reference tokens.\n                */\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::type_error::create(313, \"invalid value to unflatten\", j));\n            }\n        }\n\n        return *result;\n    }\n\n    /*!\n    @brief return a reference to the pointed to value\n\n    @note This version does not throw if a value is not present, but tries to\n          create nested values instead. For instance, calling this function\n          with pointer `\"/this/that\"` on a null value is equivalent to calling\n          `operator[](\"this\").operator[](\"that\")` on that value, effectively\n          changing the null value to an object.\n\n    @param[in] ptr  a JSON value\n\n    @return reference to the JSON value pointed to by the JSON pointer\n\n    @complexity Linear in the length of the JSON pointer.\n\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    BasicJsonType& get_unchecked(BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            // convert null values to arrays or objects before continuing\n            if (ptr->is_null())\n            {\n                // check if reference token is a number\n                const bool nums =\n                    std::all_of(reference_token.begin(), reference_token.end(),\n                                [](const unsigned char x)\n                {\n                    return std::isdigit(x);\n                });\n\n                // change value to array for numbers or \"-\" or to object otherwise\n                *ptr = (nums || reference_token == \"-\")\n                       ? detail::value_t::array\n                       : detail::value_t::object;\n            }\n\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // use unchecked object access\n                    ptr = &ptr->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (reference_token == \"-\")\n                    {\n                        // explicitly treat \"-\" as index beyond the end\n                        ptr = &ptr->operator[](ptr->m_value.array->size());\n                    }\n                    else\n                    {\n                        // convert array index to number; unchecked access\n                        ptr = &ptr->operator[](array_index(reference_token));\n                    }\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.402  if the array index '-' is used\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    BasicJsonType& get_checked(BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // note: at performs range check\n                    ptr = &ptr->at(reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" always fails the range check\n                        JSON_THROW(detail::out_of_range::create(402,\n                                                                \"array index '-' (\" + std::to_string(ptr->m_value.array->size()) +\n                                                                \") is out of range\", *ptr));\n                    }\n\n                    // note: at performs range check\n                    ptr = &ptr->at(array_index(reference_token));\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @brief return a const reference to the pointed to value\n\n    @param[in] ptr  a JSON value\n\n    @return const reference to the JSON value pointed to by the JSON\n    pointer\n\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.402  if the array index '-' is used\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // use unchecked object access\n                    ptr = &ptr->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" cannot be used for const access\n                        JSON_THROW(detail::out_of_range::create(402, \"array index '-' (\" + std::to_string(ptr->m_value.array->size()) + \") is out of range\", *ptr));\n                    }\n\n                    // use unchecked array access\n                    ptr = &ptr->operator[](array_index(reference_token));\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.402  if the array index '-' is used\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    const BasicJsonType& get_checked(const BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // note: at performs range check\n                    ptr = &ptr->at(reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" always fails the range check\n                        JSON_THROW(detail::out_of_range::create(402,\n                                                                \"array index '-' (\" + std::to_string(ptr->m_value.array->size()) +\n                                                                \") is out of range\", *ptr));\n                    }\n\n                    // note: at performs range check\n                    ptr = &ptr->at(array_index(reference_token));\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    */\n    bool contains(const BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    if (!ptr->contains(reference_token))\n                    {\n                        // we did not find the key in the object\n                        return false;\n                    }\n\n                    ptr = &ptr->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" always fails the range check\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !(\"0\" <= reference_token && reference_token <= \"9\")))\n                    {\n                        // invalid char\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))\n                        {\n                            // first char should be between '1' and '9'\n                            return false;\n                        }\n                        for (std::size_t i = 1; i < reference_token.size(); i++)\n                        {\n                            if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))\n                            {\n                                // other char should be between '0' and '9'\n                                return false;\n                            }\n                        }\n                    }\n\n                    const auto idx = array_index(reference_token);\n                    if (idx >= ptr->size())\n                    {\n                        // index out of range\n                        return false;\n                    }\n\n                    ptr = &ptr->operator[](idx);\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                {\n                    // we do not expect primitive values if there is still a\n                    // reference token to process\n                    return false;\n                }\n            }\n        }\n\n        // no reference token left means we found a primitive value\n        return true;\n    }\n\n    /*!\n    @brief split the string input to reference tokens\n\n    @note This function is only called by the json_pointer constructor.\n          All exceptions below are documented there.\n\n    @throw parse_error.107  if the pointer is not empty or begins with '/'\n    @throw parse_error.108  if character '~' is not followed by '0' or '1'\n    */\n    static std::vector<std::string> split(const std::string& reference_string)\n    {\n        std::vector<std::string> result;\n\n        // special case: empty reference string -> no reference tokens\n        if (reference_string.empty())\n        {\n            return result;\n        }\n\n        // check if nonempty reference string begins with slash\n        if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))\n        {\n            JSON_THROW(detail::parse_error::create(107, 1, \"JSON pointer must be empty or begin with '/' - was: '\" + reference_string + \"'\", BasicJsonType()));\n        }\n\n        // extract the reference tokens:\n        // - slash: position of the last read slash (or end of string)\n        // - start: position after the previous slash\n        for (\n            // search for the first slash after the first character\n            std::size_t slash = reference_string.find_first_of('/', 1),\n            // set the beginning of the first reference token\n            start = 1;\n            // we can stop if start == 0 (if slash == std::string::npos)\n            start != 0;\n            // set the beginning of the next reference token\n            // (will eventually be 0 if slash == std::string::npos)\n            start = (slash == std::string::npos) ? 0 : slash + 1,\n            // find next slash\n            slash = reference_string.find_first_of('/', start))\n        {\n            // use the text between the beginning of the reference token\n            // (start) and the last slash (slash).\n            auto reference_token = reference_string.substr(start, slash - start);\n\n            // check reference tokens are properly escaped\n            for (std::size_t pos = reference_token.find_first_of('~');\n                    pos != std::string::npos;\n                    pos = reference_token.find_first_of('~', pos + 1))\n            {\n                JSON_ASSERT(reference_token[pos] == '~');\n\n                // ~ must be followed by 0 or 1\n                if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||\n                                         (reference_token[pos + 1] != '0' &&\n                                          reference_token[pos + 1] != '1')))\n                {\n                    JSON_THROW(detail::parse_error::create(108, 0, \"escape character '~' must be followed with '0' or '1'\", BasicJsonType()));\n                }\n            }\n\n            // finally, store the reference token\n            detail::unescape(reference_token);\n            result.push_back(reference_token);\n        }\n\n        return result;\n    }\n\n  private:\n    /*!\n    @param[in] reference_string  the reference string to the current value\n    @param[in] value             the value to consider\n    @param[in,out] result        the result object to insert values to\n\n    @note Empty objects or arrays are flattened to `null`.\n    */\n    static void flatten(const std::string& reference_string,\n                        const BasicJsonType& value,\n                        BasicJsonType& result)\n    {\n        switch (value.type())\n        {\n            case detail::value_t::array:\n            {\n                if (value.m_value.array->empty())\n                {\n                    // flatten empty array as null\n                    result[reference_string] = nullptr;\n                }\n                else\n                {\n                    // iterate array and use index as reference string\n                    for (std::size_t i = 0; i < value.m_value.array->size(); ++i)\n                    {\n                        flatten(reference_string + \"/\" + std::to_string(i),\n                                value.m_value.array->operator[](i), result);\n                    }\n                }\n                break;\n            }\n\n            case detail::value_t::object:\n            {\n                if (value.m_value.object->empty())\n                {\n                    // flatten empty object as null\n                    result[reference_string] = nullptr;\n                }\n                else\n                {\n                    // iterate object and use keys as reference string\n                    for (const auto& element : *value.m_value.object)\n                    {\n                        flatten(reference_string + \"/\" + detail::escape(element.first), element.second, result);\n                    }\n                }\n                break;\n            }\n\n            case detail::value_t::null:\n            case detail::value_t::string:\n            case detail::value_t::boolean:\n            case detail::value_t::number_integer:\n            case detail::value_t::number_unsigned:\n            case detail::value_t::number_float:\n            case detail::value_t::binary:\n            case detail::value_t::discarded:\n            default:\n            {\n                // add primitive value with its reference string\n                result[reference_string] = value;\n                break;\n            }\n        }\n    }\n\n    /*!\n    @param[in] value  flattened JSON\n\n    @return unflattened JSON\n\n    @throw parse_error.109 if array index is not a number\n    @throw type_error.314  if value is not an object\n    @throw type_error.315  if object values are not primitive\n    @throw type_error.313  if value cannot be unflattened\n    */\n    static BasicJsonType\n    unflatten(const BasicJsonType& value)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!value.is_object()))\n        {\n            JSON_THROW(detail::type_error::create(314, \"only objects can be unflattened\", value));\n        }\n\n        BasicJsonType result;\n\n        // iterate the JSON object values\n        for (const auto& element : *value.m_value.object)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))\n            {\n                JSON_THROW(detail::type_error::create(315, \"values in object must be primitive\", element.second));\n            }\n\n            // assign value to reference pointed to by JSON pointer; Note that if\n            // the JSON pointer is \"\" (i.e., points to the whole value), function\n            // get_and_create returns a reference to result itself. An assignment\n            // will then create a primitive value.\n            json_pointer(element.first).get_and_create(result) = element.second;\n        }\n\n        return result;\n    }\n\n    /*!\n    @brief compares two JSON pointers for equality\n\n    @param[in] lhs  JSON pointer to compare\n    @param[in] rhs  JSON pointer to compare\n    @return whether @a lhs is equal to @a rhs\n\n    @complexity Linear in the length of the JSON pointer\n\n    @exceptionsafety No-throw guarantee: this function never throws exceptions.\n    */\n    friend bool operator==(json_pointer const& lhs,\n                           json_pointer const& rhs) noexcept\n    {\n        return lhs.reference_tokens == rhs.reference_tokens;\n    }\n\n    /*!\n    @brief compares two JSON pointers for inequality\n\n    @param[in] lhs  JSON pointer to compare\n    @param[in] rhs  JSON pointer to compare\n    @return whether @a lhs is not equal @a rhs\n\n    @complexity Linear in the length of the JSON pointer\n\n    @exceptionsafety No-throw guarantee: this function never throws exceptions.\n    */\n    friend bool operator!=(json_pointer const& lhs,\n                           json_pointer const& rhs) noexcept\n    {\n        return !(lhs == rhs);\n    }\n\n    /// the reference tokens\n    std::vector<std::string> reference_tokens;\n};\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/json_ref.hpp",
    "content": "#pragma once\n\n#include <initializer_list>\n#include <utility>\n\n#include <nlohmann/detail/meta/type_traits.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename BasicJsonType>\nclass json_ref\n{\n  public:\n    using value_type = BasicJsonType;\n\n    json_ref(value_type&& value)\n        : owned_value(std::move(value))\n    {}\n\n    json_ref(const value_type& value)\n        : value_ref(&value)\n    {}\n\n    json_ref(std::initializer_list<json_ref> init)\n        : owned_value(init)\n    {}\n\n    template <\n        class... Args,\n        enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >\n    json_ref(Args && ... args)\n        : owned_value(std::forward<Args>(args)...)\n    {}\n\n    // class should be movable only\n    json_ref(json_ref&&) noexcept = default;\n    json_ref(const json_ref&) = delete;\n    json_ref& operator=(const json_ref&) = delete;\n    json_ref& operator=(json_ref&&) = delete;\n    ~json_ref() = default;\n\n    value_type moved_or_copied() const\n    {\n        if (value_ref == nullptr)\n        {\n            return std::move(owned_value);\n        }\n        return *value_ref;\n    }\n\n    value_type const& operator*() const\n    {\n        return value_ref ? *value_ref : owned_value;\n    }\n\n    value_type const* operator->() const\n    {\n        return &** this;\n    }\n\n  private:\n    mutable value_type owned_value = nullptr;\n    value_type const* value_ref = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/macro_scope.hpp",
    "content": "#pragma once\n\n#include <utility> // declval, pair\n#include <nlohmann/thirdparty/hedley/hedley.hpp>\n#include <nlohmann/detail/meta/detected.hpp>\n\n// This file contains all internal macro definitions\n// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them\n\n// exclude unsupported compilers\n#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)\n    #if defined(__clang__)\n        #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400\n            #error \"unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers\"\n        #endif\n    #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))\n        #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800\n            #error \"unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers\"\n        #endif\n    #endif\n#endif\n\n// C++ language standard detection\n// if the user manually specified the used c++ version this is skipped\n#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)\n    #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)\n        #define JSON_HAS_CPP_20\n        #define JSON_HAS_CPP_17\n        #define JSON_HAS_CPP_14\n    #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464\n        #define JSON_HAS_CPP_17\n        #define JSON_HAS_CPP_14\n    #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)\n        #define JSON_HAS_CPP_14\n    #endif\n    // the cpp 11 flag is always specified because it is the minimal required version\n    #define JSON_HAS_CPP_11\n#endif\n\n#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)\n    #ifdef JSON_HAS_CPP_17\n        #if defined(__cpp_lib_filesystem)\n            #define JSON_HAS_FILESYSTEM 1\n        #elif defined(__cpp_lib_experimental_filesystem)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #elif !defined(__has_include)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #elif __has_include(<filesystem>)\n            #define JSON_HAS_FILESYSTEM 1\n        #elif __has_include(<experimental/filesystem>)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #endif\n\n        // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/\n        #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(__clang_major__) && __clang_major__ < 7\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(_MSC_VER) && _MSC_VER < 1940\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before iOS 13\n        #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before macOS Catalina\n        #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n    #endif\n#endif\n\n#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n    #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0\n#endif\n\n#ifndef JSON_HAS_FILESYSTEM\n    #define JSON_HAS_FILESYSTEM 0\n#endif\n\n// disable documentation warnings on clang\n#if defined(__clang__)\n    #pragma clang diagnostic push\n    #pragma clang diagnostic ignored \"-Wdocumentation\"\n    #pragma clang diagnostic ignored \"-Wdocumentation-unknown-command\"\n#endif\n\n// allow disabling exceptions\n#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)\n    #define JSON_THROW(exception) throw exception\n    #define JSON_TRY try\n    #define JSON_CATCH(exception) catch(exception)\n    #define JSON_INTERNAL_CATCH(exception) catch(exception)\n#else\n    #include <cstdlib>\n    #define JSON_THROW(exception) std::abort()\n    #define JSON_TRY if(true)\n    #define JSON_CATCH(exception) if(false)\n    #define JSON_INTERNAL_CATCH(exception) if(false)\n#endif\n\n// override exception macros\n#if defined(JSON_THROW_USER)\n    #undef JSON_THROW\n    #define JSON_THROW JSON_THROW_USER\n#endif\n#if defined(JSON_TRY_USER)\n    #undef JSON_TRY\n    #define JSON_TRY JSON_TRY_USER\n#endif\n#if defined(JSON_CATCH_USER)\n    #undef JSON_CATCH\n    #define JSON_CATCH JSON_CATCH_USER\n    #undef JSON_INTERNAL_CATCH\n    #define JSON_INTERNAL_CATCH JSON_CATCH_USER\n#endif\n#if defined(JSON_INTERNAL_CATCH_USER)\n    #undef JSON_INTERNAL_CATCH\n    #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER\n#endif\n\n// allow overriding assert\n#if !defined(JSON_ASSERT)\n    #include <cassert> // assert\n    #define JSON_ASSERT(x) assert(x)\n#endif\n\n// allow to access some private functions (needed by the test suite)\n#if defined(JSON_TESTS_PRIVATE)\n    #define JSON_PRIVATE_UNLESS_TESTED public\n#else\n    #define JSON_PRIVATE_UNLESS_TESTED private\n#endif\n\n/*!\n@brief macro to briefly define a mapping between an enum and JSON\n@def NLOHMANN_JSON_SERIALIZE_ENUM\n@since version 3.4.0\n*/\n#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \\\n    template<typename BasicJsonType>                                                            \\\n    inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \\\n    {                                                                                           \\\n        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE \" must be an enum!\");          \\\n        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \\\n        auto it = std::find_if(std::begin(m), std::end(m),                                      \\\n                               [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \\\n        {                                                                                       \\\n            return ej_pair.first == e;                                                          \\\n        });                                                                                     \\\n        j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \\\n    }                                                                                           \\\n    template<typename BasicJsonType>                                                            \\\n    inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \\\n    {                                                                                           \\\n        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE \" must be an enum!\");          \\\n        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \\\n        auto it = std::find_if(std::begin(m), std::end(m),                                      \\\n                               [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \\\n        {                                                                                       \\\n            return ej_pair.second == j;                                                         \\\n        });                                                                                     \\\n        e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \\\n    }\n\n// Ugly macros to avoid uglier copy-paste when specializing basic_json. They\n// may be removed in the future once the class is split.\n\n#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \\\n    template<template<typename, typename, typename...> class ObjectType,   \\\n             template<typename, typename...> class ArrayType,              \\\n             class StringType, class BooleanType, class NumberIntegerType, \\\n             class NumberUnsignedType, class NumberFloatType,              \\\n             template<typename> class AllocatorType,                       \\\n             template<typename, typename = void> class JSONSerializer,     \\\n             class BinaryType>\n\n#define NLOHMANN_BASIC_JSON_TPL                                            \\\n    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \\\n    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \\\n    AllocatorType, JSONSerializer, BinaryType>\n\n// Macros to simplify conversion from/to types\n\n#define NLOHMANN_JSON_EXPAND( x ) x\n#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME\n#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \\\n        NLOHMANN_JSON_PASTE64, \\\n        NLOHMANN_JSON_PASTE63, \\\n        NLOHMANN_JSON_PASTE62, \\\n        NLOHMANN_JSON_PASTE61, \\\n        NLOHMANN_JSON_PASTE60, \\\n        NLOHMANN_JSON_PASTE59, \\\n        NLOHMANN_JSON_PASTE58, \\\n        NLOHMANN_JSON_PASTE57, \\\n        NLOHMANN_JSON_PASTE56, \\\n        NLOHMANN_JSON_PASTE55, \\\n        NLOHMANN_JSON_PASTE54, \\\n        NLOHMANN_JSON_PASTE53, \\\n        NLOHMANN_JSON_PASTE52, \\\n        NLOHMANN_JSON_PASTE51, \\\n        NLOHMANN_JSON_PASTE50, \\\n        NLOHMANN_JSON_PASTE49, \\\n        NLOHMANN_JSON_PASTE48, \\\n        NLOHMANN_JSON_PASTE47, \\\n        NLOHMANN_JSON_PASTE46, \\\n        NLOHMANN_JSON_PASTE45, \\\n        NLOHMANN_JSON_PASTE44, \\\n        NLOHMANN_JSON_PASTE43, \\\n        NLOHMANN_JSON_PASTE42, \\\n        NLOHMANN_JSON_PASTE41, \\\n        NLOHMANN_JSON_PASTE40, \\\n        NLOHMANN_JSON_PASTE39, \\\n        NLOHMANN_JSON_PASTE38, \\\n        NLOHMANN_JSON_PASTE37, \\\n        NLOHMANN_JSON_PASTE36, \\\n        NLOHMANN_JSON_PASTE35, \\\n        NLOHMANN_JSON_PASTE34, \\\n        NLOHMANN_JSON_PASTE33, \\\n        NLOHMANN_JSON_PASTE32, \\\n        NLOHMANN_JSON_PASTE31, \\\n        NLOHMANN_JSON_PASTE30, \\\n        NLOHMANN_JSON_PASTE29, \\\n        NLOHMANN_JSON_PASTE28, \\\n        NLOHMANN_JSON_PASTE27, \\\n        NLOHMANN_JSON_PASTE26, \\\n        NLOHMANN_JSON_PASTE25, \\\n        NLOHMANN_JSON_PASTE24, \\\n        NLOHMANN_JSON_PASTE23, \\\n        NLOHMANN_JSON_PASTE22, \\\n        NLOHMANN_JSON_PASTE21, \\\n        NLOHMANN_JSON_PASTE20, \\\n        NLOHMANN_JSON_PASTE19, \\\n        NLOHMANN_JSON_PASTE18, \\\n        NLOHMANN_JSON_PASTE17, \\\n        NLOHMANN_JSON_PASTE16, \\\n        NLOHMANN_JSON_PASTE15, \\\n        NLOHMANN_JSON_PASTE14, \\\n        NLOHMANN_JSON_PASTE13, \\\n        NLOHMANN_JSON_PASTE12, \\\n        NLOHMANN_JSON_PASTE11, \\\n        NLOHMANN_JSON_PASTE10, \\\n        NLOHMANN_JSON_PASTE9, \\\n        NLOHMANN_JSON_PASTE8, \\\n        NLOHMANN_JSON_PASTE7, \\\n        NLOHMANN_JSON_PASTE6, \\\n        NLOHMANN_JSON_PASTE5, \\\n        NLOHMANN_JSON_PASTE4, \\\n        NLOHMANN_JSON_PASTE3, \\\n        NLOHMANN_JSON_PASTE2, \\\n        NLOHMANN_JSON_PASTE1)(__VA_ARGS__))\n#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)\n#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)\n#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)\n#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)\n#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)\n#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)\n#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)\n#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)\n#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)\n#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)\n#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)\n#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)\n#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)\n#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)\n#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)\n#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)\n#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)\n#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)\n#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)\n#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)\n#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)\n#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)\n#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)\n#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)\n#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)\n#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)\n#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)\n#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)\n#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)\n#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)\n#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)\n#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)\n#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)\n#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)\n#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)\n#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)\n#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)\n#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)\n#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)\n#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)\n#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)\n#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)\n#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)\n#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)\n#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)\n#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)\n#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)\n#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)\n#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)\n#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)\n#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)\n#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)\n#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)\n#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)\n#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)\n#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)\n#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)\n#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)\n#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)\n#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)\n#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)\n#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)\n#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)\n\n#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;\n#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);\n\n/*!\n@brief macro\n@def NLOHMANN_DEFINE_TYPE_INTRUSIVE\n@since version 3.9.0\n*/\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \\\n    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \\\n    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }\n\n/*!\n@brief macro\n@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE\n@since version 3.9.0\n*/\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \\\n    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \\\n    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }\n\n\n// inspired from https://stackoverflow.com/a/26745591\n// allows to call any std function as if (e.g. with begin):\n// using std::begin; begin(x);\n//\n// it allows using the detected idiom to retrieve the return type\n// of such an expression\n#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)                                 \\\n    namespace detail {                                                            \\\n    using std::std_name;                                                          \\\n    \\\n    template<typename... T>                                                       \\\n    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \\\n    }                                                                             \\\n    \\\n    namespace detail2 {                                                           \\\n    struct std_name##_tag                                                         \\\n    {                                                                             \\\n    };                                                                            \\\n    \\\n    template<typename... T>                                                       \\\n    std_name##_tag std_name(T&&...);                                              \\\n    \\\n    template<typename... T>                                                       \\\n    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \\\n    \\\n    template<typename... T>                                                       \\\n    struct would_call_std_##std_name                                              \\\n    {                                                                             \\\n        static constexpr auto const value = ::nlohmann::detail::                  \\\n                                            is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \\\n    };                                                                            \\\n    } /* namespace detail2 */ \\\n    \\\n    template<typename... T>                                                       \\\n    struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...>   \\\n    {                                                                             \\\n    }\n\n#ifndef JSON_USE_IMPLICIT_CONVERSIONS\n    #define JSON_USE_IMPLICIT_CONVERSIONS 1\n#endif\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    #define JSON_EXPLICIT\n#else\n    #define JSON_EXPLICIT explicit\n#endif\n\n#ifndef JSON_DIAGNOSTICS\n    #define JSON_DIAGNOSTICS 0\n#endif\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/macro_unscope.hpp",
    "content": "#pragma once\n\n// restore clang diagnostic settings\n#if defined(__clang__)\n    #pragma clang diagnostic pop\n#endif\n\n// clean up\n#undef JSON_ASSERT\n#undef JSON_INTERNAL_CATCH\n#undef JSON_CATCH\n#undef JSON_THROW\n#undef JSON_TRY\n#undef JSON_PRIVATE_UNLESS_TESTED\n#undef JSON_HAS_CPP_11\n#undef JSON_HAS_CPP_14\n#undef JSON_HAS_CPP_17\n#undef JSON_HAS_CPP_20\n#undef JSON_HAS_FILESYSTEM\n#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION\n#undef NLOHMANN_BASIC_JSON_TPL\n#undef JSON_EXPLICIT\n#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL\n\n#include <nlohmann/thirdparty/hedley/hedley_undef.hpp>\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/call_std/begin.hpp",
    "content": "#pragma once\n\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nNLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/call_std/end.hpp",
    "content": "#pragma once\n\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nNLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/cpp_future.hpp",
    "content": "#pragma once\n\n#include <cstddef> // size_t\n#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type\n#include <utility> // index_sequence, make_index_sequence, index_sequence_for\n\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\ntemplate<typename T>\nusing uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;\n\n#ifdef JSON_HAS_CPP_14\n\n// the following utilities are natively available in C++14\nusing std::enable_if_t;\nusing std::index_sequence;\nusing std::make_index_sequence;\nusing std::index_sequence_for;\n\n#else\n\n// alias templates to reduce boilerplate\ntemplate<bool B, typename T = void>\nusing enable_if_t = typename std::enable_if<B, T>::type;\n\n// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h\n// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.\n\n//// START OF CODE FROM GOOGLE ABSEIL\n\n// integer_sequence\n//\n// Class template representing a compile-time integer sequence. An instantiation\n// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its\n// type through its template arguments (which is a common need when\n// working with C++11 variadic templates). `absl::integer_sequence` is designed\n// to be a drop-in replacement for C++14's `std::integer_sequence`.\n//\n// Example:\n//\n//   template< class T, T... Ints >\n//   void user_function(integer_sequence<T, Ints...>);\n//\n//   int main()\n//   {\n//     // user_function's `T` will be deduced to `int` and `Ints...`\n//     // will be deduced to `0, 1, 2, 3, 4`.\n//     user_function(make_integer_sequence<int, 5>());\n//   }\ntemplate <typename T, T... Ints>\nstruct integer_sequence\n{\n    using value_type = T;\n    static constexpr std::size_t size() noexcept\n    {\n        return sizeof...(Ints);\n    }\n};\n\n// index_sequence\n//\n// A helper template for an `integer_sequence` of `size_t`,\n// `absl::index_sequence` is designed to be a drop-in replacement for C++14's\n// `std::index_sequence`.\ntemplate <size_t... Ints>\nusing index_sequence = integer_sequence<size_t, Ints...>;\n\nnamespace utility_internal\n{\n\ntemplate <typename Seq, size_t SeqSize, size_t Rem>\nstruct Extend;\n\n// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.\ntemplate <typename T, T... Ints, size_t SeqSize>\nstruct Extend<integer_sequence<T, Ints...>, SeqSize, 0>\n{\n    using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;\n};\n\ntemplate <typename T, T... Ints, size_t SeqSize>\nstruct Extend<integer_sequence<T, Ints...>, SeqSize, 1>\n{\n    using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;\n};\n\n// Recursion helper for 'make_integer_sequence<T, N>'.\n// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.\ntemplate <typename T, size_t N>\nstruct Gen\n{\n    using type =\n        typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;\n};\n\ntemplate <typename T>\nstruct Gen<T, 0>\n{\n    using type = integer_sequence<T>;\n};\n\n}  // namespace utility_internal\n\n// Compile-time sequences of integers\n\n// make_integer_sequence\n//\n// This template alias is equivalent to\n// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in\n// replacement for C++14's `std::make_integer_sequence`.\ntemplate <typename T, T N>\nusing make_integer_sequence = typename utility_internal::Gen<T, N>::type;\n\n// make_index_sequence\n//\n// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,\n// and is designed to be a drop-in replacement for C++14's\n// `std::make_index_sequence`.\ntemplate <size_t N>\nusing make_index_sequence = make_integer_sequence<size_t, N>;\n\n// index_sequence_for\n//\n// Converts a typename pack into an index sequence of the same length, and\n// is designed to be a drop-in replacement for C++14's\n// `std::index_sequence_for()`\ntemplate <typename... Ts>\nusing index_sequence_for = make_index_sequence<sizeof...(Ts)>;\n\n//// END OF CODE FROM GOOGLE ABSEIL\n\n#endif\n\n// dispatch utility (taken from ranges-v3)\ntemplate<unsigned N> struct priority_tag : priority_tag < N - 1 > {};\ntemplate<> struct priority_tag<0> {};\n\n// taken from ranges-v3\ntemplate<typename T>\nstruct static_const\n{\n    static constexpr T value{};\n};\n\ntemplate<typename T>\nconstexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)\n\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/detected.hpp",
    "content": "#pragma once\n\n#include <type_traits>\n\n#include <nlohmann/detail/meta/void_t.hpp>\n\n// https://en.cppreference.com/w/cpp/experimental/is_detected\nnamespace nlohmann\n{\nnamespace detail\n{\nstruct nonesuch\n{\n    nonesuch() = delete;\n    ~nonesuch() = delete;\n    nonesuch(nonesuch const&) = delete;\n    nonesuch(nonesuch const&&) = delete;\n    void operator=(nonesuch const&) = delete;\n    void operator=(nonesuch&&) = delete;\n};\n\ntemplate<class Default,\n         class AlwaysVoid,\n         template<class...> class Op,\n         class... Args>\nstruct detector\n{\n    using value_t = std::false_type;\n    using type = Default;\n};\n\ntemplate<class Default, template<class...> class Op, class... Args>\nstruct detector<Default, void_t<Op<Args...>>, Op, Args...>\n{\n    using value_t = std::true_type;\n    using type = Op<Args...>;\n};\n\ntemplate<template<class...> class Op, class... Args>\nusing is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;\n\ntemplate<template<class...> class Op, class... Args>\nstruct is_detected_lazy : is_detected<Op, Args...> { };\n\ntemplate<template<class...> class Op, class... Args>\nusing detected_t = typename detector<nonesuch, void, Op, Args...>::type;\n\ntemplate<class Default, template<class...> class Op, class... Args>\nusing detected_or = detector<Default, void, Op, Args...>;\n\ntemplate<class Default, template<class...> class Op, class... Args>\nusing detected_or_t = typename detected_or<Default, Op, Args...>::type;\n\ntemplate<class Expected, template<class...> class Op, class... Args>\nusing is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;\n\ntemplate<class To, template<class...> class Op, class... Args>\nusing is_detected_convertible =\n    std::is_convertible<detected_t<Op, Args...>, To>;\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/identity_tag.hpp",
    "content": "#pragma once\n\nnamespace nlohmann\n{\nnamespace detail\n{\n// dispatching helper struct\ntemplate <class T> struct identity_tag {};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/is_sax.hpp",
    "content": "#pragma once\n\n#include <cstdint> // size_t\n#include <utility> // declval\n#include <string> // string\n\n#include <nlohmann/detail/meta/detected.hpp>\n#include <nlohmann/detail/meta/type_traits.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename T>\nusing null_function_t = decltype(std::declval<T&>().null());\n\ntemplate<typename T>\nusing boolean_function_t =\n    decltype(std::declval<T&>().boolean(std::declval<bool>()));\n\ntemplate<typename T, typename Integer>\nusing number_integer_function_t =\n    decltype(std::declval<T&>().number_integer(std::declval<Integer>()));\n\ntemplate<typename T, typename Unsigned>\nusing number_unsigned_function_t =\n    decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));\n\ntemplate<typename T, typename Float, typename String>\nusing number_float_function_t = decltype(std::declval<T&>().number_float(\n                                    std::declval<Float>(), std::declval<const String&>()));\n\ntemplate<typename T, typename String>\nusing string_function_t =\n    decltype(std::declval<T&>().string(std::declval<String&>()));\n\ntemplate<typename T, typename Binary>\nusing binary_function_t =\n    decltype(std::declval<T&>().binary(std::declval<Binary&>()));\n\ntemplate<typename T>\nusing start_object_function_t =\n    decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));\n\ntemplate<typename T, typename String>\nusing key_function_t =\n    decltype(std::declval<T&>().key(std::declval<String&>()));\n\ntemplate<typename T>\nusing end_object_function_t = decltype(std::declval<T&>().end_object());\n\ntemplate<typename T>\nusing start_array_function_t =\n    decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));\n\ntemplate<typename T>\nusing end_array_function_t = decltype(std::declval<T&>().end_array());\n\ntemplate<typename T, typename Exception>\nusing parse_error_function_t = decltype(std::declval<T&>().parse_error(\n        std::declval<std::size_t>(), std::declval<const std::string&>(),\n        std::declval<const Exception&>()));\n\ntemplate<typename SAX, typename BasicJsonType>\nstruct is_sax\n{\n  private:\n    static_assert(is_basic_json<BasicJsonType>::value,\n                  \"BasicJsonType must be of type basic_json<...>\");\n\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using exception_t = typename BasicJsonType::exception;\n\n  public:\n    static constexpr bool value =\n        is_detected_exact<bool, null_function_t, SAX>::value &&\n        is_detected_exact<bool, boolean_function_t, SAX>::value &&\n        is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&\n        is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&\n        is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&\n        is_detected_exact<bool, string_function_t, SAX, string_t>::value &&\n        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&\n        is_detected_exact<bool, start_object_function_t, SAX>::value &&\n        is_detected_exact<bool, key_function_t, SAX, string_t>::value &&\n        is_detected_exact<bool, end_object_function_t, SAX>::value &&\n        is_detected_exact<bool, start_array_function_t, SAX>::value &&\n        is_detected_exact<bool, end_array_function_t, SAX>::value &&\n        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;\n};\n\ntemplate<typename SAX, typename BasicJsonType>\nstruct is_sax_static_asserts\n{\n  private:\n    static_assert(is_basic_json<BasicJsonType>::value,\n                  \"BasicJsonType must be of type basic_json<...>\");\n\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using exception_t = typename BasicJsonType::exception;\n\n  public:\n    static_assert(is_detected_exact<bool, null_function_t, SAX>::value,\n                  \"Missing/invalid function: bool null()\");\n    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,\n                  \"Missing/invalid function: bool boolean(bool)\");\n    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,\n                  \"Missing/invalid function: bool boolean(bool)\");\n    static_assert(\n        is_detected_exact<bool, number_integer_function_t, SAX,\n        number_integer_t>::value,\n        \"Missing/invalid function: bool number_integer(number_integer_t)\");\n    static_assert(\n        is_detected_exact<bool, number_unsigned_function_t, SAX,\n        number_unsigned_t>::value,\n        \"Missing/invalid function: bool number_unsigned(number_unsigned_t)\");\n    static_assert(is_detected_exact<bool, number_float_function_t, SAX,\n                  number_float_t, string_t>::value,\n                  \"Missing/invalid function: bool number_float(number_float_t, const string_t&)\");\n    static_assert(\n        is_detected_exact<bool, string_function_t, SAX, string_t>::value,\n        \"Missing/invalid function: bool string(string_t&)\");\n    static_assert(\n        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,\n        \"Missing/invalid function: bool binary(binary_t&)\");\n    static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,\n                  \"Missing/invalid function: bool start_object(std::size_t)\");\n    static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,\n                  \"Missing/invalid function: bool key(string_t&)\");\n    static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,\n                  \"Missing/invalid function: bool end_object()\");\n    static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,\n                  \"Missing/invalid function: bool start_array(std::size_t)\");\n    static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,\n                  \"Missing/invalid function: bool end_array()\");\n    static_assert(\n        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,\n        \"Missing/invalid function: bool parse_error(std::size_t, const \"\n        \"std::string&, const exception&)\");\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/type_traits.hpp",
    "content": "#pragma once\n\n#include <limits> // numeric_limits\n#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type\n#include <utility> // declval\n#include <tuple> // tuple\n\n#include <nlohmann/detail/macro_scope.hpp>\n\n#include <nlohmann/detail/iterators/iterator_traits.hpp>\n#include <nlohmann/detail/meta/call_std/begin.hpp>\n#include <nlohmann/detail/meta/call_std/end.hpp>\n#include <nlohmann/detail/meta/cpp_future.hpp>\n#include <nlohmann/detail/meta/detected.hpp>\n#include <nlohmann/json_fwd.hpp>\n\nnamespace nlohmann\n{\n/*!\n@brief detail namespace with internal helper functions\n\nThis namespace collects functions that should not be exposed,\nimplementations of some @ref basic_json methods, and meta-programming helpers.\n\n@since version 2.1.0\n*/\nnamespace detail\n{\n/////////////\n// helpers //\n/////////////\n\n// Note to maintainers:\n//\n// Every trait in this file expects a non CV-qualified type.\n// The only exceptions are in the 'aliases for detected' section\n// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))\n//\n// In this case, T has to be properly CV-qualified to constraint the function arguments\n// (e.g. to_json(BasicJsonType&, const T&))\n\ntemplate<typename> struct is_basic_json : std::false_type {};\n\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nstruct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};\n\n//////////////////////\n// json_ref helpers //\n//////////////////////\n\ntemplate<typename>\nclass json_ref;\n\ntemplate<typename>\nstruct is_json_ref : std::false_type {};\n\ntemplate<typename T>\nstruct is_json_ref<json_ref<T>> : std::true_type {};\n\n//////////////////////////\n// aliases for detected //\n//////////////////////////\n\ntemplate<typename T>\nusing mapped_type_t = typename T::mapped_type;\n\ntemplate<typename T>\nusing key_type_t = typename T::key_type;\n\ntemplate<typename T>\nusing value_type_t = typename T::value_type;\n\ntemplate<typename T>\nusing difference_type_t = typename T::difference_type;\n\ntemplate<typename T>\nusing pointer_t = typename T::pointer;\n\ntemplate<typename T>\nusing reference_t = typename T::reference;\n\ntemplate<typename T>\nusing iterator_category_t = typename T::iterator_category;\n\ntemplate<typename T, typename... Args>\nusing to_json_function = decltype(T::to_json(std::declval<Args>()...));\n\ntemplate<typename T, typename... Args>\nusing from_json_function = decltype(T::from_json(std::declval<Args>()...));\n\ntemplate<typename T, typename U>\nusing get_template_function = decltype(std::declval<T>().template get<U>());\n\n// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists\ntemplate<typename BasicJsonType, typename T, typename = void>\nstruct has_from_json : std::false_type {};\n\n// trait checking if j.get<T> is valid\n// use this trait instead of std::is_constructible or std::is_convertible,\n// both rely on, or make use of implicit conversions, and thus fail when T\n// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)\ntemplate <typename BasicJsonType, typename T>\nstruct is_getable\n{\n    static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;\n};\n\ntemplate<typename BasicJsonType, typename T>\nstruct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>\n{\n    using serializer = typename BasicJsonType::template json_serializer<T, void>;\n\n    static constexpr bool value =\n        is_detected_exact<void, from_json_function, serializer,\n        const BasicJsonType&, T&>::value;\n};\n\n// This trait checks if JSONSerializer<T>::from_json(json const&) exists\n// this overload is used for non-default-constructible user-defined-types\ntemplate<typename BasicJsonType, typename T, typename = void>\nstruct has_non_default_from_json : std::false_type {};\n\ntemplate<typename BasicJsonType, typename T>\nstruct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>\n{\n    using serializer = typename BasicJsonType::template json_serializer<T, void>;\n\n    static constexpr bool value =\n        is_detected_exact<T, from_json_function, serializer,\n        const BasicJsonType&>::value;\n};\n\n// This trait checks if BasicJsonType::json_serializer<T>::to_json exists\n// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.\ntemplate<typename BasicJsonType, typename T, typename = void>\nstruct has_to_json : std::false_type {};\n\ntemplate<typename BasicJsonType, typename T>\nstruct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>\n{\n    using serializer = typename BasicJsonType::template json_serializer<T, void>;\n\n    static constexpr bool value =\n        is_detected_exact<void, to_json_function, serializer, BasicJsonType&,\n        T>::value;\n};\n\n\n///////////////////\n// is_ functions //\n///////////////////\n\n// https://en.cppreference.com/w/cpp/types/conjunction\ntemplate<class...> struct conjunction : std::true_type { };\ntemplate<class B1> struct conjunction<B1> : B1 { };\ntemplate<class B1, class... Bn>\nstruct conjunction<B1, Bn...>\n: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};\n\n// https://en.cppreference.com/w/cpp/types/negation\ntemplate<class B> struct negation : std::integral_constant < bool, !B::value > { };\n\n// Reimplementation of is_constructible and is_default_constructible, due to them being broken for\n// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).\n// This causes compile errors in e.g. clang 3.5 or gcc 4.9.\ntemplate <typename T>\nstruct is_default_constructible : std::is_default_constructible<T> {};\n\ntemplate <typename T1, typename T2>\nstruct is_default_constructible<std::pair<T1, T2>>\n            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};\n\ntemplate <typename T1, typename T2>\nstruct is_default_constructible<const std::pair<T1, T2>>\n            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};\n\ntemplate <typename... Ts>\nstruct is_default_constructible<std::tuple<Ts...>>\n            : conjunction<is_default_constructible<Ts>...> {};\n\ntemplate <typename... Ts>\nstruct is_default_constructible<const std::tuple<Ts...>>\n            : conjunction<is_default_constructible<Ts>...> {};\n\n\ntemplate <typename T, typename... Args>\nstruct is_constructible : std::is_constructible<T, Args...> {};\n\ntemplate <typename T1, typename T2>\nstruct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};\n\ntemplate <typename T1, typename T2>\nstruct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};\n\ntemplate <typename... Ts>\nstruct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};\n\ntemplate <typename... Ts>\nstruct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};\n\n\ntemplate<typename T, typename = void>\nstruct is_iterator_traits : std::false_type {};\n\ntemplate<typename T>\nstruct is_iterator_traits<iterator_traits<T>>\n{\n  private:\n    using traits = iterator_traits<T>;\n\n  public:\n    static constexpr auto value =\n        is_detected<value_type_t, traits>::value &&\n        is_detected<difference_type_t, traits>::value &&\n        is_detected<pointer_t, traits>::value &&\n        is_detected<iterator_category_t, traits>::value &&\n        is_detected<reference_t, traits>::value;\n};\n\ntemplate<typename T>\nstruct is_range\n{\n  private:\n    using t_ref = typename std::add_lvalue_reference<T>::type;\n\n    using iterator = detected_t<result_of_begin, t_ref>;\n    using sentinel = detected_t<result_of_end, t_ref>;\n\n    // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator\n    // and https://en.cppreference.com/w/cpp/iterator/sentinel_for\n    // but reimplementing these would be too much work, as a lot of other concepts are used underneath\n    static constexpr auto is_iterator_begin =\n        is_iterator_traits<iterator_traits<iterator>>::value;\n\n  public:\n    static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;\n};\n\ntemplate<typename R>\nusing iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;\n\ntemplate<typename T>\nusing range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;\n\n// The following implementation of is_complete_type is taken from\n// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/\n// and is written by Xiang Fan who agreed to using it in this library.\n\ntemplate<typename T, typename = void>\nstruct is_complete_type : std::false_type {};\n\ntemplate<typename T>\nstruct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleObjectType,\n         typename = void>\nstruct is_compatible_object_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleObjectType>\nstruct is_compatible_object_type_impl <\n    BasicJsonType, CompatibleObjectType,\n    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&\n    is_detected<key_type_t, CompatibleObjectType>::value >>\n{\n    using object_t = typename BasicJsonType::object_t;\n\n    // macOS's is_constructible does not play well with nonesuch...\n    static constexpr bool value =\n        is_constructible<typename object_t::key_type,\n        typename CompatibleObjectType::key_type>::value &&\n        is_constructible<typename object_t::mapped_type,\n        typename CompatibleObjectType::mapped_type>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleObjectType>\nstruct is_compatible_object_type\n    : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType,\n         typename = void>\nstruct is_constructible_object_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType>\nstruct is_constructible_object_type_impl <\n    BasicJsonType, ConstructibleObjectType,\n    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&\n    is_detected<key_type_t, ConstructibleObjectType>::value >>\n{\n    using object_t = typename BasicJsonType::object_t;\n\n    static constexpr bool value =\n        (is_default_constructible<ConstructibleObjectType>::value &&\n         (std::is_move_assignable<ConstructibleObjectType>::value ||\n          std::is_copy_assignable<ConstructibleObjectType>::value) &&\n         (is_constructible<typename ConstructibleObjectType::key_type,\n          typename object_t::key_type>::value &&\n          std::is_same <\n          typename object_t::mapped_type,\n          typename ConstructibleObjectType::mapped_type >::value)) ||\n        (has_from_json<BasicJsonType,\n         typename ConstructibleObjectType::mapped_type>::value ||\n         has_non_default_from_json <\n         BasicJsonType,\n         typename ConstructibleObjectType::mapped_type >::value);\n};\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType>\nstruct is_constructible_object_type\n    : is_constructible_object_type_impl<BasicJsonType,\n      ConstructibleObjectType> {};\n\ntemplate<typename BasicJsonType, typename CompatibleStringType>\nstruct is_compatible_string_type\n{\n    static constexpr auto value =\n        is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;\n};\n\ntemplate<typename BasicJsonType, typename ConstructibleStringType>\nstruct is_constructible_string_type\n{\n    static constexpr auto value =\n        is_constructible<ConstructibleStringType,\n        typename BasicJsonType::string_t>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleArrayType, typename = void>\nstruct is_compatible_array_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleArrayType>\nstruct is_compatible_array_type_impl <\n    BasicJsonType, CompatibleArrayType,\n    enable_if_t <\n    is_detected<iterator_t, CompatibleArrayType>::value&&\n    is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&\n// special case for types like std::filesystem::path whose iterator's value_type are themselves\n// c.f. https://github.com/nlohmann/json/pull/3073\n    !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>\n{\n    static constexpr bool value =\n        is_constructible<BasicJsonType,\n        range_value_t<CompatibleArrayType>>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleArrayType>\nstruct is_compatible_array_type\n    : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType, typename = void>\nstruct is_constructible_array_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType>\nstruct is_constructible_array_type_impl <\n    BasicJsonType, ConstructibleArrayType,\n    enable_if_t<std::is_same<ConstructibleArrayType,\n    typename BasicJsonType::value_type>::value >>\n            : std::true_type {};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType>\nstruct is_constructible_array_type_impl <\n    BasicJsonType, ConstructibleArrayType,\n    enable_if_t < !std::is_same<ConstructibleArrayType,\n    typename BasicJsonType::value_type>::value&&\n    !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&\n    is_default_constructible<ConstructibleArrayType>::value&&\n(std::is_move_assignable<ConstructibleArrayType>::value ||\n std::is_copy_assignable<ConstructibleArrayType>::value)&&\nis_detected<iterator_t, ConstructibleArrayType>::value&&\nis_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&\nis_detected<range_value_t, ConstructibleArrayType>::value&&\n// special case for types like std::filesystem::path whose iterator's value_type are themselves\n// c.f. https://github.com/nlohmann/json/pull/3073\n!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&\n        is_complete_type <\n        detected_t<range_value_t, ConstructibleArrayType >>::value >>\n{\n    using value_type = range_value_t<ConstructibleArrayType>;\n\n    static constexpr bool value =\n        std::is_same<value_type,\n        typename BasicJsonType::array_t::value_type>::value ||\n        has_from_json<BasicJsonType,\n        value_type>::value ||\n        has_non_default_from_json <\n        BasicJsonType,\n        value_type >::value;\n};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType>\nstruct is_constructible_array_type\n    : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};\n\ntemplate<typename RealIntegerType, typename CompatibleNumberIntegerType,\n         typename = void>\nstruct is_compatible_integer_type_impl : std::false_type {};\n\ntemplate<typename RealIntegerType, typename CompatibleNumberIntegerType>\nstruct is_compatible_integer_type_impl <\n    RealIntegerType, CompatibleNumberIntegerType,\n    enable_if_t < std::is_integral<RealIntegerType>::value&&\n    std::is_integral<CompatibleNumberIntegerType>::value&&\n    !std::is_same<bool, CompatibleNumberIntegerType>::value >>\n{\n    // is there an assert somewhere on overflows?\n    using RealLimits = std::numeric_limits<RealIntegerType>;\n    using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;\n\n    static constexpr auto value =\n        is_constructible<RealIntegerType,\n        CompatibleNumberIntegerType>::value &&\n        CompatibleLimits::is_integer &&\n        RealLimits::is_signed == CompatibleLimits::is_signed;\n};\n\ntemplate<typename RealIntegerType, typename CompatibleNumberIntegerType>\nstruct is_compatible_integer_type\n    : is_compatible_integer_type_impl<RealIntegerType,\n      CompatibleNumberIntegerType> {};\n\ntemplate<typename BasicJsonType, typename CompatibleType, typename = void>\nstruct is_compatible_type_impl: std::false_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleType>\nstruct is_compatible_type_impl <\n    BasicJsonType, CompatibleType,\n    enable_if_t<is_complete_type<CompatibleType>::value >>\n{\n    static constexpr bool value =\n        has_to_json<BasicJsonType, CompatibleType>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleType>\nstruct is_compatible_type\n    : is_compatible_type_impl<BasicJsonType, CompatibleType> {};\n\ntemplate<typename T1, typename T2>\nstruct is_constructible_tuple : std::false_type {};\n\ntemplate<typename T1, typename... Args>\nstruct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};\n\n// a naive helper to check if a type is an ordered_map (exploits the fact that\n// ordered_map inherits capacity() from std::vector)\ntemplate <typename T>\nstruct is_ordered_map\n{\n    using one = char;\n\n    struct two\n    {\n        char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n    };\n\n    template <typename C> static one test( decltype(&C::capacity) ) ;\n    template <typename C> static two test(...);\n\n    enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n};\n\n// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)\ntemplate < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >\nT conditional_static_cast(U value)\n{\n    return static_cast<T>(value);\n}\n\ntemplate<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>\nT conditional_static_cast(U value)\n{\n    return value;\n}\n\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/meta/void_t.hpp",
    "content": "#pragma once\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename ...Ts> struct make_void\n{\n    using type = void;\n};\ntemplate<typename ...Ts> using void_t = typename make_void<Ts...>::type;\n} // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/output/binary_writer.hpp",
    "content": "#pragma once\n\n#include <algorithm> // reverse\n#include <array> // array\n#include <cmath> // isnan, isinf\n#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t\n#include <cstring> // memcpy\n#include <limits> // numeric_limits\n#include <string> // string\n#include <utility> // move\n\n#include <nlohmann/detail/input/binary_reader.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/output/output_adapters.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////////////\n// binary writer //\n///////////////////\n\n/*!\n@brief serialization to CBOR and MessagePack values\n*/\ntemplate<typename BasicJsonType, typename CharType>\nclass binary_writer\n{\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n\n  public:\n    /*!\n    @brief create a binary writer\n\n    @param[in] adapter  output adapter to write to\n    */\n    explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))\n    {\n        JSON_ASSERT(oa);\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    @pre       j.type() == value_t::object\n    */\n    void write_bson(const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::object:\n            {\n                write_bson_object(*j.m_value.object);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::array:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                JSON_THROW(type_error::create(317, \"to serialize to BSON, top-level type must be object, but is \" + std::string(j.type_name()), j));\n            }\n        }\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    */\n    void write_cbor(const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::null:\n            {\n                oa->write_character(to_char_type(0xF6));\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                oa->write_character(j.m_value.boolean\n                                    ? to_char_type(0xF5)\n                                    : to_char_type(0xF4));\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                if (j.m_value.number_integer >= 0)\n                {\n                    // CBOR does not differentiate between positive signed\n                    // integers and unsigned integers. Therefore, we used the\n                    // code from the value_t::number_unsigned case here.\n                    if (j.m_value.number_integer <= 0x17)\n                    {\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x18));\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x19));\n                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x1A));\n                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));\n                    }\n                    else\n                    {\n                        oa->write_character(to_char_type(0x1B));\n                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));\n                    }\n                }\n                else\n                {\n                    // The conversions below encode the sign in the first\n                    // byte, and the value is converted to a positive number.\n                    const auto positive_number = -1 - j.m_value.number_integer;\n                    if (j.m_value.number_integer >= -24)\n                    {\n                        write_number(static_cast<std::uint8_t>(0x20 + positive_number));\n                    }\n                    else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x38));\n                        write_number(static_cast<std::uint8_t>(positive_number));\n                    }\n                    else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x39));\n                        write_number(static_cast<std::uint16_t>(positive_number));\n                    }\n                    else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x3A));\n                        write_number(static_cast<std::uint32_t>(positive_number));\n                    }\n                    else\n                    {\n                        oa->write_character(to_char_type(0x3B));\n                        write_number(static_cast<std::uint64_t>(positive_number));\n                    }\n                }\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                if (j.m_value.number_unsigned <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x18));\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x19));\n                    write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x1A));\n                    write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));\n                }\n                else\n                {\n                    oa->write_character(to_char_type(0x1B));\n                    write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));\n                }\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                if (std::isnan(j.m_value.number_float))\n                {\n                    // NaN is 0xf97e00 in CBOR\n                    oa->write_character(to_char_type(0xF9));\n                    oa->write_character(to_char_type(0x7E));\n                    oa->write_character(to_char_type(0x00));\n                }\n                else if (std::isinf(j.m_value.number_float))\n                {\n                    // Infinity is 0xf97c00, -Infinity is 0xf9fc00\n                    oa->write_character(to_char_type(0xf9));\n                    oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));\n                    oa->write_character(to_char_type(0x00));\n                }\n                else\n                {\n                    write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);\n                }\n                break;\n            }\n\n            case value_t::string:\n            {\n                // step 1: write control byte and the string length\n                const auto N = j.m_value.string->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0x60 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x78));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x79));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x7A));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x7B));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write the string\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),\n                    j.m_value.string->size());\n                break;\n            }\n\n            case value_t::array:\n            {\n                // step 1: write control byte and the array size\n                const auto N = j.m_value.array->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0x80 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x98));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x99));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x9A));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x9B));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.array)\n                {\n                    write_cbor(el);\n                }\n                break;\n            }\n\n            case value_t::binary:\n            {\n                if (j.m_value.binary->has_subtype())\n                {\n                    if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xd8));\n                        write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));\n                    }\n                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xd9));\n                        write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));\n                    }\n                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xda));\n                        write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));\n                    }\n                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xdb));\n                        write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));\n                    }\n                }\n\n                // step 1: write control byte and the binary array size\n                const auto N = j.m_value.binary->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0x40 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x58));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x59));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x5A));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x5B));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write each element\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),\n                    N);\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                // step 1: write control byte and the object size\n                const auto N = j.m_value.object->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0xA0 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xB8));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xB9));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xBA));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xBB));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.object)\n                {\n                    write_cbor(el.first);\n                    write_cbor(el.second);\n                }\n                break;\n            }\n\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    */\n    void write_msgpack(const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::null: // nil\n            {\n                oa->write_character(to_char_type(0xC0));\n                break;\n            }\n\n            case value_t::boolean: // true and false\n            {\n                oa->write_character(j.m_value.boolean\n                                    ? to_char_type(0xC3)\n                                    : to_char_type(0xC2));\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                if (j.m_value.number_integer >= 0)\n                {\n                    // MessagePack does not differentiate between positive\n                    // signed integers and unsigned integers. Therefore, we used\n                    // the code from the value_t::number_unsigned case here.\n                    if (j.m_value.number_unsigned < 128)\n                    {\n                        // positive fixnum\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        // uint 8\n                        oa->write_character(to_char_type(0xCC));\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        // uint 16\n                        oa->write_character(to_char_type(0xCD));\n                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        // uint 32\n                        oa->write_character(to_char_type(0xCE));\n                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())\n                    {\n                        // uint 64\n                        oa->write_character(to_char_type(0xCF));\n                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));\n                    }\n                }\n                else\n                {\n                    if (j.m_value.number_integer >= -32)\n                    {\n                        // negative fixnum\n                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())\n                    {\n                        // int 8\n                        oa->write_character(to_char_type(0xD0));\n                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())\n                    {\n                        // int 16\n                        oa->write_character(to_char_type(0xD1));\n                        write_number(static_cast<std::int16_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())\n                    {\n                        // int 32\n                        oa->write_character(to_char_type(0xD2));\n                        write_number(static_cast<std::int32_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())\n                    {\n                        // int 64\n                        oa->write_character(to_char_type(0xD3));\n                        write_number(static_cast<std::int64_t>(j.m_value.number_integer));\n                    }\n                }\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                if (j.m_value.number_unsigned < 128)\n                {\n                    // positive fixnum\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    // uint 8\n                    oa->write_character(to_char_type(0xCC));\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // uint 16\n                    oa->write_character(to_char_type(0xCD));\n                    write_number(static_cast<std::uint16_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // uint 32\n                    oa->write_character(to_char_type(0xCE));\n                    write_number(static_cast<std::uint32_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    // uint 64\n                    oa->write_character(to_char_type(0xCF));\n                    write_number(static_cast<std::uint64_t>(j.m_value.number_integer));\n                }\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);\n                break;\n            }\n\n            case value_t::string:\n            {\n                // step 1: write control byte and the string length\n                const auto N = j.m_value.string->size();\n                if (N <= 31)\n                {\n                    // fixstr\n                    write_number(static_cast<std::uint8_t>(0xA0 | N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    // str 8\n                    oa->write_character(to_char_type(0xD9));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // str 16\n                    oa->write_character(to_char_type(0xDA));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // str 32\n                    oa->write_character(to_char_type(0xDB));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 2: write the string\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),\n                    j.m_value.string->size());\n                break;\n            }\n\n            case value_t::array:\n            {\n                // step 1: write control byte and the array size\n                const auto N = j.m_value.array->size();\n                if (N <= 15)\n                {\n                    // fixarray\n                    write_number(static_cast<std::uint8_t>(0x90 | N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // array 16\n                    oa->write_character(to_char_type(0xDC));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // array 32\n                    oa->write_character(to_char_type(0xDD));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.array)\n                {\n                    write_msgpack(el);\n                }\n                break;\n            }\n\n            case value_t::binary:\n            {\n                // step 0: determine if the binary type has a set subtype to\n                // determine whether or not to use the ext or fixext types\n                const bool use_ext = j.m_value.binary->has_subtype();\n\n                // step 1: write control byte and the byte string length\n                const auto N = j.m_value.binary->size();\n                if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    std::uint8_t output_type{};\n                    bool fixed = true;\n                    if (use_ext)\n                    {\n                        switch (N)\n                        {\n                            case 1:\n                                output_type = 0xD4; // fixext 1\n                                break;\n                            case 2:\n                                output_type = 0xD5; // fixext 2\n                                break;\n                            case 4:\n                                output_type = 0xD6; // fixext 4\n                                break;\n                            case 8:\n                                output_type = 0xD7; // fixext 8\n                                break;\n                            case 16:\n                                output_type = 0xD8; // fixext 16\n                                break;\n                            default:\n                                output_type = 0xC7; // ext 8\n                                fixed = false;\n                                break;\n                        }\n\n                    }\n                    else\n                    {\n                        output_type = 0xC4; // bin 8\n                        fixed = false;\n                    }\n\n                    oa->write_character(to_char_type(output_type));\n                    if (!fixed)\n                    {\n                        write_number(static_cast<std::uint8_t>(N));\n                    }\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    std::uint8_t output_type = use_ext\n                                               ? 0xC8 // ext 16\n                                               : 0xC5; // bin 16\n\n                    oa->write_character(to_char_type(output_type));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    std::uint8_t output_type = use_ext\n                                               ? 0xC9 // ext 32\n                                               : 0xC6; // bin 32\n\n                    oa->write_character(to_char_type(output_type));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 1.5: if this is an ext type, write the subtype\n                if (use_ext)\n                {\n                    write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));\n                }\n\n                // step 2: write the byte string\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),\n                    N);\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                // step 1: write control byte and the object size\n                const auto N = j.m_value.object->size();\n                if (N <= 15)\n                {\n                    // fixmap\n                    write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // map 16\n                    oa->write_character(to_char_type(0xDE));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // map 32\n                    oa->write_character(to_char_type(0xDF));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.object)\n                {\n                    write_msgpack(el.first);\n                    write_msgpack(el.second);\n                }\n                break;\n            }\n\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    @param[in] use_count   whether to use '#' prefixes (optimized format)\n    @param[in] use_type    whether to use '$' prefixes (optimized format)\n    @param[in] add_prefix  whether prefixes need to be used for this value\n    */\n    void write_ubjson(const BasicJsonType& j, const bool use_count,\n                      const bool use_type, const bool add_prefix = true)\n    {\n        switch (j.type())\n        {\n            case value_t::null:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('Z'));\n                }\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(j.m_value.boolean\n                                        ? to_char_type('T')\n                                        : to_char_type('F'));\n                }\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);\n                break;\n            }\n\n            case value_t::string:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('S'));\n                }\n                write_number_with_ubjson_prefix(j.m_value.string->size(), true);\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),\n                    j.m_value.string->size());\n                break;\n            }\n\n            case value_t::array:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('['));\n                }\n\n                bool prefix_required = true;\n                if (use_type && !j.m_value.array->empty())\n                {\n                    JSON_ASSERT(use_count);\n                    const CharType first_prefix = ubjson_prefix(j.front());\n                    const bool same_prefix = std::all_of(j.begin() + 1, j.end(),\n                                                         [this, first_prefix](const BasicJsonType & v)\n                    {\n                        return ubjson_prefix(v) == first_prefix;\n                    });\n\n                    if (same_prefix)\n                    {\n                        prefix_required = false;\n                        oa->write_character(to_char_type('$'));\n                        oa->write_character(first_prefix);\n                    }\n                }\n\n                if (use_count)\n                {\n                    oa->write_character(to_char_type('#'));\n                    write_number_with_ubjson_prefix(j.m_value.array->size(), true);\n                }\n\n                for (const auto& el : *j.m_value.array)\n                {\n                    write_ubjson(el, use_count, use_type, prefix_required);\n                }\n\n                if (!use_count)\n                {\n                    oa->write_character(to_char_type(']'));\n                }\n\n                break;\n            }\n\n            case value_t::binary:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('['));\n                }\n\n                if (use_type && !j.m_value.binary->empty())\n                {\n                    JSON_ASSERT(use_count);\n                    oa->write_character(to_char_type('$'));\n                    oa->write_character('U');\n                }\n\n                if (use_count)\n                {\n                    oa->write_character(to_char_type('#'));\n                    write_number_with_ubjson_prefix(j.m_value.binary->size(), true);\n                }\n\n                if (use_type)\n                {\n                    oa->write_characters(\n                        reinterpret_cast<const CharType*>(j.m_value.binary->data()),\n                        j.m_value.binary->size());\n                }\n                else\n                {\n                    for (size_t i = 0; i < j.m_value.binary->size(); ++i)\n                    {\n                        oa->write_character(to_char_type('U'));\n                        oa->write_character(j.m_value.binary->data()[i]);\n                    }\n                }\n\n                if (!use_count)\n                {\n                    oa->write_character(to_char_type(']'));\n                }\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('{'));\n                }\n\n                bool prefix_required = true;\n                if (use_type && !j.m_value.object->empty())\n                {\n                    JSON_ASSERT(use_count);\n                    const CharType first_prefix = ubjson_prefix(j.front());\n                    const bool same_prefix = std::all_of(j.begin(), j.end(),\n                                                         [this, first_prefix](const BasicJsonType & v)\n                    {\n                        return ubjson_prefix(v) == first_prefix;\n                    });\n\n                    if (same_prefix)\n                    {\n                        prefix_required = false;\n                        oa->write_character(to_char_type('$'));\n                        oa->write_character(first_prefix);\n                    }\n                }\n\n                if (use_count)\n                {\n                    oa->write_character(to_char_type('#'));\n                    write_number_with_ubjson_prefix(j.m_value.object->size(), true);\n                }\n\n                for (const auto& el : *j.m_value.object)\n                {\n                    write_number_with_ubjson_prefix(el.first.size(), true);\n                    oa->write_characters(\n                        reinterpret_cast<const CharType*>(el.first.c_str()),\n                        el.first.size());\n                    write_ubjson(el.second, use_count, use_type, prefix_required);\n                }\n\n                if (!use_count)\n                {\n                    oa->write_character(to_char_type('}'));\n                }\n\n                break;\n            }\n\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n  private:\n    //////////\n    // BSON //\n    //////////\n\n    /*!\n    @return The size of a BSON document entry header, including the id marker\n            and the entry name size (and its null-terminator).\n    */\n    static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)\n    {\n        const auto it = name.find(static_cast<typename string_t::value_type>(0));\n        if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))\n        {\n            JSON_THROW(out_of_range::create(409, \"BSON key cannot contain code point U+0000 (at byte \" + std::to_string(it) + \")\", j));\n            static_cast<void>(j);\n        }\n\n        return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;\n    }\n\n    /*!\n    @brief Writes the given @a element_type and @a name to the output adapter\n    */\n    void write_bson_entry_header(const string_t& name,\n                                 const std::uint8_t element_type)\n    {\n        oa->write_character(to_char_type(element_type)); // boolean\n        oa->write_characters(\n            reinterpret_cast<const CharType*>(name.c_str()),\n            name.size() + 1u);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and boolean value @a value\n    */\n    void write_bson_boolean(const string_t& name,\n                            const bool value)\n    {\n        write_bson_entry_header(name, 0x08);\n        oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and double value @a value\n    */\n    void write_bson_double(const string_t& name,\n                           const double value)\n    {\n        write_bson_entry_header(name, 0x01);\n        write_number<double, true>(value);\n    }\n\n    /*!\n    @return The size of the BSON-encoded string in @a value\n    */\n    static std::size_t calc_bson_string_size(const string_t& value)\n    {\n        return sizeof(std::int32_t) + value.size() + 1ul;\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and string value @a value\n    */\n    void write_bson_string(const string_t& name,\n                           const string_t& value)\n    {\n        write_bson_entry_header(name, 0x02);\n\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));\n        oa->write_characters(\n            reinterpret_cast<const CharType*>(value.c_str()),\n            value.size() + 1);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and null value\n    */\n    void write_bson_null(const string_t& name)\n    {\n        write_bson_entry_header(name, 0x0A);\n    }\n\n    /*!\n    @return The size of the BSON-encoded integer @a value\n    */\n    static std::size_t calc_bson_integer_size(const std::int64_t value)\n    {\n        return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()\n               ? sizeof(std::int32_t)\n               : sizeof(std::int64_t);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and integer @a value\n    */\n    void write_bson_integer(const string_t& name,\n                            const std::int64_t value)\n    {\n        if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())\n        {\n            write_bson_entry_header(name, 0x10); // int32\n            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));\n        }\n        else\n        {\n            write_bson_entry_header(name, 0x12); // int64\n            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));\n        }\n    }\n\n    /*!\n    @return The size of the BSON-encoded unsigned integer in @a j\n    */\n    static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept\n    {\n        return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n               ? sizeof(std::int32_t)\n               : sizeof(std::int64_t);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and unsigned @a value\n    */\n    void write_bson_unsigned(const string_t& name,\n                             const BasicJsonType& j)\n    {\n        if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n        {\n            write_bson_entry_header(name, 0x10 /* int32 */);\n            write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));\n        }\n        else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))\n        {\n            write_bson_entry_header(name, 0x12 /* int64 */);\n            write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));\n        }\n        else\n        {\n            JSON_THROW(out_of_range::create(407, \"integer number \" + std::to_string(j.m_value.number_unsigned) + \" cannot be represented by BSON as it does not fit int64\", j));\n        }\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and object @a value\n    */\n    void write_bson_object_entry(const string_t& name,\n                                 const typename BasicJsonType::object_t& value)\n    {\n        write_bson_entry_header(name, 0x03); // object\n        write_bson_object(value);\n    }\n\n    /*!\n    @return The size of the BSON-encoded array @a value\n    */\n    static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)\n    {\n        std::size_t array_index = 0ul;\n\n        const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)\n        {\n            return result + calc_bson_element_size(std::to_string(array_index++), el);\n        });\n\n        return sizeof(std::int32_t) + embedded_document_size + 1ul;\n    }\n\n    /*!\n    @return The size of the BSON-encoded binary array @a value\n    */\n    static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)\n    {\n        return sizeof(std::int32_t) + value.size() + 1ul;\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and array @a value\n    */\n    void write_bson_array(const string_t& name,\n                          const typename BasicJsonType::array_t& value)\n    {\n        write_bson_entry_header(name, 0x04); // array\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));\n\n        std::size_t array_index = 0ul;\n\n        for (const auto& el : value)\n        {\n            write_bson_element(std::to_string(array_index++), el);\n        }\n\n        oa->write_character(to_char_type(0x00));\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and binary value @a value\n    */\n    void write_bson_binary(const string_t& name,\n                           const binary_t& value)\n    {\n        write_bson_entry_header(name, 0x05);\n\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));\n        write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));\n\n        oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());\n    }\n\n    /*!\n    @brief Calculates the size necessary to serialize the JSON value @a j with its @a name\n    @return The calculated size for the BSON document entry for @a j with the given @a name.\n    */\n    static std::size_t calc_bson_element_size(const string_t& name,\n            const BasicJsonType& j)\n    {\n        const auto header_size = calc_bson_entry_header_size(name, j);\n        switch (j.type())\n        {\n            case value_t::object:\n                return header_size + calc_bson_object_size(*j.m_value.object);\n\n            case value_t::array:\n                return header_size + calc_bson_array_size(*j.m_value.array);\n\n            case value_t::binary:\n                return header_size + calc_bson_binary_size(*j.m_value.binary);\n\n            case value_t::boolean:\n                return header_size + 1ul;\n\n            case value_t::number_float:\n                return header_size + 8ul;\n\n            case value_t::number_integer:\n                return header_size + calc_bson_integer_size(j.m_value.number_integer);\n\n            case value_t::number_unsigned:\n                return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);\n\n            case value_t::string:\n                return header_size + calc_bson_string_size(*j.m_value.string);\n\n            case value_t::null:\n                return header_size + 0ul;\n\n            // LCOV_EXCL_START\n            case value_t::discarded:\n            default:\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)\n                return 0ul;\n                // LCOV_EXCL_STOP\n        }\n    }\n\n    /*!\n    @brief Serializes the JSON value @a j to BSON and associates it with the\n           key @a name.\n    @param name The name to associate with the JSON entity @a j within the\n                current BSON document\n    */\n    void write_bson_element(const string_t& name,\n                            const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::object:\n                return write_bson_object_entry(name, *j.m_value.object);\n\n            case value_t::array:\n                return write_bson_array(name, *j.m_value.array);\n\n            case value_t::binary:\n                return write_bson_binary(name, *j.m_value.binary);\n\n            case value_t::boolean:\n                return write_bson_boolean(name, j.m_value.boolean);\n\n            case value_t::number_float:\n                return write_bson_double(name, j.m_value.number_float);\n\n            case value_t::number_integer:\n                return write_bson_integer(name, j.m_value.number_integer);\n\n            case value_t::number_unsigned:\n                return write_bson_unsigned(name, j);\n\n            case value_t::string:\n                return write_bson_string(name, *j.m_value.string);\n\n            case value_t::null:\n                return write_bson_null(name);\n\n            // LCOV_EXCL_START\n            case value_t::discarded:\n            default:\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)\n                return;\n                // LCOV_EXCL_STOP\n        }\n    }\n\n    /*!\n    @brief Calculates the size of the BSON serialization of the given\n           JSON-object @a j.\n    @param[in] value  JSON value to serialize\n    @pre       value.type() == value_t::object\n    */\n    static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)\n    {\n        std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),\n                                    [](size_t result, const typename BasicJsonType::object_t::value_type & el)\n        {\n            return result += calc_bson_element_size(el.first, el.second);\n        });\n\n        return sizeof(std::int32_t) + document_size + 1ul;\n    }\n\n    /*!\n    @param[in] value  JSON value to serialize\n    @pre       value.type() == value_t::object\n    */\n    void write_bson_object(const typename BasicJsonType::object_t& value)\n    {\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));\n\n        for (const auto& el : value)\n        {\n            write_bson_element(el.first, el.second);\n        }\n\n        oa->write_character(to_char_type(0x00));\n    }\n\n    //////////\n    // CBOR //\n    //////////\n\n    static constexpr CharType get_cbor_float_prefix(float /*unused*/)\n    {\n        return to_char_type(0xFA);  // Single-Precision Float\n    }\n\n    static constexpr CharType get_cbor_float_prefix(double /*unused*/)\n    {\n        return to_char_type(0xFB);  // Double-Precision Float\n    }\n\n    /////////////\n    // MsgPack //\n    /////////////\n\n    static constexpr CharType get_msgpack_float_prefix(float /*unused*/)\n    {\n        return to_char_type(0xCA);  // float 32\n    }\n\n    static constexpr CharType get_msgpack_float_prefix(double /*unused*/)\n    {\n        return to_char_type(0xCB);  // float 64\n    }\n\n    ////////////\n    // UBJSON //\n    ////////////\n\n    // UBJSON: write number (floating point)\n    template<typename NumberType, typename std::enable_if<\n                 std::is_floating_point<NumberType>::value, int>::type = 0>\n    void write_number_with_ubjson_prefix(const NumberType n,\n                                         const bool add_prefix)\n    {\n        if (add_prefix)\n        {\n            oa->write_character(get_ubjson_float_prefix(n));\n        }\n        write_number(n);\n    }\n\n    // UBJSON: write number (unsigned integer)\n    template<typename NumberType, typename std::enable_if<\n                 std::is_unsigned<NumberType>::value, int>::type = 0>\n    void write_number_with_ubjson_prefix(const NumberType n,\n                                         const bool add_prefix)\n    {\n        if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('i'));  // int8\n            }\n            write_number(static_cast<std::uint8_t>(n));\n        }\n        else if (n <= (std::numeric_limits<std::uint8_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('U'));  // uint8\n            }\n            write_number(static_cast<std::uint8_t>(n));\n        }\n        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('I'));  // int16\n            }\n            write_number(static_cast<std::int16_t>(n));\n        }\n        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('l'));  // int32\n            }\n            write_number(static_cast<std::int32_t>(n));\n        }\n        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('L'));  // int64\n            }\n            write_number(static_cast<std::int64_t>(n));\n        }\n        else\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('H'));  // high-precision number\n            }\n\n            const auto number = BasicJsonType(n).dump();\n            write_number_with_ubjson_prefix(number.size(), true);\n            for (std::size_t i = 0; i < number.size(); ++i)\n            {\n                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));\n            }\n        }\n    }\n\n    // UBJSON: write number (signed integer)\n    template < typename NumberType, typename std::enable_if <\n                   std::is_signed<NumberType>::value&&\n                   !std::is_floating_point<NumberType>::value, int >::type = 0 >\n    void write_number_with_ubjson_prefix(const NumberType n,\n                                         const bool add_prefix)\n    {\n        if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('i'));  // int8\n            }\n            write_number(static_cast<std::int8_t>(n));\n        }\n        else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('U'));  // uint8\n            }\n            write_number(static_cast<std::uint8_t>(n));\n        }\n        else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('I'));  // int16\n            }\n            write_number(static_cast<std::int16_t>(n));\n        }\n        else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('l'));  // int32\n            }\n            write_number(static_cast<std::int32_t>(n));\n        }\n        else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('L'));  // int64\n            }\n            write_number(static_cast<std::int64_t>(n));\n        }\n        // LCOV_EXCL_START\n        else\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('H'));  // high-precision number\n            }\n\n            const auto number = BasicJsonType(n).dump();\n            write_number_with_ubjson_prefix(number.size(), true);\n            for (std::size_t i = 0; i < number.size(); ++i)\n            {\n                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));\n            }\n        }\n        // LCOV_EXCL_STOP\n    }\n\n    /*!\n    @brief determine the type prefix of container values\n    */\n    CharType ubjson_prefix(const BasicJsonType& j) const noexcept\n    {\n        switch (j.type())\n        {\n            case value_t::null:\n                return 'Z';\n\n            case value_t::boolean:\n                return j.m_value.boolean ? 'T' : 'F';\n\n            case value_t::number_integer:\n            {\n                if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())\n                {\n                    return 'i';\n                }\n                if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    return 'U';\n                }\n                if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())\n                {\n                    return 'I';\n                }\n                if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())\n                {\n                    return 'l';\n                }\n                if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())\n                {\n                    return 'L';\n                }\n                // anything else is treated as high-precision number\n                return 'H'; // LCOV_EXCL_LINE\n            }\n\n            case value_t::number_unsigned:\n            {\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))\n                {\n                    return 'i';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))\n                {\n                    return 'U';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))\n                {\n                    return 'I';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n                {\n                    return 'l';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))\n                {\n                    return 'L';\n                }\n                // anything else is treated as high-precision number\n                return 'H'; // LCOV_EXCL_LINE\n            }\n\n            case value_t::number_float:\n                return get_ubjson_float_prefix(j.m_value.number_float);\n\n            case value_t::string:\n                return 'S';\n\n            case value_t::array: // fallthrough\n            case value_t::binary:\n                return '[';\n\n            case value_t::object:\n                return '{';\n\n            case value_t::discarded:\n            default:  // discarded values\n                return 'N';\n        }\n    }\n\n    static constexpr CharType get_ubjson_float_prefix(float /*unused*/)\n    {\n        return 'd';  // float 32\n    }\n\n    static constexpr CharType get_ubjson_float_prefix(double /*unused*/)\n    {\n        return 'D';  // float 64\n    }\n\n    ///////////////////////\n    // Utility functions //\n    ///////////////////////\n\n    /*\n    @brief write a number to output input\n    @param[in] n number of type @a NumberType\n    @tparam NumberType the type of the number\n    @tparam OutputIsLittleEndian Set to true if output data is\n                                 required to be little endian\n\n    @note This function needs to respect the system's endianness, because bytes\n          in CBOR, MessagePack, and UBJSON are stored in network order (big\n          endian) and therefore need reordering on little endian systems.\n    */\n    template<typename NumberType, bool OutputIsLittleEndian = false>\n    void write_number(const NumberType n)\n    {\n        // step 1: write number to array of length NumberType\n        std::array<CharType, sizeof(NumberType)> vec{};\n        std::memcpy(vec.data(), &n, sizeof(NumberType));\n\n        // step 2: write array to output (with possible reordering)\n        if (is_little_endian != OutputIsLittleEndian)\n        {\n            // reverse byte order prior to conversion if necessary\n            std::reverse(vec.begin(), vec.end());\n        }\n\n        oa->write_characters(vec.data(), sizeof(NumberType));\n    }\n\n    void write_compact_float(const number_float_t n, detail::input_format_t format)\n    {\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n        if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&\n                static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&\n                static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))\n        {\n            oa->write_character(format == detail::input_format_t::cbor\n                                ? get_cbor_float_prefix(static_cast<float>(n))\n                                : get_msgpack_float_prefix(static_cast<float>(n)));\n            write_number(static_cast<float>(n));\n        }\n        else\n        {\n            oa->write_character(format == detail::input_format_t::cbor\n                                ? get_cbor_float_prefix(n)\n                                : get_msgpack_float_prefix(n));\n            write_number(n);\n        }\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n    }\n\n  public:\n    // The following to_char_type functions are implement the conversion\n    // between uint8_t and CharType. In case CharType is not unsigned,\n    // such a conversion is required to allow values greater than 128.\n    // See <https://github.com/nlohmann/json/issues/1286> for a discussion.\n    template < typename C = CharType,\n               enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >\n    static constexpr CharType to_char_type(std::uint8_t x) noexcept\n    {\n        return *reinterpret_cast<char*>(&x);\n    }\n\n    template < typename C = CharType,\n               enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >\n    static CharType to_char_type(std::uint8_t x) noexcept\n    {\n        static_assert(sizeof(std::uint8_t) == sizeof(CharType), \"size of CharType must be equal to std::uint8_t\");\n        static_assert(std::is_trivial<CharType>::value, \"CharType must be trivial\");\n        CharType result;\n        std::memcpy(&result, &x, sizeof(x));\n        return result;\n    }\n\n    template<typename C = CharType,\n             enable_if_t<std::is_unsigned<C>::value>* = nullptr>\n    static constexpr CharType to_char_type(std::uint8_t x) noexcept\n    {\n        return x;\n    }\n\n    template < typename InputCharType, typename C = CharType,\n               enable_if_t <\n                   std::is_signed<C>::value &&\n                   std::is_signed<char>::value &&\n                   std::is_same<char, typename std::remove_cv<InputCharType>::type>::value\n                   > * = nullptr >\n    static constexpr CharType to_char_type(InputCharType x) noexcept\n    {\n        return x;\n    }\n\n  private:\n    /// whether we can assume little endianness\n    const bool is_little_endian = little_endianness();\n\n    /// the output\n    output_adapter_t<CharType> oa = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/output/output_adapters.hpp",
    "content": "#pragma once\n\n#include <algorithm> // copy\n#include <cstddef> // size_t\n#include <iterator> // back_inserter\n#include <memory> // shared_ptr, make_shared\n#include <string> // basic_string\n#include <vector> // vector\n\n#ifndef JSON_NO_IO\n    #include <ios>      // streamsize\n    #include <ostream>  // basic_ostream\n#endif  // JSON_NO_IO\n\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/// abstract output adapter interface\ntemplate<typename CharType> struct output_adapter_protocol\n{\n    virtual void write_character(CharType c) = 0;\n    virtual void write_characters(const CharType* s, std::size_t length) = 0;\n    virtual ~output_adapter_protocol() = default;\n\n    output_adapter_protocol() = default;\n    output_adapter_protocol(const output_adapter_protocol&) = default;\n    output_adapter_protocol(output_adapter_protocol&&) noexcept = default;\n    output_adapter_protocol& operator=(const output_adapter_protocol&) = default;\n    output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;\n};\n\n/// a type to simplify interfaces\ntemplate<typename CharType>\nusing output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;\n\n/// output adapter for byte vectors\ntemplate<typename CharType, typename AllocatorType = std::allocator<CharType>>\nclass output_vector_adapter : public output_adapter_protocol<CharType>\n{\n  public:\n    explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept\n        : v(vec)\n    {}\n\n    void write_character(CharType c) override\n    {\n        v.push_back(c);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    void write_characters(const CharType* s, std::size_t length) override\n    {\n        std::copy(s, s + length, std::back_inserter(v));\n    }\n\n  private:\n    std::vector<CharType, AllocatorType>& v;\n};\n\n#ifndef JSON_NO_IO\n/// output adapter for output streams\ntemplate<typename CharType>\nclass output_stream_adapter : public output_adapter_protocol<CharType>\n{\n  public:\n    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept\n        : stream(s)\n    {}\n\n    void write_character(CharType c) override\n    {\n        stream.put(c);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    void write_characters(const CharType* s, std::size_t length) override\n    {\n        stream.write(s, static_cast<std::streamsize>(length));\n    }\n\n  private:\n    std::basic_ostream<CharType>& stream;\n};\n#endif  // JSON_NO_IO\n\n/// output adapter for basic_string\ntemplate<typename CharType, typename StringType = std::basic_string<CharType>>\nclass output_string_adapter : public output_adapter_protocol<CharType>\n{\n  public:\n    explicit output_string_adapter(StringType& s) noexcept\n        : str(s)\n    {}\n\n    void write_character(CharType c) override\n    {\n        str.push_back(c);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    void write_characters(const CharType* s, std::size_t length) override\n    {\n        str.append(s, length);\n    }\n\n  private:\n    StringType& str;\n};\n\ntemplate<typename CharType, typename StringType = std::basic_string<CharType>>\nclass output_adapter\n{\n  public:\n    template<typename AllocatorType = std::allocator<CharType>>\n    output_adapter(std::vector<CharType, AllocatorType>& vec)\n        : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}\n\n#ifndef JSON_NO_IO\n    output_adapter(std::basic_ostream<CharType>& s)\n        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}\n#endif  // JSON_NO_IO\n\n    output_adapter(StringType& s)\n        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}\n\n    operator output_adapter_t<CharType>()\n    {\n        return oa;\n    }\n\n  private:\n    output_adapter_t<CharType> oa = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/output/serializer.hpp",
    "content": "#pragma once\n\n#include <algorithm> // reverse, remove, fill, find, none_of\n#include <array> // array\n#include <clocale> // localeconv, lconv\n#include <cmath> // labs, isfinite, isnan, signbit\n#include <cstddef> // size_t, ptrdiff_t\n#include <cstdint> // uint8_t\n#include <cstdio> // snprintf\n#include <limits> // numeric_limits\n#include <string> // string, char_traits\n#include <iomanip> // setfill, setw\n#include <sstream> // stringstream\n#include <type_traits> // is_same\n#include <utility> // move\n\n#include <nlohmann/detail/conversions/to_chars.hpp>\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/meta/cpp_future.hpp>\n#include <nlohmann/detail/output/binary_writer.hpp>\n#include <nlohmann/detail/output/output_adapters.hpp>\n#include <nlohmann/detail/value_t.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////////////\n// serialization //\n///////////////////\n\n/// how to treat decoding errors\nenum class error_handler_t\n{\n    strict,  ///< throw a type_error exception in case of invalid UTF-8\n    replace, ///< replace invalid UTF-8 sequences with U+FFFD\n    ignore   ///< ignore invalid UTF-8 sequences\n};\n\ntemplate<typename BasicJsonType>\nclass serializer\n{\n    using string_t = typename BasicJsonType::string_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using binary_char_t = typename BasicJsonType::binary_t::value_type;\n    static constexpr std::uint8_t UTF8_ACCEPT = 0;\n    static constexpr std::uint8_t UTF8_REJECT = 1;\n\n  public:\n    /*!\n    @param[in] s  output stream to serialize to\n    @param[in] ichar  indentation character to use\n    @param[in] error_handler_  how to react on decoding errors\n    */\n    serializer(output_adapter_t<char> s, const char ichar,\n               error_handler_t error_handler_ = error_handler_t::strict)\n        : o(std::move(s))\n        , loc(std::localeconv())\n        , thousands_sep(loc->thousands_sep == nullptr ? '\\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))\n        , decimal_point(loc->decimal_point == nullptr ? '\\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))\n        , indent_char(ichar)\n        , indent_string(512, indent_char)\n        , error_handler(error_handler_)\n    {}\n\n    // delete because of pointer members\n    serializer(const serializer&) = delete;\n    serializer& operator=(const serializer&) = delete;\n    serializer(serializer&&) = delete;\n    serializer& operator=(serializer&&) = delete;\n    ~serializer() = default;\n\n    /*!\n    @brief internal implementation of the serialization function\n\n    This function is called by the public member function dump and organizes\n    the serialization internally. The indentation level is propagated as\n    additional parameter. In case of arrays and objects, the function is\n    called recursively.\n\n    - strings and object keys are escaped using `escape_string()`\n    - integer numbers are converted implicitly via `operator<<`\n    - floating-point numbers are converted to a string using `\"%g\"` format\n    - binary values are serialized as objects containing the subtype and the\n      byte array\n\n    @param[in] val               value to serialize\n    @param[in] pretty_print      whether the output shall be pretty-printed\n    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters\n    in the output are escaped with `\\uXXXX` sequences, and the result consists\n    of ASCII characters only.\n    @param[in] indent_step       the indent level\n    @param[in] current_indent    the current indent level (only used internally)\n    */\n    void dump(const BasicJsonType& val,\n              const bool pretty_print,\n              const bool ensure_ascii,\n              const unsigned int indent_step,\n              const unsigned int current_indent = 0)\n    {\n        switch (val.m_type)\n        {\n            case value_t::object:\n            {\n                if (val.m_value.object->empty())\n                {\n                    o->write_characters(\"{}\", 2);\n                    return;\n                }\n\n                if (pretty_print)\n                {\n                    o->write_characters(\"{\\n\", 2);\n\n                    // variable to hold indentation for recursive calls\n                    const auto new_indent = current_indent + indent_step;\n                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))\n                    {\n                        indent_string.resize(indent_string.size() * 2, ' ');\n                    }\n\n                    // first n-1 elements\n                    auto i = val.m_value.object->cbegin();\n                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)\n                    {\n                        o->write_characters(indent_string.c_str(), new_indent);\n                        o->write_character('\\\"');\n                        dump_escaped(i->first, ensure_ascii);\n                        o->write_characters(\"\\\": \", 3);\n                        dump(i->second, true, ensure_ascii, indent_step, new_indent);\n                        o->write_characters(\",\\n\", 2);\n                    }\n\n                    // last element\n                    JSON_ASSERT(i != val.m_value.object->cend());\n                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());\n                    o->write_characters(indent_string.c_str(), new_indent);\n                    o->write_character('\\\"');\n                    dump_escaped(i->first, ensure_ascii);\n                    o->write_characters(\"\\\": \", 3);\n                    dump(i->second, true, ensure_ascii, indent_step, new_indent);\n\n                    o->write_character('\\n');\n                    o->write_characters(indent_string.c_str(), current_indent);\n                    o->write_character('}');\n                }\n                else\n                {\n                    o->write_character('{');\n\n                    // first n-1 elements\n                    auto i = val.m_value.object->cbegin();\n                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)\n                    {\n                        o->write_character('\\\"');\n                        dump_escaped(i->first, ensure_ascii);\n                        o->write_characters(\"\\\":\", 2);\n                        dump(i->second, false, ensure_ascii, indent_step, current_indent);\n                        o->write_character(',');\n                    }\n\n                    // last element\n                    JSON_ASSERT(i != val.m_value.object->cend());\n                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());\n                    o->write_character('\\\"');\n                    dump_escaped(i->first, ensure_ascii);\n                    o->write_characters(\"\\\":\", 2);\n                    dump(i->second, false, ensure_ascii, indent_step, current_indent);\n\n                    o->write_character('}');\n                }\n\n                return;\n            }\n\n            case value_t::array:\n            {\n                if (val.m_value.array->empty())\n                {\n                    o->write_characters(\"[]\", 2);\n                    return;\n                }\n\n                if (pretty_print)\n                {\n                    o->write_characters(\"[\\n\", 2);\n\n                    // variable to hold indentation for recursive calls\n                    const auto new_indent = current_indent + indent_step;\n                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))\n                    {\n                        indent_string.resize(indent_string.size() * 2, ' ');\n                    }\n\n                    // first n-1 elements\n                    for (auto i = val.m_value.array->cbegin();\n                            i != val.m_value.array->cend() - 1; ++i)\n                    {\n                        o->write_characters(indent_string.c_str(), new_indent);\n                        dump(*i, true, ensure_ascii, indent_step, new_indent);\n                        o->write_characters(\",\\n\", 2);\n                    }\n\n                    // last element\n                    JSON_ASSERT(!val.m_value.array->empty());\n                    o->write_characters(indent_string.c_str(), new_indent);\n                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);\n\n                    o->write_character('\\n');\n                    o->write_characters(indent_string.c_str(), current_indent);\n                    o->write_character(']');\n                }\n                else\n                {\n                    o->write_character('[');\n\n                    // first n-1 elements\n                    for (auto i = val.m_value.array->cbegin();\n                            i != val.m_value.array->cend() - 1; ++i)\n                    {\n                        dump(*i, false, ensure_ascii, indent_step, current_indent);\n                        o->write_character(',');\n                    }\n\n                    // last element\n                    JSON_ASSERT(!val.m_value.array->empty());\n                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);\n\n                    o->write_character(']');\n                }\n\n                return;\n            }\n\n            case value_t::string:\n            {\n                o->write_character('\\\"');\n                dump_escaped(*val.m_value.string, ensure_ascii);\n                o->write_character('\\\"');\n                return;\n            }\n\n            case value_t::binary:\n            {\n                if (pretty_print)\n                {\n                    o->write_characters(\"{\\n\", 2);\n\n                    // variable to hold indentation for recursive calls\n                    const auto new_indent = current_indent + indent_step;\n                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))\n                    {\n                        indent_string.resize(indent_string.size() * 2, ' ');\n                    }\n\n                    o->write_characters(indent_string.c_str(), new_indent);\n\n                    o->write_characters(\"\\\"bytes\\\": [\", 10);\n\n                    if (!val.m_value.binary->empty())\n                    {\n                        for (auto i = val.m_value.binary->cbegin();\n                                i != val.m_value.binary->cend() - 1; ++i)\n                        {\n                            dump_integer(*i);\n                            o->write_characters(\", \", 2);\n                        }\n                        dump_integer(val.m_value.binary->back());\n                    }\n\n                    o->write_characters(\"],\\n\", 3);\n                    o->write_characters(indent_string.c_str(), new_indent);\n\n                    o->write_characters(\"\\\"subtype\\\": \", 11);\n                    if (val.m_value.binary->has_subtype())\n                    {\n                        dump_integer(val.m_value.binary->subtype());\n                    }\n                    else\n                    {\n                        o->write_characters(\"null\", 4);\n                    }\n                    o->write_character('\\n');\n                    o->write_characters(indent_string.c_str(), current_indent);\n                    o->write_character('}');\n                }\n                else\n                {\n                    o->write_characters(\"{\\\"bytes\\\":[\", 10);\n\n                    if (!val.m_value.binary->empty())\n                    {\n                        for (auto i = val.m_value.binary->cbegin();\n                                i != val.m_value.binary->cend() - 1; ++i)\n                        {\n                            dump_integer(*i);\n                            o->write_character(',');\n                        }\n                        dump_integer(val.m_value.binary->back());\n                    }\n\n                    o->write_characters(\"],\\\"subtype\\\":\", 12);\n                    if (val.m_value.binary->has_subtype())\n                    {\n                        dump_integer(val.m_value.binary->subtype());\n                        o->write_character('}');\n                    }\n                    else\n                    {\n                        o->write_characters(\"null}\", 5);\n                    }\n                }\n                return;\n            }\n\n            case value_t::boolean:\n            {\n                if (val.m_value.boolean)\n                {\n                    o->write_characters(\"true\", 4);\n                }\n                else\n                {\n                    o->write_characters(\"false\", 5);\n                }\n                return;\n            }\n\n            case value_t::number_integer:\n            {\n                dump_integer(val.m_value.number_integer);\n                return;\n            }\n\n            case value_t::number_unsigned:\n            {\n                dump_integer(val.m_value.number_unsigned);\n                return;\n            }\n\n            case value_t::number_float:\n            {\n                dump_float(val.m_value.number_float);\n                return;\n            }\n\n            case value_t::discarded:\n            {\n                o->write_characters(\"<discarded>\", 11);\n                return;\n            }\n\n            case value_t::null:\n            {\n                o->write_characters(\"null\", 4);\n                return;\n            }\n\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /*!\n    @brief dump escaped string\n\n    Escape a string by replacing certain special characters by a sequence of an\n    escape character (backslash) and another character and other control\n    characters by a sequence of \"\\u\" followed by a four-digit hex\n    representation. The escaped string is written to output stream @a o.\n\n    @param[in] s  the string to escape\n    @param[in] ensure_ascii  whether to escape non-ASCII characters with\n                             \\uXXXX sequences\n\n    @complexity Linear in the length of string @a s.\n    */\n    void dump_escaped(const string_t& s, const bool ensure_ascii)\n    {\n        std::uint32_t codepoint{};\n        std::uint8_t state = UTF8_ACCEPT;\n        std::size_t bytes = 0;  // number of bytes written to string_buffer\n\n        // number of bytes written at the point of the last valid byte\n        std::size_t bytes_after_last_accept = 0;\n        std::size_t undumped_chars = 0;\n\n        for (std::size_t i = 0; i < s.size(); ++i)\n        {\n            const auto byte = static_cast<std::uint8_t>(s[i]);\n\n            switch (decode(state, codepoint, byte))\n            {\n                case UTF8_ACCEPT:  // decode found a new code point\n                {\n                    switch (codepoint)\n                    {\n                        case 0x08: // backspace\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'b';\n                            break;\n                        }\n\n                        case 0x09: // horizontal tab\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 't';\n                            break;\n                        }\n\n                        case 0x0A: // newline\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'n';\n                            break;\n                        }\n\n                        case 0x0C: // formfeed\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'f';\n                            break;\n                        }\n\n                        case 0x0D: // carriage return\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'r';\n                            break;\n                        }\n\n                        case 0x22: // quotation mark\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = '\\\"';\n                            break;\n                        }\n\n                        case 0x5C: // reverse solidus\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = '\\\\';\n                            break;\n                        }\n\n                        default:\n                        {\n                            // escape control characters (0x00..0x1F) or, if\n                            // ensure_ascii parameter is used, non-ASCII characters\n                            if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))\n                            {\n                                if (codepoint <= 0xFFFF)\n                                {\n                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                                    static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, \"\\\\u%04x\",\n                                                                      static_cast<std::uint16_t>(codepoint)));\n                                    bytes += 6;\n                                }\n                                else\n                                {\n                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                                    static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, \"\\\\u%04x\\\\u%04x\",\n                                                                      static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),\n                                                                      static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));\n                                    bytes += 12;\n                                }\n                            }\n                            else\n                            {\n                                // copy byte to buffer (all previous bytes\n                                // been copied have in default case above)\n                                string_buffer[bytes++] = s[i];\n                            }\n                            break;\n                        }\n                    }\n\n                    // write buffer and reset index; there must be 13 bytes\n                    // left, as this is the maximal number of bytes to be\n                    // written (\"\\uxxxx\\uxxxx\\0\") for one code point\n                    if (string_buffer.size() - bytes < 13)\n                    {\n                        o->write_characters(string_buffer.data(), bytes);\n                        bytes = 0;\n                    }\n\n                    // remember the byte position of this accept\n                    bytes_after_last_accept = bytes;\n                    undumped_chars = 0;\n                    break;\n                }\n\n                case UTF8_REJECT:  // decode found invalid UTF-8 byte\n                {\n                    switch (error_handler)\n                    {\n                        case error_handler_t::strict:\n                        {\n                            std::stringstream ss;\n                            ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (byte | 0);\n                            JSON_THROW(type_error::create(316, \"invalid UTF-8 byte at index \" + std::to_string(i) + \": 0x\" + ss.str(), BasicJsonType()));\n                        }\n\n                        case error_handler_t::ignore:\n                        case error_handler_t::replace:\n                        {\n                            // in case we saw this character the first time, we\n                            // would like to read it again, because the byte\n                            // may be OK for itself, but just not OK for the\n                            // previous sequence\n                            if (undumped_chars > 0)\n                            {\n                                --i;\n                            }\n\n                            // reset length buffer to the last accepted index;\n                            // thus removing/ignoring the invalid characters\n                            bytes = bytes_after_last_accept;\n\n                            if (error_handler == error_handler_t::replace)\n                            {\n                                // add a replacement character\n                                if (ensure_ascii)\n                                {\n                                    string_buffer[bytes++] = '\\\\';\n                                    string_buffer[bytes++] = 'u';\n                                    string_buffer[bytes++] = 'f';\n                                    string_buffer[bytes++] = 'f';\n                                    string_buffer[bytes++] = 'f';\n                                    string_buffer[bytes++] = 'd';\n                                }\n                                else\n                                {\n                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\\xEF');\n                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\\xBF');\n                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\\xBD');\n                                }\n\n                                // write buffer and reset index; there must be 13 bytes\n                                // left, as this is the maximal number of bytes to be\n                                // written (\"\\uxxxx\\uxxxx\\0\") for one code point\n                                if (string_buffer.size() - bytes < 13)\n                                {\n                                    o->write_characters(string_buffer.data(), bytes);\n                                    bytes = 0;\n                                }\n\n                                bytes_after_last_accept = bytes;\n                            }\n\n                            undumped_chars = 0;\n\n                            // continue processing the string\n                            state = UTF8_ACCEPT;\n                            break;\n                        }\n\n                        default:            // LCOV_EXCL_LINE\n                            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n                    }\n                    break;\n                }\n\n                default:  // decode found yet incomplete multi-byte code point\n                {\n                    if (!ensure_ascii)\n                    {\n                        // code point will not be escaped - copy byte to buffer\n                        string_buffer[bytes++] = s[i];\n                    }\n                    ++undumped_chars;\n                    break;\n                }\n            }\n        }\n\n        // we finished processing the string\n        if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))\n        {\n            // write buffer\n            if (bytes > 0)\n            {\n                o->write_characters(string_buffer.data(), bytes);\n            }\n        }\n        else\n        {\n            // we finish reading, but do not accept: string was incomplete\n            switch (error_handler)\n            {\n                case error_handler_t::strict:\n                {\n                    std::stringstream ss;\n                    ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (static_cast<std::uint8_t>(s.back()) | 0);\n                    JSON_THROW(type_error::create(316, \"incomplete UTF-8 string; last byte: 0x\" + ss.str(), BasicJsonType()));\n                }\n\n                case error_handler_t::ignore:\n                {\n                    // write all accepted bytes\n                    o->write_characters(string_buffer.data(), bytes_after_last_accept);\n                    break;\n                }\n\n                case error_handler_t::replace:\n                {\n                    // write all accepted bytes\n                    o->write_characters(string_buffer.data(), bytes_after_last_accept);\n                    // add a replacement character\n                    if (ensure_ascii)\n                    {\n                        o->write_characters(\"\\\\ufffd\", 6);\n                    }\n                    else\n                    {\n                        o->write_characters(\"\\xEF\\xBF\\xBD\", 3);\n                    }\n                    break;\n                }\n\n                default:            // LCOV_EXCL_LINE\n                    JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n            }\n        }\n    }\n\n  private:\n    /*!\n    @brief count digits\n\n    Count the number of decimal (base 10) digits for an input unsigned integer.\n\n    @param[in] x  unsigned integer number to count its digits\n    @return    number of decimal digits\n    */\n    inline unsigned int count_digits(number_unsigned_t x) noexcept\n    {\n        unsigned int n_digits = 1;\n        for (;;)\n        {\n            if (x < 10)\n            {\n                return n_digits;\n            }\n            if (x < 100)\n            {\n                return n_digits + 1;\n            }\n            if (x < 1000)\n            {\n                return n_digits + 2;\n            }\n            if (x < 10000)\n            {\n                return n_digits + 3;\n            }\n            x = x / 10000u;\n            n_digits += 4;\n        }\n    }\n\n    // templates to avoid warnings about useless casts\n    template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>\n    bool is_negative_number(NumberType x)\n    {\n        return x < 0;\n    }\n\n    template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >\n    bool is_negative_number(NumberType /*unused*/)\n    {\n        return false;\n    }\n\n    /*!\n    @brief dump an integer\n\n    Dump a given integer to output stream @a o. Works internally with\n    @a number_buffer.\n\n    @param[in] x  integer number (signed or unsigned) to dump\n    @tparam NumberType either @a number_integer_t or @a number_unsigned_t\n    */\n    template < typename NumberType, detail::enable_if_t <\n                   std::is_integral<NumberType>::value ||\n                   std::is_same<NumberType, number_unsigned_t>::value ||\n                   std::is_same<NumberType, number_integer_t>::value ||\n                   std::is_same<NumberType, binary_char_t>::value,\n                   int > = 0 >\n    void dump_integer(NumberType x)\n    {\n        static constexpr std::array<std::array<char, 2>, 100> digits_to_99\n        {\n            {\n                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},\n                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},\n                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},\n                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},\n                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},\n                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},\n                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},\n                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},\n                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},\n                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},\n            }\n        };\n\n        // special case for \"0\"\n        if (x == 0)\n        {\n            o->write_character('0');\n            return;\n        }\n\n        // use a pointer to fill the buffer\n        auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n\n        number_unsigned_t abs_value;\n\n        unsigned int n_chars{};\n\n        if (is_negative_number(x))\n        {\n            *buffer_ptr = '-';\n            abs_value = remove_sign(static_cast<number_integer_t>(x));\n\n            // account one more byte for the minus sign\n            n_chars = 1 + count_digits(abs_value);\n        }\n        else\n        {\n            abs_value = static_cast<number_unsigned_t>(x);\n            n_chars = count_digits(abs_value);\n        }\n\n        // spare 1 byte for '\\0'\n        JSON_ASSERT(n_chars < number_buffer.size() - 1);\n\n        // jump to the end to generate the string from backward,\n        // so we later avoid reversing the result\n        buffer_ptr += n_chars;\n\n        // Fast int2ascii implementation inspired by \"Fastware\" talk by Andrei Alexandrescu\n        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg\n        while (abs_value >= 100)\n        {\n            const auto digits_index = static_cast<unsigned>((abs_value % 100));\n            abs_value /= 100;\n            *(--buffer_ptr) = digits_to_99[digits_index][1];\n            *(--buffer_ptr) = digits_to_99[digits_index][0];\n        }\n\n        if (abs_value >= 10)\n        {\n            const auto digits_index = static_cast<unsigned>(abs_value);\n            *(--buffer_ptr) = digits_to_99[digits_index][1];\n            *(--buffer_ptr) = digits_to_99[digits_index][0];\n        }\n        else\n        {\n            *(--buffer_ptr) = static_cast<char>('0' + abs_value);\n        }\n\n        o->write_characters(number_buffer.data(), n_chars);\n    }\n\n    /*!\n    @brief dump a floating-point number\n\n    Dump a given floating-point number to output stream @a o. Works internally\n    with @a number_buffer.\n\n    @param[in] x  floating-point number to dump\n    */\n    void dump_float(number_float_t x)\n    {\n        // NaN / inf\n        if (!std::isfinite(x))\n        {\n            o->write_characters(\"null\", 4);\n            return;\n        }\n\n        // If number_float_t is an IEEE-754 single or double precision number,\n        // use the Grisu2 algorithm to produce short numbers which are\n        // guaranteed to round-trip, using strtof and strtod, resp.\n        //\n        // NB: The test below works if <long double> == <double>.\n        static constexpr bool is_ieee_single_or_double\n            = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||\n              (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);\n\n        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());\n    }\n\n    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)\n    {\n        auto* begin = number_buffer.data();\n        auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);\n\n        o->write_characters(begin, static_cast<size_t>(end - begin));\n    }\n\n    void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)\n    {\n        // get number of digits for a float -> text -> float round-trip\n        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;\n\n        // the actual conversion\n        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), \"%.*g\", d, x);\n\n        // negative value indicates an error\n        JSON_ASSERT(len > 0);\n        // check if buffer was large enough\n        JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());\n\n        // erase thousands separator\n        if (thousands_sep != '\\0')\n        {\n            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081\n            const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);\n            std::fill(end, number_buffer.end(), '\\0');\n            JSON_ASSERT((end - number_buffer.begin()) <= len);\n            len = (end - number_buffer.begin());\n        }\n\n        // convert decimal point to '.'\n        if (decimal_point != '\\0' && decimal_point != '.')\n        {\n            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081\n            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);\n            if (dec_pos != number_buffer.end())\n            {\n                *dec_pos = '.';\n            }\n        }\n\n        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));\n\n        // determine if we need to append \".0\"\n        const bool value_is_int_like =\n            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,\n                         [](char c)\n        {\n            return c == '.' || c == 'e';\n        });\n\n        if (value_is_int_like)\n        {\n            o->write_characters(\".0\", 2);\n        }\n    }\n\n    /*!\n    @brief check whether a string is UTF-8 encoded\n\n    The function checks each byte of a string whether it is UTF-8 encoded. The\n    result of the check is stored in the @a state parameter. The function must\n    be called initially with state 0 (accept). State 1 means the string must\n    be rejected, because the current byte is not allowed. If the string is\n    completely processed, but the state is non-zero, the string ended\n    prematurely; that is, the last byte indicated more bytes should have\n    followed.\n\n    @param[in,out] state  the state of the decoding\n    @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)\n    @param[in] byte       next byte to decode\n    @return               new state\n\n    @note The function has been edited: a std::array is used.\n\n    @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>\n    @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/\n    */\n    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept\n    {\n        static const std::array<std::uint8_t, 400> utf8d =\n        {\n            {\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F\n                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F\n                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF\n                8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF\n                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF\n                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF\n                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0\n                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2\n                1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4\n                1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6\n                1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8\n            }\n        };\n\n        JSON_ASSERT(byte < utf8d.size());\n        const std::uint8_t type = utf8d[byte];\n\n        codep = (state != UTF8_ACCEPT)\n                ? (byte & 0x3fu) | (codep << 6u)\n                : (0xFFu >> type) & (byte);\n\n        std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);\n        JSON_ASSERT(index < 400);\n        state = utf8d[index];\n        return state;\n    }\n\n    /*\n     * Overload to make the compiler happy while it is instantiating\n     * dump_integer for number_unsigned_t.\n     * Must never be called.\n     */\n    number_unsigned_t remove_sign(number_unsigned_t x)\n    {\n        JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        return x; // LCOV_EXCL_LINE\n    }\n\n    /*\n     * Helper function for dump_integer\n     *\n     * This function takes a negative signed integer and returns its absolute\n     * value as unsigned integer. The plus/minus shuffling is necessary as we can\n     * not directly remove the sign of an arbitrary signed integer as the\n     * absolute values of INT_MIN and INT_MAX are usually not the same. See\n     * #1708 for details.\n     */\n    inline number_unsigned_t remove_sign(number_integer_t x) noexcept\n    {\n        JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)\n        return static_cast<number_unsigned_t>(-(x + 1)) + 1;\n    }\n\n  private:\n    /// the output of the serializer\n    output_adapter_t<char> o = nullptr;\n\n    /// a (hopefully) large enough character buffer\n    std::array<char, 64> number_buffer{{}};\n\n    /// the locale\n    const std::lconv* loc = nullptr;\n    /// the locale's thousand separator character\n    const char thousands_sep = '\\0';\n    /// the locale's decimal point character\n    const char decimal_point = '\\0';\n\n    /// string buffer\n    std::array<char, 512> string_buffer{{}};\n\n    /// the indentation character\n    const char indent_char;\n    /// the indentation string\n    string_t indent_string;\n\n    /// error_handler how to react on decoding errors\n    const error_handler_t error_handler;\n};\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/string_escape.hpp",
    "content": "#pragma once\n\n#include <string>\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n/*!\n@brief replace all occurrences of a substring by another string\n\n@param[in,out] s  the string to manipulate; changed so that all\n               occurrences of @a f are replaced with @a t\n@param[in]     f  the substring to replace with @a t\n@param[in]     t  the string to replace @a f\n\n@pre The search string @a f must not be empty. **This precondition is\nenforced with an assertion.**\n\n@since version 2.0.0\n*/\ninline void replace_substring(std::string& s, const std::string& f,\n                              const std::string& t)\n{\n    JSON_ASSERT(!f.empty());\n    for (auto pos = s.find(f);                // find first occurrence of f\n            pos != std::string::npos;         // make sure f was found\n            s.replace(pos, f.size(), t),      // replace with t, and\n            pos = s.find(f, pos + t.size()))  // find next occurrence of f\n    {}\n}\n\n/*!\n * @brief string escaping as described in RFC 6901 (Sect. 4)\n * @param[in] s string to escape\n * @return    escaped string\n *\n * Note the order of escaping \"~\" to \"~0\" and \"/\" to \"~1\" is important.\n */\ninline std::string escape(std::string s)\n{\n    replace_substring(s, \"~\", \"~0\");\n    replace_substring(s, \"/\", \"~1\");\n    return s;\n}\n\n/*!\n * @brief string unescaping as described in RFC 6901 (Sect. 4)\n * @param[in] s string to unescape\n * @return    unescaped string\n *\n * Note the order of escaping \"~1\" to \"/\" and \"~0\" to \"~\" is important.\n */\nstatic void unescape(std::string& s)\n{\n    replace_substring(s, \"~1\", \"/\");\n    replace_substring(s, \"~0\", \"~\");\n}\n\n} // namespace detail\n} // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/detail/value_t.hpp",
    "content": "#pragma once\n\n#include <array> // array\n#include <cstddef> // size_t\n#include <cstdint> // uint8_t\n#include <string> // string\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////////////////////\n// JSON type enumeration //\n///////////////////////////\n\n/*!\n@brief the JSON type enumeration\n\nThis enumeration collects the different JSON types. It is internally used to\ndistinguish the stored values, and the functions @ref basic_json::is_null(),\n@ref basic_json::is_object(), @ref basic_json::is_array(),\n@ref basic_json::is_string(), @ref basic_json::is_boolean(),\n@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),\n@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),\n@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and\n@ref basic_json::is_structured() rely on it.\n\n@note There are three enumeration entries (number_integer, number_unsigned, and\nnumber_float), because the library distinguishes these three types for numbers:\n@ref basic_json::number_unsigned_t is used for unsigned integers,\n@ref basic_json::number_integer_t is used for signed integers, and\n@ref basic_json::number_float_t is used for floating-point numbers or to\napproximate integers which do not fit in the limits of their respective type.\n\n@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON\nvalue with the default value for a given type\n\n@since version 1.0.0\n*/\nenum class value_t : std::uint8_t\n{\n    null,             ///< null value\n    object,           ///< object (unordered set of name/value pairs)\n    array,            ///< array (ordered collection of values)\n    string,           ///< string value\n    boolean,          ///< boolean value\n    number_integer,   ///< number value (signed integer)\n    number_unsigned,  ///< number value (unsigned integer)\n    number_float,     ///< number value (floating-point)\n    binary,           ///< binary array (ordered collection of bytes)\n    discarded         ///< discarded by the parser callback function\n};\n\n/*!\n@brief comparison operator for JSON types\n\nReturns an ordering that is similar to Python:\n- order: null < boolean < number < object < array < string < binary\n- furthermore, each type is not smaller than itself\n- discarded values are not comparable\n- binary is represented as a b\"\" string in python and directly comparable to a\n  string; however, making a binary array directly comparable with a string would\n  be surprising behavior in a JSON file.\n\n@since version 1.0.0\n*/\ninline bool operator<(const value_t lhs, const value_t rhs) noexcept\n{\n    static constexpr std::array<std::uint8_t, 9> order = {{\n            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,\n            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,\n            6 /* binary */\n        }\n    };\n\n    const auto l_index = static_cast<std::size_t>(lhs);\n    const auto r_index = static_cast<std::size_t>(rhs);\n    return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];\n}\n}  // namespace detail\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/json.hpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n/****************************************************************************\\\n * Note on documentation: The source files contain links to the online      *\n * documentation of the public API at https://json.nlohmann.me. This URL    *\n * contains the most recent documentation and should also be applicable to  *\n * previous versions; documentation for deprecated functions is not         *\n * removed, but marked deprecated. See \"Generate documentation\" section in  *\n * file doc/README.md.                                                      *\n\\****************************************************************************/\n\n#ifndef INCLUDE_NLOHMANN_JSON_HPP_\n#define INCLUDE_NLOHMANN_JSON_HPP_\n\n#define NLOHMANN_JSON_VERSION_MAJOR 3\n#define NLOHMANN_JSON_VERSION_MINOR 10\n#define NLOHMANN_JSON_VERSION_PATCH 5\n\n#include <algorithm> // all_of, find, for_each\n#include <cstddef> // nullptr_t, ptrdiff_t, size_t\n#include <functional> // hash, less\n#include <initializer_list> // initializer_list\n#ifndef JSON_NO_IO\n    #include <iosfwd> // istream, ostream\n#endif  // JSON_NO_IO\n#include <iterator> // random_access_iterator_tag\n#include <memory> // unique_ptr\n#include <numeric> // accumulate\n#include <string> // string, stoi, to_string\n#include <utility> // declval, forward, move, pair, swap\n#include <vector> // vector\n\n#include <nlohmann/adl_serializer.hpp>\n#include <nlohmann/byte_container_with_subtype.hpp>\n#include <nlohmann/detail/conversions/from_json.hpp>\n#include <nlohmann/detail/conversions/to_json.hpp>\n#include <nlohmann/detail/exceptions.hpp>\n#include <nlohmann/detail/hash.hpp>\n#include <nlohmann/detail/input/binary_reader.hpp>\n#include <nlohmann/detail/input/input_adapters.hpp>\n#include <nlohmann/detail/input/lexer.hpp>\n#include <nlohmann/detail/input/parser.hpp>\n#include <nlohmann/detail/iterators/internal_iterator.hpp>\n#include <nlohmann/detail/iterators/iter_impl.hpp>\n#include <nlohmann/detail/iterators/iteration_proxy.hpp>\n#include <nlohmann/detail/iterators/json_reverse_iterator.hpp>\n#include <nlohmann/detail/iterators/primitive_iterator.hpp>\n#include <nlohmann/detail/json_pointer.hpp>\n#include <nlohmann/detail/json_ref.hpp>\n#include <nlohmann/detail/macro_scope.hpp>\n#include <nlohmann/detail/string_escape.hpp>\n#include <nlohmann/detail/meta/cpp_future.hpp>\n#include <nlohmann/detail/meta/type_traits.hpp>\n#include <nlohmann/detail/output/binary_writer.hpp>\n#include <nlohmann/detail/output/output_adapters.hpp>\n#include <nlohmann/detail/output/serializer.hpp>\n#include <nlohmann/detail/value_t.hpp>\n#include <nlohmann/json_fwd.hpp>\n#include <nlohmann/ordered_map.hpp>\n\n#if defined(JSON_HAS_CPP_17)\n    #include <string_view>\n#endif\n\n/*!\n@brief namespace for Niels Lohmann\n@see https://github.com/nlohmann\n@since version 1.0.0\n*/\nnamespace nlohmann\n{\n\n/*!\n@brief a class to store JSON values\n\n@internal\n@invariant The member variables @a m_value and @a m_type have the following\nrelationship:\n- If `m_type == value_t::object`, then `m_value.object != nullptr`.\n- If `m_type == value_t::array`, then `m_value.array != nullptr`.\n- If `m_type == value_t::string`, then `m_value.string != nullptr`.\nThe invariants are checked by member function assert_invariant().\n\n@note ObjectType trick from https://stackoverflow.com/a/9860911\n@endinternal\n\n@since version 1.0.0\n\n@nosubgrouping\n*/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nclass basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)\n{\n  private:\n    template<detail::value_t> friend struct detail::external_constructor;\n    friend ::nlohmann::json_pointer<basic_json>;\n\n    template<typename BasicJsonType, typename InputType>\n    friend class ::nlohmann::detail::parser;\n    friend ::nlohmann::detail::serializer<basic_json>;\n    template<typename BasicJsonType>\n    friend class ::nlohmann::detail::iter_impl;\n    template<typename BasicJsonType, typename CharType>\n    friend class ::nlohmann::detail::binary_writer;\n    template<typename BasicJsonType, typename InputType, typename SAX>\n    friend class ::nlohmann::detail::binary_reader;\n    template<typename BasicJsonType>\n    friend class ::nlohmann::detail::json_sax_dom_parser;\n    template<typename BasicJsonType>\n    friend class ::nlohmann::detail::json_sax_dom_callback_parser;\n    friend class ::nlohmann::detail::exception;\n\n    /// workaround type for MSVC\n    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    // convenience aliases for types residing in namespace detail;\n    using lexer = ::nlohmann::detail::lexer_base<basic_json>;\n\n    template<typename InputAdapterType>\n    static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(\n        InputAdapterType adapter,\n        detail::parser_callback_t<basic_json>cb = nullptr,\n        const bool allow_exceptions = true,\n        const bool ignore_comments = false\n    )\n    {\n        return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),\n                std::move(cb), allow_exceptions, ignore_comments);\n    }\n\n  private:\n    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;\n    template<typename BasicJsonType>\n    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;\n    template<typename BasicJsonType>\n    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;\n    template<typename Iterator>\n    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;\n    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;\n\n    template<typename CharType>\n    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;\n\n    template<typename InputType>\n    using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;\n    template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    using serializer = ::nlohmann::detail::serializer<basic_json>;\n\n  public:\n    using value_t = detail::value_t;\n    /// JSON Pointer, see @ref nlohmann::json_pointer\n    using json_pointer = ::nlohmann::json_pointer<basic_json>;\n    template<typename T, typename SFINAE>\n    using json_serializer = JSONSerializer<T, SFINAE>;\n    /// how to treat decoding errors\n    using error_handler_t = detail::error_handler_t;\n    /// how to treat CBOR tags\n    using cbor_tag_handler_t = detail::cbor_tag_handler_t;\n    /// helper type for initializer lists of basic_json values\n    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;\n\n    using input_format_t = detail::input_format_t;\n    /// SAX interface type, see @ref nlohmann::json_sax\n    using json_sax_t = json_sax<basic_json>;\n\n    ////////////////\n    // exceptions //\n    ////////////////\n\n    /// @name exceptions\n    /// Classes to implement user-defined exceptions.\n    /// @{\n\n    using exception = detail::exception;\n    using parse_error = detail::parse_error;\n    using invalid_iterator = detail::invalid_iterator;\n    using type_error = detail::type_error;\n    using out_of_range = detail::out_of_range;\n    using other_error = detail::other_error;\n\n    /// @}\n\n\n    /////////////////////\n    // container types //\n    /////////////////////\n\n    /// @name container types\n    /// The canonic container types to use @ref basic_json like any other STL\n    /// container.\n    /// @{\n\n    /// the type of elements in a basic_json container\n    using value_type = basic_json;\n\n    /// the type of an element reference\n    using reference = value_type&;\n    /// the type of an element const reference\n    using const_reference = const value_type&;\n\n    /// a type to represent differences between iterators\n    using difference_type = std::ptrdiff_t;\n    /// a type to represent container sizes\n    using size_type = std::size_t;\n\n    /// the allocator type\n    using allocator_type = AllocatorType<basic_json>;\n\n    /// the type of an element pointer\n    using pointer = typename std::allocator_traits<allocator_type>::pointer;\n    /// the type of an element const pointer\n    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;\n\n    /// an iterator for a basic_json container\n    using iterator = iter_impl<basic_json>;\n    /// a const iterator for a basic_json container\n    using const_iterator = iter_impl<const basic_json>;\n    /// a reverse iterator for a basic_json container\n    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;\n    /// a const reverse iterator for a basic_json container\n    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;\n\n    /// @}\n\n\n    /// @brief returns the allocator associated with the container\n    /// @sa https://json.nlohmann.me/api/basic_json/get_allocator/\n    static allocator_type get_allocator()\n    {\n        return allocator_type();\n    }\n\n    /// @brief returns version information on the library\n    /// @sa https://json.nlohmann.me/api/basic_json/meta/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json meta()\n    {\n        basic_json result;\n\n        result[\"copyright\"] = \"(C) 2013-2022 Niels Lohmann\";\n        result[\"name\"] = \"JSON for Modern C++\";\n        result[\"url\"] = \"https://github.com/nlohmann/json\";\n        result[\"version\"][\"string\"] =\n            std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + \".\" +\n            std::to_string(NLOHMANN_JSON_VERSION_MINOR) + \".\" +\n            std::to_string(NLOHMANN_JSON_VERSION_PATCH);\n        result[\"version\"][\"major\"] = NLOHMANN_JSON_VERSION_MAJOR;\n        result[\"version\"][\"minor\"] = NLOHMANN_JSON_VERSION_MINOR;\n        result[\"version\"][\"patch\"] = NLOHMANN_JSON_VERSION_PATCH;\n\n#ifdef _WIN32\n        result[\"platform\"] = \"win32\";\n#elif defined __linux__\n        result[\"platform\"] = \"linux\";\n#elif defined __APPLE__\n        result[\"platform\"] = \"apple\";\n#elif defined __unix__\n        result[\"platform\"] = \"unix\";\n#else\n        result[\"platform\"] = \"unknown\";\n#endif\n\n#if defined(__ICC) || defined(__INTEL_COMPILER)\n        result[\"compiler\"] = {{\"family\", \"icc\"}, {\"version\", __INTEL_COMPILER}};\n#elif defined(__clang__)\n        result[\"compiler\"] = {{\"family\", \"clang\"}, {\"version\", __clang_version__}};\n#elif defined(__GNUC__) || defined(__GNUG__)\n        result[\"compiler\"] = {{\"family\", \"gcc\"}, {\"version\", std::to_string(__GNUC__) + \".\" + std::to_string(__GNUC_MINOR__) + \".\" + std::to_string(__GNUC_PATCHLEVEL__)}};\n#elif defined(__HP_cc) || defined(__HP_aCC)\n        result[\"compiler\"] = \"hp\"\n#elif defined(__IBMCPP__)\n        result[\"compiler\"] = {{\"family\", \"ilecpp\"}, {\"version\", __IBMCPP__}};\n#elif defined(_MSC_VER)\n        result[\"compiler\"] = {{\"family\", \"msvc\"}, {\"version\", _MSC_VER}};\n#elif defined(__PGI)\n        result[\"compiler\"] = {{\"family\", \"pgcpp\"}, {\"version\", __PGI}};\n#elif defined(__SUNPRO_CC)\n        result[\"compiler\"] = {{\"family\", \"sunpro\"}, {\"version\", __SUNPRO_CC}};\n#else\n        result[\"compiler\"] = {{\"family\", \"unknown\"}, {\"version\", \"unknown\"}};\n#endif\n\n#ifdef __cplusplus\n        result[\"compiler\"][\"c++\"] = std::to_string(__cplusplus);\n#else\n        result[\"compiler\"][\"c++\"] = \"unknown\";\n#endif\n        return result;\n    }\n\n\n    ///////////////////////////\n    // JSON value data types //\n    ///////////////////////////\n\n    /// @name JSON value data types\n    /// The data types to store a JSON value. These types are derived from\n    /// the template arguments passed to class @ref basic_json.\n    /// @{\n\n    /// @brief object key comparator type\n    /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/\n#if defined(JSON_HAS_CPP_14)\n    // Use transparent comparator if possible, combined with perfect forwarding\n    // on find() and count() calls prevents unnecessary string construction.\n    using object_comparator_t = std::less<>;\n#else\n    using object_comparator_t = std::less<StringType>;\n#endif\n\n    /// @brief a type for an object\n    /// @sa https://json.nlohmann.me/api/basic_json/object_t/\n    using object_t = ObjectType<StringType,\n          basic_json,\n          object_comparator_t,\n          AllocatorType<std::pair<const StringType,\n          basic_json>>>;\n\n    /// @brief a type for an array\n    /// @sa https://json.nlohmann.me/api/basic_json/array_t/\n    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n\n    /// @brief a type for a string\n    /// @sa https://json.nlohmann.me/api/basic_json/string_t/\n    using string_t = StringType;\n\n    /// @brief a type for a boolean\n    /// @sa https://json.nlohmann.me/api/basic_json/boolean_t/\n    using boolean_t = BooleanType;\n\n    /// @brief a type for a number (integer)\n    /// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/\n    using number_integer_t = NumberIntegerType;\n\n    /// @brief a type for a number (unsigned)\n    /// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/\n    using number_unsigned_t = NumberUnsignedType;\n\n    /// @brief a type for a number (floating-point)\n    /// @sa https://json.nlohmann.me/api/basic_json/number_float_t/\n    using number_float_t = NumberFloatType;\n\n    /// @brief a type for a packed binary type\n    /// @sa https://json.nlohmann.me/api/basic_json/binary_t/\n    using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;\n\n    /// @}\n\n  private:\n\n    /// helper for exception-safe object creation\n    template<typename T, typename... Args>\n    JSON_HEDLEY_RETURNS_NON_NULL\n    static T* create(Args&& ... args)\n    {\n        AllocatorType<T> alloc;\n        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;\n\n        auto deleter = [&](T * obj)\n        {\n            AllocatorTraits::deallocate(alloc, obj, 1);\n        };\n        std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);\n        AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);\n        JSON_ASSERT(obj != nullptr);\n        return obj.release();\n    }\n\n    ////////////////////////\n    // JSON value storage //\n    ////////////////////////\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /*!\n    @brief a JSON value\n\n    The actual storage for a JSON value of the @ref basic_json class. This\n    union combines the different storage types for the JSON value types\n    defined in @ref value_t.\n\n    JSON type | value_t type    | used type\n    --------- | --------------- | ------------------------\n    object    | object          | pointer to @ref object_t\n    array     | array           | pointer to @ref array_t\n    string    | string          | pointer to @ref string_t\n    boolean   | boolean         | @ref boolean_t\n    number    | number_integer  | @ref number_integer_t\n    number    | number_unsigned | @ref number_unsigned_t\n    number    | number_float    | @ref number_float_t\n    binary    | binary          | pointer to @ref binary_t\n    null      | null            | *no value is stored*\n\n    @note Variable-length types (objects, arrays, and strings) are stored as\n    pointers. The size of the union should not exceed 64 bits if the default\n    value types are used.\n\n    @since version 1.0.0\n    */\n    union json_value\n    {\n        /// object (stored with pointer to save storage)\n        object_t* object;\n        /// array (stored with pointer to save storage)\n        array_t* array;\n        /// string (stored with pointer to save storage)\n        string_t* string;\n        /// binary (stored with pointer to save storage)\n        binary_t* binary;\n        /// boolean\n        boolean_t boolean;\n        /// number (integer)\n        number_integer_t number_integer;\n        /// number (unsigned integer)\n        number_unsigned_t number_unsigned;\n        /// number (floating-point)\n        number_float_t number_float;\n\n        /// default constructor (for null values)\n        json_value() = default;\n        /// constructor for booleans\n        json_value(boolean_t v) noexcept : boolean(v) {}\n        /// constructor for numbers (integer)\n        json_value(number_integer_t v) noexcept : number_integer(v) {}\n        /// constructor for numbers (unsigned)\n        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}\n        /// constructor for numbers (floating-point)\n        json_value(number_float_t v) noexcept : number_float(v) {}\n        /// constructor for empty values of a given type\n        json_value(value_t t)\n        {\n            switch (t)\n            {\n                case value_t::object:\n                {\n                    object = create<object_t>();\n                    break;\n                }\n\n                case value_t::array:\n                {\n                    array = create<array_t>();\n                    break;\n                }\n\n                case value_t::string:\n                {\n                    string = create<string_t>(\"\");\n                    break;\n                }\n\n                case value_t::binary:\n                {\n                    binary = create<binary_t>();\n                    break;\n                }\n\n                case value_t::boolean:\n                {\n                    boolean = static_cast<boolean_t>(false);\n                    break;\n                }\n\n                case value_t::number_integer:\n                {\n                    number_integer = static_cast<number_integer_t>(0);\n                    break;\n                }\n\n                case value_t::number_unsigned:\n                {\n                    number_unsigned = static_cast<number_unsigned_t>(0);\n                    break;\n                }\n\n                case value_t::number_float:\n                {\n                    number_float = static_cast<number_float_t>(0.0);\n                    break;\n                }\n\n                case value_t::null:\n                {\n                    object = nullptr;  // silence warning, see #821\n                    break;\n                }\n\n                case value_t::discarded:\n                default:\n                {\n                    object = nullptr;  // silence warning, see #821\n                    if (JSON_HEDLEY_UNLIKELY(t == value_t::null))\n                    {\n                        JSON_THROW(other_error::create(500, \"961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5\", basic_json())); // LCOV_EXCL_LINE\n                    }\n                    break;\n                }\n            }\n        }\n\n        /// constructor for strings\n        json_value(const string_t& value) : string(create<string_t>(value)) {}\n\n        /// constructor for rvalue strings\n        json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}\n\n        /// constructor for objects\n        json_value(const object_t& value) : object(create<object_t>(value)) {}\n\n        /// constructor for rvalue objects\n        json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}\n\n        /// constructor for arrays\n        json_value(const array_t& value) : array(create<array_t>(value)) {}\n\n        /// constructor for rvalue arrays\n        json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}\n\n        /// constructor for binary arrays\n        json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}\n\n        /// constructor for rvalue binary arrays\n        json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}\n\n        /// constructor for binary arrays (internal type)\n        json_value(const binary_t& value) : binary(create<binary_t>(value)) {}\n\n        /// constructor for rvalue binary arrays (internal type)\n        json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}\n\n        void destroy(value_t t)\n        {\n            if (t == value_t::array || t == value_t::object)\n            {\n                // flatten the current json_value to a heap-allocated stack\n                std::vector<basic_json> stack;\n\n                // move the top-level items to stack\n                if (t == value_t::array)\n                {\n                    stack.reserve(array->size());\n                    std::move(array->begin(), array->end(), std::back_inserter(stack));\n                }\n                else\n                {\n                    stack.reserve(object->size());\n                    for (auto&& it : *object)\n                    {\n                        stack.push_back(std::move(it.second));\n                    }\n                }\n\n                while (!stack.empty())\n                {\n                    // move the last item to local variable to be processed\n                    basic_json current_item(std::move(stack.back()));\n                    stack.pop_back();\n\n                    // if current_item is array/object, move\n                    // its children to the stack to be processed later\n                    if (current_item.is_array())\n                    {\n                        std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));\n\n                        current_item.m_value.array->clear();\n                    }\n                    else if (current_item.is_object())\n                    {\n                        for (auto&& it : *current_item.m_value.object)\n                        {\n                            stack.push_back(std::move(it.second));\n                        }\n\n                        current_item.m_value.object->clear();\n                    }\n\n                    // it's now safe that current_item get destructed\n                    // since it doesn't have any children\n                }\n            }\n\n            switch (t)\n            {\n                case value_t::object:\n                {\n                    AllocatorType<object_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, object);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);\n                    break;\n                }\n\n                case value_t::array:\n                {\n                    AllocatorType<array_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, array);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);\n                    break;\n                }\n\n                case value_t::string:\n                {\n                    AllocatorType<string_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, string);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);\n                    break;\n                }\n\n                case value_t::binary:\n                {\n                    AllocatorType<binary_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);\n                    break;\n                }\n\n                case value_t::null:\n                case value_t::boolean:\n                case value_t::number_integer:\n                case value_t::number_unsigned:\n                case value_t::number_float:\n                case value_t::discarded:\n                default:\n                {\n                    break;\n                }\n            }\n        }\n    };\n\n  private:\n    /*!\n    @brief checks the class invariants\n\n    This function asserts the class invariants. It needs to be called at the\n    end of every constructor to make sure that created objects respect the\n    invariant. Furthermore, it has to be called each time the type of a JSON\n    value is changed, because the invariant expresses a relationship between\n    @a m_type and @a m_value.\n\n    Furthermore, the parent relation is checked for arrays and objects: If\n    @a check_parents true and the value is an array or object, then the\n    container's elements must have the current value as parent.\n\n    @param[in] check_parents  whether the parent relation should be checked.\n               The value is true by default and should only be set to false\n               during destruction of objects when the invariant does not\n               need to hold.\n    */\n    void assert_invariant(bool check_parents = true) const noexcept\n    {\n        JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);\n        JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);\n        JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);\n        JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);\n\n#if JSON_DIAGNOSTICS\n        JSON_TRY\n        {\n            // cppcheck-suppress assertWithSideEffect\n            JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)\n            {\n                return j.m_parent == this;\n            }));\n        }\n        JSON_CATCH(...) {} // LCOV_EXCL_LINE\n#endif\n        static_cast<void>(check_parents);\n    }\n\n    void set_parents()\n    {\n#if JSON_DIAGNOSTICS\n        switch (m_type)\n        {\n            case value_t::array:\n            {\n                for (auto& element : *m_value.array)\n                {\n                    element.m_parent = this;\n                }\n                break;\n            }\n\n            case value_t::object:\n            {\n                for (auto& element : *m_value.object)\n                {\n                    element.second.m_parent = this;\n                }\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                break;\n        }\n#endif\n    }\n\n    iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)\n    {\n#if JSON_DIAGNOSTICS\n        for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)\n        {\n            (it + i)->m_parent = this;\n        }\n#else\n        static_cast<void>(count_set_parents);\n#endif\n        return it;\n    }\n\n    reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))\n    {\n#if JSON_DIAGNOSTICS\n        if (old_capacity != static_cast<std::size_t>(-1))\n        {\n            // see https://github.com/nlohmann/json/issues/2838\n            JSON_ASSERT(type() == value_t::array);\n            if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))\n            {\n                // capacity has changed: update all parents\n                set_parents();\n                return j;\n            }\n        }\n\n        // ordered_json uses a vector internally, so pointers could have\n        // been invalidated; see https://github.com/nlohmann/json/issues/2962\n#ifdef JSON_HEDLEY_MSVC_VERSION\n#pragma warning(push )\n#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr\n#endif\n        if (detail::is_ordered_map<object_t>::value)\n        {\n            set_parents();\n            return j;\n        }\n#ifdef JSON_HEDLEY_MSVC_VERSION\n#pragma warning( pop )\n#endif\n\n        j.m_parent = this;\n#else\n        static_cast<void>(j);\n        static_cast<void>(old_capacity);\n#endif\n        return j;\n    }\n\n  public:\n    //////////////////////////\n    // JSON parser callback //\n    //////////////////////////\n\n    /// @brief parser event types\n    /// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/\n    using parse_event_t = detail::parse_event_t;\n\n    /// @brief per-element parser callback type\n    /// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/\n    using parser_callback_t = detail::parser_callback_t<basic_json>;\n\n    //////////////////\n    // constructors //\n    //////////////////\n\n    /// @name constructors and destructors\n    /// Constructors of class @ref basic_json, copy/move constructor, copy\n    /// assignment, static functions creating objects, and the destructor.\n    /// @{\n\n    /// @brief create an empty value with a given type\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(const value_t v)\n        : m_type(v), m_value(v)\n    {\n        assert_invariant();\n    }\n\n    /// @brief create a null object\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(std::nullptr_t = nullptr) noexcept\n        : basic_json(value_t::null)\n    {\n        assert_invariant();\n    }\n\n    /// @brief create a JSON value from compatible types\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    template < typename CompatibleType,\n               typename U = detail::uncvref_t<CompatibleType>,\n               detail::enable_if_t <\n                   !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >\n    basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)\n                JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),\n                                           std::forward<CompatibleType>(val))))\n    {\n        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief create a JSON value from an existing one\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    template < typename BasicJsonType,\n               detail::enable_if_t <\n                   detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >\n    basic_json(const BasicJsonType& val)\n    {\n        using other_boolean_t = typename BasicJsonType::boolean_t;\n        using other_number_float_t = typename BasicJsonType::number_float_t;\n        using other_number_integer_t = typename BasicJsonType::number_integer_t;\n        using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n        using other_string_t = typename BasicJsonType::string_t;\n        using other_object_t = typename BasicJsonType::object_t;\n        using other_array_t = typename BasicJsonType::array_t;\n        using other_binary_t = typename BasicJsonType::binary_t;\n\n        switch (val.type())\n        {\n            case value_t::boolean:\n                JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());\n                break;\n            case value_t::number_float:\n                JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());\n                break;\n            case value_t::number_integer:\n                JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());\n                break;\n            case value_t::number_unsigned:\n                JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());\n                break;\n            case value_t::string:\n                JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());\n                break;\n            case value_t::object:\n                JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());\n                break;\n            case value_t::array:\n                JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());\n                break;\n            case value_t::binary:\n                JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());\n                break;\n            case value_t::null:\n                *this = nullptr;\n                break;\n            case value_t::discarded:\n                m_type = value_t::discarded;\n                break;\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief create a container (array or object) from an initializer list\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(initializer_list_t init,\n               bool type_deduction = true,\n               value_t manual_type = value_t::array)\n    {\n        // check if each element is an array with two elements whose first\n        // element is a string\n        bool is_an_object = std::all_of(init.begin(), init.end(),\n                                        [](const detail::json_ref<basic_json>& element_ref)\n        {\n            return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();\n        });\n\n        // adjust type if type deduction is not wanted\n        if (!type_deduction)\n        {\n            // if array is wanted, do not create an object though possible\n            if (manual_type == value_t::array)\n            {\n                is_an_object = false;\n            }\n\n            // if object is wanted but impossible, throw an exception\n            if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))\n            {\n                JSON_THROW(type_error::create(301, \"cannot create object from initializer list\", basic_json()));\n            }\n        }\n\n        if (is_an_object)\n        {\n            // the initializer list is a list of pairs -> create object\n            m_type = value_t::object;\n            m_value = value_t::object;\n\n            for (auto& element_ref : init)\n            {\n                auto element = element_ref.moved_or_copied();\n                m_value.object->emplace(\n                    std::move(*((*element.m_value.array)[0].m_value.string)),\n                    std::move((*element.m_value.array)[1]));\n            }\n        }\n        else\n        {\n            // the initializer list describes an array -> create array\n            m_type = value_t::array;\n            m_value.array = create<array_t>(init.begin(), init.end());\n        }\n\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief explicitly create a binary array (without subtype)\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(const typename binary_t::container_type& init)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = init;\n        return res;\n    }\n\n    /// @brief explicitly create a binary array (with subtype)\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = binary_t(init, subtype);\n        return res;\n    }\n\n    /// @brief explicitly create a binary array\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(typename binary_t::container_type&& init)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = std::move(init);\n        return res;\n    }\n\n    /// @brief explicitly create a binary array (with subtype)\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = binary_t(std::move(init), subtype);\n        return res;\n    }\n\n    /// @brief explicitly create an array from an initializer list\n    /// @sa https://json.nlohmann.me/api/basic_json/array/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json array(initializer_list_t init = {})\n    {\n        return basic_json(init, false, value_t::array);\n    }\n\n    /// @brief explicitly create an object from an initializer list\n    /// @sa https://json.nlohmann.me/api/basic_json/object/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json object(initializer_list_t init = {})\n    {\n        return basic_json(init, false, value_t::object);\n    }\n\n    /// @brief construct an array with count copies of given value\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(size_type cnt, const basic_json& val)\n        : m_type(value_t::array)\n    {\n        m_value.array = create<array_t>(cnt, val);\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief construct a JSON container given an iterator range\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    template < class InputIT, typename std::enable_if <\n                   std::is_same<InputIT, typename basic_json_t::iterator>::value ||\n                   std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >\n    basic_json(InputIT first, InputIT last)\n    {\n        JSON_ASSERT(first.m_object != nullptr);\n        JSON_ASSERT(last.m_object != nullptr);\n\n        // make sure iterator fits the current value\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(201, \"iterators are not compatible\", basic_json()));\n        }\n\n        // copy type from first iterator\n        m_type = first.m_object->m_type;\n\n        // check if iterator range is complete for primitive values\n        switch (m_type)\n        {\n            case value_t::boolean:\n            case value_t::number_float:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::string:\n            {\n                if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()\n                                         || !last.m_it.primitive_iterator.is_end()))\n                {\n                    JSON_THROW(invalid_iterator::create(204, \"iterators out of range\", *first.m_object));\n                }\n                break;\n            }\n\n            case value_t::null:\n            case value_t::object:\n            case value_t::array:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                break;\n        }\n\n        switch (m_type)\n        {\n            case value_t::number_integer:\n            {\n                m_value.number_integer = first.m_object->m_value.number_integer;\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                m_value.number_unsigned = first.m_object->m_value.number_unsigned;\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                m_value.number_float = first.m_object->m_value.number_float;\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                m_value.boolean = first.m_object->m_value.boolean;\n                break;\n            }\n\n            case value_t::string:\n            {\n                m_value = *first.m_object->m_value.string;\n                break;\n            }\n\n            case value_t::object:\n            {\n                m_value.object = create<object_t>(first.m_it.object_iterator,\n                                                  last.m_it.object_iterator);\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_value.array = create<array_t>(first.m_it.array_iterator,\n                                                last.m_it.array_iterator);\n                break;\n            }\n\n            case value_t::binary:\n            {\n                m_value = *first.m_object->m_value.binary;\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                JSON_THROW(invalid_iterator::create(206, \"cannot construct with iterators from \" + std::string(first.m_object->type_name()), *first.m_object));\n        }\n\n        set_parents();\n        assert_invariant();\n    }\n\n\n    ///////////////////////////////////////\n    // other constructors and destructor //\n    ///////////////////////////////////////\n\n    template<typename JsonRef,\n             detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,\n                                 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >\n    basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}\n\n    /// @brief copy constructor\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(const basic_json& other)\n        : m_type(other.m_type)\n    {\n        // check of passed value is valid\n        other.assert_invariant();\n\n        switch (m_type)\n        {\n            case value_t::object:\n            {\n                m_value = *other.m_value.object;\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_value = *other.m_value.array;\n                break;\n            }\n\n            case value_t::string:\n            {\n                m_value = *other.m_value.string;\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                m_value = other.m_value.boolean;\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                m_value = other.m_value.number_integer;\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                m_value = other.m_value.number_unsigned;\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                m_value = other.m_value.number_float;\n                break;\n            }\n\n            case value_t::binary:\n            {\n                m_value = *other.m_value.binary;\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                break;\n        }\n\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief move constructor\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(basic_json&& other) noexcept\n        : m_type(std::move(other.m_type)),\n          m_value(std::move(other.m_value))\n    {\n        // check that passed value is valid\n        other.assert_invariant(false);\n\n        // invalidate payload\n        other.m_type = value_t::null;\n        other.m_value = {};\n\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief copy assignment\n    /// @sa https://json.nlohmann.me/api/basic_json/operator=/\n    basic_json& operator=(basic_json other) noexcept (\n        std::is_nothrow_move_constructible<value_t>::value&&\n        std::is_nothrow_move_assignable<value_t>::value&&\n        std::is_nothrow_move_constructible<json_value>::value&&\n        std::is_nothrow_move_assignable<json_value>::value\n    )\n    {\n        // check that passed value is valid\n        other.assert_invariant();\n\n        using std::swap;\n        swap(m_type, other.m_type);\n        swap(m_value, other.m_value);\n\n        set_parents();\n        assert_invariant();\n        return *this;\n    }\n\n    /// @brief destructor\n    /// @sa https://json.nlohmann.me/api/basic_json/~basic_json/\n    ~basic_json() noexcept\n    {\n        assert_invariant(false);\n        m_value.destroy(m_type);\n    }\n\n    /// @}\n\n  public:\n    ///////////////////////\n    // object inspection //\n    ///////////////////////\n\n    /// @name object inspection\n    /// Functions to inspect the type of a JSON value.\n    /// @{\n\n    /// @brief serialization\n    /// @sa https://json.nlohmann.me/api/basic_json/dump/\n    string_t dump(const int indent = -1,\n                  const char indent_char = ' ',\n                  const bool ensure_ascii = false,\n                  const error_handler_t error_handler = error_handler_t::strict) const\n    {\n        string_t result;\n        serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);\n\n        if (indent >= 0)\n        {\n            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));\n        }\n        else\n        {\n            s.dump(*this, false, ensure_ascii, 0);\n        }\n\n        return result;\n    }\n\n    /// @brief return the type of the JSON value (explicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/type/\n    constexpr value_t type() const noexcept\n    {\n        return m_type;\n    }\n\n    /// @brief return whether type is primitive\n    /// @sa https://json.nlohmann.me/api/basic_json/is_primitive/\n    constexpr bool is_primitive() const noexcept\n    {\n        return is_null() || is_string() || is_boolean() || is_number() || is_binary();\n    }\n\n    /// @brief return whether type is structured\n    /// @sa https://json.nlohmann.me/api/basic_json/is_structured/\n    constexpr bool is_structured() const noexcept\n    {\n        return is_array() || is_object();\n    }\n\n    /// @brief return whether value is null\n    /// @sa https://json.nlohmann.me/api/basic_json/is_null/\n    constexpr bool is_null() const noexcept\n    {\n        return m_type == value_t::null;\n    }\n\n    /// @brief return whether value is a boolean\n    /// @sa https://json.nlohmann.me/api/basic_json/is_boolean/\n    constexpr bool is_boolean() const noexcept\n    {\n        return m_type == value_t::boolean;\n    }\n\n    /// @brief return whether value is a number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number/\n    constexpr bool is_number() const noexcept\n    {\n        return is_number_integer() || is_number_float();\n    }\n\n    /// @brief return whether value is an integer number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/\n    constexpr bool is_number_integer() const noexcept\n    {\n        return m_type == value_t::number_integer || m_type == value_t::number_unsigned;\n    }\n\n    /// @brief return whether value is an unsigned integer number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/\n    constexpr bool is_number_unsigned() const noexcept\n    {\n        return m_type == value_t::number_unsigned;\n    }\n\n    /// @brief return whether value is a floating-point number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number_float/\n    constexpr bool is_number_float() const noexcept\n    {\n        return m_type == value_t::number_float;\n    }\n\n    /// @brief return whether value is an object\n    /// @sa https://json.nlohmann.me/api/basic_json/is_object/\n    constexpr bool is_object() const noexcept\n    {\n        return m_type == value_t::object;\n    }\n\n    /// @brief return whether value is an array\n    /// @sa https://json.nlohmann.me/api/basic_json/is_array/\n    constexpr bool is_array() const noexcept\n    {\n        return m_type == value_t::array;\n    }\n\n    /// @brief return whether value is a string\n    /// @sa https://json.nlohmann.me/api/basic_json/is_string/\n    constexpr bool is_string() const noexcept\n    {\n        return m_type == value_t::string;\n    }\n\n    /// @brief return whether value is a binary array\n    /// @sa https://json.nlohmann.me/api/basic_json/is_binary/\n    constexpr bool is_binary() const noexcept\n    {\n        return m_type == value_t::binary;\n    }\n\n    /// @brief return whether value is discarded\n    /// @sa https://json.nlohmann.me/api/basic_json/is_discarded/\n    constexpr bool is_discarded() const noexcept\n    {\n        return m_type == value_t::discarded;\n    }\n\n    /// @brief return the type of the JSON value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/\n    constexpr operator value_t() const noexcept\n    {\n        return m_type;\n    }\n\n    /// @}\n\n  private:\n    //////////////////\n    // value access //\n    //////////////////\n\n    /// get a boolean (explicit)\n    boolean_t get_impl(boolean_t* /*unused*/) const\n    {\n        if (JSON_HEDLEY_LIKELY(is_boolean()))\n        {\n            return m_value.boolean;\n        }\n\n        JSON_THROW(type_error::create(302, \"type must be boolean, but is \" + std::string(type_name()), *this));\n    }\n\n    /// get a pointer to the value (object)\n    object_t* get_impl_ptr(object_t* /*unused*/) noexcept\n    {\n        return is_object() ? m_value.object : nullptr;\n    }\n\n    /// get a pointer to the value (object)\n    constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept\n    {\n        return is_object() ? m_value.object : nullptr;\n    }\n\n    /// get a pointer to the value (array)\n    array_t* get_impl_ptr(array_t* /*unused*/) noexcept\n    {\n        return is_array() ? m_value.array : nullptr;\n    }\n\n    /// get a pointer to the value (array)\n    constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept\n    {\n        return is_array() ? m_value.array : nullptr;\n    }\n\n    /// get a pointer to the value (string)\n    string_t* get_impl_ptr(string_t* /*unused*/) noexcept\n    {\n        return is_string() ? m_value.string : nullptr;\n    }\n\n    /// get a pointer to the value (string)\n    constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept\n    {\n        return is_string() ? m_value.string : nullptr;\n    }\n\n    /// get a pointer to the value (boolean)\n    boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept\n    {\n        return is_boolean() ? &m_value.boolean : nullptr;\n    }\n\n    /// get a pointer to the value (boolean)\n    constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept\n    {\n        return is_boolean() ? &m_value.boolean : nullptr;\n    }\n\n    /// get a pointer to the value (integer number)\n    number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept\n    {\n        return is_number_integer() ? &m_value.number_integer : nullptr;\n    }\n\n    /// get a pointer to the value (integer number)\n    constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept\n    {\n        return is_number_integer() ? &m_value.number_integer : nullptr;\n    }\n\n    /// get a pointer to the value (unsigned number)\n    number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept\n    {\n        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;\n    }\n\n    /// get a pointer to the value (unsigned number)\n    constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept\n    {\n        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;\n    }\n\n    /// get a pointer to the value (floating-point number)\n    number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept\n    {\n        return is_number_float() ? &m_value.number_float : nullptr;\n    }\n\n    /// get a pointer to the value (floating-point number)\n    constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept\n    {\n        return is_number_float() ? &m_value.number_float : nullptr;\n    }\n\n    /// get a pointer to the value (binary)\n    binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept\n    {\n        return is_binary() ? m_value.binary : nullptr;\n    }\n\n    /// get a pointer to the value (binary)\n    constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept\n    {\n        return is_binary() ? m_value.binary : nullptr;\n    }\n\n    /*!\n    @brief helper function to implement get_ref()\n\n    This function helps to implement get_ref() without code duplication for\n    const and non-const overloads\n\n    @tparam ThisType will be deduced as `basic_json` or `const basic_json`\n\n    @throw type_error.303 if ReferenceType does not match underlying value\n    type of the current JSON\n    */\n    template<typename ReferenceType, typename ThisType>\n    static ReferenceType get_ref_impl(ThisType& obj)\n    {\n        // delegate the call to get_ptr<>()\n        auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();\n\n        if (JSON_HEDLEY_LIKELY(ptr != nullptr))\n        {\n            return *ptr;\n        }\n\n        JSON_THROW(type_error::create(303, \"incompatible ReferenceType for get_ref, actual type is \" + std::string(obj.type_name()), obj));\n    }\n\n  public:\n    /// @name value access\n    /// Direct access to the stored value of a JSON value.\n    /// @{\n\n    /// @brief get a pointer value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/\n    template<typename PointerType, typename std::enable_if<\n                 std::is_pointer<PointerType>::value, int>::type = 0>\n    auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))\n    {\n        // delegate the call to get_impl_ptr<>()\n        return get_impl_ptr(static_cast<PointerType>(nullptr));\n    }\n\n    /// @brief get a pointer value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/\n    template < typename PointerType, typename std::enable_if <\n                   std::is_pointer<PointerType>::value&&\n                   std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >\n    constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))\n    {\n        // delegate the call to get_impl_ptr<>() const\n        return get_impl_ptr(static_cast<PointerType>(nullptr));\n    }\n\n  private:\n    /*!\n    @brief get a value (explicit)\n\n    Explicit type conversion between the JSON value and a compatible value\n    which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)\n    and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).\n    The value is converted by calling the @ref json_serializer<ValueType>\n    `from_json()` method.\n\n    The function is equivalent to executing\n    @code {.cpp}\n    ValueType ret;\n    JSONSerializer<ValueType>::from_json(*this, ret);\n    return ret;\n    @endcode\n\n    This overloads is chosen if:\n    - @a ValueType is not @ref basic_json,\n    - @ref json_serializer<ValueType> has a `from_json()` method of the form\n      `void from_json(const basic_json&, ValueType&)`, and\n    - @ref json_serializer<ValueType> does not have a `from_json()` method of\n      the form `ValueType from_json(const basic_json&)`\n\n    @tparam ValueType the returned value type\n\n    @return copy of the JSON value, converted to @a ValueType\n\n    @throw what @ref json_serializer<ValueType> `from_json()` method throws\n\n    @liveexample{The example below shows several conversions from JSON values\n    to other types. There a few things to note: (1) Floating-point numbers can\n    be converted to integers\\, (2) A JSON array can be converted to a standard\n    `std::vector<short>`\\, (3) A JSON object can be converted to C++\n    associative containers such as `std::unordered_map<std::string\\,\n    json>`.,get__ValueType_const}\n\n    @since version 2.1.0\n    */\n    template < typename ValueType,\n               detail::enable_if_t <\n                   detail::is_default_constructible<ValueType>::value&&\n                   detail::has_from_json<basic_json_t, ValueType>::value,\n                   int > = 0 >\n    ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(\n                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))\n    {\n        auto ret = ValueType();\n        JSONSerializer<ValueType>::from_json(*this, ret);\n        return ret;\n    }\n\n    /*!\n    @brief get a value (explicit); special case\n\n    Explicit type conversion between the JSON value and a compatible value\n    which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)\n    and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).\n    The value is converted by calling the @ref json_serializer<ValueType>\n    `from_json()` method.\n\n    The function is equivalent to executing\n    @code {.cpp}\n    return JSONSerializer<ValueType>::from_json(*this);\n    @endcode\n\n    This overloads is chosen if:\n    - @a ValueType is not @ref basic_json and\n    - @ref json_serializer<ValueType> has a `from_json()` method of the form\n      `ValueType from_json(const basic_json&)`\n\n    @note If @ref json_serializer<ValueType> has both overloads of\n    `from_json()`, this one is chosen.\n\n    @tparam ValueType the returned value type\n\n    @return copy of the JSON value, converted to @a ValueType\n\n    @throw what @ref json_serializer<ValueType> `from_json()` method throws\n\n    @since version 2.1.0\n    */\n    template < typename ValueType,\n               detail::enable_if_t <\n                   detail::has_non_default_from_json<basic_json_t, ValueType>::value,\n                   int > = 0 >\n    ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(\n                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))\n    {\n        return JSONSerializer<ValueType>::from_json(*this);\n    }\n\n    /*!\n    @brief get special-case overload\n\n    This overloads converts the current @ref basic_json in a different\n    @ref basic_json type\n\n    @tparam BasicJsonType == @ref basic_json\n\n    @return a copy of *this, converted into @a BasicJsonType\n\n    @complexity Depending on the implementation of the called `from_json()`\n                method.\n\n    @since version 3.2.0\n    */\n    template < typename BasicJsonType,\n               detail::enable_if_t <\n                   detail::is_basic_json<BasicJsonType>::value,\n                   int > = 0 >\n    BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const\n    {\n        return *this;\n    }\n\n    /*!\n    @brief get special-case overload\n\n    This overloads avoids a lot of template boilerplate, it can be seen as the\n    identity method\n\n    @tparam BasicJsonType == @ref basic_json\n\n    @return a copy of *this\n\n    @complexity Constant.\n\n    @since version 2.1.0\n    */\n    template<typename BasicJsonType,\n             detail::enable_if_t<\n                 std::is_same<BasicJsonType, basic_json_t>::value,\n                 int> = 0>\n    basic_json get_impl(detail::priority_tag<3> /*unused*/) const\n    {\n        return *this;\n    }\n\n    /*!\n    @brief get a pointer value (explicit)\n    @copydoc get()\n    */\n    template<typename PointerType,\n             detail::enable_if_t<\n                 std::is_pointer<PointerType>::value,\n                 int> = 0>\n    constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept\n    -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())\n    {\n        // delegate the call to get_ptr\n        return get_ptr<PointerType>();\n    }\n\n  public:\n    /*!\n    @brief get a (pointer) value (explicit)\n\n    Performs explicit type conversion between the JSON value and a compatible value if required.\n\n    - If the requested type is a pointer to the internally stored JSON value that pointer is returned.\n    No copies are made.\n\n    - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible\n    from the current @ref basic_json.\n\n    - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`\n    method.\n\n    @tparam ValueTypeCV the provided value type\n    @tparam ValueType the returned value type\n\n    @return copy of the JSON value, converted to @tparam ValueType if necessary\n\n    @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required\n\n    @since version 2.1.0\n    */\n    template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>\n#if defined(JSON_HAS_CPP_14)\n    constexpr\n#endif\n    auto get() const noexcept(\n    noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))\n    -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))\n    {\n        // we cannot static_assert on ValueTypeCV being non-const, because\n        // there is support for get<const basic_json_t>(), which is why we\n        // still need the uncvref\n        static_assert(!std::is_reference<ValueTypeCV>::value,\n                      \"get() cannot be used with reference types, you might want to use get_ref()\");\n        return get_impl<ValueType>(detail::priority_tag<4> {});\n    }\n\n    /*!\n    @brief get a pointer value (explicit)\n\n    Explicit pointer access to the internally stored JSON value. No copies are\n    made.\n\n    @warning The pointer becomes invalid if the underlying JSON object\n    changes.\n\n    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref\n    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,\n    @ref number_unsigned_t, or @ref number_float_t.\n\n    @return pointer to the internally stored JSON value if the requested\n    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise\n\n    @complexity Constant.\n\n    @liveexample{The example below shows how pointers to internal values of a\n    JSON value can be requested. Note that no type conversions are made and a\n    `nullptr` is returned if the value and the requested pointer type does not\n    match.,get__PointerType}\n\n    @sa see @ref get_ptr() for explicit pointer-member access\n\n    @since version 1.0.0\n    */\n    template<typename PointerType, typename std::enable_if<\n                 std::is_pointer<PointerType>::value, int>::type = 0>\n    auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())\n    {\n        // delegate the call to get_ptr\n        return get_ptr<PointerType>();\n    }\n\n    /// @brief get a value (explicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_to/\n    template < typename ValueType,\n               detail::enable_if_t <\n                   !detail::is_basic_json<ValueType>::value&&\n                   detail::has_from_json<basic_json_t, ValueType>::value,\n                   int > = 0 >\n    ValueType & get_to(ValueType& v) const noexcept(noexcept(\n                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))\n    {\n        JSONSerializer<ValueType>::from_json(*this, v);\n        return v;\n    }\n\n    // specialization to allow calling get_to with a basic_json value\n    // see https://github.com/nlohmann/json/issues/2175\n    template<typename ValueType,\n             detail::enable_if_t <\n                 detail::is_basic_json<ValueType>::value,\n                 int> = 0>\n    ValueType & get_to(ValueType& v) const\n    {\n        v = *this;\n        return v;\n    }\n\n    template <\n        typename T, std::size_t N,\n        typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n        detail::enable_if_t <\n            detail::has_from_json<basic_json_t, Array>::value, int > = 0 >\n    Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n    noexcept(noexcept(JSONSerializer<Array>::from_json(\n                          std::declval<const basic_json_t&>(), v)))\n    {\n        JSONSerializer<Array>::from_json(*this, v);\n        return v;\n    }\n\n    /// @brief get a reference value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ref/\n    template<typename ReferenceType, typename std::enable_if<\n                 std::is_reference<ReferenceType>::value, int>::type = 0>\n    ReferenceType get_ref()\n    {\n        // delegate call to get_ref_impl\n        return get_ref_impl<ReferenceType>(*this);\n    }\n\n    /// @brief get a reference value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ref/\n    template < typename ReferenceType, typename std::enable_if <\n                   std::is_reference<ReferenceType>::value&&\n                   std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >\n    ReferenceType get_ref() const\n    {\n        // delegate call to get_ref_impl\n        return get_ref_impl<ReferenceType>(*this);\n    }\n\n    /*!\n    @brief get a value (implicit)\n\n    Implicit type conversion between the JSON value and a compatible value.\n    The call is realized by calling @ref get() const.\n\n    @tparam ValueType non-pointer type compatible to the JSON value, for\n    instance `int` for JSON integer numbers, `bool` for JSON booleans, or\n    `std::vector` types for JSON arrays. The character type of @ref string_t\n    as well as an initializer list of this type is excluded to avoid\n    ambiguities as these types implicitly convert to `std::string`.\n\n    @return copy of the JSON value, converted to type @a ValueType\n\n    @throw type_error.302 in case passed type @a ValueType is incompatible\n    to the JSON value type (e.g., the JSON value is of type boolean, but a\n    string is requested); see example below\n\n    @complexity Linear in the size of the JSON value.\n\n    @liveexample{The example below shows several conversions from JSON values\n    to other types. There a few things to note: (1) Floating-point numbers can\n    be converted to integers\\, (2) A JSON array can be converted to a standard\n    `std::vector<short>`\\, (3) A JSON object can be converted to C++\n    associative containers such as `std::unordered_map<std::string\\,\n    json>`.,operator__ValueType}\n\n    @since version 1.0.0\n    */\n    template < typename ValueType, typename std::enable_if <\n                   detail::conjunction <\n                       detail::negation<std::is_pointer<ValueType>>,\n                       detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,\n                                        detail::negation<std::is_same<ValueType, typename string_t::value_type>>,\n                                        detail::negation<detail::is_basic_json<ValueType>>,\n                                        detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,\n\n#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))\n                                                detail::negation<std::is_same<ValueType, std::string_view>>,\n#endif\n                                                detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>\n                                                >::value, int >::type = 0 >\n                                        JSON_EXPLICIT operator ValueType() const\n    {\n        // delegate the call to get<>() const\n        return get<ValueType>();\n    }\n\n    /// @brief get a binary value\n    /// @sa https://json.nlohmann.me/api/basic_json/get_binary/\n    binary_t& get_binary()\n    {\n        if (!is_binary())\n        {\n            JSON_THROW(type_error::create(302, \"type must be binary, but is \" + std::string(type_name()), *this));\n        }\n\n        return *get_ptr<binary_t*>();\n    }\n\n    /// @brief get a binary value\n    /// @sa https://json.nlohmann.me/api/basic_json/get_binary/\n    const binary_t& get_binary() const\n    {\n        if (!is_binary())\n        {\n            JSON_THROW(type_error::create(302, \"type must be binary, but is \" + std::string(type_name()), *this));\n        }\n\n        return *get_ptr<const binary_t*>();\n    }\n\n    /// @}\n\n\n    ////////////////////\n    // element access //\n    ////////////////////\n\n    /// @name element access\n    /// Access to the JSON value.\n    /// @{\n\n    /// @brief access specified array element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    reference at(size_type idx)\n    {\n        // at only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            JSON_TRY\n            {\n                return set_parent(m_value.array->at(idx));\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified array element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    const_reference at(size_type idx) const\n    {\n        // at only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            JSON_TRY\n            {\n                return m_value.array->at(idx);\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified object element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    reference at(const typename object_t::key_type& key)\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_TRY\n            {\n                return set_parent(m_value.object->at(key));\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(403, \"key '\" + key + \"' not found\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified object element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    const_reference at(const typename object_t::key_type& key) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_TRY\n            {\n                return m_value.object->at(key);\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(403, \"key '\" + key + \"' not found\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified array element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    reference operator[](size_type idx)\n    {\n        // implicitly convert null value to an empty array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value.array = create<array_t>();\n            assert_invariant();\n        }\n\n        // operator[] only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            // fill up array with null values if given idx is outside range\n            if (idx >= m_value.array->size())\n            {\n#if JSON_DIAGNOSTICS\n                // remember array size & capacity before resizing\n                const auto old_size = m_value.array->size();\n                const auto old_capacity = m_value.array->capacity();\n#endif\n                m_value.array->resize(idx + 1);\n\n#if JSON_DIAGNOSTICS\n                if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))\n                {\n                    // capacity has changed: update all parents\n                    set_parents();\n                }\n                else\n                {\n                    // set parent for values added above\n                    set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));\n                }\n#endif\n                assert_invariant();\n            }\n\n            return m_value.array->operator[](idx);\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a numeric argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified array element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    const_reference operator[](size_type idx) const\n    {\n        // const operator[] only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            return m_value.array->operator[](idx);\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a numeric argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    reference operator[](const typename object_t::key_type& key)\n    {\n        // implicitly convert null value to an empty object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value.object = create<object_t>();\n            assert_invariant();\n        }\n\n        // operator[] only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            return set_parent(m_value.object->operator[](key));\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    const_reference operator[](const typename object_t::key_type& key) const\n    {\n        // const operator[] only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());\n            return m_value.object->find(key)->second;\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    template<typename T>\n    JSON_HEDLEY_NON_NULL(2)\n    reference operator[](T* key)\n    {\n        // implicitly convert null to object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value = value_t::object;\n            assert_invariant();\n        }\n\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            return set_parent(m_value.object->operator[](key));\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    template<typename T>\n    JSON_HEDLEY_NON_NULL(2)\n    const_reference operator[](T* key) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());\n            return m_value.object->find(key)->second;\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    /// using std::is_convertible in a std::enable_if will fail when using explicit conversions\n    template < class ValueType, typename std::enable_if <\n                   detail::is_getable<basic_json_t, ValueType>::value\n                   && !std::is_same<value_t, ValueType>::value, int >::type = 0 >\n    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            // if key is found, return value and given default value otherwise\n            const auto it = find(key);\n            if (it != end())\n            {\n                return it->template get<ValueType>();\n            }\n\n            return default_value;\n        }\n\n        JSON_THROW(type_error::create(306, \"cannot use value() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    /// overload for a default value of type const char*\n    string_t value(const typename object_t::key_type& key, const char* default_value) const\n    {\n        return value(key, string_t(default_value));\n    }\n\n    /// @brief access specified object element via JSON Pointer with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    template<class ValueType, typename std::enable_if<\n                 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>\n    ValueType value(const json_pointer& ptr, const ValueType& default_value) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            // if pointer resolves a value, return it or use default value\n            JSON_TRY\n            {\n                return ptr.get_checked(this).template get<ValueType>();\n            }\n            JSON_INTERNAL_CATCH (out_of_range&)\n            {\n                return default_value;\n            }\n        }\n\n        JSON_THROW(type_error::create(306, \"cannot use value() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element via JSON Pointer with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    /// overload for a default value of type const char*\n    JSON_HEDLEY_NON_NULL(3)\n    string_t value(const json_pointer& ptr, const char* default_value) const\n    {\n        return value(ptr, string_t(default_value));\n    }\n\n    /// @brief access the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/front/\n    reference front()\n    {\n        return *begin();\n    }\n\n    /// @brief access the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/front/\n    const_reference front() const\n    {\n        return *cbegin();\n    }\n\n    /// @brief access the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/back/\n    reference back()\n    {\n        auto tmp = end();\n        --tmp;\n        return *tmp;\n    }\n\n    /// @brief access the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/back/\n    const_reference back() const\n    {\n        auto tmp = cend();\n        --tmp;\n        return *tmp;\n    }\n\n    /// @brief remove element given an iterator\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    template < class IteratorType, typename std::enable_if <\n                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||\n                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type\n               = 0 >\n    IteratorType erase(IteratorType pos)\n    {\n        // make sure iterator fits the current value\n        if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n        }\n\n        IteratorType result = end();\n\n        switch (m_type)\n        {\n            case value_t::boolean:\n            case value_t::number_float:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::string:\n            case value_t::binary:\n            {\n                if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))\n                {\n                    JSON_THROW(invalid_iterator::create(205, \"iterator out of range\", *this));\n                }\n\n                if (is_string())\n                {\n                    AllocatorType<string_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);\n                    m_value.string = nullptr;\n                }\n                else if (is_binary())\n                {\n                    AllocatorType<binary_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);\n                    m_value.binary = nullptr;\n                }\n\n                m_type = value_t::null;\n                assert_invariant();\n                break;\n            }\n\n            case value_t::object:\n            {\n                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);\n                break;\n            }\n\n            case value_t::array:\n            {\n                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n        }\n\n        return result;\n    }\n\n    /// @brief remove elements given an iterator range\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    template < class IteratorType, typename std::enable_if <\n                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||\n                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type\n               = 0 >\n    IteratorType erase(IteratorType first, IteratorType last)\n    {\n        // make sure iterator fits the current value\n        if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(203, \"iterators do not fit current value\", *this));\n        }\n\n        IteratorType result = end();\n\n        switch (m_type)\n        {\n            case value_t::boolean:\n            case value_t::number_float:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::string:\n            case value_t::binary:\n            {\n                if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()\n                                       || !last.m_it.primitive_iterator.is_end()))\n                {\n                    JSON_THROW(invalid_iterator::create(204, \"iterators out of range\", *this));\n                }\n\n                if (is_string())\n                {\n                    AllocatorType<string_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);\n                    m_value.string = nullptr;\n                }\n                else if (is_binary())\n                {\n                    AllocatorType<binary_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);\n                    m_value.binary = nullptr;\n                }\n\n                m_type = value_t::null;\n                assert_invariant();\n                break;\n            }\n\n            case value_t::object:\n            {\n                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,\n                                              last.m_it.object_iterator);\n                break;\n            }\n\n            case value_t::array:\n            {\n                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,\n                                             last.m_it.array_iterator);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n        }\n\n        return result;\n    }\n\n    /// @brief remove element from a JSON object given a key\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    size_type erase(const typename object_t::key_type& key)\n    {\n        // this erase only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            return m_value.object->erase(key);\n        }\n\n        JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief remove element from a JSON array given an index\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    void erase(const size_type idx)\n    {\n        // this erase only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            if (JSON_HEDLEY_UNLIKELY(idx >= size()))\n            {\n                JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", *this));\n            }\n\n            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));\n        }\n        else\n        {\n            JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @}\n\n\n    ////////////\n    // lookup //\n    ////////////\n\n    /// @name lookup\n    /// @{\n\n    /// @brief find an element in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/find/\n    template<typename KeyT>\n    iterator find(KeyT&& key)\n    {\n        auto result = end();\n\n        if (is_object())\n        {\n            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));\n        }\n\n        return result;\n    }\n\n    /// @brief find an element in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/find/\n    template<typename KeyT>\n    const_iterator find(KeyT&& key) const\n    {\n        auto result = cend();\n\n        if (is_object())\n        {\n            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));\n        }\n\n        return result;\n    }\n\n    /// @brief returns the number of occurrences of a key in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/count/\n    template<typename KeyT>\n    size_type count(KeyT&& key) const\n    {\n        // return 0 for all nonobject types\n        return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;\n    }\n\n    /// @brief check the existence of an element in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/contains/\n    template < typename KeyT, typename std::enable_if <\n                   !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >\n    bool contains(KeyT && key) const\n    {\n        return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();\n    }\n\n    /// @brief check the existence of an element in a JSON object given a JSON pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/contains/\n    bool contains(const json_pointer& ptr) const\n    {\n        return ptr.contains(this);\n    }\n\n    /// @}\n\n\n    ///////////////\n    // iterators //\n    ///////////////\n\n    /// @name iterators\n    /// @{\n\n    /// @brief returns an iterator to the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/begin/\n    iterator begin() noexcept\n    {\n        iterator result(this);\n        result.set_begin();\n        return result;\n    }\n\n    /// @brief returns an iterator to the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/begin/\n    const_iterator begin() const noexcept\n    {\n        return cbegin();\n    }\n\n    /// @brief returns a const iterator to the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/cbegin/\n    const_iterator cbegin() const noexcept\n    {\n        const_iterator result(this);\n        result.set_begin();\n        return result;\n    }\n\n    /// @brief returns an iterator to one past the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/end/\n    iterator end() noexcept\n    {\n        iterator result(this);\n        result.set_end();\n        return result;\n    }\n\n    /// @brief returns an iterator to one past the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/end/\n    const_iterator end() const noexcept\n    {\n        return cend();\n    }\n\n    /// @brief returns an iterator to one past the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/cend/\n    const_iterator cend() const noexcept\n    {\n        const_iterator result(this);\n        result.set_end();\n        return result;\n    }\n\n    /// @brief returns an iterator to the reverse-beginning\n    /// @sa https://json.nlohmann.me/api/basic_json/rbegin/\n    reverse_iterator rbegin() noexcept\n    {\n        return reverse_iterator(end());\n    }\n\n    /// @brief returns an iterator to the reverse-beginning\n    /// @sa https://json.nlohmann.me/api/basic_json/rbegin/\n    const_reverse_iterator rbegin() const noexcept\n    {\n        return crbegin();\n    }\n\n    /// @brief returns an iterator to the reverse-end\n    /// @sa https://json.nlohmann.me/api/basic_json/rend/\n    reverse_iterator rend() noexcept\n    {\n        return reverse_iterator(begin());\n    }\n\n    /// @brief returns an iterator to the reverse-end\n    /// @sa https://json.nlohmann.me/api/basic_json/rend/\n    const_reverse_iterator rend() const noexcept\n    {\n        return crend();\n    }\n\n    /// @brief returns a const reverse iterator to the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/crbegin/\n    const_reverse_iterator crbegin() const noexcept\n    {\n        return const_reverse_iterator(cend());\n    }\n\n    /// @brief returns a const reverse iterator to one before the first\n    /// @sa https://json.nlohmann.me/api/basic_json/crend/\n    const_reverse_iterator crend() const noexcept\n    {\n        return const_reverse_iterator(cbegin());\n    }\n\n  public:\n    /// @brief wrapper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    /// @deprecated This function is deprecated since 3.1.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use @ref items() instead;\n    ///             that is, replace `json::iterator_wrapper(j)` with `j.items()`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())\n    static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept\n    {\n        return ref.items();\n    }\n\n    /// @brief wrapper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    /// @deprecated This function is deprecated since 3.1.0 and will be removed in\n    ///         version 4.0.0 of the library. Please use @ref items() instead;\n    ///         that is, replace `json::iterator_wrapper(j)` with `j.items()`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())\n    static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept\n    {\n        return ref.items();\n    }\n\n    /// @brief helper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    iteration_proxy<iterator> items() noexcept\n    {\n        return iteration_proxy<iterator>(*this);\n    }\n\n    /// @brief helper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    iteration_proxy<const_iterator> items() const noexcept\n    {\n        return iteration_proxy<const_iterator>(*this);\n    }\n\n    /// @}\n\n\n    //////////////\n    // capacity //\n    //////////////\n\n    /// @name capacity\n    /// @{\n\n    /// @brief checks whether the container is empty.\n    /// @sa https://json.nlohmann.me/api/basic_json/empty/\n    bool empty() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::null:\n            {\n                // null values are empty\n                return true;\n            }\n\n            case value_t::array:\n            {\n                // delegate call to array_t::empty()\n                return m_value.array->empty();\n            }\n\n            case value_t::object:\n            {\n                // delegate call to object_t::empty()\n                return m_value.object->empty();\n            }\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // all other types are nonempty\n                return false;\n            }\n        }\n    }\n\n    /// @brief returns the number of elements\n    /// @sa https://json.nlohmann.me/api/basic_json/size/\n    size_type size() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::null:\n            {\n                // null values are empty\n                return 0;\n            }\n\n            case value_t::array:\n            {\n                // delegate call to array_t::size()\n                return m_value.array->size();\n            }\n\n            case value_t::object:\n            {\n                // delegate call to object_t::size()\n                return m_value.object->size();\n            }\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // all other types have size 1\n                return 1;\n            }\n        }\n    }\n\n    /// @brief returns the maximum possible number of elements\n    /// @sa https://json.nlohmann.me/api/basic_json/max_size/\n    size_type max_size() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::array:\n            {\n                // delegate call to array_t::max_size()\n                return m_value.array->max_size();\n            }\n\n            case value_t::object:\n            {\n                // delegate call to object_t::max_size()\n                return m_value.object->max_size();\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // all other types have max_size() == size()\n                return size();\n            }\n        }\n    }\n\n    /// @}\n\n\n    ///////////////\n    // modifiers //\n    ///////////////\n\n    /// @name modifiers\n    /// @{\n\n    /// @brief clears the contents\n    /// @sa https://json.nlohmann.me/api/basic_json/clear/\n    void clear() noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::number_integer:\n            {\n                m_value.number_integer = 0;\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                m_value.number_unsigned = 0;\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                m_value.number_float = 0.0;\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                m_value.boolean = false;\n                break;\n            }\n\n            case value_t::string:\n            {\n                m_value.string->clear();\n                break;\n            }\n\n            case value_t::binary:\n            {\n                m_value.binary->clear();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_value.array->clear();\n                break;\n            }\n\n            case value_t::object:\n            {\n                m_value.object->clear();\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(basic_json&& val)\n    {\n        // push_back only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))\n        {\n            JSON_THROW(type_error::create(308, \"cannot use push_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value = value_t::array;\n            assert_invariant();\n        }\n\n        // add element to array (move semantics)\n        const auto old_capacity = m_value.array->capacity();\n        m_value.array->push_back(std::move(val));\n        set_parent(m_value.array->back(), old_capacity);\n        // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(basic_json&& val)\n    {\n        push_back(std::move(val));\n        return *this;\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(const basic_json& val)\n    {\n        // push_back only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))\n        {\n            JSON_THROW(type_error::create(308, \"cannot use push_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value = value_t::array;\n            assert_invariant();\n        }\n\n        // add element to array\n        const auto old_capacity = m_value.array->capacity();\n        m_value.array->push_back(val);\n        set_parent(m_value.array->back(), old_capacity);\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(const basic_json& val)\n    {\n        push_back(val);\n        return *this;\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(const typename object_t::value_type& val)\n    {\n        // push_back only works for null objects or objects\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))\n        {\n            JSON_THROW(type_error::create(308, \"cannot use push_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value = value_t::object;\n            assert_invariant();\n        }\n\n        // add element to object\n        auto res = m_value.object->insert(val);\n        set_parent(res.first->second);\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(const typename object_t::value_type& val)\n    {\n        push_back(val);\n        return *this;\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(initializer_list_t init)\n    {\n        if (is_object() && init.size() == 2 && (*init.begin())->is_string())\n        {\n            basic_json&& key = init.begin()->moved_or_copied();\n            push_back(typename object_t::value_type(\n                          std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));\n        }\n        else\n        {\n            push_back(basic_json(init));\n        }\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(initializer_list_t init)\n    {\n        push_back(init);\n        return *this;\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/emplace_back/\n    template<class... Args>\n    reference emplace_back(Args&& ... args)\n    {\n        // emplace_back only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))\n        {\n            JSON_THROW(type_error::create(311, \"cannot use emplace_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value = value_t::array;\n            assert_invariant();\n        }\n\n        // add element to array (perfect forwarding)\n        const auto old_capacity = m_value.array->capacity();\n        m_value.array->emplace_back(std::forward<Args>(args)...);\n        return set_parent(m_value.array->back(), old_capacity);\n    }\n\n    /// @brief add an object to an object if key does not exist\n    /// @sa https://json.nlohmann.me/api/basic_json/emplace/\n    template<class... Args>\n    std::pair<iterator, bool> emplace(Args&& ... args)\n    {\n        // emplace only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))\n        {\n            JSON_THROW(type_error::create(311, \"cannot use emplace() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value = value_t::object;\n            assert_invariant();\n        }\n\n        // add element to array (perfect forwarding)\n        auto res = m_value.object->emplace(std::forward<Args>(args)...);\n        set_parent(res.first->second);\n\n        // create result iterator and set iterator to the result of emplace\n        auto it = begin();\n        it.m_it.object_iterator = res.first;\n\n        // return pair of iterator and boolean\n        return {it, res.second};\n    }\n\n    /// Helper for insertion of an iterator\n    /// @note: This uses std::distance to support GCC 4.8,\n    ///        see https://github.com/nlohmann/json/pull/1257\n    template<typename... Args>\n    iterator insert_iterator(const_iterator pos, Args&& ... args)\n    {\n        iterator result(this);\n        JSON_ASSERT(m_value.array != nullptr);\n\n        auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);\n        m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);\n        result.m_it.array_iterator = m_value.array->begin() + insert_pos;\n\n        // This could have been written as:\n        // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);\n        // but the return value of insert is missing in GCC 4.8, so it is written this way instead.\n\n        set_parents();\n        return result;\n    }\n\n    /// @brief inserts element into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, const basic_json& val)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            // check if iterator pos fits to this JSON value\n            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n            {\n                JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n            }\n\n            // insert to array and return iterator\n            return insert_iterator(pos, val);\n        }\n\n        JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief inserts element into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, basic_json&& val)\n    {\n        return insert(pos, val);\n    }\n\n    /// @brief inserts copies of element into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, size_type cnt, const basic_json& val)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            // check if iterator pos fits to this JSON value\n            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n            {\n                JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n            }\n\n            // insert to array and return iterator\n            return insert_iterator(pos, cnt, val);\n        }\n\n        JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief inserts range of elements into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, const_iterator first, const_iterator last)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_UNLIKELY(!is_array()))\n        {\n            JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n        }\n\n        // check if iterator pos fits to this JSON value\n        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n        }\n\n        // check if range iterators belong to the same JSON object\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(210, \"iterators do not fit\", *this));\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(first.m_object == this))\n        {\n            JSON_THROW(invalid_iterator::create(211, \"passed iterators may not belong to container\", *this));\n        }\n\n        // insert to array and return iterator\n        return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);\n    }\n\n    /// @brief inserts elements from initializer list into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, initializer_list_t ilist)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_UNLIKELY(!is_array()))\n        {\n            JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n        }\n\n        // check if iterator pos fits to this JSON value\n        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n        }\n\n        // insert to array and return iterator\n        return insert_iterator(pos, ilist.begin(), ilist.end());\n    }\n\n    /// @brief inserts range of elements into object\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    void insert(const_iterator first, const_iterator last)\n    {\n        // insert only works for objects\n        if (JSON_HEDLEY_UNLIKELY(!is_object()))\n        {\n            JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n        }\n\n        // check if range iterators belong to the same JSON object\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(210, \"iterators do not fit\", *this));\n        }\n\n        // passed iterators must belong to objects\n        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterators first and last must point to objects\", *this));\n        }\n\n        m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);\n    }\n\n    /// @brief updates a JSON object from another object, overwriting existing keys\n    /// @sa https://json.nlohmann.me/api/basic_json/update/\n    void update(const_reference j, bool merge_objects = false)\n    {\n        update(j.begin(), j.end(), merge_objects);\n    }\n\n    /// @brief updates a JSON object from another object, overwriting existing keys\n    /// @sa https://json.nlohmann.me/api/basic_json/update/\n    void update(const_iterator first, const_iterator last, bool merge_objects = false)\n    {\n        // implicitly convert null value to an empty object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value.object = create<object_t>();\n            assert_invariant();\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!is_object()))\n        {\n            JSON_THROW(type_error::create(312, \"cannot use update() with \" + std::string(type_name()), *this));\n        }\n\n        // check if range iterators belong to the same JSON object\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(210, \"iterators do not fit\", *this));\n        }\n\n        // passed iterators must belong to objects\n        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))\n        {\n            JSON_THROW(type_error::create(312, \"cannot use update() with \" + std::string(first.m_object->type_name()), *first.m_object));\n        }\n\n        for (auto it = first; it != last; ++it)\n        {\n            if (merge_objects && it.value().is_object())\n            {\n                auto it2 = m_value.object->find(it.key());\n                if (it2 != m_value.object->end())\n                {\n                    it2->second.update(it.value(), true);\n                    continue;\n                }\n            }\n            m_value.object->operator[](it.key()) = it.value();\n#if JSON_DIAGNOSTICS\n            m_value.object->operator[](it.key()).m_parent = this;\n#endif\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(reference other) noexcept (\n        std::is_nothrow_move_constructible<value_t>::value&&\n        std::is_nothrow_move_assignable<value_t>::value&&\n        std::is_nothrow_move_constructible<json_value>::value&&\n        std::is_nothrow_move_assignable<json_value>::value\n    )\n    {\n        std::swap(m_type, other.m_type);\n        std::swap(m_value, other.m_value);\n\n        set_parents();\n        other.set_parents();\n        assert_invariant();\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    friend void swap(reference left, reference right) noexcept (\n        std::is_nothrow_move_constructible<value_t>::value&&\n        std::is_nothrow_move_assignable<value_t>::value&&\n        std::is_nothrow_move_constructible<json_value>::value&&\n        std::is_nothrow_move_assignable<json_value>::value\n    )\n    {\n        left.swap(right);\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(array_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            std::swap(*(m_value.array), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(object_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            std::swap(*(m_value.object), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(string_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for strings\n        if (JSON_HEDLEY_LIKELY(is_string()))\n        {\n            std::swap(*(m_value.string), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(binary_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for strings\n        if (JSON_HEDLEY_LIKELY(is_binary()))\n        {\n            std::swap(*(m_value.binary), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for strings\n        if (JSON_HEDLEY_LIKELY(is_binary()))\n        {\n            std::swap(*(m_value.binary), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @}\n\n  public:\n    //////////////////////////////////////////\n    // lexicographical comparison operators //\n    //////////////////////////////////////////\n\n    /// @name lexicographical comparison operators\n    /// @{\n\n    /// @brief comparison: equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/\n    friend bool operator==(const_reference lhs, const_reference rhs) noexcept\n    {\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n        const auto lhs_type = lhs.type();\n        const auto rhs_type = rhs.type();\n\n        if (lhs_type == rhs_type)\n        {\n            switch (lhs_type)\n            {\n                case value_t::array:\n                    return *lhs.m_value.array == *rhs.m_value.array;\n\n                case value_t::object:\n                    return *lhs.m_value.object == *rhs.m_value.object;\n\n                case value_t::null:\n                    return true;\n\n                case value_t::string:\n                    return *lhs.m_value.string == *rhs.m_value.string;\n\n                case value_t::boolean:\n                    return lhs.m_value.boolean == rhs.m_value.boolean;\n\n                case value_t::number_integer:\n                    return lhs.m_value.number_integer == rhs.m_value.number_integer;\n\n                case value_t::number_unsigned:\n                    return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;\n\n                case value_t::number_float:\n                    return lhs.m_value.number_float == rhs.m_value.number_float;\n\n                case value_t::binary:\n                    return *lhs.m_value.binary == *rhs.m_value.binary;\n\n                case value_t::discarded:\n                default:\n                    return false;\n            }\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)\n        {\n            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)\n        {\n            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);\n        }\n\n        return false;\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n    }\n\n    /// @brief comparison: equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator==(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs == basic_json(rhs);\n    }\n\n    /// @brief comparison: equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator==(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) == rhs;\n    }\n\n    /// @brief comparison: not equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/\n    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(lhs == rhs);\n    }\n\n    /// @brief comparison: not equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs != basic_json(rhs);\n    }\n\n    /// @brief comparison: not equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) != rhs;\n    }\n\n    /// @brief comparison: less than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/\n    friend bool operator<(const_reference lhs, const_reference rhs) noexcept\n    {\n        const auto lhs_type = lhs.type();\n        const auto rhs_type = rhs.type();\n\n        if (lhs_type == rhs_type)\n        {\n            switch (lhs_type)\n            {\n                case value_t::array:\n                    // note parentheses are necessary, see\n                    // https://github.com/nlohmann/json/issues/1530\n                    return (*lhs.m_value.array) < (*rhs.m_value.array);\n\n                case value_t::object:\n                    return (*lhs.m_value.object) < (*rhs.m_value.object);\n\n                case value_t::null:\n                    return false;\n\n                case value_t::string:\n                    return (*lhs.m_value.string) < (*rhs.m_value.string);\n\n                case value_t::boolean:\n                    return (lhs.m_value.boolean) < (rhs.m_value.boolean);\n\n                case value_t::number_integer:\n                    return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);\n\n                case value_t::number_unsigned:\n                    return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);\n\n                case value_t::number_float:\n                    return (lhs.m_value.number_float) < (rhs.m_value.number_float);\n\n                case value_t::binary:\n                    return (*lhs.m_value.binary) < (*rhs.m_value.binary);\n\n                case value_t::discarded:\n                default:\n                    return false;\n            }\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)\n        {\n            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)\n        {\n            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;\n        }\n\n        // We only reach this line if we cannot compare values. In that case,\n        // we compare types. Note we have to call the operator explicitly,\n        // because MSVC has problems otherwise.\n        return operator<(lhs_type, rhs_type);\n    }\n\n    /// @brief comparison: less than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs < basic_json(rhs);\n    }\n\n    /// @brief comparison: less than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) < rhs;\n    }\n\n    /// @brief comparison: less than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_le/\n    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(rhs < lhs);\n    }\n\n    /// @brief comparison: less than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_le/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs <= basic_json(rhs);\n    }\n\n    /// @brief comparison: less than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_le/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) <= rhs;\n    }\n\n    /// @brief comparison: greater than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/\n    friend bool operator>(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(lhs <= rhs);\n    }\n\n    /// @brief comparison: greater than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs > basic_json(rhs);\n    }\n\n    /// @brief comparison: greater than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) > rhs;\n    }\n\n    /// @brief comparison: greater than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/\n    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(lhs < rhs);\n    }\n\n    /// @brief comparison: greater than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs >= basic_json(rhs);\n    }\n\n    /// @brief comparison: greater than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) >= rhs;\n    }\n\n    /// @}\n\n    ///////////////////\n    // serialization //\n    ///////////////////\n\n    /// @name serialization\n    /// @{\n#ifndef JSON_NO_IO\n    /// @brief serialize to stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/\n    friend std::ostream& operator<<(std::ostream& o, const basic_json& j)\n    {\n        // read width member and use it as indentation parameter if nonzero\n        const bool pretty_print = o.width() > 0;\n        const auto indentation = pretty_print ? o.width() : 0;\n\n        // reset width to 0 for subsequent calls to this stream\n        o.width(0);\n\n        // do the actual serialization\n        serializer s(detail::output_adapter<char>(o), o.fill());\n        s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));\n        return o;\n    }\n\n    /// @brief serialize to stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/\n    /// @deprecated This function is deprecated since 3.0.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use\n    ///             operator<<(std::ostream&, const basic_json&) instead; that is,\n    ///             replace calls like `j >> o;` with `o << j;`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))\n    friend std::ostream& operator>>(const basic_json& j, std::ostream& o)\n    {\n        return o << j;\n    }\n#endif  // JSON_NO_IO\n    /// @}\n\n\n    /////////////////////\n    // deserialization //\n    /////////////////////\n\n    /// @name deserialization\n    /// @{\n\n    /// @brief deserialize from a compatible input\n    /// @sa https://json.nlohmann.me/api/basic_json/parse/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json parse(InputType&& i,\n                            const parser_callback_t cb = nullptr,\n                            const bool allow_exceptions = true,\n                            const bool ignore_comments = false)\n    {\n        basic_json result;\n        parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);\n        return result;\n    }\n\n    /// @brief deserialize from a pair of character iterators\n    /// @sa https://json.nlohmann.me/api/basic_json/parse/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json parse(IteratorType first,\n                            IteratorType last,\n                            const parser_callback_t cb = nullptr,\n                            const bool allow_exceptions = true,\n                            const bool ignore_comments = false)\n    {\n        basic_json result;\n        parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);\n        return result;\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))\n    static basic_json parse(detail::span_input_adapter&& i,\n                            const parser_callback_t cb = nullptr,\n                            const bool allow_exceptions = true,\n                            const bool ignore_comments = false)\n    {\n        basic_json result;\n        parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);\n        return result;\n    }\n\n    /// @brief check if the input is valid JSON\n    /// @sa https://json.nlohmann.me/api/basic_json/accept/\n    template<typename InputType>\n    static bool accept(InputType&& i,\n                       const bool ignore_comments = false)\n    {\n        return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);\n    }\n\n    /// @brief check if the input is valid JSON\n    /// @sa https://json.nlohmann.me/api/basic_json/accept/\n    template<typename IteratorType>\n    static bool accept(IteratorType first, IteratorType last,\n                       const bool ignore_comments = false)\n    {\n        return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))\n    static bool accept(detail::span_input_adapter&& i,\n                       const bool ignore_comments = false)\n    {\n        return parser(i.get(), nullptr, false, ignore_comments).accept(true);\n    }\n\n    /// @brief generate SAX events\n    /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/\n    template <typename InputType, typename SAX>\n    JSON_HEDLEY_NON_NULL(2)\n    static bool sax_parse(InputType&& i, SAX* sax,\n                          input_format_t format = input_format_t::json,\n                          const bool strict = true,\n                          const bool ignore_comments = false)\n    {\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        return format == input_format_t::json\n               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)\n               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);\n    }\n\n    /// @brief generate SAX events\n    /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/\n    template<class IteratorType, class SAX>\n    JSON_HEDLEY_NON_NULL(3)\n    static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,\n                          input_format_t format = input_format_t::json,\n                          const bool strict = true,\n                          const bool ignore_comments = false)\n    {\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        return format == input_format_t::json\n               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)\n               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);\n    }\n\n    /// @brief generate SAX events\n    /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/\n    /// @deprecated This function is deprecated since 3.8.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use\n    ///             sax_parse(ptr, ptr + len) instead.\n    template <typename SAX>\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))\n    JSON_HEDLEY_NON_NULL(2)\n    static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,\n                          input_format_t format = input_format_t::json,\n                          const bool strict = true,\n                          const bool ignore_comments = false)\n    {\n        auto ia = i.get();\n        return format == input_format_t::json\n               // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)\n               // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);\n    }\n#ifndef JSON_NO_IO\n    /// @brief deserialize from stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/\n    /// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use\n    ///             operator>>(std::istream&, basic_json&) instead; that is,\n    ///             replace calls like `j << i;` with `i >> j;`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))\n    friend std::istream& operator<<(basic_json& j, std::istream& i)\n    {\n        return operator>>(i, j);\n    }\n\n    /// @brief deserialize from stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/\n    friend std::istream& operator>>(std::istream& i, basic_json& j)\n    {\n        parser(detail::input_adapter(i)).parse(false, j);\n        return i;\n    }\n#endif  // JSON_NO_IO\n    /// @}\n\n    ///////////////////////////\n    // convenience functions //\n    ///////////////////////////\n\n    /// @brief return the type as string\n    /// @sa https://json.nlohmann.me/api/basic_json/type_name/\n    JSON_HEDLEY_RETURNS_NON_NULL\n    const char* type_name() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::null:\n                return \"null\";\n            case value_t::object:\n                return \"object\";\n            case value_t::array:\n                return \"array\";\n            case value_t::string:\n                return \"string\";\n            case value_t::boolean:\n                return \"boolean\";\n            case value_t::binary:\n                return \"binary\";\n            case value_t::discarded:\n                return \"discarded\";\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            default:\n                return \"number\";\n        }\n    }\n\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    //////////////////////\n    // member variables //\n    //////////////////////\n\n    /// the type of the current element\n    value_t m_type = value_t::null;\n\n    /// the value of the current element\n    json_value m_value = {};\n\n#if JSON_DIAGNOSTICS\n    /// a pointer to a parent value (for debugging purposes)\n    basic_json* m_parent = nullptr;\n#endif\n\n    //////////////////////////////////////////\n    // binary serialization/deserialization //\n    //////////////////////////////////////////\n\n    /// @name binary serialization/deserialization support\n    /// @{\n\n  public:\n    /// @brief create a CBOR serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/\n    static std::vector<std::uint8_t> to_cbor(const basic_json& j)\n    {\n        std::vector<std::uint8_t> result;\n        to_cbor(j, result);\n        return result;\n    }\n\n    /// @brief create a CBOR serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/\n    static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)\n    {\n        binary_writer<std::uint8_t>(o).write_cbor(j);\n    }\n\n    /// @brief create a CBOR serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/\n    static void to_cbor(const basic_json& j, detail::output_adapter<char> o)\n    {\n        binary_writer<char>(o).write_cbor(j);\n    }\n\n    /// @brief create a MessagePack serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/\n    static std::vector<std::uint8_t> to_msgpack(const basic_json& j)\n    {\n        std::vector<std::uint8_t> result;\n        to_msgpack(j, result);\n        return result;\n    }\n\n    /// @brief create a MessagePack serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/\n    static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)\n    {\n        binary_writer<std::uint8_t>(o).write_msgpack(j);\n    }\n\n    /// @brief create a MessagePack serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/\n    static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)\n    {\n        binary_writer<char>(o).write_msgpack(j);\n    }\n\n    /// @brief create a UBJSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/\n    static std::vector<std::uint8_t> to_ubjson(const basic_json& j,\n            const bool use_size = false,\n            const bool use_type = false)\n    {\n        std::vector<std::uint8_t> result;\n        to_ubjson(j, result, use_size, use_type);\n        return result;\n    }\n\n    /// @brief create a UBJSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/\n    static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                          const bool use_size = false, const bool use_type = false)\n    {\n        binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);\n    }\n\n    /// @brief create a UBJSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/\n    static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,\n                          const bool use_size = false, const bool use_type = false)\n    {\n        binary_writer<char>(o).write_ubjson(j, use_size, use_type);\n    }\n\n    /// @brief create a BSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_bson/\n    static std::vector<std::uint8_t> to_bson(const basic_json& j)\n    {\n        std::vector<std::uint8_t> result;\n        to_bson(j, result);\n        return result;\n    }\n\n    /// @brief create a BSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_bson/\n    static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)\n    {\n        binary_writer<std::uint8_t>(o).write_bson(j);\n    }\n\n    /// @brief create a BSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_bson/\n    static void to_bson(const basic_json& j, detail::output_adapter<char> o)\n    {\n        binary_writer<char>(o).write_bson(j);\n    }\n\n    /// @brief create a JSON value from an input in CBOR format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_cbor(InputType&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in CBOR format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_cbor(IteratorType first, IteratorType last,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))\n    static basic_json from_cbor(const T* ptr, std::size_t len,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);\n    }\n\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))\n    static basic_json from_cbor(detail::span_input_adapter&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in MessagePack format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_msgpack(InputType&& i,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in MessagePack format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_msgpack(IteratorType first, IteratorType last,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))\n    static basic_json from_msgpack(const T* ptr, std::size_t len,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        return from_msgpack(ptr, ptr + len, strict, allow_exceptions);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))\n    static basic_json from_msgpack(detail::span_input_adapter&& i,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in UBJSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_ubjson(InputType&& i,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in UBJSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_ubjson(IteratorType first, IteratorType last,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))\n    static basic_json from_ubjson(const T* ptr, std::size_t len,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        return from_ubjson(ptr, ptr + len, strict, allow_exceptions);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))\n    static basic_json from_ubjson(detail::span_input_adapter&& i,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in BSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_bson/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_bson(InputType&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in BSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_bson/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_bson(IteratorType first, IteratorType last,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))\n    static basic_json from_bson(const T* ptr, std::size_t len,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        return from_bson(ptr, ptr + len, strict, allow_exceptions);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))\n    static basic_json from_bson(detail::span_input_adapter&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n    /// @}\n\n    //////////////////////////\n    // JSON Pointer support //\n    //////////////////////////\n\n    /// @name JSON Pointer functions\n    /// @{\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    reference operator[](const json_pointer& ptr)\n    {\n        return ptr.get_unchecked(this);\n    }\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    const_reference operator[](const json_pointer& ptr) const\n    {\n        return ptr.get_unchecked(this);\n    }\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    reference at(const json_pointer& ptr)\n    {\n        return ptr.get_checked(this);\n    }\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    const_reference at(const json_pointer& ptr) const\n    {\n        return ptr.get_checked(this);\n    }\n\n    /// @brief return flattened JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/flatten/\n    basic_json flatten() const\n    {\n        basic_json result(value_t::object);\n        json_pointer::flatten(\"\", *this, result);\n        return result;\n    }\n\n    /// @brief unflatten a previously flattened JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/unflatten/\n    basic_json unflatten() const\n    {\n        return json_pointer::unflatten(*this);\n    }\n\n    /// @}\n\n    //////////////////////////\n    // JSON Patch functions //\n    //////////////////////////\n\n    /// @name JSON Patch functions\n    /// @{\n\n    /// @brief applies a JSON patch\n    /// @sa https://json.nlohmann.me/api/basic_json/patch/\n    basic_json patch(const basic_json& json_patch) const\n    {\n        // make a working copy to apply the patch to\n        basic_json result = *this;\n\n        // the valid JSON Patch operations\n        enum class patch_operations {add, remove, replace, move, copy, test, invalid};\n\n        const auto get_op = [](const std::string & op)\n        {\n            if (op == \"add\")\n            {\n                return patch_operations::add;\n            }\n            if (op == \"remove\")\n            {\n                return patch_operations::remove;\n            }\n            if (op == \"replace\")\n            {\n                return patch_operations::replace;\n            }\n            if (op == \"move\")\n            {\n                return patch_operations::move;\n            }\n            if (op == \"copy\")\n            {\n                return patch_operations::copy;\n            }\n            if (op == \"test\")\n            {\n                return patch_operations::test;\n            }\n\n            return patch_operations::invalid;\n        };\n\n        // wrapper for \"add\" operation; add value at ptr\n        const auto operation_add = [&result](json_pointer & ptr, basic_json val)\n        {\n            // adding to the root of the target document means replacing it\n            if (ptr.empty())\n            {\n                result = val;\n                return;\n            }\n\n            // make sure the top element of the pointer exists\n            json_pointer top_pointer = ptr.top();\n            if (top_pointer != ptr)\n            {\n                result.at(top_pointer);\n            }\n\n            // get reference to parent of JSON pointer ptr\n            const auto last_path = ptr.back();\n            ptr.pop_back();\n            basic_json& parent = result[ptr];\n\n            switch (parent.m_type)\n            {\n                case value_t::null:\n                case value_t::object:\n                {\n                    // use operator[] to add value\n                    parent[last_path] = val;\n                    break;\n                }\n\n                case value_t::array:\n                {\n                    if (last_path == \"-\")\n                    {\n                        // special case: append to back\n                        parent.push_back(val);\n                    }\n                    else\n                    {\n                        const auto idx = json_pointer::array_index(last_path);\n                        if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))\n                        {\n                            // avoid undefined behavior\n                            JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", parent));\n                        }\n\n                        // default case: insert add offset\n                        parent.insert(parent.begin() + static_cast<difference_type>(idx), val);\n                    }\n                    break;\n                }\n\n                // if there exists a parent it cannot be primitive\n                case value_t::string: // LCOV_EXCL_LINE\n                case value_t::boolean: // LCOV_EXCL_LINE\n                case value_t::number_integer: // LCOV_EXCL_LINE\n                case value_t::number_unsigned: // LCOV_EXCL_LINE\n                case value_t::number_float: // LCOV_EXCL_LINE\n                case value_t::binary: // LCOV_EXCL_LINE\n                case value_t::discarded: // LCOV_EXCL_LINE\n                default:            // LCOV_EXCL_LINE\n                    JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n            }\n        };\n\n        // wrapper for \"remove\" operation; remove value at ptr\n        const auto operation_remove = [this, &result](json_pointer & ptr)\n        {\n            // get reference to parent of JSON pointer ptr\n            const auto last_path = ptr.back();\n            ptr.pop_back();\n            basic_json& parent = result.at(ptr);\n\n            // remove child\n            if (parent.is_object())\n            {\n                // perform range check\n                auto it = parent.find(last_path);\n                if (JSON_HEDLEY_LIKELY(it != parent.end()))\n                {\n                    parent.erase(it);\n                }\n                else\n                {\n                    JSON_THROW(out_of_range::create(403, \"key '\" + last_path + \"' not found\", *this));\n                }\n            }\n            else if (parent.is_array())\n            {\n                // note erase performs range check\n                parent.erase(json_pointer::array_index(last_path));\n            }\n        };\n\n        // type check: top level value must be an array\n        if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))\n        {\n            JSON_THROW(parse_error::create(104, 0, \"JSON patch must be an array of objects\", json_patch));\n        }\n\n        // iterate and apply the operations\n        for (const auto& val : json_patch)\n        {\n            // wrapper to get a value for an operation\n            const auto get_value = [&val](const std::string & op,\n                                          const std::string & member,\n                                          bool string_type) -> basic_json &\n            {\n                // find value\n                auto it = val.m_value.object->find(member);\n\n                // context-sensitive error message\n                const auto error_msg = (op == \"op\") ? \"operation\" : \"operation '\" + op + \"'\";\n\n                // check if desired value is present\n                if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))\n                {\n                    // NOLINTNEXTLINE(performance-inefficient-string-concatenation)\n                    JSON_THROW(parse_error::create(105, 0, error_msg + \" must have member '\" + member + \"'\", val));\n                }\n\n                // check if result is of type string\n                if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))\n                {\n                    // NOLINTNEXTLINE(performance-inefficient-string-concatenation)\n                    JSON_THROW(parse_error::create(105, 0, error_msg + \" must have string member '\" + member + \"'\", val));\n                }\n\n                // no error: return value\n                return it->second;\n            };\n\n            // type check: every element of the array must be an object\n            if (JSON_HEDLEY_UNLIKELY(!val.is_object()))\n            {\n                JSON_THROW(parse_error::create(104, 0, \"JSON patch must be an array of objects\", val));\n            }\n\n            // collect mandatory members\n            const auto op = get_value(\"op\", \"op\", true).template get<std::string>();\n            const auto path = get_value(op, \"path\", true).template get<std::string>();\n            json_pointer ptr(path);\n\n            switch (get_op(op))\n            {\n                case patch_operations::add:\n                {\n                    operation_add(ptr, get_value(\"add\", \"value\", false));\n                    break;\n                }\n\n                case patch_operations::remove:\n                {\n                    operation_remove(ptr);\n                    break;\n                }\n\n                case patch_operations::replace:\n                {\n                    // the \"path\" location must exist - use at()\n                    result.at(ptr) = get_value(\"replace\", \"value\", false);\n                    break;\n                }\n\n                case patch_operations::move:\n                {\n                    const auto from_path = get_value(\"move\", \"from\", true).template get<std::string>();\n                    json_pointer from_ptr(from_path);\n\n                    // the \"from\" location must exist - use at()\n                    basic_json v = result.at(from_ptr);\n\n                    // The move operation is functionally identical to a\n                    // \"remove\" operation on the \"from\" location, followed\n                    // immediately by an \"add\" operation at the target\n                    // location with the value that was just removed.\n                    operation_remove(from_ptr);\n                    operation_add(ptr, v);\n                    break;\n                }\n\n                case patch_operations::copy:\n                {\n                    const auto from_path = get_value(\"copy\", \"from\", true).template get<std::string>();\n                    const json_pointer from_ptr(from_path);\n\n                    // the \"from\" location must exist - use at()\n                    basic_json v = result.at(from_ptr);\n\n                    // The copy is functionally identical to an \"add\"\n                    // operation at the target location using the value\n                    // specified in the \"from\" member.\n                    operation_add(ptr, v);\n                    break;\n                }\n\n                case patch_operations::test:\n                {\n                    bool success = false;\n                    JSON_TRY\n                    {\n                        // check if \"value\" matches the one at \"path\"\n                        // the \"path\" location must exist - use at()\n                        success = (result.at(ptr) == get_value(\"test\", \"value\", false));\n                    }\n                    JSON_INTERNAL_CATCH (out_of_range&)\n                    {\n                        // ignore out of range errors: success remains false\n                    }\n\n                    // throw an exception if test fails\n                    if (JSON_HEDLEY_UNLIKELY(!success))\n                    {\n                        JSON_THROW(other_error::create(501, \"unsuccessful: \" + val.dump(), val));\n                    }\n\n                    break;\n                }\n\n                case patch_operations::invalid:\n                default:\n                {\n                    // op must be \"add\", \"remove\", \"replace\", \"move\", \"copy\", or\n                    // \"test\"\n                    JSON_THROW(parse_error::create(105, 0, \"operation value '\" + op + \"' is invalid\", val));\n                }\n            }\n        }\n\n        return result;\n    }\n\n    /// @brief creates a diff as a JSON patch\n    /// @sa https://json.nlohmann.me/api/basic_json/diff/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json diff(const basic_json& source, const basic_json& target,\n                           const std::string& path = \"\")\n    {\n        // the patch\n        basic_json result(value_t::array);\n\n        // if the values are the same, return empty patch\n        if (source == target)\n        {\n            return result;\n        }\n\n        if (source.type() != target.type())\n        {\n            // different types: replace value\n            result.push_back(\n            {\n                {\"op\", \"replace\"}, {\"path\", path}, {\"value\", target}\n            });\n            return result;\n        }\n\n        switch (source.type())\n        {\n            case value_t::array:\n            {\n                // first pass: traverse common elements\n                std::size_t i = 0;\n                while (i < source.size() && i < target.size())\n                {\n                    // recursive call to compare array values at index i\n                    auto temp_diff = diff(source[i], target[i], path + \"/\" + std::to_string(i));\n                    result.insert(result.end(), temp_diff.begin(), temp_diff.end());\n                    ++i;\n                }\n\n                // We now reached the end of at least one array\n                // in a second pass, traverse the remaining elements\n\n                // remove my remaining elements\n                const auto end_index = static_cast<difference_type>(result.size());\n                while (i < source.size())\n                {\n                    // add operations in reverse order to avoid invalid\n                    // indices\n                    result.insert(result.begin() + end_index, object(\n                    {\n                        {\"op\", \"remove\"},\n                        {\"path\", path + \"/\" + std::to_string(i)}\n                    }));\n                    ++i;\n                }\n\n                // add other remaining elements\n                while (i < target.size())\n                {\n                    result.push_back(\n                    {\n                        {\"op\", \"add\"},\n                        {\"path\", path + \"/-\"},\n                        {\"value\", target[i]}\n                    });\n                    ++i;\n                }\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                // first pass: traverse this object's elements\n                for (auto it = source.cbegin(); it != source.cend(); ++it)\n                {\n                    // escape the key name to be used in a JSON patch\n                    const auto path_key = path + \"/\" + detail::escape(it.key());\n\n                    if (target.find(it.key()) != target.end())\n                    {\n                        // recursive call to compare object values at key it\n                        auto temp_diff = diff(it.value(), target[it.key()], path_key);\n                        result.insert(result.end(), temp_diff.begin(), temp_diff.end());\n                    }\n                    else\n                    {\n                        // found a key that is not in o -> remove it\n                        result.push_back(object(\n                        {\n                            {\"op\", \"remove\"}, {\"path\", path_key}\n                        }));\n                    }\n                }\n\n                // second pass: traverse other object's elements\n                for (auto it = target.cbegin(); it != target.cend(); ++it)\n                {\n                    if (source.find(it.key()) == source.end())\n                    {\n                        // found a key that is not in this -> add it\n                        const auto path_key = path + \"/\" + detail::escape(it.key());\n                        result.push_back(\n                        {\n                            {\"op\", \"add\"}, {\"path\", path_key},\n                            {\"value\", it.value()}\n                        });\n                    }\n                }\n\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // both primitive type: replace value\n                result.push_back(\n                {\n                    {\"op\", \"replace\"}, {\"path\", path}, {\"value\", target}\n                });\n                break;\n            }\n        }\n\n        return result;\n    }\n\n    /// @}\n\n    ////////////////////////////////\n    // JSON Merge Patch functions //\n    ////////////////////////////////\n\n    /// @name JSON Merge Patch functions\n    /// @{\n\n    /// @brief applies a JSON Merge Patch\n    /// @sa https://json.nlohmann.me/api/basic_json/merge_patch/\n    void merge_patch(const basic_json& apply_patch)\n    {\n        if (apply_patch.is_object())\n        {\n            if (!is_object())\n            {\n                *this = object();\n            }\n            for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)\n            {\n                if (it.value().is_null())\n                {\n                    erase(it.key());\n                }\n                else\n                {\n                    operator[](it.key()).merge_patch(it.value());\n                }\n            }\n        }\n        else\n        {\n            *this = apply_patch;\n        }\n    }\n\n    /// @}\n};\n\n/// @brief user-defined to_string function for JSON values\n/// @sa https://json.nlohmann.me/api/basic_json/to_string/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nstd::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)\n{\n    return j.dump();\n}\n\n} // namespace nlohmann\n\n///////////////////////\n// nonmember support //\n///////////////////////\n\nnamespace std // NOLINT(cert-dcl58-cpp)\n{\n\n/// @brief hash value for JSON objects\n/// @sa https://json.nlohmann.me/api/basic_json/std_hash/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nstruct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>\n{\n    std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const\n    {\n        return nlohmann::detail::hash(j);\n    }\n};\n\n// specialization for std::less<value_t>\ntemplate<>\nstruct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679\n{\n    /*!\n    @brief compare two value_t enum values\n    @since version 3.0.0\n    */\n    bool operator()(nlohmann::detail::value_t lhs,\n                    nlohmann::detail::value_t rhs) const noexcept\n    {\n        return nlohmann::detail::operator<(lhs, rhs);\n    }\n};\n\n// C++20 prohibit function specialization in the std namespace.\n#ifndef JSON_HAS_CPP_20\n\n/// @brief exchanges the values of two JSON objects\n/// @sa https://json.nlohmann.me/api/basic_json/std_swap/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\ninline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept(  // NOLINT(readability-inconsistent-declaration-parameter-name)\n    is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&&                          // NOLINT(misc-redundant-expression)\n    is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)\n{\n    j1.swap(j2);\n}\n\n#endif\n\n} // namespace std\n\n/// @brief user-defined string literal for JSON values\n/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/\nJSON_HEDLEY_NON_NULL(1)\ninline nlohmann::json operator \"\" _json(const char* s, std::size_t n)\n{\n    return nlohmann::json::parse(s, s + n);\n}\n\n/// @brief user-defined string literal for JSON pointer\n/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/\nJSON_HEDLEY_NON_NULL(1)\ninline nlohmann::json::json_pointer operator \"\" _json_pointer(const char* s, std::size_t n)\n{\n    return nlohmann::json::json_pointer(std::string(s, n));\n}\n\n#include <nlohmann/detail/macro_unscope.hpp>\n\n#endif  // INCLUDE_NLOHMANN_JSON_HPP_\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/json_fwd.hpp",
    "content": "#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_\n#define INCLUDE_NLOHMANN_JSON_FWD_HPP_\n\n#include <cstdint> // int64_t, uint64_t\n#include <map> // map\n#include <memory> // allocator\n#include <string> // string\n#include <vector> // vector\n\n/*!\n@brief namespace for Niels Lohmann\n@see https://github.com/nlohmann\n@since version 1.0.0\n*/\nnamespace nlohmann\n{\n/*!\n@brief default JSONSerializer template argument\n\nThis serializer ignores the template arguments and uses ADL\n([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))\nfor serialization.\n*/\ntemplate<typename T = void, typename SFINAE = void>\nstruct adl_serializer;\n\n/// a class to store JSON values\n/// @sa https://json.nlohmann.me/api/basic_json/\ntemplate<template<typename U, typename V, typename... Args> class ObjectType =\n         std::map,\n         template<typename U, typename... Args> class ArrayType = std::vector,\n         class StringType = std::string, class BooleanType = bool,\n         class NumberIntegerType = std::int64_t,\n         class NumberUnsignedType = std::uint64_t,\n         class NumberFloatType = double,\n         template<typename U> class AllocatorType = std::allocator,\n         template<typename T, typename SFINAE = void> class JSONSerializer =\n         adl_serializer,\n         class BinaryType = std::vector<std::uint8_t>>\nclass basic_json;\n\n/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document\n/// @sa https://json.nlohmann.me/api/json_pointer/\ntemplate<typename BasicJsonType>\nclass json_pointer;\n\n/*!\n@brief default specialization\n@sa https://json.nlohmann.me/api/json/\n*/\nusing json = basic_json<>;\n\n/// @brief a minimal map-like container that preserves insertion order\n/// @sa https://json.nlohmann.me/api/ordered_map/\ntemplate<class Key, class T, class IgnoredLess, class Allocator>\nstruct ordered_map;\n\n/// @brief specialization that maintains the insertion order of object keys\n/// @sa https://json.nlohmann.me/api/ordered_json/\nusing ordered_json = basic_json<nlohmann::ordered_map>;\n\n}  // namespace nlohmann\n\n#endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/ordered_map.hpp",
    "content": "#pragma once\n\n#include <functional> // less\n#include <initializer_list> // initializer_list\n#include <iterator> // input_iterator_tag, iterator_traits\n#include <memory> // allocator\n#include <stdexcept> // for out_of_range\n#include <type_traits> // enable_if, is_convertible\n#include <utility> // pair\n#include <vector> // vector\n\n#include <nlohmann/detail/macro_scope.hpp>\n\nnamespace nlohmann\n{\n\n/// ordered_map: a minimal map-like container that preserves insertion order\n/// for use within nlohmann::basic_json<ordered_map>\ntemplate <class Key, class T, class IgnoredLess = std::less<Key>,\n          class Allocator = std::allocator<std::pair<const Key, T>>>\n                  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>\n{\n    using key_type = Key;\n    using mapped_type = T;\n    using Container = std::vector<std::pair<const Key, T>, Allocator>;\n    using iterator = typename Container::iterator;\n    using const_iterator = typename Container::const_iterator;\n    using size_type = typename Container::size_type;\n    using value_type = typename Container::value_type;\n\n    // Explicit constructors instead of `using Container::Container`\n    // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)\n    ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}\n    template <class It>\n    ordered_map(It first, It last, const Allocator& alloc = Allocator())\n        : Container{first, last, alloc} {}\n    ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )\n        : Container{init, alloc} {}\n\n    std::pair<iterator, bool> emplace(const key_type& key, T&& t)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return {it, false};\n            }\n        }\n        Container::emplace_back(key, t);\n        return {--this->end(), true};\n    }\n\n    T& operator[](const Key& key)\n    {\n        return emplace(key, T{}).first->second;\n    }\n\n    const T& operator[](const Key& key) const\n    {\n        return at(key);\n    }\n\n    T& at(const Key& key)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it->second;\n            }\n        }\n\n        JSON_THROW(std::out_of_range(\"key not found\"));\n    }\n\n    const T& at(const Key& key) const\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it->second;\n            }\n        }\n\n        JSON_THROW(std::out_of_range(\"key not found\"));\n    }\n\n    size_type erase(const Key& key)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                // Since we cannot move const Keys, re-construct them in place\n                for (auto next = it; ++next != this->end(); ++it)\n                {\n                    it->~value_type(); // Destroy but keep allocation\n                    new (&*it) value_type{std::move(*next)};\n                }\n                Container::pop_back();\n                return 1;\n            }\n        }\n        return 0;\n    }\n\n    iterator erase(iterator pos)\n    {\n        return erase(pos, std::next(pos));\n    }\n\n    iterator erase(iterator first, iterator last)\n    {\n        const auto elements_affected = std::distance(first, last);\n        const auto offset = std::distance(Container::begin(), first);\n\n        // This is the start situation. We need to delete elements_affected\n        // elements (3 in this example: e, f, g), and need to return an\n        // iterator past the last deleted element (h in this example).\n        // Note that offset is the distance from the start of the vector\n        // to first. We will need this later.\n\n        // [ a, b, c, d, e, f, g, h, i, j ]\n        //               ^        ^\n        //             first    last\n\n        // Since we cannot move const Keys, we re-construct them in place.\n        // We start at first and re-construct (viz. copy) the elements from\n        // the back of the vector. Example for first iteration:\n\n        //               ,--------.\n        //               v        |   destroy e and re-construct with h\n        // [ a, b, c, d, e, f, g, h, i, j ]\n        //               ^        ^\n        //               it       it + elements_affected\n\n        for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)\n        {\n            it->~value_type(); // destroy but keep allocation\n            new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // \"move\" next element to it\n        }\n\n        // [ a, b, c, d, h, i, j, h, i, j ]\n        //               ^        ^\n        //             first    last\n\n        // remove the unneeded elements at the end of the vector\n        Container::resize(this->size() - static_cast<size_type>(elements_affected));\n\n        // [ a, b, c, d, h, i, j ]\n        //               ^        ^\n        //             first    last\n\n        // first is now pointing past the last deleted element, but we cannot\n        // use this iterator, because it may have been invalidated by the\n        // resize call. Instead, we can return begin() + offset.\n        return Container::begin() + offset;\n    }\n\n    size_type count(const Key& key) const\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return 1;\n            }\n        }\n        return 0;\n    }\n\n    iterator find(const Key& key)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it;\n            }\n        }\n        return Container::end();\n    }\n\n    const_iterator find(const Key& key) const\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it;\n            }\n        }\n        return Container::end();\n    }\n\n    std::pair<iterator, bool> insert( value_type&& value )\n    {\n        return emplace(value.first, std::move(value.second));\n    }\n\n    std::pair<iterator, bool> insert( const value_type& value )\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == value.first)\n            {\n                return {it, false};\n            }\n        }\n        Container::push_back(value);\n        return {--this->end(), true};\n    }\n\n    template<typename InputIt>\n    using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,\n            std::input_iterator_tag>::value>::type;\n\n    template<typename InputIt, typename = require_input_iter<InputIt>>\n    void insert(InputIt first, InputIt last)\n    {\n        for (auto it = first; it != last; ++it)\n        {\n            insert(*it);\n        }\n    }\n};\n\n}  // namespace nlohmann\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/thirdparty/hedley/hedley.hpp",
    "content": "#pragma once\n\n/* Hedley - https://nemequ.github.io/hedley\n * Created by Evan Nemerson <evan@nemerson.com>\n *\n * To the extent possible under law, the author(s) have dedicated all\n * copyright and related and neighboring rights to this software to\n * the public domain worldwide. This software is distributed without\n * any warranty.\n *\n * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.\n * SPDX-License-Identifier: CC0-1.0\n */\n\n#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)\n#if defined(JSON_HEDLEY_VERSION)\n    #undef JSON_HEDLEY_VERSION\n#endif\n#define JSON_HEDLEY_VERSION 15\n\n#if defined(JSON_HEDLEY_STRINGIFY_EX)\n    #undef JSON_HEDLEY_STRINGIFY_EX\n#endif\n#define JSON_HEDLEY_STRINGIFY_EX(x) #x\n\n#if defined(JSON_HEDLEY_STRINGIFY)\n    #undef JSON_HEDLEY_STRINGIFY\n#endif\n#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)\n\n#if defined(JSON_HEDLEY_CONCAT_EX)\n    #undef JSON_HEDLEY_CONCAT_EX\n#endif\n#define JSON_HEDLEY_CONCAT_EX(a,b) a##b\n\n#if defined(JSON_HEDLEY_CONCAT)\n    #undef JSON_HEDLEY_CONCAT\n#endif\n#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)\n\n#if defined(JSON_HEDLEY_CONCAT3_EX)\n    #undef JSON_HEDLEY_CONCAT3_EX\n#endif\n#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c\n\n#if defined(JSON_HEDLEY_CONCAT3)\n    #undef JSON_HEDLEY_CONCAT3\n#endif\n#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)\n\n#if defined(JSON_HEDLEY_VERSION_ENCODE)\n    #undef JSON_HEDLEY_VERSION_ENCODE\n#endif\n#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))\n\n#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)\n    #undef JSON_HEDLEY_VERSION_DECODE_MAJOR\n#endif\n#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)\n\n#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)\n    #undef JSON_HEDLEY_VERSION_DECODE_MINOR\n#endif\n#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)\n\n#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)\n    #undef JSON_HEDLEY_VERSION_DECODE_REVISION\n#endif\n#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)\n\n#if defined(JSON_HEDLEY_GNUC_VERSION)\n    #undef JSON_HEDLEY_GNUC_VERSION\n#endif\n#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)\n    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)\n#elif defined(__GNUC__)\n    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)\n    #undef JSON_HEDLEY_GNUC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_GNUC_VERSION)\n    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_MSVC_VERSION)\n    #undef JSON_HEDLEY_MSVC_VERSION\n#endif\n#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)\n    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)\n#elif defined(_MSC_FULL_VER) && !defined(__ICL)\n    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)\n#elif defined(_MSC_VER) && !defined(__ICL)\n    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)\n#endif\n\n#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)\n    #undef JSON_HEDLEY_MSVC_VERSION_CHECK\n#endif\n#if !defined(JSON_HEDLEY_MSVC_VERSION)\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)\n#elif defined(_MSC_VER) && (_MSC_VER >= 1400)\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))\n#elif defined(_MSC_VER) && (_MSC_VER >= 1200)\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))\n#else\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_VERSION)\n    #undef JSON_HEDLEY_INTEL_VERSION\n#endif\n#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)\n    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)\n#elif defined(__INTEL_COMPILER) && !defined(__ICL)\n    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)\n    #undef JSON_HEDLEY_INTEL_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_INTEL_VERSION)\n    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_CL_VERSION)\n    #undef JSON_HEDLEY_INTEL_CL_VERSION\n#endif\n#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)\n    #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)\n    #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_INTEL_CL_VERSION)\n    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_PGI_VERSION)\n    #undef JSON_HEDLEY_PGI_VERSION\n#endif\n#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)\n    #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)\n#endif\n\n#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)\n    #undef JSON_HEDLEY_PGI_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_PGI_VERSION)\n    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_SUNPRO_VERSION)\n    #undef JSON_HEDLEY_SUNPRO_VERSION\n#endif\n#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)\n#elif defined(__SUNPRO_C)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)\n#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)\n#elif defined(__SUNPRO_CC)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)\n#endif\n\n#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)\n    #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_SUNPRO_VERSION)\n    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)\n    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION\n#endif\n#if defined(__EMSCRIPTEN__)\n    #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)\n#endif\n\n#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)\n    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)\n    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_ARM_VERSION)\n    #undef JSON_HEDLEY_ARM_VERSION\n#endif\n#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)\n    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)\n#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)\n    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)\n#endif\n\n#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)\n    #undef JSON_HEDLEY_ARM_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_ARM_VERSION)\n    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_IBM_VERSION)\n    #undef JSON_HEDLEY_IBM_VERSION\n#endif\n#if defined(__ibmxl__)\n    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)\n#elif defined(__xlC__) && defined(__xlC_ver__)\n    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)\n#elif defined(__xlC__)\n    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)\n#endif\n\n#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)\n    #undef JSON_HEDLEY_IBM_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_IBM_VERSION)\n    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_VERSION)\n    #undef JSON_HEDLEY_TI_VERSION\n#endif\n#if \\\n    defined(__TI_COMPILER_VERSION__) && \\\n    ( \\\n      defined(__TMS470__) || defined(__TI_ARM__) || \\\n      defined(__MSP430__) || \\\n      defined(__TMS320C2000__) \\\n    )\n#if (__TI_COMPILER_VERSION__ >= 16000000)\n    #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n#endif\n\n#if defined(JSON_HEDLEY_TI_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_VERSION)\n    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL2000_VERSION)\n    #undef JSON_HEDLEY_TI_CL2000_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)\n    #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL2000_VERSION)\n    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL430_VERSION)\n    #undef JSON_HEDLEY_TI_CL430_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)\n    #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL430_VERSION)\n    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)\n    #undef JSON_HEDLEY_TI_ARMCL_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))\n    #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)\n    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL6X_VERSION)\n    #undef JSON_HEDLEY_TI_CL6X_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)\n    #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL6X_VERSION)\n    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL7X_VERSION)\n    #undef JSON_HEDLEY_TI_CL7X_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)\n    #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL7X_VERSION)\n    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)\n    #undef JSON_HEDLEY_TI_CLPRU_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)\n    #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)\n    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_CRAY_VERSION)\n    #undef JSON_HEDLEY_CRAY_VERSION\n#endif\n#if defined(_CRAYC)\n    #if defined(_RELEASE_PATCHLEVEL)\n        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)\n    #else\n        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)\n    #endif\n#endif\n\n#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)\n    #undef JSON_HEDLEY_CRAY_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_CRAY_VERSION)\n    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_IAR_VERSION)\n    #undef JSON_HEDLEY_IAR_VERSION\n#endif\n#if defined(__IAR_SYSTEMS_ICC__)\n    #if __VER__ > 1000\n        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))\n    #else\n        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)\n    #endif\n#endif\n\n#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)\n    #undef JSON_HEDLEY_IAR_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_IAR_VERSION)\n    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TINYC_VERSION)\n    #undef JSON_HEDLEY_TINYC_VERSION\n#endif\n#if defined(__TINYC__)\n    #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)\n#endif\n\n#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)\n    #undef JSON_HEDLEY_TINYC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TINYC_VERSION)\n    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_DMC_VERSION)\n    #undef JSON_HEDLEY_DMC_VERSION\n#endif\n#if defined(__DMC__)\n    #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)\n#endif\n\n#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)\n    #undef JSON_HEDLEY_DMC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_DMC_VERSION)\n    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_COMPCERT_VERSION)\n    #undef JSON_HEDLEY_COMPCERT_VERSION\n#endif\n#if defined(__COMPCERT_VERSION__)\n    #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)\n#endif\n\n#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)\n    #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_COMPCERT_VERSION)\n    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_PELLES_VERSION)\n    #undef JSON_HEDLEY_PELLES_VERSION\n#endif\n#if defined(__POCC__)\n    #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)\n#endif\n\n#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)\n    #undef JSON_HEDLEY_PELLES_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_PELLES_VERSION)\n    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_MCST_LCC_VERSION)\n    #undef JSON_HEDLEY_MCST_LCC_VERSION\n#endif\n#if defined(__LCC__) && defined(__LCC_MINOR__)\n    #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)\n#endif\n\n#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)\n    #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_MCST_LCC_VERSION)\n    #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_VERSION)\n    #undef JSON_HEDLEY_GCC_VERSION\n#endif\n#if \\\n    defined(JSON_HEDLEY_GNUC_VERSION) && \\\n    !defined(__clang__) && \\\n    !defined(JSON_HEDLEY_INTEL_VERSION) && \\\n    !defined(JSON_HEDLEY_PGI_VERSION) && \\\n    !defined(JSON_HEDLEY_ARM_VERSION) && \\\n    !defined(JSON_HEDLEY_CRAY_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL430_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \\\n    !defined(__COMPCERT__) && \\\n    !defined(JSON_HEDLEY_MCST_LCC_VERSION)\n    #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION\n#endif\n\n#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)\n    #undef JSON_HEDLEY_GCC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_GCC_VERSION)\n    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_HAS_ATTRIBUTE\n#endif\n#if \\\n  defined(__has_attribute) && \\\n  ( \\\n    (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \\\n  )\n#  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)\n#else\n#  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE\n#endif\n#if defined(__has_attribute)\n    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE\n#endif\n#if defined(__has_attribute)\n    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)\n#else\n    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE\n#endif\n#if \\\n    defined(__has_cpp_attribute) && \\\n    defined(__cplusplus) && \\\n    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)\n#else\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)\n    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS\n#endif\n#if !defined(__cplusplus) || !defined(__has_cpp_attribute)\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)\n#elif \\\n    !defined(JSON_HEDLEY_PGI_VERSION) && \\\n    !defined(JSON_HEDLEY_IAR_VERSION) && \\\n    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \\\n    (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)\n#else\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE\n#endif\n#if defined(__has_cpp_attribute) && defined(__cplusplus)\n    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE\n#endif\n#if defined(__has_cpp_attribute) && defined(__cplusplus)\n    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_BUILTIN)\n    #undef JSON_HEDLEY_HAS_BUILTIN\n#endif\n#if defined(__has_builtin)\n    #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)\n#else\n    #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)\n    #undef JSON_HEDLEY_GNUC_HAS_BUILTIN\n#endif\n#if defined(__has_builtin)\n    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)\n    #undef JSON_HEDLEY_GCC_HAS_BUILTIN\n#endif\n#if defined(__has_builtin)\n    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)\n#else\n    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_FEATURE)\n    #undef JSON_HEDLEY_HAS_FEATURE\n#endif\n#if defined(__has_feature)\n    #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)\n#else\n    #define JSON_HEDLEY_HAS_FEATURE(feature) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)\n    #undef JSON_HEDLEY_GNUC_HAS_FEATURE\n#endif\n#if defined(__has_feature)\n    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)\n    #undef JSON_HEDLEY_GCC_HAS_FEATURE\n#endif\n#if defined(__has_feature)\n    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)\n#else\n    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_EXTENSION)\n    #undef JSON_HEDLEY_HAS_EXTENSION\n#endif\n#if defined(__has_extension)\n    #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)\n#else\n    #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)\n    #undef JSON_HEDLEY_GNUC_HAS_EXTENSION\n#endif\n#if defined(__has_extension)\n    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)\n    #undef JSON_HEDLEY_GCC_HAS_EXTENSION\n#endif\n#if defined(__has_extension)\n    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)\n#else\n    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE\n#endif\n#if defined(__has_declspec_attribute)\n    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)\n#else\n    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE\n#endif\n#if defined(__has_declspec_attribute)\n    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE\n#endif\n#if defined(__has_declspec_attribute)\n    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_WARNING)\n    #undef JSON_HEDLEY_HAS_WARNING\n#endif\n#if defined(__has_warning)\n    #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)\n#else\n    #define JSON_HEDLEY_HAS_WARNING(warning) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)\n    #undef JSON_HEDLEY_GNUC_HAS_WARNING\n#endif\n#if defined(__has_warning)\n    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_WARNING)\n    #undef JSON_HEDLEY_GCC_HAS_WARNING\n#endif\n#if defined(__has_warning)\n    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)\n#else\n    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if \\\n    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \\\n    defined(__clang__) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \\\n    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \\\n    (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))\n    #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)\n    #define JSON_HEDLEY_PRAGMA(value) __pragma(value)\n#else\n    #define JSON_HEDLEY_PRAGMA(value)\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)\n    #undef JSON_HEDLEY_DIAGNOSTIC_PUSH\n#endif\n#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)\n    #undef JSON_HEDLEY_DIAGNOSTIC_POP\n#endif\n#if defined(__clang__)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"clang diagnostic push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"clang diagnostic pop\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"warning(push)\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"warning(pop)\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"GCC diagnostic push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"GCC diagnostic pop\")\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))\n    #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))\n#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"pop\")\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"diag_push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"diag_pop\")\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"warning(push)\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"warning(pop)\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH\n    #define JSON_HEDLEY_DIAGNOSTIC_POP\n#endif\n\n/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for\n   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_\n#endif\n#if defined(__cplusplus)\n#  if JSON_HEDLEY_HAS_WARNING(\"-Wc++98-compat\")\n#    if JSON_HEDLEY_HAS_WARNING(\"-Wc++17-extensions\")\n#      if JSON_HEDLEY_HAS_WARNING(\"-Wc++1z-extensions\")\n#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++98-compat\\\"\") \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++17-extensions\\\"\") \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++1z-extensions\\\"\") \\\n    xpr \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#      else\n#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++98-compat\\\"\") \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++17-extensions\\\"\") \\\n    xpr \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#      endif\n#    else\n#      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++98-compat\\\"\") \\\n    xpr \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#    endif\n#  endif\n#endif\n#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x\n#endif\n\n#if defined(JSON_HEDLEY_CONST_CAST)\n    #undef JSON_HEDLEY_CONST_CAST\n#endif\n#if defined(__cplusplus)\n#  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))\n#elif \\\n  JSON_HEDLEY_HAS_WARNING(\"-Wcast-qual\") || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n#  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \\\n        JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n        JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \\\n        ((T) (expr)); \\\n        JSON_HEDLEY_DIAGNOSTIC_POP \\\n    }))\n#else\n#  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))\n#endif\n\n#if defined(JSON_HEDLEY_REINTERPRET_CAST)\n    #undef JSON_HEDLEY_REINTERPRET_CAST\n#endif\n#if defined(__cplusplus)\n    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))\n#else\n    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))\n#endif\n\n#if defined(JSON_HEDLEY_STATIC_CAST)\n    #undef JSON_HEDLEY_STATIC_CAST\n#endif\n#if defined(__cplusplus)\n    #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))\n#else\n    #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))\n#endif\n\n#if defined(JSON_HEDLEY_CPP_CAST)\n    #undef JSON_HEDLEY_CPP_CAST\n#endif\n#if defined(__cplusplus)\n#  if JSON_HEDLEY_HAS_WARNING(\"-Wold-style-cast\")\n#    define JSON_HEDLEY_CPP_CAST(T, expr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wold-style-cast\\\"\") \\\n    ((T) (expr)) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)\n#    define JSON_HEDLEY_CPP_CAST(T, expr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"diag_suppress=Pe137\") \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#  else\n#    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))\n#  endif\n#else\n#  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wdeprecated-declarations\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"clang diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"warning(disable:1478 1786)\")\n#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1215,1216,1444,1445\")\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1215,1444\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"GCC diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1215,1444\")\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1291,1718\")\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)\")\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"error_messages(off,symdeprecated,symdeprecated2)\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress=Pe1444,Pe1215\")\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"warn(disable:2241)\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-pragmas\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"clang diagnostic ignored \\\"-Wunknown-pragmas\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"warning(disable:161)\")\n#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 1675\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"GCC diagnostic ignored \\\"-Wunknown-pragmas\\\"\")\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 163\")\n#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 163\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress=Pe161\")\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 161\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-attributes\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"clang diagnostic ignored \\\"-Wunknown-attributes\\\"\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"GCC diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"warning(disable:1292)\")\n#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1097,1098\")\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1097\")\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"error_messages(off,attrskipunsup)\")\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1173\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress=Pe1097\")\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1097\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wcast-qual\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma(\"clang diagnostic ignored \\\"-Wcast-qual\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma(\"warning(disable:2203 2331)\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma(\"GCC diagnostic ignored \\\"-Wcast-qual\\\"\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunused-function\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma(\"clang diagnostic ignored \\\"-Wunused-function\\\"\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma(\"GCC diagnostic ignored \\\"-Wunused-function\\\"\")\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma(\"diag_suppress 3142\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION\n#endif\n\n#if defined(JSON_HEDLEY_DEPRECATED)\n    #undef JSON_HEDLEY_DEPRECATED\n#endif\n#if defined(JSON_HEDLEY_DEPRECATED_FOR)\n    #undef JSON_HEDLEY_DEPRECATED_FOR\n#endif\n#if \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated(\"Since \" # since))\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated(\"Since \" #since \"; use \" #replacement))\n#elif \\\n    (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__(\"Since \" #since)))\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__(\"Since \" #since \"; use \" #replacement)))\n#elif defined(__cplusplus) && (__cplusplus >= 201402L)\n    #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated(\"Since \" #since)]])\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated(\"Since \" #since \"; use \" #replacement)]])\n#elif \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DEPRECATED(since) _Pragma(\"deprecated\")\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma(\"deprecated\")\n#else\n    #define JSON_HEDLEY_DEPRECATED(since)\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)\n#endif\n\n#if defined(JSON_HEDLEY_UNAVAILABLE)\n    #undef JSON_HEDLEY_UNAVAILABLE\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__(\"Not available until \" #available_since)))\n#else\n    #define JSON_HEDLEY_UNAVAILABLE(available_since)\n#endif\n\n#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)\n    #undef JSON_HEDLEY_WARN_UNUSED_RESULT\n#endif\n#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)\n    #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))\n#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])\n#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])\n#elif defined(_Check_return_) /* SAL */\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_\n#else\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)\n#endif\n\n#if defined(JSON_HEDLEY_SENTINEL)\n    #undef JSON_HEDLEY_SENTINEL\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))\n#else\n    #define JSON_HEDLEY_SENTINEL(position)\n#endif\n\n#if defined(JSON_HEDLEY_NO_RETURN)\n    #undef JSON_HEDLEY_NO_RETURN\n#endif\n#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_NO_RETURN __noreturn\n#elif \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))\n#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L\n    #define JSON_HEDLEY_NO_RETURN _Noreturn\n#elif defined(__cplusplus) && (__cplusplus >= 201103L)\n    #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])\n#elif \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n    #define JSON_HEDLEY_NO_RETURN _Pragma(\"does_not_return\")\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)\n#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_NO_RETURN _Pragma(\"FUNC_NEVER_RETURNS;\")\n#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)\n    #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)\n    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)\n#else\n    #define JSON_HEDLEY_NO_RETURN\n#endif\n\n#if defined(JSON_HEDLEY_NO_ESCAPE)\n    #undef JSON_HEDLEY_NO_ESCAPE\n#endif\n#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)\n    #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))\n#else\n    #define JSON_HEDLEY_NO_ESCAPE\n#endif\n\n#if defined(JSON_HEDLEY_UNREACHABLE)\n    #undef JSON_HEDLEY_UNREACHABLE\n#endif\n#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)\n    #undef JSON_HEDLEY_UNREACHABLE_RETURN\n#endif\n#if defined(JSON_HEDLEY_ASSUME)\n    #undef JSON_HEDLEY_ASSUME\n#endif\n#if \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_ASSUME(expr) __assume(expr)\n#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)\n    #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)\n#elif \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)\n    #if defined(__cplusplus)\n        #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)\n    #else\n        #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)\n    #endif\n#endif\n#if \\\n    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \\\n    JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()\n#elif defined(JSON_HEDLEY_ASSUME)\n    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)\n#endif\n#if !defined(JSON_HEDLEY_ASSUME)\n    #if defined(JSON_HEDLEY_UNREACHABLE)\n        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))\n    #else\n        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)\n    #endif\n#endif\n#if defined(JSON_HEDLEY_UNREACHABLE)\n    #if  \\\n        JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \\\n        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)\n        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))\n    #else\n        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()\n    #endif\n#else\n    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)\n#endif\n#if !defined(JSON_HEDLEY_UNREACHABLE)\n    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)\n#endif\n\nJSON_HEDLEY_DIAGNOSTIC_PUSH\n#if JSON_HEDLEY_HAS_WARNING(\"-Wpedantic\")\n    #pragma clang diagnostic ignored \"-Wpedantic\"\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wc++98-compat-pedantic\") && defined(__cplusplus)\n    #pragma clang diagnostic ignored \"-Wc++98-compat-pedantic\"\n#endif\n#if JSON_HEDLEY_GCC_HAS_WARNING(\"-Wvariadic-macros\",4,0,0)\n    #if defined(__clang__)\n        #pragma clang diagnostic ignored \"-Wvariadic-macros\"\n    #elif defined(JSON_HEDLEY_GCC_VERSION)\n        #pragma GCC diagnostic ignored \"-Wvariadic-macros\"\n    #endif\n#endif\n#if defined(JSON_HEDLEY_NON_NULL)\n    #undef JSON_HEDLEY_NON_NULL\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)\n    #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))\n#else\n    #define JSON_HEDLEY_NON_NULL(...)\n#endif\nJSON_HEDLEY_DIAGNOSTIC_POP\n\n#if defined(JSON_HEDLEY_PRINTF_FORMAT)\n    #undef JSON_HEDLEY_PRINTF_FORMAT\n#endif\n#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))\n#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))\n#elif \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(format) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))\n#else\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)\n#endif\n\n#if defined(JSON_HEDLEY_CONSTEXPR)\n    #undef JSON_HEDLEY_CONSTEXPR\n#endif\n#if defined(__cplusplus)\n    #if __cplusplus >= 201103L\n        #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)\n    #endif\n#endif\n#if !defined(JSON_HEDLEY_CONSTEXPR)\n    #define JSON_HEDLEY_CONSTEXPR\n#endif\n\n#if defined(JSON_HEDLEY_PREDICT)\n    #undef JSON_HEDLEY_PREDICT\n#endif\n#if defined(JSON_HEDLEY_LIKELY)\n    #undef JSON_HEDLEY_LIKELY\n#endif\n#if defined(JSON_HEDLEY_UNLIKELY)\n    #undef JSON_HEDLEY_UNLIKELY\n#endif\n#if defined(JSON_HEDLEY_UNPREDICTABLE)\n    #undef JSON_HEDLEY_UNPREDICTABLE\n#endif\n#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)\n    #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))\n#endif\n#if \\\n  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))\n#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))\n#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))\n#  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )\n#  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )\n#elif \\\n  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \\\n  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \\\n  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \\\n  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \\\n  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \\\n  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \\\n  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#  define JSON_HEDLEY_PREDICT(expr, expected, probability) \\\n    (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))\n#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \\\n    (__extension__ ({ \\\n        double hedley_probability_ = (probability); \\\n        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \\\n    }))\n#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \\\n    (__extension__ ({ \\\n        double hedley_probability_ = (probability); \\\n        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \\\n    }))\n#  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)\n#  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)\n#else\n#  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))\n#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))\n#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))\n#  define JSON_HEDLEY_LIKELY(expr) (!!(expr))\n#  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))\n#endif\n#if !defined(JSON_HEDLEY_UNPREDICTABLE)\n    #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)\n#endif\n\n#if defined(JSON_HEDLEY_MALLOC)\n    #undef JSON_HEDLEY_MALLOC\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n    #define JSON_HEDLEY_MALLOC _Pragma(\"returns_new_memory\")\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_MALLOC __declspec(restrict)\n#else\n    #define JSON_HEDLEY_MALLOC\n#endif\n\n#if defined(JSON_HEDLEY_PURE)\n    #undef JSON_HEDLEY_PURE\n#endif\n#if \\\n  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#  define JSON_HEDLEY_PURE __attribute__((__pure__))\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n#  define JSON_HEDLEY_PURE _Pragma(\"does_not_write_global_data\")\n#elif defined(__cplusplus) && \\\n    ( \\\n      JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \\\n      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \\\n      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \\\n    )\n#  define JSON_HEDLEY_PURE _Pragma(\"FUNC_IS_PURE;\")\n#else\n#  define JSON_HEDLEY_PURE\n#endif\n\n#if defined(JSON_HEDLEY_CONST)\n    #undef JSON_HEDLEY_CONST\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(const) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_CONST __attribute__((__const__))\n#elif \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n    #define JSON_HEDLEY_CONST _Pragma(\"no_side_effect\")\n#else\n    #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE\n#endif\n\n#if defined(JSON_HEDLEY_RESTRICT)\n    #undef JSON_HEDLEY_RESTRICT\n#endif\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)\n    #define JSON_HEDLEY_RESTRICT restrict\n#elif \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \\\n    defined(__clang__) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_RESTRICT __restrict\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)\n    #define JSON_HEDLEY_RESTRICT _Restrict\n#else\n    #define JSON_HEDLEY_RESTRICT\n#endif\n\n#if defined(JSON_HEDLEY_INLINE)\n    #undef JSON_HEDLEY_INLINE\n#endif\n#if \\\n    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \\\n    (defined(__cplusplus) && (__cplusplus >= 199711L))\n    #define JSON_HEDLEY_INLINE inline\n#elif \\\n    defined(JSON_HEDLEY_GCC_VERSION) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)\n    #define JSON_HEDLEY_INLINE __inline__\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_INLINE __inline\n#else\n    #define JSON_HEDLEY_INLINE\n#endif\n\n#if defined(JSON_HEDLEY_ALWAYS_INLINE)\n    #undef JSON_HEDLEY_ALWAYS_INLINE\n#endif\n#if \\\n  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \\\n  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n#  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE\n#elif \\\n  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \\\n  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n#  define JSON_HEDLEY_ALWAYS_INLINE __forceinline\n#elif defined(__cplusplus) && \\\n    ( \\\n      JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n      JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n      JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \\\n      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n      JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \\\n    )\n#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma(\"FUNC_ALWAYS_INLINE;\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma(\"inline=forced\")\n#else\n#  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE\n#endif\n\n#if defined(JSON_HEDLEY_NEVER_INLINE)\n    #undef JSON_HEDLEY_NEVER_INLINE\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n    #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)\n    #define JSON_HEDLEY_NEVER_INLINE _Pragma(\"noinline\")\n#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_NEVER_INLINE _Pragma(\"FUNC_CANNOT_INLINE;\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_NEVER_INLINE _Pragma(\"inline=never\")\n#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)\n    #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)\n    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)\n#else\n    #define JSON_HEDLEY_NEVER_INLINE\n#endif\n\n#if defined(JSON_HEDLEY_PRIVATE)\n    #undef JSON_HEDLEY_PRIVATE\n#endif\n#if defined(JSON_HEDLEY_PUBLIC)\n    #undef JSON_HEDLEY_PUBLIC\n#endif\n#if defined(JSON_HEDLEY_IMPORT)\n    #undef JSON_HEDLEY_IMPORT\n#endif\n#if defined(_WIN32) || defined(__CYGWIN__)\n#  define JSON_HEDLEY_PRIVATE\n#  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)\n#  define JSON_HEDLEY_IMPORT   __declspec(dllimport)\n#else\n#  if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \\\n    ( \\\n      defined(__TI_EABI__) && \\\n      ( \\\n        (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \\\n      ) \\\n    ) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__(\"hidden\")))\n#    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__(\"default\")))\n#  else\n#    define JSON_HEDLEY_PRIVATE\n#    define JSON_HEDLEY_PUBLIC\n#  endif\n#  define JSON_HEDLEY_IMPORT    extern\n#endif\n\n#if defined(JSON_HEDLEY_NO_THROW)\n    #undef JSON_HEDLEY_NO_THROW\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)\n    #define JSON_HEDLEY_NO_THROW __declspec(nothrow)\n#else\n    #define JSON_HEDLEY_NO_THROW\n#endif\n\n#if defined(JSON_HEDLEY_FALL_THROUGH)\n    #undef JSON_HEDLEY_FALL_THROUGH\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))\n#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)\n    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])\n#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)\n    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])\n#elif defined(__fallthrough) /* SAL */\n    #define JSON_HEDLEY_FALL_THROUGH __fallthrough\n#else\n    #define JSON_HEDLEY_FALL_THROUGH\n#endif\n\n#if defined(JSON_HEDLEY_RETURNS_NON_NULL)\n    #undef JSON_HEDLEY_RETURNS_NON_NULL\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))\n#elif defined(_Ret_notnull_) /* SAL */\n    #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_\n#else\n    #define JSON_HEDLEY_RETURNS_NON_NULL\n#endif\n\n#if defined(JSON_HEDLEY_ARRAY_PARAM)\n    #undef JSON_HEDLEY_ARRAY_PARAM\n#endif\n#if \\\n    defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \\\n    !defined(__STDC_NO_VLA__) && \\\n    !defined(__cplusplus) && \\\n    !defined(JSON_HEDLEY_PGI_VERSION) && \\\n    !defined(JSON_HEDLEY_TINYC_VERSION)\n    #define JSON_HEDLEY_ARRAY_PARAM(name) (name)\n#else\n    #define JSON_HEDLEY_ARRAY_PARAM(name)\n#endif\n\n#if defined(JSON_HEDLEY_IS_CONSTANT)\n    #undef JSON_HEDLEY_IS_CONSTANT\n#endif\n#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)\n    #undef JSON_HEDLEY_REQUIRE_CONSTEXPR\n#endif\n/* JSON_HEDLEY_IS_CONSTEXPR_ is for\n   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */\n#if defined(JSON_HEDLEY_IS_CONSTEXPR_)\n    #undef JSON_HEDLEY_IS_CONSTEXPR_\n#endif\n#if \\\n    JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \\\n    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \\\n    JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)\n#endif\n#if !defined(__cplusplus)\n#  if \\\n       JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \\\n       JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \\\n       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n       JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \\\n       JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \\\n       JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \\\n       JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)\n#if defined(__INTPTR_TYPE__)\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)\n#else\n    #include <stdint.h>\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)\n#endif\n#  elif \\\n       ( \\\n          defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \\\n          !defined(JSON_HEDLEY_SUNPRO_VERSION) && \\\n          !defined(JSON_HEDLEY_PGI_VERSION) && \\\n          !defined(JSON_HEDLEY_IAR_VERSION)) || \\\n       (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \\\n       JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \\\n       JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \\\n       JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \\\n       JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)\n#if defined(__INTPTR_TYPE__)\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)\n#else\n    #include <stdint.h>\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)\n#endif\n#  elif \\\n       defined(JSON_HEDLEY_GCC_VERSION) || \\\n       defined(JSON_HEDLEY_INTEL_VERSION) || \\\n       defined(JSON_HEDLEY_TINYC_VERSION) || \\\n       defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \\\n       JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \\\n       defined(JSON_HEDLEY_TI_CL2000_VERSION) || \\\n       defined(JSON_HEDLEY_TI_CL6X_VERSION) || \\\n       defined(JSON_HEDLEY_TI_CL7X_VERSION) || \\\n       defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \\\n       defined(__clang__)\n#    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \\\n        sizeof(void) != \\\n        sizeof(*( \\\n                  1 ? \\\n                  ((void*) ((expr) * 0L) ) : \\\n((struct { char v[sizeof(void) * 2]; } *) 1) \\\n                ) \\\n              ) \\\n                                            )\n#  endif\n#endif\n#if defined(JSON_HEDLEY_IS_CONSTEXPR_)\n    #if !defined(JSON_HEDLEY_IS_CONSTANT)\n        #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)\n    #endif\n    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))\n#else\n    #if !defined(JSON_HEDLEY_IS_CONSTANT)\n        #define JSON_HEDLEY_IS_CONSTANT(expr) (0)\n    #endif\n    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)\n#endif\n\n#if defined(JSON_HEDLEY_BEGIN_C_DECLS)\n    #undef JSON_HEDLEY_BEGIN_C_DECLS\n#endif\n#if defined(JSON_HEDLEY_END_C_DECLS)\n    #undef JSON_HEDLEY_END_C_DECLS\n#endif\n#if defined(JSON_HEDLEY_C_DECL)\n    #undef JSON_HEDLEY_C_DECL\n#endif\n#if defined(__cplusplus)\n    #define JSON_HEDLEY_BEGIN_C_DECLS extern \"C\" {\n    #define JSON_HEDLEY_END_C_DECLS }\n    #define JSON_HEDLEY_C_DECL extern \"C\"\n#else\n    #define JSON_HEDLEY_BEGIN_C_DECLS\n    #define JSON_HEDLEY_END_C_DECLS\n    #define JSON_HEDLEY_C_DECL\n#endif\n\n#if defined(JSON_HEDLEY_STATIC_ASSERT)\n    #undef JSON_HEDLEY_STATIC_ASSERT\n#endif\n#if \\\n  !defined(__cplusplus) && ( \\\n      (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \\\n      (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \\\n      JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \\\n      JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n      defined(_Static_assert) \\\n    )\n#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)\n#elif \\\n  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \\\n  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \\\n  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))\n#else\n#  define JSON_HEDLEY_STATIC_ASSERT(expr, message)\n#endif\n\n#if defined(JSON_HEDLEY_NULL)\n    #undef JSON_HEDLEY_NULL\n#endif\n#if defined(__cplusplus)\n    #if __cplusplus >= 201103L\n        #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)\n    #elif defined(NULL)\n        #define JSON_HEDLEY_NULL NULL\n    #else\n        #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)\n    #endif\n#elif defined(NULL)\n    #define JSON_HEDLEY_NULL NULL\n#else\n    #define JSON_HEDLEY_NULL ((void*) 0)\n#endif\n\n#if defined(JSON_HEDLEY_MESSAGE)\n    #undef JSON_HEDLEY_MESSAGE\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-pragmas\")\n#  define JSON_HEDLEY_MESSAGE(msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \\\n    JSON_HEDLEY_PRAGMA(message msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#elif \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)\n#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))\n#else\n#  define JSON_HEDLEY_MESSAGE(msg)\n#endif\n\n#if defined(JSON_HEDLEY_WARNING)\n    #undef JSON_HEDLEY_WARNING\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-pragmas\")\n#  define JSON_HEDLEY_WARNING(msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \\\n    JSON_HEDLEY_PRAGMA(clang warning msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#elif \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \\\n  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)\n#elif \\\n  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \\\n  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))\n#else\n#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)\n#endif\n\n#if defined(JSON_HEDLEY_REQUIRE)\n    #undef JSON_HEDLEY_REQUIRE\n#endif\n#if defined(JSON_HEDLEY_REQUIRE_MSG)\n    #undef JSON_HEDLEY_REQUIRE_MSG\n#endif\n#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)\n#  if JSON_HEDLEY_HAS_WARNING(\"-Wgcc-compat\")\n#    define JSON_HEDLEY_REQUIRE(expr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wgcc-compat\\\"\") \\\n    __attribute__((diagnose_if(!(expr), #expr, \"error\"))) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wgcc-compat\\\"\") \\\n    __attribute__((diagnose_if(!(expr), msg, \"error\"))) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#  else\n#    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, \"error\")))\n#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, \"error\")))\n#  endif\n#else\n#  define JSON_HEDLEY_REQUIRE(expr)\n#  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)\n#endif\n\n#if defined(JSON_HEDLEY_FLAGS)\n    #undef JSON_HEDLEY_FLAGS\n#endif\n#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING(\"-Wbitfield-enum-conversion\"))\n    #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))\n#else\n    #define JSON_HEDLEY_FLAGS\n#endif\n\n#if defined(JSON_HEDLEY_FLAGS_CAST)\n    #undef JSON_HEDLEY_FLAGS_CAST\n#endif\n#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)\n#  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \\\n        JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n        _Pragma(\"warning(disable:188)\") \\\n        ((T) (expr)); \\\n        JSON_HEDLEY_DIAGNOSTIC_POP \\\n    }))\n#else\n#  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)\n#endif\n\n#if defined(JSON_HEDLEY_EMPTY_BASES)\n    #undef JSON_HEDLEY_EMPTY_BASES\n#endif\n#if \\\n    (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)\n#else\n    #define JSON_HEDLEY_EMPTY_BASES\n#endif\n\n/* Remaining macros are deprecated. */\n\n#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)\n    #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK\n#endif\n#if defined(__clang__)\n    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)\n#else\n    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)\n    #undef JSON_HEDLEY_CLANG_HAS_BUILTIN\n#endif\n#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)\n    #undef JSON_HEDLEY_CLANG_HAS_FEATURE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)\n    #undef JSON_HEDLEY_CLANG_HAS_EXTENSION\n#endif\n#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)\n    #undef JSON_HEDLEY_CLANG_HAS_WARNING\n#endif\n#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)\n\n#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */\n"
  },
  {
    "path": "subprojects/nlohmann_json/include/nlohmann/thirdparty/hedley/hedley_undef.hpp",
    "content": "#pragma once\n\n#undef JSON_HEDLEY_ALWAYS_INLINE\n#undef JSON_HEDLEY_ARM_VERSION\n#undef JSON_HEDLEY_ARM_VERSION_CHECK\n#undef JSON_HEDLEY_ARRAY_PARAM\n#undef JSON_HEDLEY_ASSUME\n#undef JSON_HEDLEY_BEGIN_C_DECLS\n#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_CLANG_HAS_BUILTIN\n#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_CLANG_HAS_EXTENSION\n#undef JSON_HEDLEY_CLANG_HAS_FEATURE\n#undef JSON_HEDLEY_CLANG_HAS_WARNING\n#undef JSON_HEDLEY_COMPCERT_VERSION\n#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK\n#undef JSON_HEDLEY_CONCAT\n#undef JSON_HEDLEY_CONCAT3\n#undef JSON_HEDLEY_CONCAT3_EX\n#undef JSON_HEDLEY_CONCAT_EX\n#undef JSON_HEDLEY_CONST\n#undef JSON_HEDLEY_CONSTEXPR\n#undef JSON_HEDLEY_CONST_CAST\n#undef JSON_HEDLEY_CPP_CAST\n#undef JSON_HEDLEY_CRAY_VERSION\n#undef JSON_HEDLEY_CRAY_VERSION_CHECK\n#undef JSON_HEDLEY_C_DECL\n#undef JSON_HEDLEY_DEPRECATED\n#undef JSON_HEDLEY_DEPRECATED_FOR\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION\n#undef JSON_HEDLEY_DIAGNOSTIC_POP\n#undef JSON_HEDLEY_DIAGNOSTIC_PUSH\n#undef JSON_HEDLEY_DMC_VERSION\n#undef JSON_HEDLEY_DMC_VERSION_CHECK\n#undef JSON_HEDLEY_EMPTY_BASES\n#undef JSON_HEDLEY_EMSCRIPTEN_VERSION\n#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK\n#undef JSON_HEDLEY_END_C_DECLS\n#undef JSON_HEDLEY_FLAGS\n#undef JSON_HEDLEY_FLAGS_CAST\n#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_GCC_HAS_BUILTIN\n#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_GCC_HAS_EXTENSION\n#undef JSON_HEDLEY_GCC_HAS_FEATURE\n#undef JSON_HEDLEY_GCC_HAS_WARNING\n#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK\n#undef JSON_HEDLEY_GCC_VERSION\n#undef JSON_HEDLEY_GCC_VERSION_CHECK\n#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_GNUC_HAS_BUILTIN\n#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_GNUC_HAS_EXTENSION\n#undef JSON_HEDLEY_GNUC_HAS_FEATURE\n#undef JSON_HEDLEY_GNUC_HAS_WARNING\n#undef JSON_HEDLEY_GNUC_VERSION\n#undef JSON_HEDLEY_GNUC_VERSION_CHECK\n#undef JSON_HEDLEY_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_HAS_BUILTIN\n#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS\n#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_HAS_EXTENSION\n#undef JSON_HEDLEY_HAS_FEATURE\n#undef JSON_HEDLEY_HAS_WARNING\n#undef JSON_HEDLEY_IAR_VERSION\n#undef JSON_HEDLEY_IAR_VERSION_CHECK\n#undef JSON_HEDLEY_IBM_VERSION\n#undef JSON_HEDLEY_IBM_VERSION_CHECK\n#undef JSON_HEDLEY_IMPORT\n#undef JSON_HEDLEY_INLINE\n#undef JSON_HEDLEY_INTEL_CL_VERSION\n#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK\n#undef JSON_HEDLEY_INTEL_VERSION\n#undef JSON_HEDLEY_INTEL_VERSION_CHECK\n#undef JSON_HEDLEY_IS_CONSTANT\n#undef JSON_HEDLEY_IS_CONSTEXPR_\n#undef JSON_HEDLEY_LIKELY\n#undef JSON_HEDLEY_MALLOC\n#undef JSON_HEDLEY_MCST_LCC_VERSION\n#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK\n#undef JSON_HEDLEY_MESSAGE\n#undef JSON_HEDLEY_MSVC_VERSION\n#undef JSON_HEDLEY_MSVC_VERSION_CHECK\n#undef JSON_HEDLEY_NEVER_INLINE\n#undef JSON_HEDLEY_NON_NULL\n#undef JSON_HEDLEY_NO_ESCAPE\n#undef JSON_HEDLEY_NO_RETURN\n#undef JSON_HEDLEY_NO_THROW\n#undef JSON_HEDLEY_NULL\n#undef JSON_HEDLEY_PELLES_VERSION\n#undef JSON_HEDLEY_PELLES_VERSION_CHECK\n#undef JSON_HEDLEY_PGI_VERSION\n#undef JSON_HEDLEY_PGI_VERSION_CHECK\n#undef JSON_HEDLEY_PREDICT\n#undef JSON_HEDLEY_PRINTF_FORMAT\n#undef JSON_HEDLEY_PRIVATE\n#undef JSON_HEDLEY_PUBLIC\n#undef JSON_HEDLEY_PURE\n#undef JSON_HEDLEY_REINTERPRET_CAST\n#undef JSON_HEDLEY_REQUIRE\n#undef JSON_HEDLEY_REQUIRE_CONSTEXPR\n#undef JSON_HEDLEY_REQUIRE_MSG\n#undef JSON_HEDLEY_RESTRICT\n#undef JSON_HEDLEY_RETURNS_NON_NULL\n#undef JSON_HEDLEY_SENTINEL\n#undef JSON_HEDLEY_STATIC_ASSERT\n#undef JSON_HEDLEY_STATIC_CAST\n#undef JSON_HEDLEY_STRINGIFY\n#undef JSON_HEDLEY_STRINGIFY_EX\n#undef JSON_HEDLEY_SUNPRO_VERSION\n#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK\n#undef JSON_HEDLEY_TINYC_VERSION\n#undef JSON_HEDLEY_TINYC_VERSION_CHECK\n#undef JSON_HEDLEY_TI_ARMCL_VERSION\n#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL2000_VERSION\n#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL430_VERSION\n#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL6X_VERSION\n#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL7X_VERSION\n#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CLPRU_VERSION\n#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK\n#undef JSON_HEDLEY_TI_VERSION\n#undef JSON_HEDLEY_TI_VERSION_CHECK\n#undef JSON_HEDLEY_UNAVAILABLE\n#undef JSON_HEDLEY_UNLIKELY\n#undef JSON_HEDLEY_UNPREDICTABLE\n#undef JSON_HEDLEY_UNREACHABLE\n#undef JSON_HEDLEY_UNREACHABLE_RETURN\n#undef JSON_HEDLEY_VERSION\n#undef JSON_HEDLEY_VERSION_DECODE_MAJOR\n#undef JSON_HEDLEY_VERSION_DECODE_MINOR\n#undef JSON_HEDLEY_VERSION_DECODE_REVISION\n#undef JSON_HEDLEY_VERSION_ENCODE\n#undef JSON_HEDLEY_WARNING\n#undef JSON_HEDLEY_WARN_UNUSED_RESULT\n#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG\n#undef JSON_HEDLEY_FALL_THROUGH\n"
  },
  {
    "path": "subprojects/nlohmann_json/meson.build",
    "content": "project('nlohmann_json',\n    'cpp',\n    version : '3.10.5',\n    license : 'MIT',\n)\n\nnlohmann_json_dep = declare_dependency(\n    include_directories: include_directories('single_include')\n)\n\nnlohmann_json_multiple_headers = declare_dependency(\n    include_directories: include_directories('include')\n)\n\nif not meson.is_subproject()\ninstall_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann')\n\npkgc = import('pkgconfig')\npkgc.generate(name: 'nlohmann_json',\n    version: meson.project_version(),\n    description: 'JSON for Modern C++'\n)\nendif\n"
  },
  {
    "path": "subprojects/nlohmann_json/nlohmann_json.natvis",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<AutoVisualizer xmlns=\"http://schemas.microsoft.com/vstudio/debugger/natvis/2010\">\n    <Type Name=\"nlohmann::basic_json&lt;*&gt;\">\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::null\">null</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::object\">{*(m_value.object)}</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::array\">{*(m_value.array)}</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::string\">{*(m_value.string)}</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::boolean\">{m_value.boolean}</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::number_integer\">{m_value.number_integer}</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::number_unsigned\">{m_value.number_unsigned}</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::number_float\">{m_value.number_float}</DisplayString>\n        <DisplayString Condition=\"m_type == nlohmann::detail::value_t::discarded\">discarded</DisplayString>\n        <Expand>\n            <ExpandedItem Condition=\"m_type == nlohmann::detail::value_t::object\">\n                *(m_value.object),view(simple)\n            </ExpandedItem>\n            <ExpandedItem Condition=\"m_type == nlohmann::detail::value_t::array\">\n                *(m_value.array),view(simple)\n            </ExpandedItem>\n        </Expand>\n    </Type>\n\n    <!--    skip the pair first/second members in the treeview while traversing a map.\n            Only works in VS 2015 Update 2 and beyond using the new visualization -->\n    <Type Name=\"std::pair&lt;*, nlohmann::basic_json&lt;*&gt;&gt;\" IncludeView=\"MapHelper\">\n        <DisplayString>{second}</DisplayString>\n        <Expand>\n            <ExpandedItem>second</ExpandedItem>\n        </Expand>\n    </Type>\n\n</AutoVisualizer>\n"
  },
  {
    "path": "subprojects/nlohmann_json/single_include/nlohmann/json.hpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n/****************************************************************************\\\n * Note on documentation: The source files contain links to the online      *\n * documentation of the public API at https://json.nlohmann.me. This URL    *\n * contains the most recent documentation and should also be applicable to  *\n * previous versions; documentation for deprecated functions is not         *\n * removed, but marked deprecated. See \"Generate documentation\" section in  *\n * file doc/README.md.                                                      *\n\\****************************************************************************/\n\n#ifndef INCLUDE_NLOHMANN_JSON_HPP_\n#define INCLUDE_NLOHMANN_JSON_HPP_\n\n#define NLOHMANN_JSON_VERSION_MAJOR 3\n#define NLOHMANN_JSON_VERSION_MINOR 10\n#define NLOHMANN_JSON_VERSION_PATCH 5\n\n#include <algorithm> // all_of, find, for_each\n#include <cstddef> // nullptr_t, ptrdiff_t, size_t\n#include <functional> // hash, less\n#include <initializer_list> // initializer_list\n#ifndef JSON_NO_IO\n    #include <iosfwd> // istream, ostream\n#endif  // JSON_NO_IO\n#include <iterator> // random_access_iterator_tag\n#include <memory> // unique_ptr\n#include <numeric> // accumulate\n#include <string> // string, stoi, to_string\n#include <utility> // declval, forward, move, pair, swap\n#include <vector> // vector\n\n// #include <nlohmann/adl_serializer.hpp>\n\n\n#include <type_traits>\n#include <utility>\n\n// #include <nlohmann/detail/conversions/from_json.hpp>\n\n\n#include <algorithm> // transform\n#include <array> // array\n#include <forward_list> // forward_list\n#include <iterator> // inserter, front_inserter, end\n#include <map> // map\n#include <string> // string\n#include <tuple> // tuple, make_tuple\n#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible\n#include <unordered_map> // unordered_map\n#include <utility> // pair, declval\n#include <valarray> // valarray\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n\n#include <exception> // exception\n#include <stdexcept> // runtime_error\n#include <string> // to_string\n#include <vector> // vector\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\n#include <array> // array\n#include <cstddef> // size_t\n#include <cstdint> // uint8_t\n#include <string> // string\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////////////////////\n// JSON type enumeration //\n///////////////////////////\n\n/*!\n@brief the JSON type enumeration\n\nThis enumeration collects the different JSON types. It is internally used to\ndistinguish the stored values, and the functions @ref basic_json::is_null(),\n@ref basic_json::is_object(), @ref basic_json::is_array(),\n@ref basic_json::is_string(), @ref basic_json::is_boolean(),\n@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),\n@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),\n@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and\n@ref basic_json::is_structured() rely on it.\n\n@note There are three enumeration entries (number_integer, number_unsigned, and\nnumber_float), because the library distinguishes these three types for numbers:\n@ref basic_json::number_unsigned_t is used for unsigned integers,\n@ref basic_json::number_integer_t is used for signed integers, and\n@ref basic_json::number_float_t is used for floating-point numbers or to\napproximate integers which do not fit in the limits of their respective type.\n\n@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON\nvalue with the default value for a given type\n\n@since version 1.0.0\n*/\nenum class value_t : std::uint8_t\n{\n    null,             ///< null value\n    object,           ///< object (unordered set of name/value pairs)\n    array,            ///< array (ordered collection of values)\n    string,           ///< string value\n    boolean,          ///< boolean value\n    number_integer,   ///< number value (signed integer)\n    number_unsigned,  ///< number value (unsigned integer)\n    number_float,     ///< number value (floating-point)\n    binary,           ///< binary array (ordered collection of bytes)\n    discarded         ///< discarded by the parser callback function\n};\n\n/*!\n@brief comparison operator for JSON types\n\nReturns an ordering that is similar to Python:\n- order: null < boolean < number < object < array < string < binary\n- furthermore, each type is not smaller than itself\n- discarded values are not comparable\n- binary is represented as a b\"\" string in python and directly comparable to a\n  string; however, making a binary array directly comparable with a string would\n  be surprising behavior in a JSON file.\n\n@since version 1.0.0\n*/\ninline bool operator<(const value_t lhs, const value_t rhs) noexcept\n{\n    static constexpr std::array<std::uint8_t, 9> order = {{\n            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,\n            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,\n            6 /* binary */\n        }\n    };\n\n    const auto l_index = static_cast<std::size_t>(lhs);\n    const auto r_index = static_cast<std::size_t>(rhs);\n    return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];\n}\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/string_escape.hpp>\n\n\n#include <string>\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\n#include <utility> // declval, pair\n// #include <nlohmann/thirdparty/hedley/hedley.hpp>\n\n\n/* Hedley - https://nemequ.github.io/hedley\n * Created by Evan Nemerson <evan@nemerson.com>\n *\n * To the extent possible under law, the author(s) have dedicated all\n * copyright and related and neighboring rights to this software to\n * the public domain worldwide. This software is distributed without\n * any warranty.\n *\n * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.\n * SPDX-License-Identifier: CC0-1.0\n */\n\n#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)\n#if defined(JSON_HEDLEY_VERSION)\n    #undef JSON_HEDLEY_VERSION\n#endif\n#define JSON_HEDLEY_VERSION 15\n\n#if defined(JSON_HEDLEY_STRINGIFY_EX)\n    #undef JSON_HEDLEY_STRINGIFY_EX\n#endif\n#define JSON_HEDLEY_STRINGIFY_EX(x) #x\n\n#if defined(JSON_HEDLEY_STRINGIFY)\n    #undef JSON_HEDLEY_STRINGIFY\n#endif\n#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)\n\n#if defined(JSON_HEDLEY_CONCAT_EX)\n    #undef JSON_HEDLEY_CONCAT_EX\n#endif\n#define JSON_HEDLEY_CONCAT_EX(a,b) a##b\n\n#if defined(JSON_HEDLEY_CONCAT)\n    #undef JSON_HEDLEY_CONCAT\n#endif\n#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)\n\n#if defined(JSON_HEDLEY_CONCAT3_EX)\n    #undef JSON_HEDLEY_CONCAT3_EX\n#endif\n#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c\n\n#if defined(JSON_HEDLEY_CONCAT3)\n    #undef JSON_HEDLEY_CONCAT3\n#endif\n#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)\n\n#if defined(JSON_HEDLEY_VERSION_ENCODE)\n    #undef JSON_HEDLEY_VERSION_ENCODE\n#endif\n#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))\n\n#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)\n    #undef JSON_HEDLEY_VERSION_DECODE_MAJOR\n#endif\n#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)\n\n#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)\n    #undef JSON_HEDLEY_VERSION_DECODE_MINOR\n#endif\n#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)\n\n#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)\n    #undef JSON_HEDLEY_VERSION_DECODE_REVISION\n#endif\n#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)\n\n#if defined(JSON_HEDLEY_GNUC_VERSION)\n    #undef JSON_HEDLEY_GNUC_VERSION\n#endif\n#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)\n    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)\n#elif defined(__GNUC__)\n    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)\n    #undef JSON_HEDLEY_GNUC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_GNUC_VERSION)\n    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_MSVC_VERSION)\n    #undef JSON_HEDLEY_MSVC_VERSION\n#endif\n#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)\n    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)\n#elif defined(_MSC_FULL_VER) && !defined(__ICL)\n    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)\n#elif defined(_MSC_VER) && !defined(__ICL)\n    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)\n#endif\n\n#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)\n    #undef JSON_HEDLEY_MSVC_VERSION_CHECK\n#endif\n#if !defined(JSON_HEDLEY_MSVC_VERSION)\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)\n#elif defined(_MSC_VER) && (_MSC_VER >= 1400)\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))\n#elif defined(_MSC_VER) && (_MSC_VER >= 1200)\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))\n#else\n    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_VERSION)\n    #undef JSON_HEDLEY_INTEL_VERSION\n#endif\n#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)\n    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)\n#elif defined(__INTEL_COMPILER) && !defined(__ICL)\n    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)\n    #undef JSON_HEDLEY_INTEL_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_INTEL_VERSION)\n    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_CL_VERSION)\n    #undef JSON_HEDLEY_INTEL_CL_VERSION\n#endif\n#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)\n    #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)\n#endif\n\n#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)\n    #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_INTEL_CL_VERSION)\n    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_PGI_VERSION)\n    #undef JSON_HEDLEY_PGI_VERSION\n#endif\n#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)\n    #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)\n#endif\n\n#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)\n    #undef JSON_HEDLEY_PGI_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_PGI_VERSION)\n    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_SUNPRO_VERSION)\n    #undef JSON_HEDLEY_SUNPRO_VERSION\n#endif\n#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)\n#elif defined(__SUNPRO_C)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)\n#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)\n#elif defined(__SUNPRO_CC)\n    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)\n#endif\n\n#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)\n    #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_SUNPRO_VERSION)\n    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)\n    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION\n#endif\n#if defined(__EMSCRIPTEN__)\n    #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)\n#endif\n\n#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)\n    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)\n    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_ARM_VERSION)\n    #undef JSON_HEDLEY_ARM_VERSION\n#endif\n#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)\n    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)\n#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)\n    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)\n#endif\n\n#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)\n    #undef JSON_HEDLEY_ARM_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_ARM_VERSION)\n    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_IBM_VERSION)\n    #undef JSON_HEDLEY_IBM_VERSION\n#endif\n#if defined(__ibmxl__)\n    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)\n#elif defined(__xlC__) && defined(__xlC_ver__)\n    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)\n#elif defined(__xlC__)\n    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)\n#endif\n\n#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)\n    #undef JSON_HEDLEY_IBM_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_IBM_VERSION)\n    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_VERSION)\n    #undef JSON_HEDLEY_TI_VERSION\n#endif\n#if \\\n    defined(__TI_COMPILER_VERSION__) && \\\n    ( \\\n      defined(__TMS470__) || defined(__TI_ARM__) || \\\n      defined(__MSP430__) || \\\n      defined(__TMS320C2000__) \\\n    )\n#if (__TI_COMPILER_VERSION__ >= 16000000)\n    #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n#endif\n\n#if defined(JSON_HEDLEY_TI_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_VERSION)\n    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL2000_VERSION)\n    #undef JSON_HEDLEY_TI_CL2000_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)\n    #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL2000_VERSION)\n    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL430_VERSION)\n    #undef JSON_HEDLEY_TI_CL430_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)\n    #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL430_VERSION)\n    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)\n    #undef JSON_HEDLEY_TI_ARMCL_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))\n    #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)\n    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL6X_VERSION)\n    #undef JSON_HEDLEY_TI_CL6X_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)\n    #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL6X_VERSION)\n    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL7X_VERSION)\n    #undef JSON_HEDLEY_TI_CL7X_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)\n    #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CL7X_VERSION)\n    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)\n    #undef JSON_HEDLEY_TI_CLPRU_VERSION\n#endif\n#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)\n    #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))\n#endif\n\n#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)\n    #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)\n    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_CRAY_VERSION)\n    #undef JSON_HEDLEY_CRAY_VERSION\n#endif\n#if defined(_CRAYC)\n    #if defined(_RELEASE_PATCHLEVEL)\n        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)\n    #else\n        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)\n    #endif\n#endif\n\n#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)\n    #undef JSON_HEDLEY_CRAY_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_CRAY_VERSION)\n    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_IAR_VERSION)\n    #undef JSON_HEDLEY_IAR_VERSION\n#endif\n#if defined(__IAR_SYSTEMS_ICC__)\n    #if __VER__ > 1000\n        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))\n    #else\n        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)\n    #endif\n#endif\n\n#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)\n    #undef JSON_HEDLEY_IAR_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_IAR_VERSION)\n    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_TINYC_VERSION)\n    #undef JSON_HEDLEY_TINYC_VERSION\n#endif\n#if defined(__TINYC__)\n    #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)\n#endif\n\n#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)\n    #undef JSON_HEDLEY_TINYC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_TINYC_VERSION)\n    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_DMC_VERSION)\n    #undef JSON_HEDLEY_DMC_VERSION\n#endif\n#if defined(__DMC__)\n    #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)\n#endif\n\n#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)\n    #undef JSON_HEDLEY_DMC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_DMC_VERSION)\n    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_COMPCERT_VERSION)\n    #undef JSON_HEDLEY_COMPCERT_VERSION\n#endif\n#if defined(__COMPCERT_VERSION__)\n    #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)\n#endif\n\n#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)\n    #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_COMPCERT_VERSION)\n    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_PELLES_VERSION)\n    #undef JSON_HEDLEY_PELLES_VERSION\n#endif\n#if defined(__POCC__)\n    #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)\n#endif\n\n#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)\n    #undef JSON_HEDLEY_PELLES_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_PELLES_VERSION)\n    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_MCST_LCC_VERSION)\n    #undef JSON_HEDLEY_MCST_LCC_VERSION\n#endif\n#if defined(__LCC__) && defined(__LCC_MINOR__)\n    #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)\n#endif\n\n#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)\n    #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_MCST_LCC_VERSION)\n    #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_VERSION)\n    #undef JSON_HEDLEY_GCC_VERSION\n#endif\n#if \\\n    defined(JSON_HEDLEY_GNUC_VERSION) && \\\n    !defined(__clang__) && \\\n    !defined(JSON_HEDLEY_INTEL_VERSION) && \\\n    !defined(JSON_HEDLEY_PGI_VERSION) && \\\n    !defined(JSON_HEDLEY_ARM_VERSION) && \\\n    !defined(JSON_HEDLEY_CRAY_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL430_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \\\n    !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \\\n    !defined(__COMPCERT__) && \\\n    !defined(JSON_HEDLEY_MCST_LCC_VERSION)\n    #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION\n#endif\n\n#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)\n    #undef JSON_HEDLEY_GCC_VERSION_CHECK\n#endif\n#if defined(JSON_HEDLEY_GCC_VERSION)\n    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))\n#else\n    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_HAS_ATTRIBUTE\n#endif\n#if \\\n  defined(__has_attribute) && \\\n  ( \\\n    (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \\\n  )\n#  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)\n#else\n#  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE\n#endif\n#if defined(__has_attribute)\n    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE\n#endif\n#if defined(__has_attribute)\n    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)\n#else\n    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE\n#endif\n#if \\\n    defined(__has_cpp_attribute) && \\\n    defined(__cplusplus) && \\\n    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)\n#else\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)\n    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS\n#endif\n#if !defined(__cplusplus) || !defined(__has_cpp_attribute)\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)\n#elif \\\n    !defined(JSON_HEDLEY_PGI_VERSION) && \\\n    !defined(JSON_HEDLEY_IAR_VERSION) && \\\n    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \\\n    (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)\n#else\n    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE\n#endif\n#if defined(__has_cpp_attribute) && defined(__cplusplus)\n    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE\n#endif\n#if defined(__has_cpp_attribute) && defined(__cplusplus)\n    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_BUILTIN)\n    #undef JSON_HEDLEY_HAS_BUILTIN\n#endif\n#if defined(__has_builtin)\n    #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)\n#else\n    #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)\n    #undef JSON_HEDLEY_GNUC_HAS_BUILTIN\n#endif\n#if defined(__has_builtin)\n    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)\n    #undef JSON_HEDLEY_GCC_HAS_BUILTIN\n#endif\n#if defined(__has_builtin)\n    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)\n#else\n    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_FEATURE)\n    #undef JSON_HEDLEY_HAS_FEATURE\n#endif\n#if defined(__has_feature)\n    #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)\n#else\n    #define JSON_HEDLEY_HAS_FEATURE(feature) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)\n    #undef JSON_HEDLEY_GNUC_HAS_FEATURE\n#endif\n#if defined(__has_feature)\n    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)\n    #undef JSON_HEDLEY_GCC_HAS_FEATURE\n#endif\n#if defined(__has_feature)\n    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)\n#else\n    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_EXTENSION)\n    #undef JSON_HEDLEY_HAS_EXTENSION\n#endif\n#if defined(__has_extension)\n    #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)\n#else\n    #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)\n    #undef JSON_HEDLEY_GNUC_HAS_EXTENSION\n#endif\n#if defined(__has_extension)\n    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)\n    #undef JSON_HEDLEY_GCC_HAS_EXTENSION\n#endif\n#if defined(__has_extension)\n    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)\n#else\n    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE\n#endif\n#if defined(__has_declspec_attribute)\n    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)\n#else\n    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE\n#endif\n#if defined(__has_declspec_attribute)\n    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE\n#endif\n#if defined(__has_declspec_attribute)\n    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)\n#else\n    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_HAS_WARNING)\n    #undef JSON_HEDLEY_HAS_WARNING\n#endif\n#if defined(__has_warning)\n    #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)\n#else\n    #define JSON_HEDLEY_HAS_WARNING(warning) (0)\n#endif\n\n#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)\n    #undef JSON_HEDLEY_GNUC_HAS_WARNING\n#endif\n#if defined(__has_warning)\n    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)\n#else\n    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_GCC_HAS_WARNING)\n    #undef JSON_HEDLEY_GCC_HAS_WARNING\n#endif\n#if defined(__has_warning)\n    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)\n#else\n    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if \\\n    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \\\n    defined(__clang__) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \\\n    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \\\n    (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))\n    #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)\n    #define JSON_HEDLEY_PRAGMA(value) __pragma(value)\n#else\n    #define JSON_HEDLEY_PRAGMA(value)\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)\n    #undef JSON_HEDLEY_DIAGNOSTIC_PUSH\n#endif\n#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)\n    #undef JSON_HEDLEY_DIAGNOSTIC_POP\n#endif\n#if defined(__clang__)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"clang diagnostic push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"clang diagnostic pop\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"warning(push)\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"warning(pop)\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"GCC diagnostic push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"GCC diagnostic pop\")\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))\n    #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))\n#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"pop\")\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"diag_push\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"diag_pop\")\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma(\"warning(push)\")\n    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma(\"warning(pop)\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_PUSH\n    #define JSON_HEDLEY_DIAGNOSTIC_POP\n#endif\n\n/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for\n   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_\n#endif\n#if defined(__cplusplus)\n#  if JSON_HEDLEY_HAS_WARNING(\"-Wc++98-compat\")\n#    if JSON_HEDLEY_HAS_WARNING(\"-Wc++17-extensions\")\n#      if JSON_HEDLEY_HAS_WARNING(\"-Wc++1z-extensions\")\n#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++98-compat\\\"\") \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++17-extensions\\\"\") \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++1z-extensions\\\"\") \\\n    xpr \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#      else\n#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++98-compat\\\"\") \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++17-extensions\\\"\") \\\n    xpr \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#      endif\n#    else\n#      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wc++98-compat\\\"\") \\\n    xpr \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#    endif\n#  endif\n#endif\n#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x\n#endif\n\n#if defined(JSON_HEDLEY_CONST_CAST)\n    #undef JSON_HEDLEY_CONST_CAST\n#endif\n#if defined(__cplusplus)\n#  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))\n#elif \\\n  JSON_HEDLEY_HAS_WARNING(\"-Wcast-qual\") || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n#  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \\\n        JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n        JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \\\n        ((T) (expr)); \\\n        JSON_HEDLEY_DIAGNOSTIC_POP \\\n    }))\n#else\n#  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))\n#endif\n\n#if defined(JSON_HEDLEY_REINTERPRET_CAST)\n    #undef JSON_HEDLEY_REINTERPRET_CAST\n#endif\n#if defined(__cplusplus)\n    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))\n#else\n    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))\n#endif\n\n#if defined(JSON_HEDLEY_STATIC_CAST)\n    #undef JSON_HEDLEY_STATIC_CAST\n#endif\n#if defined(__cplusplus)\n    #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))\n#else\n    #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))\n#endif\n\n#if defined(JSON_HEDLEY_CPP_CAST)\n    #undef JSON_HEDLEY_CPP_CAST\n#endif\n#if defined(__cplusplus)\n#  if JSON_HEDLEY_HAS_WARNING(\"-Wold-style-cast\")\n#    define JSON_HEDLEY_CPP_CAST(T, expr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wold-style-cast\\\"\") \\\n    ((T) (expr)) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)\n#    define JSON_HEDLEY_CPP_CAST(T, expr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"diag_suppress=Pe137\") \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#  else\n#    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))\n#  endif\n#else\n#  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wdeprecated-declarations\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"clang diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"warning(disable:1478 1786)\")\n#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1215,1216,1444,1445\")\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1215,1444\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"GCC diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1215,1444\")\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress 1291,1718\")\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)\")\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"error_messages(off,symdeprecated,symdeprecated2)\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"diag_suppress=Pe1444,Pe1215\")\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma(\"warn(disable:2241)\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-pragmas\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"clang diagnostic ignored \\\"-Wunknown-pragmas\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"warning(disable:161)\")\n#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 1675\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"GCC diagnostic ignored \\\"-Wunknown-pragmas\\\"\")\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 163\")\n#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 163\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress=Pe161\")\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma(\"diag_suppress 161\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-attributes\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"clang diagnostic ignored \\\"-Wunknown-attributes\\\"\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"GCC diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"warning(disable:1292)\")\n#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1097,1098\")\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1097\")\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"error_messages(off,attrskipunsup)\")\n#elif \\\n    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1173\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress=Pe1097\")\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma(\"diag_suppress 1097\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wcast-qual\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma(\"clang diagnostic ignored \\\"-Wcast-qual\\\"\")\n#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma(\"warning(disable:2203 2331)\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma(\"GCC diagnostic ignored \\\"-Wcast-qual\\\"\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL\n#endif\n\n#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)\n    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunused-function\")\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma(\"clang diagnostic ignored \\\"-Wunused-function\\\"\")\n#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma(\"GCC diagnostic ignored \\\"-Wunused-function\\\"\")\n#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))\n#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma(\"diag_suppress 3142\")\n#else\n    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION\n#endif\n\n#if defined(JSON_HEDLEY_DEPRECATED)\n    #undef JSON_HEDLEY_DEPRECATED\n#endif\n#if defined(JSON_HEDLEY_DEPRECATED_FOR)\n    #undef JSON_HEDLEY_DEPRECATED_FOR\n#endif\n#if \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated(\"Since \" # since))\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated(\"Since \" #since \"; use \" #replacement))\n#elif \\\n    (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__(\"Since \" #since)))\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__(\"Since \" #since \"; use \" #replacement)))\n#elif defined(__cplusplus) && (__cplusplus >= 201402L)\n    #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated(\"Since \" #since)]])\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated(\"Since \" #since \"; use \" #replacement)]])\n#elif \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_DEPRECATED(since) _Pragma(\"deprecated\")\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma(\"deprecated\")\n#else\n    #define JSON_HEDLEY_DEPRECATED(since)\n    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)\n#endif\n\n#if defined(JSON_HEDLEY_UNAVAILABLE)\n    #undef JSON_HEDLEY_UNAVAILABLE\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__(\"Not available until \" #available_since)))\n#else\n    #define JSON_HEDLEY_UNAVAILABLE(available_since)\n#endif\n\n#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)\n    #undef JSON_HEDLEY_WARN_UNUSED_RESULT\n#endif\n#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)\n    #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))\n#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])\n#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])\n#elif defined(_Check_return_) /* SAL */\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_\n#else\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT\n    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)\n#endif\n\n#if defined(JSON_HEDLEY_SENTINEL)\n    #undef JSON_HEDLEY_SENTINEL\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))\n#else\n    #define JSON_HEDLEY_SENTINEL(position)\n#endif\n\n#if defined(JSON_HEDLEY_NO_RETURN)\n    #undef JSON_HEDLEY_NO_RETURN\n#endif\n#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_NO_RETURN __noreturn\n#elif \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))\n#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L\n    #define JSON_HEDLEY_NO_RETURN _Noreturn\n#elif defined(__cplusplus) && (__cplusplus >= 201103L)\n    #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])\n#elif \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n    #define JSON_HEDLEY_NO_RETURN _Pragma(\"does_not_return\")\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)\n#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_NO_RETURN _Pragma(\"FUNC_NEVER_RETURNS;\")\n#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)\n    #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)\n    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)\n#else\n    #define JSON_HEDLEY_NO_RETURN\n#endif\n\n#if defined(JSON_HEDLEY_NO_ESCAPE)\n    #undef JSON_HEDLEY_NO_ESCAPE\n#endif\n#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)\n    #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))\n#else\n    #define JSON_HEDLEY_NO_ESCAPE\n#endif\n\n#if defined(JSON_HEDLEY_UNREACHABLE)\n    #undef JSON_HEDLEY_UNREACHABLE\n#endif\n#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)\n    #undef JSON_HEDLEY_UNREACHABLE_RETURN\n#endif\n#if defined(JSON_HEDLEY_ASSUME)\n    #undef JSON_HEDLEY_ASSUME\n#endif\n#if \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_ASSUME(expr) __assume(expr)\n#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)\n    #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)\n#elif \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)\n    #if defined(__cplusplus)\n        #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)\n    #else\n        #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)\n    #endif\n#endif\n#if \\\n    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \\\n    JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()\n#elif defined(JSON_HEDLEY_ASSUME)\n    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)\n#endif\n#if !defined(JSON_HEDLEY_ASSUME)\n    #if defined(JSON_HEDLEY_UNREACHABLE)\n        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))\n    #else\n        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)\n    #endif\n#endif\n#if defined(JSON_HEDLEY_UNREACHABLE)\n    #if  \\\n        JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \\\n        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)\n        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))\n    #else\n        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()\n    #endif\n#else\n    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)\n#endif\n#if !defined(JSON_HEDLEY_UNREACHABLE)\n    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)\n#endif\n\nJSON_HEDLEY_DIAGNOSTIC_PUSH\n#if JSON_HEDLEY_HAS_WARNING(\"-Wpedantic\")\n    #pragma clang diagnostic ignored \"-Wpedantic\"\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wc++98-compat-pedantic\") && defined(__cplusplus)\n    #pragma clang diagnostic ignored \"-Wc++98-compat-pedantic\"\n#endif\n#if JSON_HEDLEY_GCC_HAS_WARNING(\"-Wvariadic-macros\",4,0,0)\n    #if defined(__clang__)\n        #pragma clang diagnostic ignored \"-Wvariadic-macros\"\n    #elif defined(JSON_HEDLEY_GCC_VERSION)\n        #pragma GCC diagnostic ignored \"-Wvariadic-macros\"\n    #endif\n#endif\n#if defined(JSON_HEDLEY_NON_NULL)\n    #undef JSON_HEDLEY_NON_NULL\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)\n    #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))\n#else\n    #define JSON_HEDLEY_NON_NULL(...)\n#endif\nJSON_HEDLEY_DIAGNOSTIC_POP\n\n#if defined(JSON_HEDLEY_PRINTF_FORMAT)\n    #undef JSON_HEDLEY_PRINTF_FORMAT\n#endif\n#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))\n#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))\n#elif \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(format) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))\n#else\n    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)\n#endif\n\n#if defined(JSON_HEDLEY_CONSTEXPR)\n    #undef JSON_HEDLEY_CONSTEXPR\n#endif\n#if defined(__cplusplus)\n    #if __cplusplus >= 201103L\n        #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)\n    #endif\n#endif\n#if !defined(JSON_HEDLEY_CONSTEXPR)\n    #define JSON_HEDLEY_CONSTEXPR\n#endif\n\n#if defined(JSON_HEDLEY_PREDICT)\n    #undef JSON_HEDLEY_PREDICT\n#endif\n#if defined(JSON_HEDLEY_LIKELY)\n    #undef JSON_HEDLEY_LIKELY\n#endif\n#if defined(JSON_HEDLEY_UNLIKELY)\n    #undef JSON_HEDLEY_UNLIKELY\n#endif\n#if defined(JSON_HEDLEY_UNPREDICTABLE)\n    #undef JSON_HEDLEY_UNPREDICTABLE\n#endif\n#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)\n    #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))\n#endif\n#if \\\n  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))\n#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))\n#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))\n#  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )\n#  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )\n#elif \\\n  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \\\n  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \\\n  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \\\n  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \\\n  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \\\n  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \\\n  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#  define JSON_HEDLEY_PREDICT(expr, expected, probability) \\\n    (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))\n#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \\\n    (__extension__ ({ \\\n        double hedley_probability_ = (probability); \\\n        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \\\n    }))\n#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \\\n    (__extension__ ({ \\\n        double hedley_probability_ = (probability); \\\n        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \\\n    }))\n#  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)\n#  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)\n#else\n#  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))\n#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))\n#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))\n#  define JSON_HEDLEY_LIKELY(expr) (!!(expr))\n#  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))\n#endif\n#if !defined(JSON_HEDLEY_UNPREDICTABLE)\n    #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)\n#endif\n\n#if defined(JSON_HEDLEY_MALLOC)\n    #undef JSON_HEDLEY_MALLOC\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n    #define JSON_HEDLEY_MALLOC _Pragma(\"returns_new_memory\")\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_MALLOC __declspec(restrict)\n#else\n    #define JSON_HEDLEY_MALLOC\n#endif\n\n#if defined(JSON_HEDLEY_PURE)\n    #undef JSON_HEDLEY_PURE\n#endif\n#if \\\n  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#  define JSON_HEDLEY_PURE __attribute__((__pure__))\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n#  define JSON_HEDLEY_PURE _Pragma(\"does_not_write_global_data\")\n#elif defined(__cplusplus) && \\\n    ( \\\n      JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \\\n      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \\\n      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \\\n    )\n#  define JSON_HEDLEY_PURE _Pragma(\"FUNC_IS_PURE;\")\n#else\n#  define JSON_HEDLEY_PURE\n#endif\n\n#if defined(JSON_HEDLEY_CONST)\n    #undef JSON_HEDLEY_CONST\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(const) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_CONST __attribute__((__const__))\n#elif \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)\n    #define JSON_HEDLEY_CONST _Pragma(\"no_side_effect\")\n#else\n    #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE\n#endif\n\n#if defined(JSON_HEDLEY_RESTRICT)\n    #undef JSON_HEDLEY_RESTRICT\n#endif\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)\n    #define JSON_HEDLEY_RESTRICT restrict\n#elif \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \\\n    defined(__clang__) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_RESTRICT __restrict\n#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)\n    #define JSON_HEDLEY_RESTRICT _Restrict\n#else\n    #define JSON_HEDLEY_RESTRICT\n#endif\n\n#if defined(JSON_HEDLEY_INLINE)\n    #undef JSON_HEDLEY_INLINE\n#endif\n#if \\\n    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \\\n    (defined(__cplusplus) && (__cplusplus >= 199711L))\n    #define JSON_HEDLEY_INLINE inline\n#elif \\\n    defined(JSON_HEDLEY_GCC_VERSION) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)\n    #define JSON_HEDLEY_INLINE __inline__\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_INLINE __inline\n#else\n    #define JSON_HEDLEY_INLINE\n#endif\n\n#if defined(JSON_HEDLEY_ALWAYS_INLINE)\n    #undef JSON_HEDLEY_ALWAYS_INLINE\n#endif\n#if \\\n  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \\\n  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n#  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE\n#elif \\\n  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \\\n  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n#  define JSON_HEDLEY_ALWAYS_INLINE __forceinline\n#elif defined(__cplusplus) && \\\n    ( \\\n      JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n      JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n      JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \\\n      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n      JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \\\n    )\n#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma(\"FUNC_ALWAYS_INLINE;\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma(\"inline=forced\")\n#else\n#  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE\n#endif\n\n#if defined(JSON_HEDLEY_NEVER_INLINE)\n    #undef JSON_HEDLEY_NEVER_INLINE\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \\\n    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \\\n    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \\\n    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \\\n    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \\\n    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \\\n    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \\\n    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \\\n    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)\n    #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)\n#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)\n    #define JSON_HEDLEY_NEVER_INLINE _Pragma(\"noinline\")\n#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)\n    #define JSON_HEDLEY_NEVER_INLINE _Pragma(\"FUNC_CANNOT_INLINE;\")\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n    #define JSON_HEDLEY_NEVER_INLINE _Pragma(\"inline=never\")\n#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)\n    #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)\n    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)\n#else\n    #define JSON_HEDLEY_NEVER_INLINE\n#endif\n\n#if defined(JSON_HEDLEY_PRIVATE)\n    #undef JSON_HEDLEY_PRIVATE\n#endif\n#if defined(JSON_HEDLEY_PUBLIC)\n    #undef JSON_HEDLEY_PUBLIC\n#endif\n#if defined(JSON_HEDLEY_IMPORT)\n    #undef JSON_HEDLEY_IMPORT\n#endif\n#if defined(_WIN32) || defined(__CYGWIN__)\n#  define JSON_HEDLEY_PRIVATE\n#  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)\n#  define JSON_HEDLEY_IMPORT   __declspec(dllimport)\n#else\n#  if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \\\n    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \\\n    ( \\\n      defined(__TI_EABI__) && \\\n      ( \\\n        (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \\\n        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \\\n      ) \\\n    ) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n#    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__(\"hidden\")))\n#    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__(\"default\")))\n#  else\n#    define JSON_HEDLEY_PRIVATE\n#    define JSON_HEDLEY_PUBLIC\n#  endif\n#  define JSON_HEDLEY_IMPORT    extern\n#endif\n\n#if defined(JSON_HEDLEY_NO_THROW)\n    #undef JSON_HEDLEY_NO_THROW\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))\n#elif \\\n    JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)\n    #define JSON_HEDLEY_NO_THROW __declspec(nothrow)\n#else\n    #define JSON_HEDLEY_NO_THROW\n#endif\n\n#if defined(JSON_HEDLEY_FALL_THROUGH)\n    #undef JSON_HEDLEY_FALL_THROUGH\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))\n#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)\n    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])\n#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)\n    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])\n#elif defined(__fallthrough) /* SAL */\n    #define JSON_HEDLEY_FALL_THROUGH __fallthrough\n#else\n    #define JSON_HEDLEY_FALL_THROUGH\n#endif\n\n#if defined(JSON_HEDLEY_RETURNS_NON_NULL)\n    #undef JSON_HEDLEY_RETURNS_NON_NULL\n#endif\n#if \\\n    JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))\n#elif defined(_Ret_notnull_) /* SAL */\n    #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_\n#else\n    #define JSON_HEDLEY_RETURNS_NON_NULL\n#endif\n\n#if defined(JSON_HEDLEY_ARRAY_PARAM)\n    #undef JSON_HEDLEY_ARRAY_PARAM\n#endif\n#if \\\n    defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \\\n    !defined(__STDC_NO_VLA__) && \\\n    !defined(__cplusplus) && \\\n    !defined(JSON_HEDLEY_PGI_VERSION) && \\\n    !defined(JSON_HEDLEY_TINYC_VERSION)\n    #define JSON_HEDLEY_ARRAY_PARAM(name) (name)\n#else\n    #define JSON_HEDLEY_ARRAY_PARAM(name)\n#endif\n\n#if defined(JSON_HEDLEY_IS_CONSTANT)\n    #undef JSON_HEDLEY_IS_CONSTANT\n#endif\n#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)\n    #undef JSON_HEDLEY_REQUIRE_CONSTEXPR\n#endif\n/* JSON_HEDLEY_IS_CONSTEXPR_ is for\n   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */\n#if defined(JSON_HEDLEY_IS_CONSTEXPR_)\n    #undef JSON_HEDLEY_IS_CONSTEXPR_\n#endif\n#if \\\n    JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \\\n    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \\\n    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \\\n    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \\\n    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \\\n    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \\\n    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \\\n    JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \\\n    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)\n    #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)\n#endif\n#if !defined(__cplusplus)\n#  if \\\n       JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \\\n       JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \\\n       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n       JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \\\n       JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \\\n       JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \\\n       JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)\n#if defined(__INTPTR_TYPE__)\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)\n#else\n    #include <stdint.h>\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)\n#endif\n#  elif \\\n       ( \\\n          defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \\\n          !defined(JSON_HEDLEY_SUNPRO_VERSION) && \\\n          !defined(JSON_HEDLEY_PGI_VERSION) && \\\n          !defined(JSON_HEDLEY_IAR_VERSION)) || \\\n       (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \\\n       JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \\\n       JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \\\n       JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \\\n       JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)\n#if defined(__INTPTR_TYPE__)\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)\n#else\n    #include <stdint.h>\n    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)\n#endif\n#  elif \\\n       defined(JSON_HEDLEY_GCC_VERSION) || \\\n       defined(JSON_HEDLEY_INTEL_VERSION) || \\\n       defined(JSON_HEDLEY_TINYC_VERSION) || \\\n       defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \\\n       JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \\\n       defined(JSON_HEDLEY_TI_CL2000_VERSION) || \\\n       defined(JSON_HEDLEY_TI_CL6X_VERSION) || \\\n       defined(JSON_HEDLEY_TI_CL7X_VERSION) || \\\n       defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \\\n       defined(__clang__)\n#    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \\\n        sizeof(void) != \\\n        sizeof(*( \\\n                  1 ? \\\n                  ((void*) ((expr) * 0L) ) : \\\n((struct { char v[sizeof(void) * 2]; } *) 1) \\\n                ) \\\n              ) \\\n                                            )\n#  endif\n#endif\n#if defined(JSON_HEDLEY_IS_CONSTEXPR_)\n    #if !defined(JSON_HEDLEY_IS_CONSTANT)\n        #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)\n    #endif\n    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))\n#else\n    #if !defined(JSON_HEDLEY_IS_CONSTANT)\n        #define JSON_HEDLEY_IS_CONSTANT(expr) (0)\n    #endif\n    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)\n#endif\n\n#if defined(JSON_HEDLEY_BEGIN_C_DECLS)\n    #undef JSON_HEDLEY_BEGIN_C_DECLS\n#endif\n#if defined(JSON_HEDLEY_END_C_DECLS)\n    #undef JSON_HEDLEY_END_C_DECLS\n#endif\n#if defined(JSON_HEDLEY_C_DECL)\n    #undef JSON_HEDLEY_C_DECL\n#endif\n#if defined(__cplusplus)\n    #define JSON_HEDLEY_BEGIN_C_DECLS extern \"C\" {\n    #define JSON_HEDLEY_END_C_DECLS }\n    #define JSON_HEDLEY_C_DECL extern \"C\"\n#else\n    #define JSON_HEDLEY_BEGIN_C_DECLS\n    #define JSON_HEDLEY_END_C_DECLS\n    #define JSON_HEDLEY_C_DECL\n#endif\n\n#if defined(JSON_HEDLEY_STATIC_ASSERT)\n    #undef JSON_HEDLEY_STATIC_ASSERT\n#endif\n#if \\\n  !defined(__cplusplus) && ( \\\n      (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \\\n      (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \\\n      JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \\\n      JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \\\n      defined(_Static_assert) \\\n    )\n#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)\n#elif \\\n  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \\\n  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \\\n  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))\n#else\n#  define JSON_HEDLEY_STATIC_ASSERT(expr, message)\n#endif\n\n#if defined(JSON_HEDLEY_NULL)\n    #undef JSON_HEDLEY_NULL\n#endif\n#if defined(__cplusplus)\n    #if __cplusplus >= 201103L\n        #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)\n    #elif defined(NULL)\n        #define JSON_HEDLEY_NULL NULL\n    #else\n        #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)\n    #endif\n#elif defined(NULL)\n    #define JSON_HEDLEY_NULL NULL\n#else\n    #define JSON_HEDLEY_NULL ((void*) 0)\n#endif\n\n#if defined(JSON_HEDLEY_MESSAGE)\n    #undef JSON_HEDLEY_MESSAGE\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-pragmas\")\n#  define JSON_HEDLEY_MESSAGE(msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \\\n    JSON_HEDLEY_PRAGMA(message msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#elif \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)\n#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)\n#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))\n#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)\n#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))\n#else\n#  define JSON_HEDLEY_MESSAGE(msg)\n#endif\n\n#if defined(JSON_HEDLEY_WARNING)\n    #undef JSON_HEDLEY_WARNING\n#endif\n#if JSON_HEDLEY_HAS_WARNING(\"-Wunknown-pragmas\")\n#  define JSON_HEDLEY_WARNING(msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \\\n    JSON_HEDLEY_PRAGMA(clang warning msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#elif \\\n  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \\\n  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \\\n  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)\n#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)\n#elif \\\n  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \\\n  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))\n#else\n#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)\n#endif\n\n#if defined(JSON_HEDLEY_REQUIRE)\n    #undef JSON_HEDLEY_REQUIRE\n#endif\n#if defined(JSON_HEDLEY_REQUIRE_MSG)\n    #undef JSON_HEDLEY_REQUIRE_MSG\n#endif\n#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)\n#  if JSON_HEDLEY_HAS_WARNING(\"-Wgcc-compat\")\n#    define JSON_HEDLEY_REQUIRE(expr) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wgcc-compat\\\"\") \\\n    __attribute__((diagnose_if(!(expr), #expr, \"error\"))) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \\\n    JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wgcc-compat\\\"\") \\\n    __attribute__((diagnose_if(!(expr), msg, \"error\"))) \\\n    JSON_HEDLEY_DIAGNOSTIC_POP\n#  else\n#    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, \"error\")))\n#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, \"error\")))\n#  endif\n#else\n#  define JSON_HEDLEY_REQUIRE(expr)\n#  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)\n#endif\n\n#if defined(JSON_HEDLEY_FLAGS)\n    #undef JSON_HEDLEY_FLAGS\n#endif\n#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING(\"-Wbitfield-enum-conversion\"))\n    #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))\n#else\n    #define JSON_HEDLEY_FLAGS\n#endif\n\n#if defined(JSON_HEDLEY_FLAGS_CAST)\n    #undef JSON_HEDLEY_FLAGS_CAST\n#endif\n#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)\n#  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \\\n        JSON_HEDLEY_DIAGNOSTIC_PUSH \\\n        _Pragma(\"warning(disable:188)\") \\\n        ((T) (expr)); \\\n        JSON_HEDLEY_DIAGNOSTIC_POP \\\n    }))\n#else\n#  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)\n#endif\n\n#if defined(JSON_HEDLEY_EMPTY_BASES)\n    #undef JSON_HEDLEY_EMPTY_BASES\n#endif\n#if \\\n    (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \\\n    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)\n    #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)\n#else\n    #define JSON_HEDLEY_EMPTY_BASES\n#endif\n\n/* Remaining macros are deprecated. */\n\n#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)\n    #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK\n#endif\n#if defined(__clang__)\n    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)\n#else\n    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)\n#endif\n\n#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)\n    #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)\n    #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)\n    #undef JSON_HEDLEY_CLANG_HAS_BUILTIN\n#endif\n#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)\n    #undef JSON_HEDLEY_CLANG_HAS_FEATURE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)\n    #undef JSON_HEDLEY_CLANG_HAS_EXTENSION\n#endif\n#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)\n    #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE\n#endif\n#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)\n\n#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)\n    #undef JSON_HEDLEY_CLANG_HAS_WARNING\n#endif\n#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)\n\n#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */\n\n// #include <nlohmann/detail/meta/detected.hpp>\n\n\n#include <type_traits>\n\n// #include <nlohmann/detail/meta/void_t.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename ...Ts> struct make_void\n{\n    using type = void;\n};\ntemplate<typename ...Ts> using void_t = typename make_void<Ts...>::type;\n} // namespace detail\n}  // namespace nlohmann\n\n\n// https://en.cppreference.com/w/cpp/experimental/is_detected\nnamespace nlohmann\n{\nnamespace detail\n{\nstruct nonesuch\n{\n    nonesuch() = delete;\n    ~nonesuch() = delete;\n    nonesuch(nonesuch const&) = delete;\n    nonesuch(nonesuch const&&) = delete;\n    void operator=(nonesuch const&) = delete;\n    void operator=(nonesuch&&) = delete;\n};\n\ntemplate<class Default,\n         class AlwaysVoid,\n         template<class...> class Op,\n         class... Args>\nstruct detector\n{\n    using value_t = std::false_type;\n    using type = Default;\n};\n\ntemplate<class Default, template<class...> class Op, class... Args>\nstruct detector<Default, void_t<Op<Args...>>, Op, Args...>\n{\n    using value_t = std::true_type;\n    using type = Op<Args...>;\n};\n\ntemplate<template<class...> class Op, class... Args>\nusing is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;\n\ntemplate<template<class...> class Op, class... Args>\nstruct is_detected_lazy : is_detected<Op, Args...> { };\n\ntemplate<template<class...> class Op, class... Args>\nusing detected_t = typename detector<nonesuch, void, Op, Args...>::type;\n\ntemplate<class Default, template<class...> class Op, class... Args>\nusing detected_or = detector<Default, void, Op, Args...>;\n\ntemplate<class Default, template<class...> class Op, class... Args>\nusing detected_or_t = typename detected_or<Default, Op, Args...>::type;\n\ntemplate<class Expected, template<class...> class Op, class... Args>\nusing is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;\n\ntemplate<class To, template<class...> class Op, class... Args>\nusing is_detected_convertible =\n    std::is_convertible<detected_t<Op, Args...>, To>;\n}  // namespace detail\n}  // namespace nlohmann\n\n\n// This file contains all internal macro definitions\n// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them\n\n// exclude unsupported compilers\n#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)\n    #if defined(__clang__)\n        #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400\n            #error \"unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers\"\n        #endif\n    #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))\n        #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800\n            #error \"unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers\"\n        #endif\n    #endif\n#endif\n\n// C++ language standard detection\n// if the user manually specified the used c++ version this is skipped\n#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)\n    #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)\n        #define JSON_HAS_CPP_20\n        #define JSON_HAS_CPP_17\n        #define JSON_HAS_CPP_14\n    #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464\n        #define JSON_HAS_CPP_17\n        #define JSON_HAS_CPP_14\n    #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)\n        #define JSON_HAS_CPP_14\n    #endif\n    // the cpp 11 flag is always specified because it is the minimal required version\n    #define JSON_HAS_CPP_11\n#endif\n\n#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)\n    #ifdef JSON_HAS_CPP_17\n        #if defined(__cpp_lib_filesystem)\n            #define JSON_HAS_FILESYSTEM 1\n        #elif defined(__cpp_lib_experimental_filesystem)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #elif !defined(__has_include)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #elif __has_include(<filesystem>)\n            #define JSON_HAS_FILESYSTEM 1\n        #elif __has_include(<experimental/filesystem>)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #endif\n\n        // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/\n        #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(__clang_major__) && __clang_major__ < 7\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(_MSC_VER) && _MSC_VER < 1940\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before iOS 13\n        #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before macOS Catalina\n        #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n    #endif\n#endif\n\n#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n    #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0\n#endif\n\n#ifndef JSON_HAS_FILESYSTEM\n    #define JSON_HAS_FILESYSTEM 0\n#endif\n\n// disable documentation warnings on clang\n#if defined(__clang__)\n    #pragma clang diagnostic push\n    #pragma clang diagnostic ignored \"-Wdocumentation\"\n    #pragma clang diagnostic ignored \"-Wdocumentation-unknown-command\"\n#endif\n\n// allow disabling exceptions\n#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)\n    #define JSON_THROW(exception) throw exception\n    #define JSON_TRY try\n    #define JSON_CATCH(exception) catch(exception)\n    #define JSON_INTERNAL_CATCH(exception) catch(exception)\n#else\n    #include <cstdlib>\n    #define JSON_THROW(exception) std::abort()\n    #define JSON_TRY if(true)\n    #define JSON_CATCH(exception) if(false)\n    #define JSON_INTERNAL_CATCH(exception) if(false)\n#endif\n\n// override exception macros\n#if defined(JSON_THROW_USER)\n    #undef JSON_THROW\n    #define JSON_THROW JSON_THROW_USER\n#endif\n#if defined(JSON_TRY_USER)\n    #undef JSON_TRY\n    #define JSON_TRY JSON_TRY_USER\n#endif\n#if defined(JSON_CATCH_USER)\n    #undef JSON_CATCH\n    #define JSON_CATCH JSON_CATCH_USER\n    #undef JSON_INTERNAL_CATCH\n    #define JSON_INTERNAL_CATCH JSON_CATCH_USER\n#endif\n#if defined(JSON_INTERNAL_CATCH_USER)\n    #undef JSON_INTERNAL_CATCH\n    #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER\n#endif\n\n// allow overriding assert\n#if !defined(JSON_ASSERT)\n    #include <cassert> // assert\n    #define JSON_ASSERT(x) assert(x)\n#endif\n\n// allow to access some private functions (needed by the test suite)\n#if defined(JSON_TESTS_PRIVATE)\n    #define JSON_PRIVATE_UNLESS_TESTED public\n#else\n    #define JSON_PRIVATE_UNLESS_TESTED private\n#endif\n\n/*!\n@brief macro to briefly define a mapping between an enum and JSON\n@def NLOHMANN_JSON_SERIALIZE_ENUM\n@since version 3.4.0\n*/\n#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \\\n    template<typename BasicJsonType>                                                            \\\n    inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \\\n    {                                                                                           \\\n        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE \" must be an enum!\");          \\\n        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \\\n        auto it = std::find_if(std::begin(m), std::end(m),                                      \\\n                               [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \\\n        {                                                                                       \\\n            return ej_pair.first == e;                                                          \\\n        });                                                                                     \\\n        j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \\\n    }                                                                                           \\\n    template<typename BasicJsonType>                                                            \\\n    inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \\\n    {                                                                                           \\\n        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE \" must be an enum!\");          \\\n        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \\\n        auto it = std::find_if(std::begin(m), std::end(m),                                      \\\n                               [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \\\n        {                                                                                       \\\n            return ej_pair.second == j;                                                         \\\n        });                                                                                     \\\n        e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \\\n    }\n\n// Ugly macros to avoid uglier copy-paste when specializing basic_json. They\n// may be removed in the future once the class is split.\n\n#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \\\n    template<template<typename, typename, typename...> class ObjectType,   \\\n             template<typename, typename...> class ArrayType,              \\\n             class StringType, class BooleanType, class NumberIntegerType, \\\n             class NumberUnsignedType, class NumberFloatType,              \\\n             template<typename> class AllocatorType,                       \\\n             template<typename, typename = void> class JSONSerializer,     \\\n             class BinaryType>\n\n#define NLOHMANN_BASIC_JSON_TPL                                            \\\n    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \\\n    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \\\n    AllocatorType, JSONSerializer, BinaryType>\n\n// Macros to simplify conversion from/to types\n\n#define NLOHMANN_JSON_EXPAND( x ) x\n#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME\n#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \\\n        NLOHMANN_JSON_PASTE64, \\\n        NLOHMANN_JSON_PASTE63, \\\n        NLOHMANN_JSON_PASTE62, \\\n        NLOHMANN_JSON_PASTE61, \\\n        NLOHMANN_JSON_PASTE60, \\\n        NLOHMANN_JSON_PASTE59, \\\n        NLOHMANN_JSON_PASTE58, \\\n        NLOHMANN_JSON_PASTE57, \\\n        NLOHMANN_JSON_PASTE56, \\\n        NLOHMANN_JSON_PASTE55, \\\n        NLOHMANN_JSON_PASTE54, \\\n        NLOHMANN_JSON_PASTE53, \\\n        NLOHMANN_JSON_PASTE52, \\\n        NLOHMANN_JSON_PASTE51, \\\n        NLOHMANN_JSON_PASTE50, \\\n        NLOHMANN_JSON_PASTE49, \\\n        NLOHMANN_JSON_PASTE48, \\\n        NLOHMANN_JSON_PASTE47, \\\n        NLOHMANN_JSON_PASTE46, \\\n        NLOHMANN_JSON_PASTE45, \\\n        NLOHMANN_JSON_PASTE44, \\\n        NLOHMANN_JSON_PASTE43, \\\n        NLOHMANN_JSON_PASTE42, \\\n        NLOHMANN_JSON_PASTE41, \\\n        NLOHMANN_JSON_PASTE40, \\\n        NLOHMANN_JSON_PASTE39, \\\n        NLOHMANN_JSON_PASTE38, \\\n        NLOHMANN_JSON_PASTE37, \\\n        NLOHMANN_JSON_PASTE36, \\\n        NLOHMANN_JSON_PASTE35, \\\n        NLOHMANN_JSON_PASTE34, \\\n        NLOHMANN_JSON_PASTE33, \\\n        NLOHMANN_JSON_PASTE32, \\\n        NLOHMANN_JSON_PASTE31, \\\n        NLOHMANN_JSON_PASTE30, \\\n        NLOHMANN_JSON_PASTE29, \\\n        NLOHMANN_JSON_PASTE28, \\\n        NLOHMANN_JSON_PASTE27, \\\n        NLOHMANN_JSON_PASTE26, \\\n        NLOHMANN_JSON_PASTE25, \\\n        NLOHMANN_JSON_PASTE24, \\\n        NLOHMANN_JSON_PASTE23, \\\n        NLOHMANN_JSON_PASTE22, \\\n        NLOHMANN_JSON_PASTE21, \\\n        NLOHMANN_JSON_PASTE20, \\\n        NLOHMANN_JSON_PASTE19, \\\n        NLOHMANN_JSON_PASTE18, \\\n        NLOHMANN_JSON_PASTE17, \\\n        NLOHMANN_JSON_PASTE16, \\\n        NLOHMANN_JSON_PASTE15, \\\n        NLOHMANN_JSON_PASTE14, \\\n        NLOHMANN_JSON_PASTE13, \\\n        NLOHMANN_JSON_PASTE12, \\\n        NLOHMANN_JSON_PASTE11, \\\n        NLOHMANN_JSON_PASTE10, \\\n        NLOHMANN_JSON_PASTE9, \\\n        NLOHMANN_JSON_PASTE8, \\\n        NLOHMANN_JSON_PASTE7, \\\n        NLOHMANN_JSON_PASTE6, \\\n        NLOHMANN_JSON_PASTE5, \\\n        NLOHMANN_JSON_PASTE4, \\\n        NLOHMANN_JSON_PASTE3, \\\n        NLOHMANN_JSON_PASTE2, \\\n        NLOHMANN_JSON_PASTE1)(__VA_ARGS__))\n#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)\n#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)\n#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)\n#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)\n#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)\n#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)\n#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)\n#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)\n#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)\n#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)\n#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)\n#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)\n#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)\n#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)\n#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)\n#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)\n#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)\n#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)\n#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)\n#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)\n#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)\n#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)\n#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)\n#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)\n#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)\n#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)\n#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)\n#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)\n#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)\n#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)\n#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)\n#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)\n#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)\n#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)\n#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)\n#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)\n#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)\n#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)\n#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)\n#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)\n#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)\n#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)\n#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)\n#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)\n#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)\n#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)\n#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)\n#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)\n#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)\n#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)\n#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)\n#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)\n#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)\n#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)\n#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)\n#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)\n#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)\n#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)\n#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)\n#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)\n#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)\n#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)\n#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)\n\n#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;\n#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);\n\n/*!\n@brief macro\n@def NLOHMANN_DEFINE_TYPE_INTRUSIVE\n@since version 3.9.0\n*/\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \\\n    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \\\n    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }\n\n/*!\n@brief macro\n@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE\n@since version 3.9.0\n*/\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \\\n    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \\\n    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }\n\n\n// inspired from https://stackoverflow.com/a/26745591\n// allows to call any std function as if (e.g. with begin):\n// using std::begin; begin(x);\n//\n// it allows using the detected idiom to retrieve the return type\n// of such an expression\n#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)                                 \\\n    namespace detail {                                                            \\\n    using std::std_name;                                                          \\\n    \\\n    template<typename... T>                                                       \\\n    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \\\n    }                                                                             \\\n    \\\n    namespace detail2 {                                                           \\\n    struct std_name##_tag                                                         \\\n    {                                                                             \\\n    };                                                                            \\\n    \\\n    template<typename... T>                                                       \\\n    std_name##_tag std_name(T&&...);                                              \\\n    \\\n    template<typename... T>                                                       \\\n    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \\\n    \\\n    template<typename... T>                                                       \\\n    struct would_call_std_##std_name                                              \\\n    {                                                                             \\\n        static constexpr auto const value = ::nlohmann::detail::                  \\\n                                            is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \\\n    };                                                                            \\\n    } /* namespace detail2 */ \\\n    \\\n    template<typename... T>                                                       \\\n    struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...>   \\\n    {                                                                             \\\n    }\n\n#ifndef JSON_USE_IMPLICIT_CONVERSIONS\n    #define JSON_USE_IMPLICIT_CONVERSIONS 1\n#endif\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    #define JSON_EXPLICIT\n#else\n    #define JSON_EXPLICIT explicit\n#endif\n\n#ifndef JSON_DIAGNOSTICS\n    #define JSON_DIAGNOSTICS 0\n#endif\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n/*!\n@brief replace all occurrences of a substring by another string\n\n@param[in,out] s  the string to manipulate; changed so that all\n               occurrences of @a f are replaced with @a t\n@param[in]     f  the substring to replace with @a t\n@param[in]     t  the string to replace @a f\n\n@pre The search string @a f must not be empty. **This precondition is\nenforced with an assertion.**\n\n@since version 2.0.0\n*/\ninline void replace_substring(std::string& s, const std::string& f,\n                              const std::string& t)\n{\n    JSON_ASSERT(!f.empty());\n    for (auto pos = s.find(f);                // find first occurrence of f\n            pos != std::string::npos;         // make sure f was found\n            s.replace(pos, f.size(), t),      // replace with t, and\n            pos = s.find(f, pos + t.size()))  // find next occurrence of f\n    {}\n}\n\n/*!\n * @brief string escaping as described in RFC 6901 (Sect. 4)\n * @param[in] s string to escape\n * @return    escaped string\n *\n * Note the order of escaping \"~\" to \"~0\" and \"/\" to \"~1\" is important.\n */\ninline std::string escape(std::string s)\n{\n    replace_substring(s, \"~\", \"~0\");\n    replace_substring(s, \"/\", \"~1\");\n    return s;\n}\n\n/*!\n * @brief string unescaping as described in RFC 6901 (Sect. 4)\n * @param[in] s string to unescape\n * @return    unescaped string\n *\n * Note the order of escaping \"~1\" to \"/\" and \"~0\" to \"~\" is important.\n */\nstatic void unescape(std::string& s)\n{\n    replace_substring(s, \"~1\", \"/\");\n    replace_substring(s, \"~0\", \"~\");\n}\n\n} // namespace detail\n} // namespace nlohmann\n\n// #include <nlohmann/detail/input/position_t.hpp>\n\n\n#include <cstddef> // size_t\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/// struct to capture the start position of the current token\nstruct position_t\n{\n    /// the total number of characters read\n    std::size_t chars_read_total = 0;\n    /// the number of characters read in the current line\n    std::size_t chars_read_current_line = 0;\n    /// the number of lines read\n    std::size_t lines_read = 0;\n\n    /// conversion to size_t to preserve SAX interface\n    constexpr operator size_t() const\n    {\n        return chars_read_total;\n    }\n};\n\n} // namespace detail\n} // namespace nlohmann\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n////////////////\n// exceptions //\n////////////////\n\n/// @brief general exception of the @ref basic_json class\n/// @sa https://json.nlohmann.me/api/basic_json/exception/\nclass exception : public std::exception\n{\n  public:\n    /// returns the explanatory string\n    const char* what() const noexcept override\n    {\n        return m.what();\n    }\n\n    /// the id of the exception\n    const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)\n\n  protected:\n    JSON_HEDLEY_NON_NULL(3)\n    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)\n\n    static std::string name(const std::string& ename, int id_)\n    {\n        return \"[json.exception.\" + ename + \".\" + std::to_string(id_) + \"] \";\n    }\n\n    template<typename BasicJsonType>\n    static std::string diagnostics(const BasicJsonType& leaf_element)\n    {\n#if JSON_DIAGNOSTICS\n        std::vector<std::string> tokens;\n        for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)\n        {\n            switch (current->m_parent->type())\n            {\n                case value_t::array:\n                {\n                    for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)\n                    {\n                        if (&current->m_parent->m_value.array->operator[](i) == current)\n                        {\n                            tokens.emplace_back(std::to_string(i));\n                            break;\n                        }\n                    }\n                    break;\n                }\n\n                case value_t::object:\n                {\n                    for (const auto& element : *current->m_parent->m_value.object)\n                    {\n                        if (&element.second == current)\n                        {\n                            tokens.emplace_back(element.first.c_str());\n                            break;\n                        }\n                    }\n                    break;\n                }\n\n                case value_t::null: // LCOV_EXCL_LINE\n                case value_t::string: // LCOV_EXCL_LINE\n                case value_t::boolean: // LCOV_EXCL_LINE\n                case value_t::number_integer: // LCOV_EXCL_LINE\n                case value_t::number_unsigned: // LCOV_EXCL_LINE\n                case value_t::number_float: // LCOV_EXCL_LINE\n                case value_t::binary: // LCOV_EXCL_LINE\n                case value_t::discarded: // LCOV_EXCL_LINE\n                default:   // LCOV_EXCL_LINE\n                    break; // LCOV_EXCL_LINE\n            }\n        }\n\n        if (tokens.empty())\n        {\n            return \"\";\n        }\n\n        return \"(\" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},\n                                     [](const std::string & a, const std::string & b)\n        {\n            return a + \"/\" + detail::escape(b);\n        }) + \") \";\n#else\n        static_cast<void>(leaf_element);\n        return \"\";\n#endif\n    }\n\n  private:\n    /// an exception object as storage for error messages\n    std::runtime_error m;\n};\n\n/// @brief exception indicating a parse error\n/// @sa https://json.nlohmann.me/api/basic_json/parse_error/\nclass parse_error : public exception\n{\n  public:\n    /*!\n    @brief create a parse error exception\n    @param[in] id_       the id of the exception\n    @param[in] pos       the position where the error occurred (or with\n                         chars_read_total=0 if the position cannot be\n                         determined)\n    @param[in] what_arg  the explanatory string\n    @return parse_error object\n    */\n    template<typename BasicJsonType>\n    static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"parse_error\", id_) + \"parse error\" +\n                        position_string(pos) + \": \" + exception::diagnostics(context) + what_arg;\n        return {id_, pos.chars_read_total, w.c_str()};\n    }\n\n    template<typename BasicJsonType>\n    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"parse_error\", id_) + \"parse error\" +\n                        (byte_ != 0 ? (\" at byte \" + std::to_string(byte_)) : \"\") +\n                        \": \" + exception::diagnostics(context) + what_arg;\n        return {id_, byte_, w.c_str()};\n    }\n\n    /*!\n    @brief byte index of the parse error\n\n    The byte index of the last read character in the input file.\n\n    @note For an input with n bytes, 1 is the index of the first character and\n          n+1 is the index of the terminating null byte or the end of file.\n          This also holds true when reading a byte vector (CBOR or MessagePack).\n    */\n    const std::size_t byte;\n\n  private:\n    parse_error(int id_, std::size_t byte_, const char* what_arg)\n        : exception(id_, what_arg), byte(byte_) {}\n\n    static std::string position_string(const position_t& pos)\n    {\n        return \" at line \" + std::to_string(pos.lines_read + 1) +\n               \", column \" + std::to_string(pos.chars_read_current_line);\n    }\n};\n\n/// @brief exception indicating errors with iterators\n/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/\nclass invalid_iterator : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"invalid_iterator\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    invalid_iterator(int id_, const char* what_arg)\n        : exception(id_, what_arg) {}\n};\n\n/// @brief exception indicating executing a member function with a wrong type\n/// @sa https://json.nlohmann.me/api/basic_json/type_error/\nclass type_error : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"type_error\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}\n};\n\n/// @brief exception indicating access out of the defined range\n/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/\nclass out_of_range : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"out_of_range\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}\n};\n\n/// @brief exception indicating other library errors\n/// @sa https://json.nlohmann.me/api/basic_json/other_error/\nclass other_error : public exception\n{\n  public:\n    template<typename BasicJsonType>\n    static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)\n    {\n        std::string w = exception::name(\"other_error\", id_) + exception::diagnostics(context) + what_arg;\n        return {id_, w.c_str()};\n    }\n\n  private:\n    JSON_HEDLEY_NON_NULL(3)\n    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}\n};\n\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/meta/cpp_future.hpp>\n\n\n#include <cstddef> // size_t\n#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type\n#include <utility> // index_sequence, make_index_sequence, index_sequence_for\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\ntemplate<typename T>\nusing uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;\n\n#ifdef JSON_HAS_CPP_14\n\n// the following utilities are natively available in C++14\nusing std::enable_if_t;\nusing std::index_sequence;\nusing std::make_index_sequence;\nusing std::index_sequence_for;\n\n#else\n\n// alias templates to reduce boilerplate\ntemplate<bool B, typename T = void>\nusing enable_if_t = typename std::enable_if<B, T>::type;\n\n// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h\n// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.\n\n//// START OF CODE FROM GOOGLE ABSEIL\n\n// integer_sequence\n//\n// Class template representing a compile-time integer sequence. An instantiation\n// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its\n// type through its template arguments (which is a common need when\n// working with C++11 variadic templates). `absl::integer_sequence` is designed\n// to be a drop-in replacement for C++14's `std::integer_sequence`.\n//\n// Example:\n//\n//   template< class T, T... Ints >\n//   void user_function(integer_sequence<T, Ints...>);\n//\n//   int main()\n//   {\n//     // user_function's `T` will be deduced to `int` and `Ints...`\n//     // will be deduced to `0, 1, 2, 3, 4`.\n//     user_function(make_integer_sequence<int, 5>());\n//   }\ntemplate <typename T, T... Ints>\nstruct integer_sequence\n{\n    using value_type = T;\n    static constexpr std::size_t size() noexcept\n    {\n        return sizeof...(Ints);\n    }\n};\n\n// index_sequence\n//\n// A helper template for an `integer_sequence` of `size_t`,\n// `absl::index_sequence` is designed to be a drop-in replacement for C++14's\n// `std::index_sequence`.\ntemplate <size_t... Ints>\nusing index_sequence = integer_sequence<size_t, Ints...>;\n\nnamespace utility_internal\n{\n\ntemplate <typename Seq, size_t SeqSize, size_t Rem>\nstruct Extend;\n\n// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.\ntemplate <typename T, T... Ints, size_t SeqSize>\nstruct Extend<integer_sequence<T, Ints...>, SeqSize, 0>\n{\n    using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;\n};\n\ntemplate <typename T, T... Ints, size_t SeqSize>\nstruct Extend<integer_sequence<T, Ints...>, SeqSize, 1>\n{\n    using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;\n};\n\n// Recursion helper for 'make_integer_sequence<T, N>'.\n// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.\ntemplate <typename T, size_t N>\nstruct Gen\n{\n    using type =\n        typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;\n};\n\ntemplate <typename T>\nstruct Gen<T, 0>\n{\n    using type = integer_sequence<T>;\n};\n\n}  // namespace utility_internal\n\n// Compile-time sequences of integers\n\n// make_integer_sequence\n//\n// This template alias is equivalent to\n// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in\n// replacement for C++14's `std::make_integer_sequence`.\ntemplate <typename T, T N>\nusing make_integer_sequence = typename utility_internal::Gen<T, N>::type;\n\n// make_index_sequence\n//\n// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,\n// and is designed to be a drop-in replacement for C++14's\n// `std::make_index_sequence`.\ntemplate <size_t N>\nusing make_index_sequence = make_integer_sequence<size_t, N>;\n\n// index_sequence_for\n//\n// Converts a typename pack into an index sequence of the same length, and\n// is designed to be a drop-in replacement for C++14's\n// `std::index_sequence_for()`\ntemplate <typename... Ts>\nusing index_sequence_for = make_index_sequence<sizeof...(Ts)>;\n\n//// END OF CODE FROM GOOGLE ABSEIL\n\n#endif\n\n// dispatch utility (taken from ranges-v3)\ntemplate<unsigned N> struct priority_tag : priority_tag < N - 1 > {};\ntemplate<> struct priority_tag<0> {};\n\n// taken from ranges-v3\ntemplate<typename T>\nstruct static_const\n{\n    static constexpr T value{};\n};\n\ntemplate<typename T>\nconstexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)\n\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/meta/identity_tag.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n// dispatching helper struct\ntemplate <class T> struct identity_tag {};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n\n#include <limits> // numeric_limits\n#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type\n#include <utility> // declval\n#include <tuple> // tuple\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\n// #include <nlohmann/detail/iterators/iterator_traits.hpp>\n\n\n#include <iterator> // random_access_iterator_tag\n\n// #include <nlohmann/detail/meta/void_t.hpp>\n\n// #include <nlohmann/detail/meta/cpp_future.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename It, typename = void>\nstruct iterator_types {};\n\ntemplate<typename It>\nstruct iterator_types <\n    It,\n    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,\n    typename It::reference, typename It::iterator_category >>\n{\n    using difference_type = typename It::difference_type;\n    using value_type = typename It::value_type;\n    using pointer = typename It::pointer;\n    using reference = typename It::reference;\n    using iterator_category = typename It::iterator_category;\n};\n\n// This is required as some compilers implement std::iterator_traits in a way that\n// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.\ntemplate<typename T, typename = void>\nstruct iterator_traits\n{\n};\n\ntemplate<typename T>\nstruct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>\n            : iterator_types<T>\n{\n};\n\ntemplate<typename T>\nstruct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>\n{\n    using iterator_category = std::random_access_iterator_tag;\n    using value_type = T;\n    using difference_type = ptrdiff_t;\n    using pointer = T*;\n    using reference = T&;\n};\n} // namespace detail\n} // namespace nlohmann\n\n// #include <nlohmann/detail/meta/call_std/begin.hpp>\n\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nNLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);\n} // namespace nlohmann\n\n// #include <nlohmann/detail/meta/call_std/end.hpp>\n\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nNLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/meta/cpp_future.hpp>\n\n// #include <nlohmann/detail/meta/detected.hpp>\n\n// #include <nlohmann/json_fwd.hpp>\n#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_\n#define INCLUDE_NLOHMANN_JSON_FWD_HPP_\n\n#include <cstdint> // int64_t, uint64_t\n#include <map> // map\n#include <memory> // allocator\n#include <string> // string\n#include <vector> // vector\n\n/*!\n@brief namespace for Niels Lohmann\n@see https://github.com/nlohmann\n@since version 1.0.0\n*/\nnamespace nlohmann\n{\n/*!\n@brief default JSONSerializer template argument\n\nThis serializer ignores the template arguments and uses ADL\n([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))\nfor serialization.\n*/\ntemplate<typename T = void, typename SFINAE = void>\nstruct adl_serializer;\n\n/// a class to store JSON values\n/// @sa https://json.nlohmann.me/api/basic_json/\ntemplate<template<typename U, typename V, typename... Args> class ObjectType =\n         std::map,\n         template<typename U, typename... Args> class ArrayType = std::vector,\n         class StringType = std::string, class BooleanType = bool,\n         class NumberIntegerType = std::int64_t,\n         class NumberUnsignedType = std::uint64_t,\n         class NumberFloatType = double,\n         template<typename U> class AllocatorType = std::allocator,\n         template<typename T, typename SFINAE = void> class JSONSerializer =\n         adl_serializer,\n         class BinaryType = std::vector<std::uint8_t>>\nclass basic_json;\n\n/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document\n/// @sa https://json.nlohmann.me/api/json_pointer/\ntemplate<typename BasicJsonType>\nclass json_pointer;\n\n/*!\n@brief default specialization\n@sa https://json.nlohmann.me/api/json/\n*/\nusing json = basic_json<>;\n\n/// @brief a minimal map-like container that preserves insertion order\n/// @sa https://json.nlohmann.me/api/ordered_map/\ntemplate<class Key, class T, class IgnoredLess, class Allocator>\nstruct ordered_map;\n\n/// @brief specialization that maintains the insertion order of object keys\n/// @sa https://json.nlohmann.me/api/ordered_json/\nusing ordered_json = basic_json<nlohmann::ordered_map>;\n\n}  // namespace nlohmann\n\n#endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_\n\n\nnamespace nlohmann\n{\n/*!\n@brief detail namespace with internal helper functions\n\nThis namespace collects functions that should not be exposed,\nimplementations of some @ref basic_json methods, and meta-programming helpers.\n\n@since version 2.1.0\n*/\nnamespace detail\n{\n/////////////\n// helpers //\n/////////////\n\n// Note to maintainers:\n//\n// Every trait in this file expects a non CV-qualified type.\n// The only exceptions are in the 'aliases for detected' section\n// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))\n//\n// In this case, T has to be properly CV-qualified to constraint the function arguments\n// (e.g. to_json(BasicJsonType&, const T&))\n\ntemplate<typename> struct is_basic_json : std::false_type {};\n\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nstruct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};\n\n//////////////////////\n// json_ref helpers //\n//////////////////////\n\ntemplate<typename>\nclass json_ref;\n\ntemplate<typename>\nstruct is_json_ref : std::false_type {};\n\ntemplate<typename T>\nstruct is_json_ref<json_ref<T>> : std::true_type {};\n\n//////////////////////////\n// aliases for detected //\n//////////////////////////\n\ntemplate<typename T>\nusing mapped_type_t = typename T::mapped_type;\n\ntemplate<typename T>\nusing key_type_t = typename T::key_type;\n\ntemplate<typename T>\nusing value_type_t = typename T::value_type;\n\ntemplate<typename T>\nusing difference_type_t = typename T::difference_type;\n\ntemplate<typename T>\nusing pointer_t = typename T::pointer;\n\ntemplate<typename T>\nusing reference_t = typename T::reference;\n\ntemplate<typename T>\nusing iterator_category_t = typename T::iterator_category;\n\ntemplate<typename T, typename... Args>\nusing to_json_function = decltype(T::to_json(std::declval<Args>()...));\n\ntemplate<typename T, typename... Args>\nusing from_json_function = decltype(T::from_json(std::declval<Args>()...));\n\ntemplate<typename T, typename U>\nusing get_template_function = decltype(std::declval<T>().template get<U>());\n\n// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists\ntemplate<typename BasicJsonType, typename T, typename = void>\nstruct has_from_json : std::false_type {};\n\n// trait checking if j.get<T> is valid\n// use this trait instead of std::is_constructible or std::is_convertible,\n// both rely on, or make use of implicit conversions, and thus fail when T\n// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)\ntemplate <typename BasicJsonType, typename T>\nstruct is_getable\n{\n    static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;\n};\n\ntemplate<typename BasicJsonType, typename T>\nstruct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>\n{\n    using serializer = typename BasicJsonType::template json_serializer<T, void>;\n\n    static constexpr bool value =\n        is_detected_exact<void, from_json_function, serializer,\n        const BasicJsonType&, T&>::value;\n};\n\n// This trait checks if JSONSerializer<T>::from_json(json const&) exists\n// this overload is used for non-default-constructible user-defined-types\ntemplate<typename BasicJsonType, typename T, typename = void>\nstruct has_non_default_from_json : std::false_type {};\n\ntemplate<typename BasicJsonType, typename T>\nstruct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>\n{\n    using serializer = typename BasicJsonType::template json_serializer<T, void>;\n\n    static constexpr bool value =\n        is_detected_exact<T, from_json_function, serializer,\n        const BasicJsonType&>::value;\n};\n\n// This trait checks if BasicJsonType::json_serializer<T>::to_json exists\n// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.\ntemplate<typename BasicJsonType, typename T, typename = void>\nstruct has_to_json : std::false_type {};\n\ntemplate<typename BasicJsonType, typename T>\nstruct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>\n{\n    using serializer = typename BasicJsonType::template json_serializer<T, void>;\n\n    static constexpr bool value =\n        is_detected_exact<void, to_json_function, serializer, BasicJsonType&,\n        T>::value;\n};\n\n\n///////////////////\n// is_ functions //\n///////////////////\n\n// https://en.cppreference.com/w/cpp/types/conjunction\ntemplate<class...> struct conjunction : std::true_type { };\ntemplate<class B1> struct conjunction<B1> : B1 { };\ntemplate<class B1, class... Bn>\nstruct conjunction<B1, Bn...>\n: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};\n\n// https://en.cppreference.com/w/cpp/types/negation\ntemplate<class B> struct negation : std::integral_constant < bool, !B::value > { };\n\n// Reimplementation of is_constructible and is_default_constructible, due to them being broken for\n// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).\n// This causes compile errors in e.g. clang 3.5 or gcc 4.9.\ntemplate <typename T>\nstruct is_default_constructible : std::is_default_constructible<T> {};\n\ntemplate <typename T1, typename T2>\nstruct is_default_constructible<std::pair<T1, T2>>\n            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};\n\ntemplate <typename T1, typename T2>\nstruct is_default_constructible<const std::pair<T1, T2>>\n            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};\n\ntemplate <typename... Ts>\nstruct is_default_constructible<std::tuple<Ts...>>\n            : conjunction<is_default_constructible<Ts>...> {};\n\ntemplate <typename... Ts>\nstruct is_default_constructible<const std::tuple<Ts...>>\n            : conjunction<is_default_constructible<Ts>...> {};\n\n\ntemplate <typename T, typename... Args>\nstruct is_constructible : std::is_constructible<T, Args...> {};\n\ntemplate <typename T1, typename T2>\nstruct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};\n\ntemplate <typename T1, typename T2>\nstruct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};\n\ntemplate <typename... Ts>\nstruct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};\n\ntemplate <typename... Ts>\nstruct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};\n\n\ntemplate<typename T, typename = void>\nstruct is_iterator_traits : std::false_type {};\n\ntemplate<typename T>\nstruct is_iterator_traits<iterator_traits<T>>\n{\n  private:\n    using traits = iterator_traits<T>;\n\n  public:\n    static constexpr auto value =\n        is_detected<value_type_t, traits>::value &&\n        is_detected<difference_type_t, traits>::value &&\n        is_detected<pointer_t, traits>::value &&\n        is_detected<iterator_category_t, traits>::value &&\n        is_detected<reference_t, traits>::value;\n};\n\ntemplate<typename T>\nstruct is_range\n{\n  private:\n    using t_ref = typename std::add_lvalue_reference<T>::type;\n\n    using iterator = detected_t<result_of_begin, t_ref>;\n    using sentinel = detected_t<result_of_end, t_ref>;\n\n    // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator\n    // and https://en.cppreference.com/w/cpp/iterator/sentinel_for\n    // but reimplementing these would be too much work, as a lot of other concepts are used underneath\n    static constexpr auto is_iterator_begin =\n        is_iterator_traits<iterator_traits<iterator>>::value;\n\n  public:\n    static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;\n};\n\ntemplate<typename R>\nusing iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;\n\ntemplate<typename T>\nusing range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;\n\n// The following implementation of is_complete_type is taken from\n// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/\n// and is written by Xiang Fan who agreed to using it in this library.\n\ntemplate<typename T, typename = void>\nstruct is_complete_type : std::false_type {};\n\ntemplate<typename T>\nstruct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleObjectType,\n         typename = void>\nstruct is_compatible_object_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleObjectType>\nstruct is_compatible_object_type_impl <\n    BasicJsonType, CompatibleObjectType,\n    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&\n    is_detected<key_type_t, CompatibleObjectType>::value >>\n{\n    using object_t = typename BasicJsonType::object_t;\n\n    // macOS's is_constructible does not play well with nonesuch...\n    static constexpr bool value =\n        is_constructible<typename object_t::key_type,\n        typename CompatibleObjectType::key_type>::value &&\n        is_constructible<typename object_t::mapped_type,\n        typename CompatibleObjectType::mapped_type>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleObjectType>\nstruct is_compatible_object_type\n    : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType,\n         typename = void>\nstruct is_constructible_object_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType>\nstruct is_constructible_object_type_impl <\n    BasicJsonType, ConstructibleObjectType,\n    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&\n    is_detected<key_type_t, ConstructibleObjectType>::value >>\n{\n    using object_t = typename BasicJsonType::object_t;\n\n    static constexpr bool value =\n        (is_default_constructible<ConstructibleObjectType>::value &&\n         (std::is_move_assignable<ConstructibleObjectType>::value ||\n          std::is_copy_assignable<ConstructibleObjectType>::value) &&\n         (is_constructible<typename ConstructibleObjectType::key_type,\n          typename object_t::key_type>::value &&\n          std::is_same <\n          typename object_t::mapped_type,\n          typename ConstructibleObjectType::mapped_type >::value)) ||\n        (has_from_json<BasicJsonType,\n         typename ConstructibleObjectType::mapped_type>::value ||\n         has_non_default_from_json <\n         BasicJsonType,\n         typename ConstructibleObjectType::mapped_type >::value);\n};\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType>\nstruct is_constructible_object_type\n    : is_constructible_object_type_impl<BasicJsonType,\n      ConstructibleObjectType> {};\n\ntemplate<typename BasicJsonType, typename CompatibleStringType>\nstruct is_compatible_string_type\n{\n    static constexpr auto value =\n        is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;\n};\n\ntemplate<typename BasicJsonType, typename ConstructibleStringType>\nstruct is_constructible_string_type\n{\n    static constexpr auto value =\n        is_constructible<ConstructibleStringType,\n        typename BasicJsonType::string_t>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleArrayType, typename = void>\nstruct is_compatible_array_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleArrayType>\nstruct is_compatible_array_type_impl <\n    BasicJsonType, CompatibleArrayType,\n    enable_if_t <\n    is_detected<iterator_t, CompatibleArrayType>::value&&\n    is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&\n// special case for types like std::filesystem::path whose iterator's value_type are themselves\n// c.f. https://github.com/nlohmann/json/pull/3073\n    !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>\n{\n    static constexpr bool value =\n        is_constructible<BasicJsonType,\n        range_value_t<CompatibleArrayType>>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleArrayType>\nstruct is_compatible_array_type\n    : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType, typename = void>\nstruct is_constructible_array_type_impl : std::false_type {};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType>\nstruct is_constructible_array_type_impl <\n    BasicJsonType, ConstructibleArrayType,\n    enable_if_t<std::is_same<ConstructibleArrayType,\n    typename BasicJsonType::value_type>::value >>\n            : std::true_type {};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType>\nstruct is_constructible_array_type_impl <\n    BasicJsonType, ConstructibleArrayType,\n    enable_if_t < !std::is_same<ConstructibleArrayType,\n    typename BasicJsonType::value_type>::value&&\n    !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&\n    is_default_constructible<ConstructibleArrayType>::value&&\n(std::is_move_assignable<ConstructibleArrayType>::value ||\n std::is_copy_assignable<ConstructibleArrayType>::value)&&\nis_detected<iterator_t, ConstructibleArrayType>::value&&\nis_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&\nis_detected<range_value_t, ConstructibleArrayType>::value&&\n// special case for types like std::filesystem::path whose iterator's value_type are themselves\n// c.f. https://github.com/nlohmann/json/pull/3073\n!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&\n        is_complete_type <\n        detected_t<range_value_t, ConstructibleArrayType >>::value >>\n{\n    using value_type = range_value_t<ConstructibleArrayType>;\n\n    static constexpr bool value =\n        std::is_same<value_type,\n        typename BasicJsonType::array_t::value_type>::value ||\n        has_from_json<BasicJsonType,\n        value_type>::value ||\n        has_non_default_from_json <\n        BasicJsonType,\n        value_type >::value;\n};\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType>\nstruct is_constructible_array_type\n    : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};\n\ntemplate<typename RealIntegerType, typename CompatibleNumberIntegerType,\n         typename = void>\nstruct is_compatible_integer_type_impl : std::false_type {};\n\ntemplate<typename RealIntegerType, typename CompatibleNumberIntegerType>\nstruct is_compatible_integer_type_impl <\n    RealIntegerType, CompatibleNumberIntegerType,\n    enable_if_t < std::is_integral<RealIntegerType>::value&&\n    std::is_integral<CompatibleNumberIntegerType>::value&&\n    !std::is_same<bool, CompatibleNumberIntegerType>::value >>\n{\n    // is there an assert somewhere on overflows?\n    using RealLimits = std::numeric_limits<RealIntegerType>;\n    using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;\n\n    static constexpr auto value =\n        is_constructible<RealIntegerType,\n        CompatibleNumberIntegerType>::value &&\n        CompatibleLimits::is_integer &&\n        RealLimits::is_signed == CompatibleLimits::is_signed;\n};\n\ntemplate<typename RealIntegerType, typename CompatibleNumberIntegerType>\nstruct is_compatible_integer_type\n    : is_compatible_integer_type_impl<RealIntegerType,\n      CompatibleNumberIntegerType> {};\n\ntemplate<typename BasicJsonType, typename CompatibleType, typename = void>\nstruct is_compatible_type_impl: std::false_type {};\n\ntemplate<typename BasicJsonType, typename CompatibleType>\nstruct is_compatible_type_impl <\n    BasicJsonType, CompatibleType,\n    enable_if_t<is_complete_type<CompatibleType>::value >>\n{\n    static constexpr bool value =\n        has_to_json<BasicJsonType, CompatibleType>::value;\n};\n\ntemplate<typename BasicJsonType, typename CompatibleType>\nstruct is_compatible_type\n    : is_compatible_type_impl<BasicJsonType, CompatibleType> {};\n\ntemplate<typename T1, typename T2>\nstruct is_constructible_tuple : std::false_type {};\n\ntemplate<typename T1, typename... Args>\nstruct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};\n\n// a naive helper to check if a type is an ordered_map (exploits the fact that\n// ordered_map inherits capacity() from std::vector)\ntemplate <typename T>\nstruct is_ordered_map\n{\n    using one = char;\n\n    struct two\n    {\n        char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n    };\n\n    template <typename C> static one test( decltype(&C::capacity) ) ;\n    template <typename C> static two test(...);\n\n    enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n};\n\n// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)\ntemplate < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >\nT conditional_static_cast(U value)\n{\n    return static_cast<T>(value);\n}\n\ntemplate<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>\nT conditional_static_cast(U value)\n{\n    return value;\n}\n\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\n#if JSON_HAS_EXPERIMENTAL_FILESYSTEM\n#include <experimental/filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::experimental::filesystem;\n} // namespace nlohmann::detail\n#elif JSON_HAS_FILESYSTEM\n#include <filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::filesystem;\n} // namespace nlohmann::detail\n#endif\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename std::nullptr_t& n)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_null()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be null, but is \" + std::string(j.type_name()), j));\n    }\n    n = nullptr;\n}\n\n// overloads for basic_json template parameters\ntemplate < typename BasicJsonType, typename ArithmeticType,\n           enable_if_t < std::is_arithmetic<ArithmeticType>::value&&\n                         !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,\n                         int > = 0 >\nvoid get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)\n{\n    switch (static_cast<value_t>(j))\n    {\n        case value_t::number_unsigned:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());\n            break;\n        }\n        case value_t::number_integer:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());\n            break;\n        }\n        case value_t::number_float:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());\n            break;\n        }\n\n        case value_t::null:\n        case value_t::object:\n        case value_t::array:\n        case value_t::string:\n        case value_t::boolean:\n        case value_t::binary:\n        case value_t::discarded:\n        default:\n            JSON_THROW(type_error::create(302, \"type must be number, but is \" + std::string(j.type_name()), j));\n    }\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be boolean, but is \" + std::string(j.type_name()), j));\n    }\n    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be string, but is \" + std::string(j.type_name()), j));\n    }\n    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();\n}\n\ntemplate <\n    typename BasicJsonType, typename ConstructibleStringType,\n    enable_if_t <\n        is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&\n        !std::is_same<typename BasicJsonType::string_t,\n                      ConstructibleStringType>::value,\n        int > = 0 >\nvoid from_json(const BasicJsonType& j, ConstructibleStringType& s)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be string, but is \" + std::string(j.type_name()), j));\n    }\n\n    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)\n{\n    get_arithmetic_value(j, val);\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)\n{\n    get_arithmetic_value(j, val);\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)\n{\n    get_arithmetic_value(j, val);\n}\n\ntemplate<typename BasicJsonType, typename EnumType,\n         enable_if_t<std::is_enum<EnumType>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, EnumType& e)\n{\n    typename std::underlying_type<EnumType>::type val;\n    get_arithmetic_value(j, val);\n    e = static_cast<EnumType>(val);\n}\n\n// forward_list doesn't have an insert method\ntemplate<typename BasicJsonType, typename T, typename Allocator,\n         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    l.clear();\n    std::transform(j.rbegin(), j.rend(),\n                   std::front_inserter(l), [](const BasicJsonType & i)\n    {\n        return i.template get<T>();\n    });\n}\n\n// valarray doesn't have an insert method\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, std::valarray<T>& l)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    l.resize(j.size());\n    std::transform(j.begin(), j.end(), std::begin(l),\n                   [](const BasicJsonType & elem)\n    {\n        return elem.template get<T>();\n    });\n}\n\ntemplate<typename BasicJsonType, typename T, std::size_t N>\nauto from_json(const BasicJsonType& j, T (&arr)[N])  // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n-> decltype(j.template get<T>(), void())\n{\n    for (std::size_t i = 0; i < N; ++i)\n    {\n        arr[i] = j.at(i).template get<T>();\n    }\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)\n{\n    arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();\n}\n\ntemplate<typename BasicJsonType, typename T, std::size_t N>\nauto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,\n                          priority_tag<2> /*unused*/)\n-> decltype(j.template get<T>(), void())\n{\n    for (std::size_t i = 0; i < N; ++i)\n    {\n        arr[i] = j.at(i).template get<T>();\n    }\n}\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType,\n         enable_if_t<\n             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,\n             int> = 0>\nauto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)\n-> decltype(\n    arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),\n    j.template get<typename ConstructibleArrayType::value_type>(),\n    void())\n{\n    using std::end;\n\n    ConstructibleArrayType ret;\n    ret.reserve(j.size());\n    std::transform(j.begin(), j.end(),\n                   std::inserter(ret, end(ret)), [](const BasicJsonType & i)\n    {\n        // get<BasicJsonType>() returns *this, this won't call a from_json\n        // method when value_type is BasicJsonType\n        return i.template get<typename ConstructibleArrayType::value_type>();\n    });\n    arr = std::move(ret);\n}\n\ntemplate<typename BasicJsonType, typename ConstructibleArrayType,\n         enable_if_t<\n             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,\n             int> = 0>\nvoid from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,\n                          priority_tag<0> /*unused*/)\n{\n    using std::end;\n\n    ConstructibleArrayType ret;\n    std::transform(\n        j.begin(), j.end(), std::inserter(ret, end(ret)),\n        [](const BasicJsonType & i)\n    {\n        // get<BasicJsonType>() returns *this, this won't call a from_json\n        // method when value_type is BasicJsonType\n        return i.template get<typename ConstructibleArrayType::value_type>();\n    });\n    arr = std::move(ret);\n}\n\ntemplate < typename BasicJsonType, typename ConstructibleArrayType,\n           enable_if_t <\n               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&\n               !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&\n               !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&\n               !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&\n               !is_basic_json<ConstructibleArrayType>::value,\n               int > = 0 >\nauto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)\n-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),\nj.template get<typename ConstructibleArrayType::value_type>(),\nvoid())\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n\n    from_json_array_impl(j, arr, priority_tag<3> {});\n}\n\ntemplate < typename BasicJsonType, typename T, std::size_t... Idx >\nstd::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,\n        identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)\n{\n    return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };\n}\n\ntemplate < typename BasicJsonType, typename T, std::size_t N >\nauto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)\n-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n\n    return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be binary, but is \" + std::string(j.type_name()), j));\n    }\n\n    bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();\n}\n\ntemplate<typename BasicJsonType, typename ConstructibleObjectType,\n         enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>\nvoid from_json(const BasicJsonType& j, ConstructibleObjectType& obj)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_object()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be object, but is \" + std::string(j.type_name()), j));\n    }\n\n    ConstructibleObjectType ret;\n    const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();\n    using value_type = typename ConstructibleObjectType::value_type;\n    std::transform(\n        inner_object->begin(), inner_object->end(),\n        std::inserter(ret, ret.begin()),\n        [](typename BasicJsonType::object_t::value_type const & p)\n    {\n        return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());\n    });\n    obj = std::move(ret);\n}\n\n// overload for arithmetic types, not chosen for basic_json template arguments\n// (BooleanType, etc..); note: Is it really necessary to provide explicit\n// overloads for boolean_t etc. in case of a custom BooleanType which is not\n// an arithmetic type?\ntemplate < typename BasicJsonType, typename ArithmeticType,\n           enable_if_t <\n               std::is_arithmetic<ArithmeticType>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&\n               !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,\n               int > = 0 >\nvoid from_json(const BasicJsonType& j, ArithmeticType& val)\n{\n    switch (static_cast<value_t>(j))\n    {\n        case value_t::number_unsigned:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());\n            break;\n        }\n        case value_t::number_integer:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());\n            break;\n        }\n        case value_t::number_float:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());\n            break;\n        }\n        case value_t::boolean:\n        {\n            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());\n            break;\n        }\n\n        case value_t::null:\n        case value_t::object:\n        case value_t::array:\n        case value_t::string:\n        case value_t::binary:\n        case value_t::discarded:\n        default:\n            JSON_THROW(type_error::create(302, \"type must be number, but is \" + std::string(j.type_name()), j));\n    }\n}\n\ntemplate<typename BasicJsonType, typename... Args, std::size_t... Idx>\nstd::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)\n{\n    return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);\n}\n\ntemplate < typename BasicJsonType, class A1, class A2 >\nstd::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)\n{\n    return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),\n            std::forward<BasicJsonType>(j).at(1).template get<A2>()};\n}\n\ntemplate<typename BasicJsonType, typename A1, typename A2>\nvoid from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)\n{\n    p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});\n}\n\ntemplate<typename BasicJsonType, typename... Args>\nstd::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)\n{\n    return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});\n}\n\ntemplate<typename BasicJsonType, typename... Args>\nvoid from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)\n{\n    t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});\n}\n\ntemplate<typename BasicJsonType, typename TupleRelated>\nauto from_json(BasicJsonType&& j, TupleRelated&& t)\n-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n\n    return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});\n}\n\ntemplate < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,\n           typename = enable_if_t < !std::is_constructible <\n                                        typename BasicJsonType::string_t, Key >::value >>\nvoid from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    m.clear();\n    for (const auto& p : j)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))\n        {\n            JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(p.type_name()), j));\n        }\n        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());\n    }\n}\n\ntemplate < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,\n           typename = enable_if_t < !std::is_constructible <\n                                        typename BasicJsonType::string_t, Key >::value >>\nvoid from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(j.type_name()), j));\n    }\n    m.clear();\n    for (const auto& p : j)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))\n        {\n            JSON_THROW(type_error::create(302, \"type must be array, but is \" + std::string(p.type_name()), j));\n        }\n        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());\n    }\n}\n\n#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, std_fs::path& p)\n{\n    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))\n    {\n        JSON_THROW(type_error::create(302, \"type must be string, but is \" + std::string(j.type_name()), j));\n    }\n    p = *j.template get_ptr<const typename BasicJsonType::string_t*>();\n}\n#endif\n\nstruct from_json_fn\n{\n    template<typename BasicJsonType, typename T>\n    auto operator()(const BasicJsonType& j, T&& val) const\n    noexcept(noexcept(from_json(j, std::forward<T>(val))))\n    -> decltype(from_json(j, std::forward<T>(val)))\n    {\n        return from_json(j, std::forward<T>(val));\n    }\n};\n}  // namespace detail\n\n/// namespace to hold default `from_json` function\n/// to see why this is required:\n/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html\nnamespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)\n{\nconstexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)\n} // namespace\n} // namespace nlohmann\n\n// #include <nlohmann/detail/conversions/to_json.hpp>\n\n\n#include <algorithm> // copy\n#include <iterator> // begin, end\n#include <string> // string\n#include <tuple> // tuple, get\n#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type\n#include <utility> // move, forward, declval, pair\n#include <valarray> // valarray\n#include <vector> // vector\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/iterators/iteration_proxy.hpp>\n\n\n#include <cstddef> // size_t\n#include <iterator> // input_iterator_tag\n#include <string> // string, to_string\n#include <tuple> // tuple_size, get, tuple_element\n#include <utility> // move\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename string_type>\nvoid int_to_string( string_type& target, std::size_t value )\n{\n    // For ADL\n    using std::to_string;\n    target = to_string(value);\n}\ntemplate<typename IteratorType> class iteration_proxy_value\n{\n  public:\n    using difference_type = std::ptrdiff_t;\n    using value_type = iteration_proxy_value;\n    using pointer = value_type * ;\n    using reference = value_type & ;\n    using iterator_category = std::input_iterator_tag;\n    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;\n\n  private:\n    /// the iterator\n    IteratorType anchor;\n    /// an index for arrays (used to create key names)\n    std::size_t array_index = 0;\n    /// last stringified array index\n    mutable std::size_t array_index_last = 0;\n    /// a string representation of the array index\n    mutable string_type array_index_str = \"0\";\n    /// an empty string (to return a reference for primitive values)\n    const string_type empty_str{};\n\n  public:\n    explicit iteration_proxy_value(IteratorType it) noexcept\n        : anchor(std::move(it))\n    {}\n\n    /// dereference operator (needed for range-based for)\n    iteration_proxy_value& operator*()\n    {\n        return *this;\n    }\n\n    /// increment operator (needed for range-based for)\n    iteration_proxy_value& operator++()\n    {\n        ++anchor;\n        ++array_index;\n\n        return *this;\n    }\n\n    /// equality operator (needed for InputIterator)\n    bool operator==(const iteration_proxy_value& o) const\n    {\n        return anchor == o.anchor;\n    }\n\n    /// inequality operator (needed for range-based for)\n    bool operator!=(const iteration_proxy_value& o) const\n    {\n        return anchor != o.anchor;\n    }\n\n    /// return key of the iterator\n    const string_type& key() const\n    {\n        JSON_ASSERT(anchor.m_object != nullptr);\n\n        switch (anchor.m_object->type())\n        {\n            // use integer array index as key\n            case value_t::array:\n            {\n                if (array_index != array_index_last)\n                {\n                    int_to_string( array_index_str, array_index );\n                    array_index_last = array_index;\n                }\n                return array_index_str;\n            }\n\n            // use key from the object\n            case value_t::object:\n                return anchor.key();\n\n            // use an empty key for all primitive types\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return empty_str;\n        }\n    }\n\n    /// return value of the iterator\n    typename IteratorType::reference value() const\n    {\n        return anchor.value();\n    }\n};\n\n/// proxy class for the items() function\ntemplate<typename IteratorType> class iteration_proxy\n{\n  private:\n    /// the container to iterate\n    typename IteratorType::reference container;\n\n  public:\n    /// construct iteration proxy from a container\n    explicit iteration_proxy(typename IteratorType::reference cont) noexcept\n        : container(cont) {}\n\n    /// return iterator begin (needed for range-based for)\n    iteration_proxy_value<IteratorType> begin() noexcept\n    {\n        return iteration_proxy_value<IteratorType>(container.begin());\n    }\n\n    /// return iterator end (needed for range-based for)\n    iteration_proxy_value<IteratorType> end() noexcept\n    {\n        return iteration_proxy_value<IteratorType>(container.end());\n    }\n};\n// Structured Bindings Support\n// For further reference see https://blog.tartanllama.xyz/structured-bindings/\n// And see https://github.com/nlohmann/json/pull/1391\ntemplate<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>\nauto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())\n{\n    return i.key();\n}\n// Structured Bindings Support\n// For further reference see https://blog.tartanllama.xyz/structured-bindings/\n// And see https://github.com/nlohmann/json/pull/1391\ntemplate<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>\nauto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())\n{\n    return i.value();\n}\n}  // namespace detail\n}  // namespace nlohmann\n\n// The Addition to the STD Namespace is required to add\n// Structured Bindings Support to the iteration_proxy_value class\n// For further reference see https://blog.tartanllama.xyz/structured-bindings/\n// And see https://github.com/nlohmann/json/pull/1391\nnamespace std\n{\n#if defined(__clang__)\n    // Fix: https://github.com/nlohmann/json/issues/1401\n    #pragma clang diagnostic push\n    #pragma clang diagnostic ignored \"-Wmismatched-tags\"\n#endif\ntemplate<typename IteratorType>\nclass tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>\n            : public std::integral_constant<std::size_t, 2> {};\n\ntemplate<std::size_t N, typename IteratorType>\nclass tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>\n{\n  public:\n    using type = decltype(\n                     get<N>(std::declval <\n                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));\n};\n#if defined(__clang__)\n    #pragma clang diagnostic pop\n#endif\n} // namespace std\n\n// #include <nlohmann/detail/meta/cpp_future.hpp>\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\n#if JSON_HAS_EXPERIMENTAL_FILESYSTEM\n#include <experimental/filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::experimental::filesystem;\n} // namespace nlohmann::detail\n#elif JSON_HAS_FILESYSTEM\n#include <filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::filesystem;\n} // namespace nlohmann::detail\n#endif\n\nnamespace nlohmann\n{\nnamespace detail\n{\n//////////////////\n// constructors //\n//////////////////\n\n/*\n * Note all external_constructor<>::construct functions need to call\n * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an\n * allocated value (e.g., a string). See bug issue\n * https://github.com/nlohmann/json/issues/2865 for more information.\n */\n\ntemplate<value_t> struct external_constructor;\n\ntemplate<>\nstruct external_constructor<value_t::boolean>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::boolean;\n        j.m_value = b;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::string>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::string;\n        j.m_value = s;\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::string;\n        j.m_value = std::move(s);\n        j.assert_invariant();\n    }\n\n    template < typename BasicJsonType, typename CompatibleStringType,\n               enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,\n                             int > = 0 >\n    static void construct(BasicJsonType& j, const CompatibleStringType& str)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::string;\n        j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::binary>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::binary;\n        j.m_value = typename BasicJsonType::binary_t(b);\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::binary;\n        j.m_value = typename BasicJsonType::binary_t(std::move(b));\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::number_float>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::number_float;\n        j.m_value = val;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::number_unsigned>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::number_unsigned;\n        j.m_value = val;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::number_integer>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::number_integer;\n        j.m_value = val;\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::array>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = arr;\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = std::move(arr);\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template < typename BasicJsonType, typename CompatibleArrayType,\n               enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,\n                             int > = 0 >\n    static void construct(BasicJsonType& j, const CompatibleArrayType& arr)\n    {\n        using std::begin;\n        using std::end;\n\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const std::vector<bool>& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = value_t::array;\n        j.m_value.array->reserve(arr.size());\n        for (const bool x : arr)\n        {\n            j.m_value.array->push_back(x);\n            j.set_parent(j.m_value.array->back());\n        }\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType, typename T,\n             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>\n    static void construct(BasicJsonType& j, const std::valarray<T>& arr)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::array;\n        j.m_value = value_t::array;\n        j.m_value.array->resize(arr.size());\n        if (arr.size() > 0)\n        {\n            std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());\n        }\n        j.set_parents();\n        j.assert_invariant();\n    }\n};\n\ntemplate<>\nstruct external_constructor<value_t::object>\n{\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::object;\n        j.m_value = obj;\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template<typename BasicJsonType>\n    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)\n    {\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::object;\n        j.m_value = std::move(obj);\n        j.set_parents();\n        j.assert_invariant();\n    }\n\n    template < typename BasicJsonType, typename CompatibleObjectType,\n               enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >\n    static void construct(BasicJsonType& j, const CompatibleObjectType& obj)\n    {\n        using std::begin;\n        using std::end;\n\n        j.m_value.destroy(j.m_type);\n        j.m_type = value_t::object;\n        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));\n        j.set_parents();\n        j.assert_invariant();\n    }\n};\n\n/////////////\n// to_json //\n/////////////\n\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>\nvoid to_json(BasicJsonType& j, T b) noexcept\n{\n    external_constructor<value_t::boolean>::construct(j, b);\n}\n\ntemplate<typename BasicJsonType, typename CompatibleString,\n         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>\nvoid to_json(BasicJsonType& j, const CompatibleString& s)\n{\n    external_constructor<value_t::string>::construct(j, s);\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)\n{\n    external_constructor<value_t::string>::construct(j, std::move(s));\n}\n\ntemplate<typename BasicJsonType, typename FloatType,\n         enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, FloatType val) noexcept\n{\n    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));\n}\n\ntemplate<typename BasicJsonType, typename CompatibleNumberUnsignedType,\n         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept\n{\n    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));\n}\n\ntemplate<typename BasicJsonType, typename CompatibleNumberIntegerType,\n         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept\n{\n    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));\n}\n\ntemplate<typename BasicJsonType, typename EnumType,\n         enable_if_t<std::is_enum<EnumType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, EnumType e) noexcept\n{\n    using underlying_type = typename std::underlying_type<EnumType>::type;\n    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const std::vector<bool>& e)\n{\n    external_constructor<value_t::array>::construct(j, e);\n}\n\ntemplate < typename BasicJsonType, typename CompatibleArrayType,\n           enable_if_t < is_compatible_array_type<BasicJsonType,\n                         CompatibleArrayType>::value&&\n                         !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&\n                         !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&\n                         !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&\n                         !is_basic_json<CompatibleArrayType>::value,\n                         int > = 0 >\nvoid to_json(BasicJsonType& j, const CompatibleArrayType& arr)\n{\n    external_constructor<value_t::array>::construct(j, arr);\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)\n{\n    external_constructor<value_t::binary>::construct(j, bin);\n}\n\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>\nvoid to_json(BasicJsonType& j, const std::valarray<T>& arr)\n{\n    external_constructor<value_t::array>::construct(j, std::move(arr));\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)\n{\n    external_constructor<value_t::array>::construct(j, std::move(arr));\n}\n\ntemplate < typename BasicJsonType, typename CompatibleObjectType,\n           enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >\nvoid to_json(BasicJsonType& j, const CompatibleObjectType& obj)\n{\n    external_constructor<value_t::object>::construct(j, obj);\n}\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)\n{\n    external_constructor<value_t::object>::construct(j, std::move(obj));\n}\n\ntemplate <\n    typename BasicJsonType, typename T, std::size_t N,\n    enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,\n                  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n                  int > = 0 >\nvoid to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n{\n    external_constructor<value_t::array>::construct(j, arr);\n}\n\ntemplate < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >\nvoid to_json(BasicJsonType& j, const std::pair<T1, T2>& p)\n{\n    j = { p.first, p.second };\n}\n\n// for https://github.com/nlohmann/json/pull/1134\ntemplate<typename BasicJsonType, typename T,\n         enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>\nvoid to_json(BasicJsonType& j, const T& b)\n{\n    j = { {b.key(), b.value()} };\n}\n\ntemplate<typename BasicJsonType, typename Tuple, std::size_t... Idx>\nvoid to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)\n{\n    j = { std::get<Idx>(t)... };\n}\n\ntemplate<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>\nvoid to_json(BasicJsonType& j, const T& t)\n{\n    to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});\n}\n\n#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const std_fs::path& p)\n{\n    j = p.string();\n}\n#endif\n\nstruct to_json_fn\n{\n    template<typename BasicJsonType, typename T>\n    auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))\n    -> decltype(to_json(j, std::forward<T>(val)), void())\n    {\n        return to_json(j, std::forward<T>(val));\n    }\n};\n}  // namespace detail\n\n/// namespace to hold default `to_json` function\n/// to see why this is required:\n/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html\nnamespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)\n{\nconstexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)\n} // namespace\n} // namespace nlohmann\n\n// #include <nlohmann/detail/meta/identity_tag.hpp>\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n\nnamespace nlohmann\n{\n\n/// @sa https://json.nlohmann.me/api/adl_serializer/\ntemplate<typename ValueType, typename>\nstruct adl_serializer\n{\n    /// @brief convert a JSON value to any value type\n    /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/\n    template<typename BasicJsonType, typename TargetType = ValueType>\n    static auto from_json(BasicJsonType && j, TargetType& val) noexcept(\n        noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))\n    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())\n    {\n        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);\n    }\n\n    /// @brief convert a JSON value to any value type\n    /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/\n    template<typename BasicJsonType, typename TargetType = ValueType>\n    static auto from_json(BasicJsonType && j) noexcept(\n    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))\n    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))\n    {\n        return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});\n    }\n\n    /// @brief convert any value type to a JSON value\n    /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/\n    template<typename BasicJsonType, typename TargetType = ValueType>\n    static auto to_json(BasicJsonType& j, TargetType && val) noexcept(\n        noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))\n    -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())\n    {\n        ::nlohmann::to_json(j, std::forward<TargetType>(val));\n    }\n};\n}  // namespace nlohmann\n\n// #include <nlohmann/byte_container_with_subtype.hpp>\n\n\n#include <cstdint> // uint8_t, uint64_t\n#include <tuple> // tie\n#include <utility> // move\n\nnamespace nlohmann\n{\n\n/// @brief an internal type for a backed binary type\n/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/\ntemplate<typename BinaryType>\nclass byte_container_with_subtype : public BinaryType\n{\n  public:\n    using container_type = BinaryType;\n    using subtype_type = std::uint64_t;\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype() noexcept(noexcept(container_type()))\n        : container_type()\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))\n        : container_type(b)\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))\n        : container_type(std::move(b))\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))\n        : container_type(b)\n        , m_subtype(subtype_)\n        , m_has_subtype(true)\n    {}\n\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/\n    byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))\n        : container_type(std::move(b))\n        , m_subtype(subtype_)\n        , m_has_subtype(true)\n    {}\n\n    bool operator==(const byte_container_with_subtype& rhs) const\n    {\n        return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==\n               std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);\n    }\n\n    bool operator!=(const byte_container_with_subtype& rhs) const\n    {\n        return !(rhs == *this);\n    }\n\n    /// @brief sets the binary subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/\n    void set_subtype(subtype_type subtype_) noexcept\n    {\n        m_subtype = subtype_;\n        m_has_subtype = true;\n    }\n\n    /// @brief return the binary subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/\n    constexpr subtype_type subtype() const noexcept\n    {\n        return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);\n    }\n\n    /// @brief return whether the value has a subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/\n    constexpr bool has_subtype() const noexcept\n    {\n        return m_has_subtype;\n    }\n\n    /// @brief clears the binary subtype\n    /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/\n    void clear_subtype() noexcept\n    {\n        m_subtype = 0;\n        m_has_subtype = false;\n    }\n\n  private:\n    subtype_type m_subtype = 0;\n    bool m_has_subtype = false;\n};\n\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/conversions/from_json.hpp>\n\n// #include <nlohmann/detail/conversions/to_json.hpp>\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n// #include <nlohmann/detail/hash.hpp>\n\n\n#include <cstdint> // uint8_t\n#include <cstddef> // size_t\n#include <functional> // hash\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n// boost::hash_combine\ninline std::size_t combine(std::size_t seed, std::size_t h) noexcept\n{\n    seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);\n    return seed;\n}\n\n/*!\n@brief hash a JSON value\n\nThe hash function tries to rely on std::hash where possible. Furthermore, the\ntype of the JSON value is taken into account to have different hash values for\nnull, 0, 0U, and false, etc.\n\n@tparam BasicJsonType basic_json specialization\n@param j JSON value to hash\n@return hash value of j\n*/\ntemplate<typename BasicJsonType>\nstd::size_t hash(const BasicJsonType& j)\n{\n    using string_t = typename BasicJsonType::string_t;\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n\n    const auto type = static_cast<std::size_t>(j.type());\n    switch (j.type())\n    {\n        case BasicJsonType::value_t::null:\n        case BasicJsonType::value_t::discarded:\n        {\n            return combine(type, 0);\n        }\n\n        case BasicJsonType::value_t::object:\n        {\n            auto seed = combine(type, j.size());\n            for (const auto& element : j.items())\n            {\n                const auto h = std::hash<string_t> {}(element.key());\n                seed = combine(seed, h);\n                seed = combine(seed, hash(element.value()));\n            }\n            return seed;\n        }\n\n        case BasicJsonType::value_t::array:\n        {\n            auto seed = combine(type, j.size());\n            for (const auto& element : j)\n            {\n                seed = combine(seed, hash(element));\n            }\n            return seed;\n        }\n\n        case BasicJsonType::value_t::string:\n        {\n            const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::boolean:\n        {\n            const auto h = std::hash<bool> {}(j.template get<bool>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::number_integer:\n        {\n            const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::number_unsigned:\n        {\n            const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::number_float:\n        {\n            const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());\n            return combine(type, h);\n        }\n\n        case BasicJsonType::value_t::binary:\n        {\n            auto seed = combine(type, j.get_binary().size());\n            const auto h = std::hash<bool> {}(j.get_binary().has_subtype());\n            seed = combine(seed, h);\n            seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));\n            for (const auto byte : j.get_binary())\n            {\n                seed = combine(seed, std::hash<std::uint8_t> {}(byte));\n            }\n            return seed;\n        }\n\n        default:                   // LCOV_EXCL_LINE\n            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n            return 0;              // LCOV_EXCL_LINE\n    }\n}\n\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/input/binary_reader.hpp>\n\n\n#include <algorithm> // generate_n\n#include <array> // array\n#include <cmath> // ldexp\n#include <cstddef> // size_t\n#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t\n#include <cstdio> // snprintf\n#include <cstring> // memcpy\n#include <iterator> // back_inserter\n#include <limits> // numeric_limits\n#include <string> // char_traits, string\n#include <utility> // make_pair, move\n#include <vector> // vector\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n// #include <nlohmann/detail/input/input_adapters.hpp>\n\n\n#include <array> // array\n#include <cstddef> // size_t\n#include <cstring> // strlen\n#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next\n#include <memory> // shared_ptr, make_shared, addressof\n#include <numeric> // accumulate\n#include <string> // string, char_traits\n#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer\n#include <utility> // pair, declval\n\n#ifndef JSON_NO_IO\n    #include <cstdio>   // FILE *\n    #include <istream>  // istream\n#endif                  // JSON_NO_IO\n\n// #include <nlohmann/detail/iterators/iterator_traits.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/// the supported input formats\nenum class input_format_t { json, cbor, msgpack, ubjson, bson };\n\n////////////////////\n// input adapters //\n////////////////////\n\n#ifndef JSON_NO_IO\n/*!\nInput adapter for stdio file access. This adapter read only 1 byte and do not use any\n buffer. This adapter is a very low level adapter.\n*/\nclass file_input_adapter\n{\n  public:\n    using char_type = char;\n\n    JSON_HEDLEY_NON_NULL(2)\n    explicit file_input_adapter(std::FILE* f) noexcept\n        : m_file(f)\n    {}\n\n    // make class move-only\n    file_input_adapter(const file_input_adapter&) = delete;\n    file_input_adapter(file_input_adapter&&) noexcept = default;\n    file_input_adapter& operator=(const file_input_adapter&) = delete;\n    file_input_adapter& operator=(file_input_adapter&&) = delete;\n    ~file_input_adapter() = default;\n\n    std::char_traits<char>::int_type get_character() noexcept\n    {\n        return std::fgetc(m_file);\n    }\n\n  private:\n    /// the file pointer to read from\n    std::FILE* m_file;\n};\n\n\n/*!\nInput adapter for a (caching) istream. Ignores a UFT Byte Order Mark at\nbeginning of input. Does not support changing the underlying std::streambuf\nin mid-input. Maintains underlying std::istream and std::streambuf to support\nsubsequent use of standard std::istream operations to process any input\ncharacters following those used in parsing the JSON input.  Clears the\nstd::istream flags; any input errors (e.g., EOF) will be detected by the first\nsubsequent call for input from the std::istream.\n*/\nclass input_stream_adapter\n{\n  public:\n    using char_type = char;\n\n    ~input_stream_adapter()\n    {\n        // clear stream flags; we use underlying streambuf I/O, do not\n        // maintain ifstream flags, except eof\n        if (is != nullptr)\n        {\n            is->clear(is->rdstate() & std::ios::eofbit);\n        }\n    }\n\n    explicit input_stream_adapter(std::istream& i)\n        : is(&i), sb(i.rdbuf())\n    {}\n\n    // delete because of pointer members\n    input_stream_adapter(const input_stream_adapter&) = delete;\n    input_stream_adapter& operator=(input_stream_adapter&) = delete;\n    input_stream_adapter& operator=(input_stream_adapter&&) = delete;\n\n    input_stream_adapter(input_stream_adapter&& rhs) noexcept\n        : is(rhs.is), sb(rhs.sb)\n    {\n        rhs.is = nullptr;\n        rhs.sb = nullptr;\n    }\n\n    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to\n    // ensure that std::char_traits<char>::eof() and the character 0xFF do not\n    // end up as the same value, e.g. 0xFFFFFFFF.\n    std::char_traits<char>::int_type get_character()\n    {\n        auto res = sb->sbumpc();\n        // set eof manually, as we don't use the istream interface.\n        if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))\n        {\n            is->clear(is->rdstate() | std::ios::eofbit);\n        }\n        return res;\n    }\n\n  private:\n    /// the associated input stream\n    std::istream* is = nullptr;\n    std::streambuf* sb = nullptr;\n};\n#endif  // JSON_NO_IO\n\n// General-purpose iterator-based adapter. It might not be as fast as\n// theoretically possible for some containers, but it is extremely versatile.\ntemplate<typename IteratorType>\nclass iterator_input_adapter\n{\n  public:\n    using char_type = typename std::iterator_traits<IteratorType>::value_type;\n\n    iterator_input_adapter(IteratorType first, IteratorType last)\n        : current(std::move(first)), end(std::move(last))\n    {}\n\n    typename std::char_traits<char_type>::int_type get_character()\n    {\n        if (JSON_HEDLEY_LIKELY(current != end))\n        {\n            auto result = std::char_traits<char_type>::to_int_type(*current);\n            std::advance(current, 1);\n            return result;\n        }\n\n        return std::char_traits<char_type>::eof();\n    }\n\n  private:\n    IteratorType current;\n    IteratorType end;\n\n    template<typename BaseInputAdapter, size_t T>\n    friend struct wide_string_input_helper;\n\n    bool empty() const\n    {\n        return current == end;\n    }\n};\n\n\ntemplate<typename BaseInputAdapter, size_t T>\nstruct wide_string_input_helper;\n\ntemplate<typename BaseInputAdapter>\nstruct wide_string_input_helper<BaseInputAdapter, 4>\n{\n    // UTF-32\n    static void fill_buffer(BaseInputAdapter& input,\n                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,\n                            size_t& utf8_bytes_index,\n                            size_t& utf8_bytes_filled)\n    {\n        utf8_bytes_index = 0;\n\n        if (JSON_HEDLEY_UNLIKELY(input.empty()))\n        {\n            utf8_bytes[0] = std::char_traits<char>::eof();\n            utf8_bytes_filled = 1;\n        }\n        else\n        {\n            // get the current character\n            const auto wc = input.get_character();\n\n            // UTF-32 to UTF-8 encoding\n            if (wc < 0x80)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                utf8_bytes_filled = 1;\n            }\n            else if (wc <= 0x7FF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 2;\n            }\n            else if (wc <= 0xFFFF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));\n                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 3;\n            }\n            else if (wc <= 0x10FFFF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));\n                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));\n                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 4;\n            }\n            else\n            {\n                // unknown character\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                utf8_bytes_filled = 1;\n            }\n        }\n    }\n};\n\ntemplate<typename BaseInputAdapter>\nstruct wide_string_input_helper<BaseInputAdapter, 2>\n{\n    // UTF-16\n    static void fill_buffer(BaseInputAdapter& input,\n                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,\n                            size_t& utf8_bytes_index,\n                            size_t& utf8_bytes_filled)\n    {\n        utf8_bytes_index = 0;\n\n        if (JSON_HEDLEY_UNLIKELY(input.empty()))\n        {\n            utf8_bytes[0] = std::char_traits<char>::eof();\n            utf8_bytes_filled = 1;\n        }\n        else\n        {\n            // get the current character\n            const auto wc = input.get_character();\n\n            // UTF-16 to UTF-8 encoding\n            if (wc < 0x80)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                utf8_bytes_filled = 1;\n            }\n            else if (wc <= 0x7FF)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 2;\n            }\n            else if (0xD800 > wc || wc >= 0xE000)\n            {\n                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));\n                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));\n                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));\n                utf8_bytes_filled = 3;\n            }\n            else\n            {\n                if (JSON_HEDLEY_UNLIKELY(!input.empty()))\n                {\n                    const auto wc2 = static_cast<unsigned int>(input.get_character());\n                    const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));\n                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));\n                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));\n                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));\n                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));\n                    utf8_bytes_filled = 4;\n                }\n                else\n                {\n                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);\n                    utf8_bytes_filled = 1;\n                }\n            }\n        }\n    }\n};\n\n// Wraps another input apdater to convert wide character types into individual bytes.\ntemplate<typename BaseInputAdapter, typename WideCharType>\nclass wide_string_input_adapter\n{\n  public:\n    using char_type = char;\n\n    wide_string_input_adapter(BaseInputAdapter base)\n        : base_adapter(base) {}\n\n    typename std::char_traits<char>::int_type get_character() noexcept\n    {\n        // check if buffer needs to be filled\n        if (utf8_bytes_index == utf8_bytes_filled)\n        {\n            fill_buffer<sizeof(WideCharType)>();\n\n            JSON_ASSERT(utf8_bytes_filled > 0);\n            JSON_ASSERT(utf8_bytes_index == 0);\n        }\n\n        // use buffer\n        JSON_ASSERT(utf8_bytes_filled > 0);\n        JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);\n        return utf8_bytes[utf8_bytes_index++];\n    }\n\n  private:\n    BaseInputAdapter base_adapter;\n\n    template<size_t T>\n    void fill_buffer()\n    {\n        wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);\n    }\n\n    /// a buffer for UTF-8 bytes\n    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};\n\n    /// index to the utf8_codes array for the next valid byte\n    std::size_t utf8_bytes_index = 0;\n    /// number of valid bytes in the utf8_codes array\n    std::size_t utf8_bytes_filled = 0;\n};\n\n\ntemplate<typename IteratorType, typename Enable = void>\nstruct iterator_input_adapter_factory\n{\n    using iterator_type = IteratorType;\n    using char_type = typename std::iterator_traits<iterator_type>::value_type;\n    using adapter_type = iterator_input_adapter<iterator_type>;\n\n    static adapter_type create(IteratorType first, IteratorType last)\n    {\n        return adapter_type(std::move(first), std::move(last));\n    }\n};\n\ntemplate<typename T>\nstruct is_iterator_of_multibyte\n{\n    using value_type = typename std::iterator_traits<T>::value_type;\n    enum\n    {\n        value = sizeof(value_type) > 1\n    };\n};\n\ntemplate<typename IteratorType>\nstruct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>\n{\n    using iterator_type = IteratorType;\n    using char_type = typename std::iterator_traits<iterator_type>::value_type;\n    using base_adapter_type = iterator_input_adapter<iterator_type>;\n    using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;\n\n    static adapter_type create(IteratorType first, IteratorType last)\n    {\n        return adapter_type(base_adapter_type(std::move(first), std::move(last)));\n    }\n};\n\n// General purpose iterator-based input\ntemplate<typename IteratorType>\ntypename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)\n{\n    using factory_type = iterator_input_adapter_factory<IteratorType>;\n    return factory_type::create(first, last);\n}\n\n// Convenience shorthand from container to iterator\n// Enables ADL on begin(container) and end(container)\n// Encloses the using declarations in namespace for not to leak them to outside scope\n\nnamespace container_input_adapter_factory_impl\n{\n\nusing std::begin;\nusing std::end;\n\ntemplate<typename ContainerType, typename Enable = void>\nstruct container_input_adapter_factory {};\n\ntemplate<typename ContainerType>\nstruct container_input_adapter_factory< ContainerType,\n       void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>\n       {\n           using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));\n\n           static adapter_type create(const ContainerType& container)\n{\n    return input_adapter(begin(container), end(container));\n}\n       };\n\n} // namespace container_input_adapter_factory_impl\n\ntemplate<typename ContainerType>\ntypename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)\n{\n    return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);\n}\n\n#ifndef JSON_NO_IO\n// Special cases with fast paths\ninline file_input_adapter input_adapter(std::FILE* file)\n{\n    return file_input_adapter(file);\n}\n\ninline input_stream_adapter input_adapter(std::istream& stream)\n{\n    return input_stream_adapter(stream);\n}\n\ninline input_stream_adapter input_adapter(std::istream&& stream)\n{\n    return input_stream_adapter(stream);\n}\n#endif  // JSON_NO_IO\n\nusing contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));\n\n// Null-delimited strings, and the like.\ntemplate < typename CharT,\n           typename std::enable_if <\n               std::is_pointer<CharT>::value&&\n               !std::is_array<CharT>::value&&\n               std::is_integral<typename std::remove_pointer<CharT>::type>::value&&\n               sizeof(typename std::remove_pointer<CharT>::type) == 1,\n               int >::type = 0 >\ncontiguous_bytes_input_adapter input_adapter(CharT b)\n{\n    auto length = std::strlen(reinterpret_cast<const char*>(b));\n    const auto* ptr = reinterpret_cast<const char*>(b);\n    return input_adapter(ptr, ptr + length);\n}\n\ntemplate<typename T, std::size_t N>\nauto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n{\n    return input_adapter(array, array + N);\n}\n\n// This class only handles inputs of input_buffer_adapter type.\n// It's required so that expressions like {ptr, len} can be implicitly cast\n// to the correct adapter.\nclass span_input_adapter\n{\n  public:\n    template < typename CharT,\n               typename std::enable_if <\n                   std::is_pointer<CharT>::value&&\n                   std::is_integral<typename std::remove_pointer<CharT>::type>::value&&\n                   sizeof(typename std::remove_pointer<CharT>::type) == 1,\n                   int >::type = 0 >\n    span_input_adapter(CharT b, std::size_t l)\n        : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}\n\n    template<class IteratorType,\n             typename std::enable_if<\n                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,\n                 int>::type = 0>\n    span_input_adapter(IteratorType first, IteratorType last)\n        : ia(input_adapter(first, last)) {}\n\n    contiguous_bytes_input_adapter&& get()\n    {\n        return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)\n    }\n\n  private:\n    contiguous_bytes_input_adapter ia;\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/input/json_sax.hpp>\n\n\n#include <cstddef>\n#include <string> // string\n#include <utility> // move\n#include <vector> // vector\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\n\n/*!\n@brief SAX interface\n\nThis class describes the SAX interface used by @ref nlohmann::json::sax_parse.\nEach function is called in different situations while the input is parsed. The\nboolean return value informs the parser whether to continue processing the\ninput.\n*/\ntemplate<typename BasicJsonType>\nstruct json_sax\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n\n    /*!\n    @brief a null value was read\n    @return whether parsing should proceed\n    */\n    virtual bool null() = 0;\n\n    /*!\n    @brief a boolean value was read\n    @param[in] val  boolean value\n    @return whether parsing should proceed\n    */\n    virtual bool boolean(bool val) = 0;\n\n    /*!\n    @brief an integer number was read\n    @param[in] val  integer value\n    @return whether parsing should proceed\n    */\n    virtual bool number_integer(number_integer_t val) = 0;\n\n    /*!\n    @brief an unsigned integer number was read\n    @param[in] val  unsigned integer value\n    @return whether parsing should proceed\n    */\n    virtual bool number_unsigned(number_unsigned_t val) = 0;\n\n    /*!\n    @brief a floating-point number was read\n    @param[in] val  floating-point value\n    @param[in] s    raw token value\n    @return whether parsing should proceed\n    */\n    virtual bool number_float(number_float_t val, const string_t& s) = 0;\n\n    /*!\n    @brief a string value was read\n    @param[in] val  string value\n    @return whether parsing should proceed\n    @note It is safe to move the passed string value.\n    */\n    virtual bool string(string_t& val) = 0;\n\n    /*!\n    @brief a binary value was read\n    @param[in] val  binary value\n    @return whether parsing should proceed\n    @note It is safe to move the passed binary value.\n    */\n    virtual bool binary(binary_t& val) = 0;\n\n    /*!\n    @brief the beginning of an object was read\n    @param[in] elements  number of object elements or -1 if unknown\n    @return whether parsing should proceed\n    @note binary formats may report the number of elements\n    */\n    virtual bool start_object(std::size_t elements) = 0;\n\n    /*!\n    @brief an object key was read\n    @param[in] val  object key\n    @return whether parsing should proceed\n    @note It is safe to move the passed string.\n    */\n    virtual bool key(string_t& val) = 0;\n\n    /*!\n    @brief the end of an object was read\n    @return whether parsing should proceed\n    */\n    virtual bool end_object() = 0;\n\n    /*!\n    @brief the beginning of an array was read\n    @param[in] elements  number of array elements or -1 if unknown\n    @return whether parsing should proceed\n    @note binary formats may report the number of elements\n    */\n    virtual bool start_array(std::size_t elements) = 0;\n\n    /*!\n    @brief the end of an array was read\n    @return whether parsing should proceed\n    */\n    virtual bool end_array() = 0;\n\n    /*!\n    @brief a parse error occurred\n    @param[in] position    the position in the input where the error occurs\n    @param[in] last_token  the last read token\n    @param[in] ex          an exception object describing the error\n    @return whether parsing should proceed (must return false)\n    */\n    virtual bool parse_error(std::size_t position,\n                             const std::string& last_token,\n                             const detail::exception& ex) = 0;\n\n    json_sax() = default;\n    json_sax(const json_sax&) = default;\n    json_sax(json_sax&&) noexcept = default;\n    json_sax& operator=(const json_sax&) = default;\n    json_sax& operator=(json_sax&&) noexcept = default;\n    virtual ~json_sax() = default;\n};\n\n\nnamespace detail\n{\n/*!\n@brief SAX implementation to create a JSON value from SAX events\n\nThis class implements the @ref json_sax interface and processes the SAX events\nto create a JSON value which makes it basically a DOM parser. The structure or\nhierarchy of the JSON value is managed by the stack `ref_stack` which contains\na pointer to the respective array or object for each recursion depth.\n\nAfter successful parsing, the value that is passed by reference to the\nconstructor contains the parsed value.\n\n@tparam BasicJsonType  the JSON type\n*/\ntemplate<typename BasicJsonType>\nclass json_sax_dom_parser\n{\n  public:\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n\n    /*!\n    @param[in,out] r  reference to a JSON value that is manipulated while\n                       parsing\n    @param[in] allow_exceptions_  whether parse errors yield exceptions\n    */\n    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)\n        : root(r), allow_exceptions(allow_exceptions_)\n    {}\n\n    // make class move-only\n    json_sax_dom_parser(const json_sax_dom_parser&) = delete;\n    json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;\n    json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~json_sax_dom_parser() = default;\n\n    bool null()\n    {\n        handle_value(nullptr);\n        return true;\n    }\n\n    bool boolean(bool val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_integer(number_integer_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& /*unused*/)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool string(string_t& val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool binary(binary_t& val)\n    {\n        handle_value(std::move(val));\n        return true;\n    }\n\n    bool start_object(std::size_t len)\n    {\n        ref_stack.push_back(handle_value(BasicJsonType::value_t::object));\n\n        if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive object size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool key(string_t& val)\n    {\n        // add null at given key and store the reference for later\n        object_element = &(ref_stack.back()->m_value.object->operator[](val));\n        return true;\n    }\n\n    bool end_object()\n    {\n        ref_stack.back()->set_parents();\n        ref_stack.pop_back();\n        return true;\n    }\n\n    bool start_array(std::size_t len)\n    {\n        ref_stack.push_back(handle_value(BasicJsonType::value_t::array));\n\n        if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive array size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool end_array()\n    {\n        ref_stack.back()->set_parents();\n        ref_stack.pop_back();\n        return true;\n    }\n\n    template<class Exception>\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,\n                     const Exception& ex)\n    {\n        errored = true;\n        static_cast<void>(ex);\n        if (allow_exceptions)\n        {\n            JSON_THROW(ex);\n        }\n        return false;\n    }\n\n    constexpr bool is_errored() const\n    {\n        return errored;\n    }\n\n  private:\n    /*!\n    @invariant If the ref stack is empty, then the passed value will be the new\n               root.\n    @invariant If the ref stack contains a value, then it is an array or an\n               object to which we can add elements\n    */\n    template<typename Value>\n    JSON_HEDLEY_RETURNS_NON_NULL\n    BasicJsonType* handle_value(Value&& v)\n    {\n        if (ref_stack.empty())\n        {\n            root = BasicJsonType(std::forward<Value>(v));\n            return &root;\n        }\n\n        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());\n\n        if (ref_stack.back()->is_array())\n        {\n            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));\n            return &(ref_stack.back()->m_value.array->back());\n        }\n\n        JSON_ASSERT(ref_stack.back()->is_object());\n        JSON_ASSERT(object_element);\n        *object_element = BasicJsonType(std::forward<Value>(v));\n        return object_element;\n    }\n\n    /// the parsed JSON value\n    BasicJsonType& root;\n    /// stack to model hierarchy of values\n    std::vector<BasicJsonType*> ref_stack {};\n    /// helper to hold the reference for the next object element\n    BasicJsonType* object_element = nullptr;\n    /// whether a syntax error occurred\n    bool errored = false;\n    /// whether to throw exceptions in case of errors\n    const bool allow_exceptions = true;\n};\n\ntemplate<typename BasicJsonType>\nclass json_sax_dom_callback_parser\n{\n  public:\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using parser_callback_t = typename BasicJsonType::parser_callback_t;\n    using parse_event_t = typename BasicJsonType::parse_event_t;\n\n    json_sax_dom_callback_parser(BasicJsonType& r,\n                                 const parser_callback_t cb,\n                                 const bool allow_exceptions_ = true)\n        : root(r), callback(cb), allow_exceptions(allow_exceptions_)\n    {\n        keep_stack.push_back(true);\n    }\n\n    // make class move-only\n    json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;\n    json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;\n    json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~json_sax_dom_callback_parser() = default;\n\n    bool null()\n    {\n        handle_value(nullptr);\n        return true;\n    }\n\n    bool boolean(bool val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_integer(number_integer_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& /*unused*/)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool string(string_t& val)\n    {\n        handle_value(val);\n        return true;\n    }\n\n    bool binary(binary_t& val)\n    {\n        handle_value(std::move(val));\n        return true;\n    }\n\n    bool start_object(std::size_t len)\n    {\n        // check callback for object start\n        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);\n        keep_stack.push_back(keep);\n\n        auto val = handle_value(BasicJsonType::value_t::object, true);\n        ref_stack.push_back(val.second);\n\n        // check object limit\n        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive object size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool key(string_t& val)\n    {\n        BasicJsonType k = BasicJsonType(val);\n\n        // check callback for key\n        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);\n        key_keep_stack.push_back(keep);\n\n        // add discarded value at given key and store the reference for later\n        if (keep && ref_stack.back())\n        {\n            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);\n        }\n\n        return true;\n    }\n\n    bool end_object()\n    {\n        if (ref_stack.back())\n        {\n            if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))\n            {\n                // discard object\n                *ref_stack.back() = discarded;\n            }\n            else\n            {\n                ref_stack.back()->set_parents();\n            }\n        }\n\n        JSON_ASSERT(!ref_stack.empty());\n        JSON_ASSERT(!keep_stack.empty());\n        ref_stack.pop_back();\n        keep_stack.pop_back();\n\n        if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())\n        {\n            // remove discarded value\n            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)\n            {\n                if (it->is_discarded())\n                {\n                    ref_stack.back()->erase(it);\n                    break;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    bool start_array(std::size_t len)\n    {\n        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);\n        keep_stack.push_back(keep);\n\n        auto val = handle_value(BasicJsonType::value_t::array, true);\n        ref_stack.push_back(val.second);\n\n        // check array limit\n        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))\n        {\n            JSON_THROW(out_of_range::create(408, \"excessive array size: \" + std::to_string(len), *ref_stack.back()));\n        }\n\n        return true;\n    }\n\n    bool end_array()\n    {\n        bool keep = true;\n\n        if (ref_stack.back())\n        {\n            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());\n            if (keep)\n            {\n                ref_stack.back()->set_parents();\n            }\n            else\n            {\n                // discard array\n                *ref_stack.back() = discarded;\n            }\n        }\n\n        JSON_ASSERT(!ref_stack.empty());\n        JSON_ASSERT(!keep_stack.empty());\n        ref_stack.pop_back();\n        keep_stack.pop_back();\n\n        // remove discarded value\n        if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())\n        {\n            ref_stack.back()->m_value.array->pop_back();\n        }\n\n        return true;\n    }\n\n    template<class Exception>\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,\n                     const Exception& ex)\n    {\n        errored = true;\n        static_cast<void>(ex);\n        if (allow_exceptions)\n        {\n            JSON_THROW(ex);\n        }\n        return false;\n    }\n\n    constexpr bool is_errored() const\n    {\n        return errored;\n    }\n\n  private:\n    /*!\n    @param[in] v  value to add to the JSON value we build during parsing\n    @param[in] skip_callback  whether we should skip calling the callback\n               function; this is required after start_array() and\n               start_object() SAX events, because otherwise we would call the\n               callback function with an empty array or object, respectively.\n\n    @invariant If the ref stack is empty, then the passed value will be the new\n               root.\n    @invariant If the ref stack contains a value, then it is an array or an\n               object to which we can add elements\n\n    @return pair of boolean (whether value should be kept) and pointer (to the\n            passed value in the ref_stack hierarchy; nullptr if not kept)\n    */\n    template<typename Value>\n    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)\n    {\n        JSON_ASSERT(!keep_stack.empty());\n\n        // do not handle this value if we know it would be added to a discarded\n        // container\n        if (!keep_stack.back())\n        {\n            return {false, nullptr};\n        }\n\n        // create value\n        auto value = BasicJsonType(std::forward<Value>(v));\n\n        // check callback\n        const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);\n\n        // do not handle this value if we just learnt it shall be discarded\n        if (!keep)\n        {\n            return {false, nullptr};\n        }\n\n        if (ref_stack.empty())\n        {\n            root = std::move(value);\n            return {true, &root};\n        }\n\n        // skip this value if we already decided to skip the parent\n        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)\n        if (!ref_stack.back())\n        {\n            return {false, nullptr};\n        }\n\n        // we now only expect arrays and objects\n        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());\n\n        // array\n        if (ref_stack.back()->is_array())\n        {\n            ref_stack.back()->m_value.array->emplace_back(std::move(value));\n            return {true, &(ref_stack.back()->m_value.array->back())};\n        }\n\n        // object\n        JSON_ASSERT(ref_stack.back()->is_object());\n        // check if we should store an element for the current key\n        JSON_ASSERT(!key_keep_stack.empty());\n        const bool store_element = key_keep_stack.back();\n        key_keep_stack.pop_back();\n\n        if (!store_element)\n        {\n            return {false, nullptr};\n        }\n\n        JSON_ASSERT(object_element);\n        *object_element = std::move(value);\n        return {true, object_element};\n    }\n\n    /// the parsed JSON value\n    BasicJsonType& root;\n    /// stack to model hierarchy of values\n    std::vector<BasicJsonType*> ref_stack {};\n    /// stack to manage which values to keep\n    std::vector<bool> keep_stack {};\n    /// stack to manage which object keys to keep\n    std::vector<bool> key_keep_stack {};\n    /// helper to hold the reference for the next object element\n    BasicJsonType* object_element = nullptr;\n    /// whether a syntax error occurred\n    bool errored = false;\n    /// callback function\n    const parser_callback_t callback = nullptr;\n    /// whether to throw exceptions in case of errors\n    const bool allow_exceptions = true;\n    /// a discarded value for the callback\n    BasicJsonType discarded = BasicJsonType::value_t::discarded;\n};\n\ntemplate<typename BasicJsonType>\nclass json_sax_acceptor\n{\n  public:\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n\n    bool null()\n    {\n        return true;\n    }\n\n    bool boolean(bool /*unused*/)\n    {\n        return true;\n    }\n\n    bool number_integer(number_integer_t /*unused*/)\n    {\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t /*unused*/)\n    {\n        return true;\n    }\n\n    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool string(string_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool binary(binary_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))\n    {\n        return true;\n    }\n\n    bool key(string_t& /*unused*/)\n    {\n        return true;\n    }\n\n    bool end_object()\n    {\n        return true;\n    }\n\n    bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))\n    {\n        return true;\n    }\n\n    bool end_array()\n    {\n        return true;\n    }\n\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)\n    {\n        return false;\n    }\n};\n}  // namespace detail\n\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/input/lexer.hpp>\n\n\n#include <array> // array\n#include <clocale> // localeconv\n#include <cstddef> // size_t\n#include <cstdio> // snprintf\n#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull\n#include <initializer_list> // initializer_list\n#include <string> // char_traits, string\n#include <utility> // move\n#include <vector> // vector\n\n// #include <nlohmann/detail/input/input_adapters.hpp>\n\n// #include <nlohmann/detail/input/position_t.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////\n// lexer //\n///////////\n\ntemplate<typename BasicJsonType>\nclass lexer_base\n{\n  public:\n    /// token types for the parser\n    enum class token_type\n    {\n        uninitialized,    ///< indicating the scanner is uninitialized\n        literal_true,     ///< the `true` literal\n        literal_false,    ///< the `false` literal\n        literal_null,     ///< the `null` literal\n        value_string,     ///< a string -- use get_string() for actual value\n        value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value\n        value_integer,    ///< a signed integer -- use get_number_integer() for actual value\n        value_float,      ///< an floating point number -- use get_number_float() for actual value\n        begin_array,      ///< the character for array begin `[`\n        begin_object,     ///< the character for object begin `{`\n        end_array,        ///< the character for array end `]`\n        end_object,       ///< the character for object end `}`\n        name_separator,   ///< the name separator `:`\n        value_separator,  ///< the value separator `,`\n        parse_error,      ///< indicating a parse error\n        end_of_input,     ///< indicating the end of the input buffer\n        literal_or_value  ///< a literal or the begin of a value (only for diagnostics)\n    };\n\n    /// return name of values of type token_type (only used for errors)\n    JSON_HEDLEY_RETURNS_NON_NULL\n    JSON_HEDLEY_CONST\n    static const char* token_type_name(const token_type t) noexcept\n    {\n        switch (t)\n        {\n            case token_type::uninitialized:\n                return \"<uninitialized>\";\n            case token_type::literal_true:\n                return \"true literal\";\n            case token_type::literal_false:\n                return \"false literal\";\n            case token_type::literal_null:\n                return \"null literal\";\n            case token_type::value_string:\n                return \"string literal\";\n            case token_type::value_unsigned:\n            case token_type::value_integer:\n            case token_type::value_float:\n                return \"number literal\";\n            case token_type::begin_array:\n                return \"'['\";\n            case token_type::begin_object:\n                return \"'{'\";\n            case token_type::end_array:\n                return \"']'\";\n            case token_type::end_object:\n                return \"'}'\";\n            case token_type::name_separator:\n                return \"':'\";\n            case token_type::value_separator:\n                return \"','\";\n            case token_type::parse_error:\n                return \"<parse error>\";\n            case token_type::end_of_input:\n                return \"end of input\";\n            case token_type::literal_or_value:\n                return \"'[', '{', or a literal\";\n            // LCOV_EXCL_START\n            default: // catch non-enum values\n                return \"unknown token\";\n                // LCOV_EXCL_STOP\n        }\n    }\n};\n/*!\n@brief lexical analysis\n\nThis class organizes the lexical analysis during JSON deserialization.\n*/\ntemplate<typename BasicJsonType, typename InputAdapterType>\nclass lexer : public lexer_base<BasicJsonType>\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using char_type = typename InputAdapterType::char_type;\n    using char_int_type = typename std::char_traits<char_type>::int_type;\n\n  public:\n    using token_type = typename lexer_base<BasicJsonType>::token_type;\n\n    explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept\n        : ia(std::move(adapter))\n        , ignore_comments(ignore_comments_)\n        , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))\n    {}\n\n    // delete because of pointer members\n    lexer(const lexer&) = delete;\n    lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    lexer& operator=(lexer&) = delete;\n    lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~lexer() = default;\n\n  private:\n    /////////////////////\n    // locales\n    /////////////////////\n\n    /// return the locale-dependent decimal point\n    JSON_HEDLEY_PURE\n    static char get_decimal_point() noexcept\n    {\n        const auto* loc = localeconv();\n        JSON_ASSERT(loc != nullptr);\n        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);\n    }\n\n    /////////////////////\n    // scan functions\n    /////////////////////\n\n    /*!\n    @brief get codepoint from 4 hex characters following `\\u`\n\n    For input \"\\u c1 c2 c3 c4\" the codepoint is:\n      (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4\n    = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)\n\n    Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'\n    must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The\n    conversion is done by subtracting the offset (0x30, 0x37, and 0x57)\n    between the ASCII value of the character and the desired integer value.\n\n    @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or\n            non-hex character)\n    */\n    int get_codepoint()\n    {\n        // this function only makes sense after reading `\\u`\n        JSON_ASSERT(current == 'u');\n        int codepoint = 0;\n\n        const auto factors = { 12u, 8u, 4u, 0u };\n        for (const auto factor : factors)\n        {\n            get();\n\n            if (current >= '0' && current <= '9')\n            {\n                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);\n            }\n            else if (current >= 'A' && current <= 'F')\n            {\n                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);\n            }\n            else if (current >= 'a' && current <= 'f')\n            {\n                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);\n        return codepoint;\n    }\n\n    /*!\n    @brief check if the next byte(s) are inside a given range\n\n    Adds the current byte and, for each passed range, reads a new byte and\n    checks if it is inside the range. If a violation was detected, set up an\n    error message and return false. Otherwise, return true.\n\n    @param[in] ranges  list of integers; interpreted as list of pairs of\n                       inclusive lower and upper bound, respectively\n\n    @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,\n         1, 2, or 3 pairs. This precondition is enforced by an assertion.\n\n    @return true if and only if no range violation was detected\n    */\n    bool next_byte_in_range(std::initializer_list<char_int_type> ranges)\n    {\n        JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);\n        add(current);\n\n        for (auto range = ranges.begin(); range != ranges.end(); ++range)\n        {\n            get();\n            if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))\n            {\n                add(current);\n            }\n            else\n            {\n                error_message = \"invalid string: ill-formed UTF-8 byte\";\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /*!\n    @brief scan a string literal\n\n    This function scans a string according to Sect. 7 of RFC 8259. While\n    scanning, bytes are escaped and copied into buffer token_buffer. Then the\n    function returns successfully, token_buffer is *not* null-terminated (as it\n    may contain \\0 bytes), and token_buffer.size() is the number of bytes in the\n    string.\n\n    @return token_type::value_string if string could be successfully scanned,\n            token_type::parse_error otherwise\n\n    @note In case of errors, variable error_message contains a textual\n          description.\n    */\n    token_type scan_string()\n    {\n        // reset token_buffer (ignore opening quote)\n        reset();\n\n        // we entered the function by reading an open quote\n        JSON_ASSERT(current == '\\\"');\n\n        while (true)\n        {\n            // get next character\n            switch (get())\n            {\n                // end of file while parsing string\n                case std::char_traits<char_type>::eof():\n                {\n                    error_message = \"invalid string: missing closing quote\";\n                    return token_type::parse_error;\n                }\n\n                // closing quote\n                case '\\\"':\n                {\n                    return token_type::value_string;\n                }\n\n                // escapes\n                case '\\\\':\n                {\n                    switch (get())\n                    {\n                        // quotation mark\n                        case '\\\"':\n                            add('\\\"');\n                            break;\n                        // reverse solidus\n                        case '\\\\':\n                            add('\\\\');\n                            break;\n                        // solidus\n                        case '/':\n                            add('/');\n                            break;\n                        // backspace\n                        case 'b':\n                            add('\\b');\n                            break;\n                        // form feed\n                        case 'f':\n                            add('\\f');\n                            break;\n                        // line feed\n                        case 'n':\n                            add('\\n');\n                            break;\n                        // carriage return\n                        case 'r':\n                            add('\\r');\n                            break;\n                        // tab\n                        case 't':\n                            add('\\t');\n                            break;\n\n                        // unicode escapes\n                        case 'u':\n                        {\n                            const int codepoint1 = get_codepoint();\n                            int codepoint = codepoint1; // start with codepoint1\n\n                            if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))\n                            {\n                                error_message = \"invalid string: '\\\\u' must be followed by 4 hex digits\";\n                                return token_type::parse_error;\n                            }\n\n                            // check if code point is a high surrogate\n                            if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)\n                            {\n                                // expect next \\uxxxx entry\n                                if (JSON_HEDLEY_LIKELY(get() == '\\\\' && get() == 'u'))\n                                {\n                                    const int codepoint2 = get_codepoint();\n\n                                    if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))\n                                    {\n                                        error_message = \"invalid string: '\\\\u' must be followed by 4 hex digits\";\n                                        return token_type::parse_error;\n                                    }\n\n                                    // check if codepoint2 is a low surrogate\n                                    if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))\n                                    {\n                                        // overwrite codepoint\n                                        codepoint = static_cast<int>(\n                                                        // high surrogate occupies the most significant 22 bits\n                                                        (static_cast<unsigned int>(codepoint1) << 10u)\n                                                        // low surrogate occupies the least significant 15 bits\n                                                        + static_cast<unsigned int>(codepoint2)\n                                                        // there is still the 0xD800, 0xDC00 and 0x10000 noise\n                                                        // in the result, so we have to subtract with:\n                                                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00\n                                                        - 0x35FDC00u);\n                                    }\n                                    else\n                                    {\n                                        error_message = \"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF\";\n                                        return token_type::parse_error;\n                                    }\n                                }\n                                else\n                                {\n                                    error_message = \"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF\";\n                                    return token_type::parse_error;\n                                }\n                            }\n                            else\n                            {\n                                if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))\n                                {\n                                    error_message = \"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF\";\n                                    return token_type::parse_error;\n                                }\n                            }\n\n                            // result of the above calculation yields a proper codepoint\n                            JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);\n\n                            // translate codepoint into bytes\n                            if (codepoint < 0x80)\n                            {\n                                // 1-byte characters: 0xxxxxxx (ASCII)\n                                add(static_cast<char_int_type>(codepoint));\n                            }\n                            else if (codepoint <= 0x7FF)\n                            {\n                                // 2-byte characters: 110xxxxx 10xxxxxx\n                                add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));\n                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));\n                            }\n                            else if (codepoint <= 0xFFFF)\n                            {\n                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx\n                                add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));\n                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));\n                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));\n                            }\n                            else\n                            {\n                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n                                add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));\n                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));\n                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));\n                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));\n                            }\n\n                            break;\n                        }\n\n                        // other characters after escape\n                        default:\n                            error_message = \"invalid string: forbidden character after backslash\";\n                            return token_type::parse_error;\n                    }\n\n                    break;\n                }\n\n                // invalid control characters\n                case 0x00:\n                {\n                    error_message = \"invalid string: control character U+0000 (NUL) must be escaped to \\\\u0000\";\n                    return token_type::parse_error;\n                }\n\n                case 0x01:\n                {\n                    error_message = \"invalid string: control character U+0001 (SOH) must be escaped to \\\\u0001\";\n                    return token_type::parse_error;\n                }\n\n                case 0x02:\n                {\n                    error_message = \"invalid string: control character U+0002 (STX) must be escaped to \\\\u0002\";\n                    return token_type::parse_error;\n                }\n\n                case 0x03:\n                {\n                    error_message = \"invalid string: control character U+0003 (ETX) must be escaped to \\\\u0003\";\n                    return token_type::parse_error;\n                }\n\n                case 0x04:\n                {\n                    error_message = \"invalid string: control character U+0004 (EOT) must be escaped to \\\\u0004\";\n                    return token_type::parse_error;\n                }\n\n                case 0x05:\n                {\n                    error_message = \"invalid string: control character U+0005 (ENQ) must be escaped to \\\\u0005\";\n                    return token_type::parse_error;\n                }\n\n                case 0x06:\n                {\n                    error_message = \"invalid string: control character U+0006 (ACK) must be escaped to \\\\u0006\";\n                    return token_type::parse_error;\n                }\n\n                case 0x07:\n                {\n                    error_message = \"invalid string: control character U+0007 (BEL) must be escaped to \\\\u0007\";\n                    return token_type::parse_error;\n                }\n\n                case 0x08:\n                {\n                    error_message = \"invalid string: control character U+0008 (BS) must be escaped to \\\\u0008 or \\\\b\";\n                    return token_type::parse_error;\n                }\n\n                case 0x09:\n                {\n                    error_message = \"invalid string: control character U+0009 (HT) must be escaped to \\\\u0009 or \\\\t\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0A:\n                {\n                    error_message = \"invalid string: control character U+000A (LF) must be escaped to \\\\u000A or \\\\n\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0B:\n                {\n                    error_message = \"invalid string: control character U+000B (VT) must be escaped to \\\\u000B\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0C:\n                {\n                    error_message = \"invalid string: control character U+000C (FF) must be escaped to \\\\u000C or \\\\f\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0D:\n                {\n                    error_message = \"invalid string: control character U+000D (CR) must be escaped to \\\\u000D or \\\\r\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0E:\n                {\n                    error_message = \"invalid string: control character U+000E (SO) must be escaped to \\\\u000E\";\n                    return token_type::parse_error;\n                }\n\n                case 0x0F:\n                {\n                    error_message = \"invalid string: control character U+000F (SI) must be escaped to \\\\u000F\";\n                    return token_type::parse_error;\n                }\n\n                case 0x10:\n                {\n                    error_message = \"invalid string: control character U+0010 (DLE) must be escaped to \\\\u0010\";\n                    return token_type::parse_error;\n                }\n\n                case 0x11:\n                {\n                    error_message = \"invalid string: control character U+0011 (DC1) must be escaped to \\\\u0011\";\n                    return token_type::parse_error;\n                }\n\n                case 0x12:\n                {\n                    error_message = \"invalid string: control character U+0012 (DC2) must be escaped to \\\\u0012\";\n                    return token_type::parse_error;\n                }\n\n                case 0x13:\n                {\n                    error_message = \"invalid string: control character U+0013 (DC3) must be escaped to \\\\u0013\";\n                    return token_type::parse_error;\n                }\n\n                case 0x14:\n                {\n                    error_message = \"invalid string: control character U+0014 (DC4) must be escaped to \\\\u0014\";\n                    return token_type::parse_error;\n                }\n\n                case 0x15:\n                {\n                    error_message = \"invalid string: control character U+0015 (NAK) must be escaped to \\\\u0015\";\n                    return token_type::parse_error;\n                }\n\n                case 0x16:\n                {\n                    error_message = \"invalid string: control character U+0016 (SYN) must be escaped to \\\\u0016\";\n                    return token_type::parse_error;\n                }\n\n                case 0x17:\n                {\n                    error_message = \"invalid string: control character U+0017 (ETB) must be escaped to \\\\u0017\";\n                    return token_type::parse_error;\n                }\n\n                case 0x18:\n                {\n                    error_message = \"invalid string: control character U+0018 (CAN) must be escaped to \\\\u0018\";\n                    return token_type::parse_error;\n                }\n\n                case 0x19:\n                {\n                    error_message = \"invalid string: control character U+0019 (EM) must be escaped to \\\\u0019\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1A:\n                {\n                    error_message = \"invalid string: control character U+001A (SUB) must be escaped to \\\\u001A\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1B:\n                {\n                    error_message = \"invalid string: control character U+001B (ESC) must be escaped to \\\\u001B\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1C:\n                {\n                    error_message = \"invalid string: control character U+001C (FS) must be escaped to \\\\u001C\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1D:\n                {\n                    error_message = \"invalid string: control character U+001D (GS) must be escaped to \\\\u001D\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1E:\n                {\n                    error_message = \"invalid string: control character U+001E (RS) must be escaped to \\\\u001E\";\n                    return token_type::parse_error;\n                }\n\n                case 0x1F:\n                {\n                    error_message = \"invalid string: control character U+001F (US) must be escaped to \\\\u001F\";\n                    return token_type::parse_error;\n                }\n\n                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))\n                case 0x20:\n                case 0x21:\n                case 0x23:\n                case 0x24:\n                case 0x25:\n                case 0x26:\n                case 0x27:\n                case 0x28:\n                case 0x29:\n                case 0x2A:\n                case 0x2B:\n                case 0x2C:\n                case 0x2D:\n                case 0x2E:\n                case 0x2F:\n                case 0x30:\n                case 0x31:\n                case 0x32:\n                case 0x33:\n                case 0x34:\n                case 0x35:\n                case 0x36:\n                case 0x37:\n                case 0x38:\n                case 0x39:\n                case 0x3A:\n                case 0x3B:\n                case 0x3C:\n                case 0x3D:\n                case 0x3E:\n                case 0x3F:\n                case 0x40:\n                case 0x41:\n                case 0x42:\n                case 0x43:\n                case 0x44:\n                case 0x45:\n                case 0x46:\n                case 0x47:\n                case 0x48:\n                case 0x49:\n                case 0x4A:\n                case 0x4B:\n                case 0x4C:\n                case 0x4D:\n                case 0x4E:\n                case 0x4F:\n                case 0x50:\n                case 0x51:\n                case 0x52:\n                case 0x53:\n                case 0x54:\n                case 0x55:\n                case 0x56:\n                case 0x57:\n                case 0x58:\n                case 0x59:\n                case 0x5A:\n                case 0x5B:\n                case 0x5D:\n                case 0x5E:\n                case 0x5F:\n                case 0x60:\n                case 0x61:\n                case 0x62:\n                case 0x63:\n                case 0x64:\n                case 0x65:\n                case 0x66:\n                case 0x67:\n                case 0x68:\n                case 0x69:\n                case 0x6A:\n                case 0x6B:\n                case 0x6C:\n                case 0x6D:\n                case 0x6E:\n                case 0x6F:\n                case 0x70:\n                case 0x71:\n                case 0x72:\n                case 0x73:\n                case 0x74:\n                case 0x75:\n                case 0x76:\n                case 0x77:\n                case 0x78:\n                case 0x79:\n                case 0x7A:\n                case 0x7B:\n                case 0x7C:\n                case 0x7D:\n                case 0x7E:\n                case 0x7F:\n                {\n                    add(current);\n                    break;\n                }\n\n                // U+0080..U+07FF: bytes C2..DF 80..BF\n                case 0xC2:\n                case 0xC3:\n                case 0xC4:\n                case 0xC5:\n                case 0xC6:\n                case 0xC7:\n                case 0xC8:\n                case 0xC9:\n                case 0xCA:\n                case 0xCB:\n                case 0xCC:\n                case 0xCD:\n                case 0xCE:\n                case 0xCF:\n                case 0xD0:\n                case 0xD1:\n                case 0xD2:\n                case 0xD3:\n                case 0xD4:\n                case 0xD5:\n                case 0xD6:\n                case 0xD7:\n                case 0xD8:\n                case 0xD9:\n                case 0xDA:\n                case 0xDB:\n                case 0xDC:\n                case 0xDD:\n                case 0xDE:\n                case 0xDF:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF\n                case 0xE0:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF\n                // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF\n                case 0xE1:\n                case 0xE2:\n                case 0xE3:\n                case 0xE4:\n                case 0xE5:\n                case 0xE6:\n                case 0xE7:\n                case 0xE8:\n                case 0xE9:\n                case 0xEA:\n                case 0xEB:\n                case 0xEC:\n                case 0xEE:\n                case 0xEF:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+D000..U+D7FF: bytes ED 80..9F 80..BF\n                case 0xED:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF\n                case 0xF0:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF\n                case 0xF1:\n                case 0xF2:\n                case 0xF3:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF\n                case 0xF4:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))\n                    {\n                        return token_type::parse_error;\n                    }\n                    break;\n                }\n\n                // remaining bytes (80..C1 and F5..FF) are ill-formed\n                default:\n                {\n                    error_message = \"invalid string: ill-formed UTF-8 byte\";\n                    return token_type::parse_error;\n                }\n            }\n        }\n    }\n\n    /*!\n     * @brief scan a comment\n     * @return whether comment could be scanned successfully\n     */\n    bool scan_comment()\n    {\n        switch (get())\n        {\n            // single-line comments skip input until a newline or EOF is read\n            case '/':\n            {\n                while (true)\n                {\n                    switch (get())\n                    {\n                        case '\\n':\n                        case '\\r':\n                        case std::char_traits<char_type>::eof():\n                        case '\\0':\n                            return true;\n\n                        default:\n                            break;\n                    }\n                }\n            }\n\n            // multi-line comments skip input until */ is read\n            case '*':\n            {\n                while (true)\n                {\n                    switch (get())\n                    {\n                        case std::char_traits<char_type>::eof():\n                        case '\\0':\n                        {\n                            error_message = \"invalid comment; missing closing '*/'\";\n                            return false;\n                        }\n\n                        case '*':\n                        {\n                            switch (get())\n                            {\n                                case '/':\n                                    return true;\n\n                                default:\n                                {\n                                    unget();\n                                    continue;\n                                }\n                            }\n                        }\n\n                        default:\n                            continue;\n                    }\n                }\n            }\n\n            // unexpected character after reading '/'\n            default:\n            {\n                error_message = \"invalid comment; expecting '/' or '*' after '/'\";\n                return false;\n            }\n        }\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    static void strtof(float& f, const char* str, char** endptr) noexcept\n    {\n        f = std::strtof(str, endptr);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    static void strtof(double& f, const char* str, char** endptr) noexcept\n    {\n        f = std::strtod(str, endptr);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    static void strtof(long double& f, const char* str, char** endptr) noexcept\n    {\n        f = std::strtold(str, endptr);\n    }\n\n    /*!\n    @brief scan a number literal\n\n    This function scans a string according to Sect. 6 of RFC 8259.\n\n    The function is realized with a deterministic finite state machine derived\n    from the grammar described in RFC 8259. Starting in state \"init\", the\n    input is read and used to determined the next state. Only state \"done\"\n    accepts the number. State \"error\" is a trap state to model errors. In the\n    table below, \"anything\" means any character but the ones listed before.\n\n    state    | 0        | 1-9      | e E      | +       | -       | .        | anything\n    ---------|----------|----------|----------|---------|---------|----------|-----------\n    init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]\n    minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]\n    zero     | done     | done     | exponent | done    | done    | decimal1 | done\n    any1     | any1     | any1     | exponent | done    | done    | decimal1 | done\n    decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]\n    decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done\n    exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]\n    sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]\n    any2     | any2     | any2     | done     | done    | done    | done     | done\n\n    The state machine is realized with one label per state (prefixed with\n    \"scan_number_\") and `goto` statements between them. The state machine\n    contains cycles, but any cycle can be left when EOF is read. Therefore,\n    the function is guaranteed to terminate.\n\n    During scanning, the read bytes are stored in token_buffer. This string is\n    then converted to a signed integer, an unsigned integer, or a\n    floating-point number.\n\n    @return token_type::value_unsigned, token_type::value_integer, or\n            token_type::value_float if number could be successfully scanned,\n            token_type::parse_error otherwise\n\n    @note The scanner is independent of the current locale. Internally, the\n          locale's decimal point is used instead of `.` to work with the\n          locale-dependent converters.\n    */\n    token_type scan_number()  // lgtm [cpp/use-of-goto]\n    {\n        // reset token_buffer to store the number's bytes\n        reset();\n\n        // the type of the parsed number; initially set to unsigned; will be\n        // changed if minus sign, decimal point or exponent is read\n        token_type number_type = token_type::value_unsigned;\n\n        // state (init): we just found out we need to scan a number\n        switch (current)\n        {\n            case '-':\n            {\n                add(current);\n                goto scan_number_minus;\n            }\n\n            case '0':\n            {\n                add(current);\n                goto scan_number_zero;\n            }\n\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any1;\n            }\n\n            // all other characters are rejected outside scan_number()\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n\nscan_number_minus:\n        // state: we just parsed a leading minus sign\n        number_type = token_type::value_integer;\n        switch (get())\n        {\n            case '0':\n            {\n                add(current);\n                goto scan_number_zero;\n            }\n\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any1;\n            }\n\n            default:\n            {\n                error_message = \"invalid number; expected digit after '-'\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_zero:\n        // state: we just parse a zero (maybe with a leading minus sign)\n        switch (get())\n        {\n            case '.':\n            {\n                add(decimal_point_char);\n                goto scan_number_decimal1;\n            }\n\n            case 'e':\n            case 'E':\n            {\n                add(current);\n                goto scan_number_exponent;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_any1:\n        // state: we just parsed a number 0-9 (maybe with a leading minus sign)\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any1;\n            }\n\n            case '.':\n            {\n                add(decimal_point_char);\n                goto scan_number_decimal1;\n            }\n\n            case 'e':\n            case 'E':\n            {\n                add(current);\n                goto scan_number_exponent;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_decimal1:\n        // state: we just parsed a decimal point\n        number_type = token_type::value_float;\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_decimal2;\n            }\n\n            default:\n            {\n                error_message = \"invalid number; expected digit after '.'\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_decimal2:\n        // we just parsed at least one number after a decimal point\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_decimal2;\n            }\n\n            case 'e':\n            case 'E':\n            {\n                add(current);\n                goto scan_number_exponent;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_exponent:\n        // we just parsed an exponent\n        number_type = token_type::value_float;\n        switch (get())\n        {\n            case '+':\n            case '-':\n            {\n                add(current);\n                goto scan_number_sign;\n            }\n\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any2;\n            }\n\n            default:\n            {\n                error_message =\n                    \"invalid number; expected '+', '-', or digit after exponent\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_sign:\n        // we just parsed an exponent sign\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any2;\n            }\n\n            default:\n            {\n                error_message = \"invalid number; expected digit after exponent sign\";\n                return token_type::parse_error;\n            }\n        }\n\nscan_number_any2:\n        // we just parsed a number after the exponent or exponent sign\n        switch (get())\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            {\n                add(current);\n                goto scan_number_any2;\n            }\n\n            default:\n                goto scan_number_done;\n        }\n\nscan_number_done:\n        // unget the character after the number (we only read it to know that\n        // we are done scanning a number)\n        unget();\n\n        char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n        errno = 0;\n\n        // try to parse integers first and fall back to floats\n        if (number_type == token_type::value_unsigned)\n        {\n            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);\n\n            // we checked the number format before\n            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());\n\n            if (errno == 0)\n            {\n                value_unsigned = static_cast<number_unsigned_t>(x);\n                if (value_unsigned == x)\n                {\n                    return token_type::value_unsigned;\n                }\n            }\n        }\n        else if (number_type == token_type::value_integer)\n        {\n            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);\n\n            // we checked the number format before\n            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());\n\n            if (errno == 0)\n            {\n                value_integer = static_cast<number_integer_t>(x);\n                if (value_integer == x)\n                {\n                    return token_type::value_integer;\n                }\n            }\n        }\n\n        // this code is reached if we parse a floating-point number or if an\n        // integer conversion above failed\n        strtof(value_float, token_buffer.data(), &endptr);\n\n        // we checked the number format before\n        JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());\n\n        return token_type::value_float;\n    }\n\n    /*!\n    @param[in] literal_text  the literal text to expect\n    @param[in] length        the length of the passed literal text\n    @param[in] return_type   the token type to return on success\n    */\n    JSON_HEDLEY_NON_NULL(2)\n    token_type scan_literal(const char_type* literal_text, const std::size_t length,\n                            token_type return_type)\n    {\n        JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);\n        for (std::size_t i = 1; i < length; ++i)\n        {\n            if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))\n            {\n                error_message = \"invalid literal\";\n                return token_type::parse_error;\n            }\n        }\n        return return_type;\n    }\n\n    /////////////////////\n    // input management\n    /////////////////////\n\n    /// reset token_buffer; current character is beginning of token\n    void reset() noexcept\n    {\n        token_buffer.clear();\n        token_string.clear();\n        token_string.push_back(std::char_traits<char_type>::to_char_type(current));\n    }\n\n    /*\n    @brief get next character from the input\n\n    This function provides the interface to the used input adapter. It does\n    not throw in case the input reached EOF, but returns a\n    `std::char_traits<char>::eof()` in that case.  Stores the scanned characters\n    for use in error messages.\n\n    @return character read from the input\n    */\n    char_int_type get()\n    {\n        ++position.chars_read_total;\n        ++position.chars_read_current_line;\n\n        if (next_unget)\n        {\n            // just reset the next_unget variable and work with current\n            next_unget = false;\n        }\n        else\n        {\n            current = ia.get_character();\n        }\n\n        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))\n        {\n            token_string.push_back(std::char_traits<char_type>::to_char_type(current));\n        }\n\n        if (current == '\\n')\n        {\n            ++position.lines_read;\n            position.chars_read_current_line = 0;\n        }\n\n        return current;\n    }\n\n    /*!\n    @brief unget current character (read it again on next get)\n\n    We implement unget by setting variable next_unget to true. The input is not\n    changed - we just simulate ungetting by modifying chars_read_total,\n    chars_read_current_line, and token_string. The next call to get() will\n    behave as if the unget character is read again.\n    */\n    void unget()\n    {\n        next_unget = true;\n\n        --position.chars_read_total;\n\n        // in case we \"unget\" a newline, we have to also decrement the lines_read\n        if (position.chars_read_current_line == 0)\n        {\n            if (position.lines_read > 0)\n            {\n                --position.lines_read;\n            }\n        }\n        else\n        {\n            --position.chars_read_current_line;\n        }\n\n        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))\n        {\n            JSON_ASSERT(!token_string.empty());\n            token_string.pop_back();\n        }\n    }\n\n    /// add a character to token_buffer\n    void add(char_int_type c)\n    {\n        token_buffer.push_back(static_cast<typename string_t::value_type>(c));\n    }\n\n  public:\n    /////////////////////\n    // value getters\n    /////////////////////\n\n    /// return integer value\n    constexpr number_integer_t get_number_integer() const noexcept\n    {\n        return value_integer;\n    }\n\n    /// return unsigned integer value\n    constexpr number_unsigned_t get_number_unsigned() const noexcept\n    {\n        return value_unsigned;\n    }\n\n    /// return floating-point value\n    constexpr number_float_t get_number_float() const noexcept\n    {\n        return value_float;\n    }\n\n    /// return current string value (implicitly resets the token; useful only once)\n    string_t& get_string()\n    {\n        return token_buffer;\n    }\n\n    /////////////////////\n    // diagnostics\n    /////////////////////\n\n    /// return position of last read token\n    constexpr position_t get_position() const noexcept\n    {\n        return position;\n    }\n\n    /// return the last read token (for errors only).  Will never contain EOF\n    /// (an arbitrary value that is not a valid char value, often -1), because\n    /// 255 may legitimately occur.  May contain NUL, which should be escaped.\n    std::string get_token_string() const\n    {\n        // escape control characters\n        std::string result;\n        for (const auto c : token_string)\n        {\n            if (static_cast<unsigned char>(c) <= '\\x1F')\n            {\n                // escape control characters\n                std::array<char, 9> cs{{}};\n                static_cast<void>((std::snprintf)(cs.data(), cs.size(), \"<U+%.4X>\", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                result += cs.data();\n            }\n            else\n            {\n                // add character as is\n                result.push_back(static_cast<std::string::value_type>(c));\n            }\n        }\n\n        return result;\n    }\n\n    /// return syntax error message\n    JSON_HEDLEY_RETURNS_NON_NULL\n    constexpr const char* get_error_message() const noexcept\n    {\n        return error_message;\n    }\n\n    /////////////////////\n    // actual scanner\n    /////////////////////\n\n    /*!\n    @brief skip the UTF-8 byte order mark\n    @return true iff there is no BOM or the correct BOM has been skipped\n    */\n    bool skip_bom()\n    {\n        if (get() == 0xEF)\n        {\n            // check if we completely parse the BOM\n            return get() == 0xBB && get() == 0xBF;\n        }\n\n        // the first character is not the beginning of the BOM; unget it to\n        // process is later\n        unget();\n        return true;\n    }\n\n    void skip_whitespace()\n    {\n        do\n        {\n            get();\n        }\n        while (current == ' ' || current == '\\t' || current == '\\n' || current == '\\r');\n    }\n\n    token_type scan()\n    {\n        // initially, skip the BOM\n        if (position.chars_read_total == 0 && !skip_bom())\n        {\n            error_message = \"invalid BOM; must be 0xEF 0xBB 0xBF if given\";\n            return token_type::parse_error;\n        }\n\n        // read next character and ignore whitespace\n        skip_whitespace();\n\n        // ignore comments\n        while (ignore_comments && current == '/')\n        {\n            if (!scan_comment())\n            {\n                return token_type::parse_error;\n            }\n\n            // skip following whitespace\n            skip_whitespace();\n        }\n\n        switch (current)\n        {\n            // structural characters\n            case '[':\n                return token_type::begin_array;\n            case ']':\n                return token_type::end_array;\n            case '{':\n                return token_type::begin_object;\n            case '}':\n                return token_type::end_object;\n            case ':':\n                return token_type::name_separator;\n            case ',':\n                return token_type::value_separator;\n\n            // literals\n            case 't':\n            {\n                std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};\n                return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);\n            }\n            case 'f':\n            {\n                std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};\n                return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);\n            }\n            case 'n':\n            {\n                std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};\n                return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);\n            }\n\n            // string\n            case '\\\"':\n                return scan_string();\n\n            // number\n            case '-':\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n                return scan_number();\n\n            // end of input (the null byte is needed when parsing from\n            // string literals)\n            case '\\0':\n            case std::char_traits<char_type>::eof():\n                return token_type::end_of_input;\n\n            // error\n            default:\n                error_message = \"invalid literal\";\n                return token_type::parse_error;\n        }\n    }\n\n  private:\n    /// input adapter\n    InputAdapterType ia;\n\n    /// whether comments should be ignored (true) or signaled as errors (false)\n    const bool ignore_comments = false;\n\n    /// the current character\n    char_int_type current = std::char_traits<char_type>::eof();\n\n    /// whether the next get() call should just return current\n    bool next_unget = false;\n\n    /// the start position of the current token\n    position_t position {};\n\n    /// raw input token string (for error messages)\n    std::vector<char_type> token_string {};\n\n    /// buffer for variable-length tokens (numbers, strings)\n    string_t token_buffer {};\n\n    /// a description of occurred lexer errors\n    const char* error_message = \"\";\n\n    // number values\n    number_integer_t value_integer = 0;\n    number_unsigned_t value_unsigned = 0;\n    number_float_t value_float = 0;\n\n    /// the decimal point\n    const char_int_type decimal_point_char = '.';\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/meta/is_sax.hpp>\n\n\n#include <cstdint> // size_t\n#include <utility> // declval\n#include <string> // string\n\n// #include <nlohmann/detail/meta/detected.hpp>\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename T>\nusing null_function_t = decltype(std::declval<T&>().null());\n\ntemplate<typename T>\nusing boolean_function_t =\n    decltype(std::declval<T&>().boolean(std::declval<bool>()));\n\ntemplate<typename T, typename Integer>\nusing number_integer_function_t =\n    decltype(std::declval<T&>().number_integer(std::declval<Integer>()));\n\ntemplate<typename T, typename Unsigned>\nusing number_unsigned_function_t =\n    decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));\n\ntemplate<typename T, typename Float, typename String>\nusing number_float_function_t = decltype(std::declval<T&>().number_float(\n                                    std::declval<Float>(), std::declval<const String&>()));\n\ntemplate<typename T, typename String>\nusing string_function_t =\n    decltype(std::declval<T&>().string(std::declval<String&>()));\n\ntemplate<typename T, typename Binary>\nusing binary_function_t =\n    decltype(std::declval<T&>().binary(std::declval<Binary&>()));\n\ntemplate<typename T>\nusing start_object_function_t =\n    decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));\n\ntemplate<typename T, typename String>\nusing key_function_t =\n    decltype(std::declval<T&>().key(std::declval<String&>()));\n\ntemplate<typename T>\nusing end_object_function_t = decltype(std::declval<T&>().end_object());\n\ntemplate<typename T>\nusing start_array_function_t =\n    decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));\n\ntemplate<typename T>\nusing end_array_function_t = decltype(std::declval<T&>().end_array());\n\ntemplate<typename T, typename Exception>\nusing parse_error_function_t = decltype(std::declval<T&>().parse_error(\n        std::declval<std::size_t>(), std::declval<const std::string&>(),\n        std::declval<const Exception&>()));\n\ntemplate<typename SAX, typename BasicJsonType>\nstruct is_sax\n{\n  private:\n    static_assert(is_basic_json<BasicJsonType>::value,\n                  \"BasicJsonType must be of type basic_json<...>\");\n\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using exception_t = typename BasicJsonType::exception;\n\n  public:\n    static constexpr bool value =\n        is_detected_exact<bool, null_function_t, SAX>::value &&\n        is_detected_exact<bool, boolean_function_t, SAX>::value &&\n        is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&\n        is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&\n        is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&\n        is_detected_exact<bool, string_function_t, SAX, string_t>::value &&\n        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&\n        is_detected_exact<bool, start_object_function_t, SAX>::value &&\n        is_detected_exact<bool, key_function_t, SAX, string_t>::value &&\n        is_detected_exact<bool, end_object_function_t, SAX>::value &&\n        is_detected_exact<bool, start_array_function_t, SAX>::value &&\n        is_detected_exact<bool, end_array_function_t, SAX>::value &&\n        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;\n};\n\ntemplate<typename SAX, typename BasicJsonType>\nstruct is_sax_static_asserts\n{\n  private:\n    static_assert(is_basic_json<BasicJsonType>::value,\n                  \"BasicJsonType must be of type basic_json<...>\");\n\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using exception_t = typename BasicJsonType::exception;\n\n  public:\n    static_assert(is_detected_exact<bool, null_function_t, SAX>::value,\n                  \"Missing/invalid function: bool null()\");\n    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,\n                  \"Missing/invalid function: bool boolean(bool)\");\n    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,\n                  \"Missing/invalid function: bool boolean(bool)\");\n    static_assert(\n        is_detected_exact<bool, number_integer_function_t, SAX,\n        number_integer_t>::value,\n        \"Missing/invalid function: bool number_integer(number_integer_t)\");\n    static_assert(\n        is_detected_exact<bool, number_unsigned_function_t, SAX,\n        number_unsigned_t>::value,\n        \"Missing/invalid function: bool number_unsigned(number_unsigned_t)\");\n    static_assert(is_detected_exact<bool, number_float_function_t, SAX,\n                  number_float_t, string_t>::value,\n                  \"Missing/invalid function: bool number_float(number_float_t, const string_t&)\");\n    static_assert(\n        is_detected_exact<bool, string_function_t, SAX, string_t>::value,\n        \"Missing/invalid function: bool string(string_t&)\");\n    static_assert(\n        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,\n        \"Missing/invalid function: bool binary(binary_t&)\");\n    static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,\n                  \"Missing/invalid function: bool start_object(std::size_t)\");\n    static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,\n                  \"Missing/invalid function: bool key(string_t&)\");\n    static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,\n                  \"Missing/invalid function: bool end_object()\");\n    static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,\n                  \"Missing/invalid function: bool start_array(std::size_t)\");\n    static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,\n                  \"Missing/invalid function: bool end_array()\");\n    static_assert(\n        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,\n        \"Missing/invalid function: bool parse_error(std::size_t, const \"\n        \"std::string&, const exception&)\");\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n/// how to treat CBOR tags\nenum class cbor_tag_handler_t\n{\n    error,   ///< throw a parse_error exception in case of a tag\n    ignore,  ///< ignore tags\n    store    ///< store tags as binary type\n};\n\n/*!\n@brief determine system byte order\n\n@return true if and only if system's byte order is little endian\n\n@note from https://stackoverflow.com/a/1001328/266378\n*/\nstatic inline bool little_endianness(int num = 1) noexcept\n{\n    return *reinterpret_cast<char*>(&num) == 1;\n}\n\n\n///////////////////\n// binary reader //\n///////////////////\n\n/*!\n@brief deserialization of CBOR, MessagePack, and UBJSON values\n*/\ntemplate<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>\nclass binary_reader\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using json_sax_t = SAX;\n    using char_type = typename InputAdapterType::char_type;\n    using char_int_type = typename std::char_traits<char_type>::int_type;\n\n  public:\n    /*!\n    @brief create a binary reader\n\n    @param[in] adapter  input adapter to read from\n    */\n    explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))\n    {\n        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};\n    }\n\n    // make class move-only\n    binary_reader(const binary_reader&) = delete;\n    binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    binary_reader& operator=(const binary_reader&) = delete;\n    binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)\n    ~binary_reader() = default;\n\n    /*!\n    @param[in] format  the binary format to parse\n    @param[in] sax_    a SAX event processor\n    @param[in] strict  whether to expect the input to be consumed completed\n    @param[in] tag_handler  how to treat CBOR tags\n\n    @return whether parsing was successful\n    */\n    JSON_HEDLEY_NON_NULL(3)\n    bool sax_parse(const input_format_t format,\n                   json_sax_t* sax_,\n                   const bool strict = true,\n                   const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        sax = sax_;\n        bool result = false;\n\n        switch (format)\n        {\n            case input_format_t::bson:\n                result = parse_bson_internal();\n                break;\n\n            case input_format_t::cbor:\n                result = parse_cbor_internal(true, tag_handler);\n                break;\n\n            case input_format_t::msgpack:\n                result = parse_msgpack_internal();\n                break;\n\n            case input_format_t::ubjson:\n                result = parse_ubjson_internal();\n                break;\n\n            case input_format_t::json: // LCOV_EXCL_LINE\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n\n        // strict mode: next byte must be EOF\n        if (result && strict)\n        {\n            if (format == input_format_t::ubjson)\n            {\n                get_ignore_noop();\n            }\n            else\n            {\n                get();\n            }\n\n            if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))\n            {\n                return sax->parse_error(chars_read, get_token_string(),\n                                        parse_error::create(110, chars_read, exception_message(format, \"expected end of input; last byte: 0x\" + get_token_string(), \"value\"), BasicJsonType()));\n            }\n        }\n\n        return result;\n    }\n\n  private:\n    //////////\n    // BSON //\n    //////////\n\n    /*!\n    @brief Reads in a BSON-object and passes it to the SAX-parser.\n    @return whether a valid BSON-value was passed to the SAX parser\n    */\n    bool parse_bson_internal()\n    {\n        std::int32_t document_size{};\n        get_number<std::int32_t, true>(input_format_t::bson, document_size);\n\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))\n        {\n            return false;\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))\n        {\n            return false;\n        }\n\n        return sax->end_object();\n    }\n\n    /*!\n    @brief Parses a C-style string from the BSON input.\n    @param[in,out] result  A reference to the string variable where the read\n                            string is to be stored.\n    @return `true` if the \\x00-byte indicating the end of the string was\n             encountered before the EOF; false` indicates an unexpected EOF.\n    */\n    bool get_bson_cstr(string_t& result)\n    {\n        auto out = std::back_inserter(result);\n        while (true)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, \"cstring\")))\n            {\n                return false;\n            }\n            if (current == 0x00)\n            {\n                return true;\n            }\n            *out++ = static_cast<typename string_t::value_type>(current);\n        }\n    }\n\n    /*!\n    @brief Parses a zero-terminated string of length @a len from the BSON\n           input.\n    @param[in] len  The length (including the zero-byte at the end) of the\n                    string to be read.\n    @param[in,out] result  A reference to the string variable where the read\n                            string is to be stored.\n    @tparam NumberType The type of the length @a len\n    @pre len >= 1\n    @return `true` if the string was successfully parsed\n    */\n    template<typename NumberType>\n    bool get_bson_string(const NumberType len, string_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(len < 1))\n        {\n            auto last_token = get_token_string();\n            return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, \"string length must be at least 1, is \" + std::to_string(len), \"string\"), BasicJsonType()));\n        }\n\n        return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();\n    }\n\n    /*!\n    @brief Parses a byte array input of length @a len from the BSON input.\n    @param[in] len  The length of the byte array to be read.\n    @param[in,out] result  A reference to the binary variable where the read\n                            array is to be stored.\n    @tparam NumberType The type of the length @a len\n    @pre len >= 0\n    @return `true` if the byte array was successfully parsed\n    */\n    template<typename NumberType>\n    bool get_bson_binary(const NumberType len, binary_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(len < 0))\n        {\n            auto last_token = get_token_string();\n            return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, \"byte array length cannot be negative, is \" + std::to_string(len), \"binary\"), BasicJsonType()));\n        }\n\n        // All BSON binary values have a subtype\n        std::uint8_t subtype{};\n        get_number<std::uint8_t>(input_format_t::bson, subtype);\n        result.set_subtype(subtype);\n\n        return get_binary(input_format_t::bson, len, result);\n    }\n\n    /*!\n    @brief Read a BSON document element of the given @a element_type.\n    @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html\n    @param[in] element_type_parse_position The position in the input stream,\n               where the `element_type` was read.\n    @warning Not all BSON element types are supported yet. An unsupported\n             @a element_type will give rise to a parse_error.114:\n             Unsupported BSON record type 0x...\n    @return whether a valid BSON-object/array was passed to the SAX parser\n    */\n    bool parse_bson_element_internal(const char_int_type element_type,\n                                     const std::size_t element_type_parse_position)\n    {\n        switch (element_type)\n        {\n            case 0x01: // double\n            {\n                double number{};\n                return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0x02: // string\n            {\n                std::int32_t len{};\n                string_t value;\n                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);\n            }\n\n            case 0x03: // object\n            {\n                return parse_bson_internal();\n            }\n\n            case 0x04: // array\n            {\n                return parse_bson_array();\n            }\n\n            case 0x05: // binary\n            {\n                std::int32_t len{};\n                binary_t value;\n                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);\n            }\n\n            case 0x08: // boolean\n            {\n                return sax->boolean(get() != 0);\n            }\n\n            case 0x0A: // null\n            {\n                return sax->null();\n            }\n\n            case 0x10: // int32\n            {\n                std::int32_t value{};\n                return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);\n            }\n\n            case 0x12: // int64\n            {\n                std::int64_t value{};\n                return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);\n            }\n\n            default: // anything else not supported (yet)\n            {\n                std::array<char, 3> cr{{}};\n                static_cast<void>((std::snprintf)(cr.data(), cr.size(), \"%.2hhX\", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, \"Unsupported BSON record type 0x\" + std::string(cr.data()), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief Read a BSON element list (as specified in the BSON-spec)\n\n    The same binary layout is used for objects and arrays, hence it must be\n    indicated with the argument @a is_array which one is expected\n    (true --> array, false --> object).\n\n    @param[in] is_array Determines if the element list being read is to be\n                        treated as an object (@a is_array == false), or as an\n                        array (@a is_array == true).\n    @return whether a valid BSON-object/array was passed to the SAX parser\n    */\n    bool parse_bson_element_list(const bool is_array)\n    {\n        string_t key;\n\n        while (auto element_type = get())\n        {\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, \"element list\")))\n            {\n                return false;\n            }\n\n            const std::size_t element_type_parse_position = chars_read;\n            if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))\n            {\n                return false;\n            }\n\n            if (!is_array && !sax->key(key))\n            {\n                return false;\n            }\n\n            if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))\n            {\n                return false;\n            }\n\n            // get_bson_cstr only appends\n            key.clear();\n        }\n\n        return true;\n    }\n\n    /*!\n    @brief Reads an array from the BSON input and passes it to the SAX-parser.\n    @return whether a valid BSON-array was passed to the SAX parser\n    */\n    bool parse_bson_array()\n    {\n        std::int32_t document_size{};\n        get_number<std::int32_t, true>(input_format_t::bson, document_size);\n\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))\n        {\n            return false;\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))\n        {\n            return false;\n        }\n\n        return sax->end_array();\n    }\n\n    //////////\n    // CBOR //\n    //////////\n\n    /*!\n    @param[in] get_char  whether a new character should be retrieved from the\n                         input (true) or whether the last read character should\n                         be considered instead (false)\n    @param[in] tag_handler how CBOR tags should be treated\n\n    @return whether a valid CBOR value was passed to the SAX parser\n    */\n    bool parse_cbor_internal(const bool get_char,\n                             const cbor_tag_handler_t tag_handler)\n    {\n        switch (get_char ? get() : current)\n        {\n            // EOF\n            case std::char_traits<char_type>::eof():\n                return unexpect_eof(input_format_t::cbor, \"value\");\n\n            // Integer 0x00..0x17 (0..23)\n            case 0x00:\n            case 0x01:\n            case 0x02:\n            case 0x03:\n            case 0x04:\n            case 0x05:\n            case 0x06:\n            case 0x07:\n            case 0x08:\n            case 0x09:\n            case 0x0A:\n            case 0x0B:\n            case 0x0C:\n            case 0x0D:\n            case 0x0E:\n            case 0x0F:\n            case 0x10:\n            case 0x11:\n            case 0x12:\n            case 0x13:\n            case 0x14:\n            case 0x15:\n            case 0x16:\n            case 0x17:\n                return sax->number_unsigned(static_cast<number_unsigned_t>(current));\n\n            case 0x18: // Unsigned integer (one-byte uint8_t follows)\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            case 0x19: // Unsigned integer (two-byte uint16_t follows)\n            {\n                std::uint16_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            case 0x1A: // Unsigned integer (four-byte uint32_t follows)\n            {\n                std::uint32_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            case 0x1B: // Unsigned integer (eight-byte uint64_t follows)\n            {\n                std::uint64_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);\n            }\n\n            // Negative integer -1-0x00..-1-0x17 (-1..-24)\n            case 0x20:\n            case 0x21:\n            case 0x22:\n            case 0x23:\n            case 0x24:\n            case 0x25:\n            case 0x26:\n            case 0x27:\n            case 0x28:\n            case 0x29:\n            case 0x2A:\n            case 0x2B:\n            case 0x2C:\n            case 0x2D:\n            case 0x2E:\n            case 0x2F:\n            case 0x30:\n            case 0x31:\n            case 0x32:\n            case 0x33:\n            case 0x34:\n            case 0x35:\n            case 0x36:\n            case 0x37:\n                return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));\n\n            case 0x38: // Negative integer (one-byte uint8_t follows)\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);\n            }\n\n            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)\n            {\n                std::uint16_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);\n            }\n\n            case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)\n            {\n                std::uint32_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);\n            }\n\n            case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)\n            {\n                std::uint64_t number{};\n                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)\n                        - static_cast<number_integer_t>(number));\n            }\n\n            // Binary data (0x00..0x17 bytes follow)\n            case 0x40:\n            case 0x41:\n            case 0x42:\n            case 0x43:\n            case 0x44:\n            case 0x45:\n            case 0x46:\n            case 0x47:\n            case 0x48:\n            case 0x49:\n            case 0x4A:\n            case 0x4B:\n            case 0x4C:\n            case 0x4D:\n            case 0x4E:\n            case 0x4F:\n            case 0x50:\n            case 0x51:\n            case 0x52:\n            case 0x53:\n            case 0x54:\n            case 0x55:\n            case 0x56:\n            case 0x57:\n            case 0x58: // Binary data (one-byte uint8_t for n follows)\n            case 0x59: // Binary data (two-byte uint16_t for n follow)\n            case 0x5A: // Binary data (four-byte uint32_t for n follow)\n            case 0x5B: // Binary data (eight-byte uint64_t for n follow)\n            case 0x5F: // Binary data (indefinite length)\n            {\n                binary_t b;\n                return get_cbor_binary(b) && sax->binary(b);\n            }\n\n            // UTF-8 string (0x00..0x17 bytes follow)\n            case 0x60:\n            case 0x61:\n            case 0x62:\n            case 0x63:\n            case 0x64:\n            case 0x65:\n            case 0x66:\n            case 0x67:\n            case 0x68:\n            case 0x69:\n            case 0x6A:\n            case 0x6B:\n            case 0x6C:\n            case 0x6D:\n            case 0x6E:\n            case 0x6F:\n            case 0x70:\n            case 0x71:\n            case 0x72:\n            case 0x73:\n            case 0x74:\n            case 0x75:\n            case 0x76:\n            case 0x77:\n            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)\n            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)\n            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)\n            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)\n            case 0x7F: // UTF-8 string (indefinite length)\n            {\n                string_t s;\n                return get_cbor_string(s) && sax->string(s);\n            }\n\n            // array (0x00..0x17 data items follow)\n            case 0x80:\n            case 0x81:\n            case 0x82:\n            case 0x83:\n            case 0x84:\n            case 0x85:\n            case 0x86:\n            case 0x87:\n            case 0x88:\n            case 0x89:\n            case 0x8A:\n            case 0x8B:\n            case 0x8C:\n            case 0x8D:\n            case 0x8E:\n            case 0x8F:\n            case 0x90:\n            case 0x91:\n            case 0x92:\n            case 0x93:\n            case 0x94:\n            case 0x95:\n            case 0x96:\n            case 0x97:\n                return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);\n\n            case 0x98: // array (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x99: // array (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x9A: // array (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x9B: // array (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0x9F: // array (indefinite length)\n                return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);\n\n            // map (0x00..0x17 pairs of data items follow)\n            case 0xA0:\n            case 0xA1:\n            case 0xA2:\n            case 0xA3:\n            case 0xA4:\n            case 0xA5:\n            case 0xA6:\n            case 0xA7:\n            case 0xA8:\n            case 0xA9:\n            case 0xAA:\n            case 0xAB:\n            case 0xAC:\n            case 0xAD:\n            case 0xAE:\n            case 0xAF:\n            case 0xB0:\n            case 0xB1:\n            case 0xB2:\n            case 0xB3:\n            case 0xB4:\n            case 0xB5:\n            case 0xB6:\n            case 0xB7:\n                return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);\n\n            case 0xB8: // map (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xB9: // map (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xBA: // map (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xBB: // map (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);\n            }\n\n            case 0xBF: // map (indefinite length)\n                return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);\n\n            case 0xC6: // tagged item\n            case 0xC7:\n            case 0xC8:\n            case 0xC9:\n            case 0xCA:\n            case 0xCB:\n            case 0xCC:\n            case 0xCD:\n            case 0xCE:\n            case 0xCF:\n            case 0xD0:\n            case 0xD1:\n            case 0xD2:\n            case 0xD3:\n            case 0xD4:\n            case 0xD8: // tagged item (1 bytes follow)\n            case 0xD9: // tagged item (2 bytes follow)\n            case 0xDA: // tagged item (4 bytes follow)\n            case 0xDB: // tagged item (8 bytes follow)\n            {\n                switch (tag_handler)\n                {\n                    case cbor_tag_handler_t::error:\n                    {\n                        auto last_token = get_token_string();\n                        return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n                    }\n\n                    case cbor_tag_handler_t::ignore:\n                    {\n                        // ignore binary subtype\n                        switch (current)\n                        {\n                            case 0xD8:\n                            {\n                                std::uint8_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            case 0xD9:\n                            {\n                                std::uint16_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            case 0xDA:\n                            {\n                                std::uint32_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            case 0xDB:\n                            {\n                                std::uint64_t subtype_to_ignore{};\n                                get_number(input_format_t::cbor, subtype_to_ignore);\n                                break;\n                            }\n                            default:\n                                break;\n                        }\n                        return parse_cbor_internal(true, tag_handler);\n                    }\n\n                    case cbor_tag_handler_t::store:\n                    {\n                        binary_t b;\n                        // use binary subtype and store in binary container\n                        switch (current)\n                        {\n                            case 0xD8:\n                            {\n                                std::uint8_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            case 0xD9:\n                            {\n                                std::uint16_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            case 0xDA:\n                            {\n                                std::uint32_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            case 0xDB:\n                            {\n                                std::uint64_t subtype{};\n                                get_number(input_format_t::cbor, subtype);\n                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));\n                                break;\n                            }\n                            default:\n                                return parse_cbor_internal(true, tag_handler);\n                        }\n                        get();\n                        return get_cbor_binary(b) && sax->binary(b);\n                    }\n\n                    default:                 // LCOV_EXCL_LINE\n                        JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n                        return false;        // LCOV_EXCL_LINE\n                }\n            }\n\n            case 0xF4: // false\n                return sax->boolean(false);\n\n            case 0xF5: // true\n                return sax->boolean(true);\n\n            case 0xF6: // null\n                return sax->null();\n\n            case 0xF9: // Half-Precision Float (two-byte IEEE 754)\n            {\n                const auto byte1_raw = get();\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"number\")))\n                {\n                    return false;\n                }\n                const auto byte2_raw = get();\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"number\")))\n                {\n                    return false;\n                }\n\n                const auto byte1 = static_cast<unsigned char>(byte1_raw);\n                const auto byte2 = static_cast<unsigned char>(byte2_raw);\n\n                // code from RFC 7049, Appendix D, Figure 3:\n                // As half-precision floating-point numbers were only added\n                // to IEEE 754 in 2008, today's programming platforms often\n                // still only have limited support for them. It is very\n                // easy to include at least decoding support for them even\n                // without such support. An example of a small decoder for\n                // half-precision floating-point numbers in the C language\n                // is shown in Fig. 3.\n                const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);\n                const double val = [&half]\n                {\n                    const int exp = (half >> 10u) & 0x1Fu;\n                    const unsigned int mant = half & 0x3FFu;\n                    JSON_ASSERT(0 <= exp&& exp <= 32);\n                    JSON_ASSERT(mant <= 1024);\n                    switch (exp)\n                    {\n                        case 0:\n                            return std::ldexp(mant, -24);\n                        case 31:\n                            return (mant == 0)\n                            ? std::numeric_limits<double>::infinity()\n                            : std::numeric_limits<double>::quiet_NaN();\n                        default:\n                            return std::ldexp(mant + 1024, exp - 25);\n                    }\n                }();\n                return sax->number_float((half & 0x8000u) != 0\n                                         ? static_cast<number_float_t>(-val)\n                                         : static_cast<number_float_t>(val), \"\");\n            }\n\n            case 0xFA: // Single-Precision Float (four-byte IEEE 754)\n            {\n                float number{};\n                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0xFB: // Double-Precision Float (eight-byte IEEE 754)\n            {\n                double number{};\n                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            default: // anything else (0xFF is handled inside the other types)\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a CBOR string\n\n    This function first reads starting bytes to determine the expected\n    string length and then copies this number of bytes into a string.\n    Additionally, CBOR's strings with indefinite lengths are supported.\n\n    @param[out] result  created string\n\n    @return whether string creation completed\n    */\n    bool get_cbor_string(string_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"string\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            // UTF-8 string (0x00..0x17 bytes follow)\n            case 0x60:\n            case 0x61:\n            case 0x62:\n            case 0x63:\n            case 0x64:\n            case 0x65:\n            case 0x66:\n            case 0x67:\n            case 0x68:\n            case 0x69:\n            case 0x6A:\n            case 0x6B:\n            case 0x6C:\n            case 0x6D:\n            case 0x6E:\n            case 0x6F:\n            case 0x70:\n            case 0x71:\n            case 0x72:\n            case 0x73:\n            case 0x74:\n            case 0x75:\n            case 0x76:\n            case 0x77:\n            {\n                return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);\n            }\n\n            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);\n            }\n\n            case 0x7F: // UTF-8 string (indefinite length)\n            {\n                while (get() != 0xFF)\n                {\n                    string_t chunk;\n                    if (!get_cbor_string(chunk))\n                    {\n                        return false;\n                    }\n                    result.append(chunk);\n                }\n                return true;\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, \"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x\" + last_token, \"string\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a CBOR byte array\n\n    This function first reads starting bytes to determine the expected\n    byte array length and then copies this number of bytes into the byte array.\n    Additionally, CBOR's byte arrays with indefinite lengths are supported.\n\n    @param[out] result  created byte array\n\n    @return whether byte array creation completed\n    */\n    bool get_cbor_binary(binary_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, \"binary\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            // Binary data (0x00..0x17 bytes follow)\n            case 0x40:\n            case 0x41:\n            case 0x42:\n            case 0x43:\n            case 0x44:\n            case 0x45:\n            case 0x46:\n            case 0x47:\n            case 0x48:\n            case 0x49:\n            case 0x4A:\n            case 0x4B:\n            case 0x4C:\n            case 0x4D:\n            case 0x4E:\n            case 0x4F:\n            case 0x50:\n            case 0x51:\n            case 0x52:\n            case 0x53:\n            case 0x54:\n            case 0x55:\n            case 0x56:\n            case 0x57:\n            {\n                return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);\n            }\n\n            case 0x58: // Binary data (one-byte uint8_t for n follows)\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x59: // Binary data (two-byte uint16_t for n follow)\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x5A: // Binary data (four-byte uint32_t for n follow)\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x5B: // Binary data (eight-byte uint64_t for n follow)\n            {\n                std::uint64_t len{};\n                return get_number(input_format_t::cbor, len) &&\n                       get_binary(input_format_t::cbor, len, result);\n            }\n\n            case 0x5F: // Binary data (indefinite length)\n            {\n                while (get() != 0xFF)\n                {\n                    binary_t chunk;\n                    if (!get_cbor_binary(chunk))\n                    {\n                        return false;\n                    }\n                    result.insert(result.end(), chunk.begin(), chunk.end());\n                }\n                return true;\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, \"expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x\" + last_token, \"binary\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @param[in] len  the length of the array or static_cast<std::size_t>(-1) for an\n                    array of indefinite size\n    @param[in] tag_handler how CBOR tags should be treated\n    @return whether array creation completed\n    */\n    bool get_cbor_array(const std::size_t len,\n                        const cbor_tag_handler_t tag_handler)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))\n        {\n            return false;\n        }\n\n        if (len != static_cast<std::size_t>(-1))\n        {\n            for (std::size_t i = 0; i < len; ++i)\n            {\n                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))\n                {\n                    return false;\n                }\n            }\n        }\n        else\n        {\n            while (get() != 0xFF)\n            {\n                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))\n                {\n                    return false;\n                }\n            }\n        }\n\n        return sax->end_array();\n    }\n\n    /*!\n    @param[in] len  the length of the object or static_cast<std::size_t>(-1) for an\n                    object of indefinite size\n    @param[in] tag_handler how CBOR tags should be treated\n    @return whether object creation completed\n    */\n    bool get_cbor_object(const std::size_t len,\n                         const cbor_tag_handler_t tag_handler)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))\n        {\n            return false;\n        }\n\n        if (len != 0)\n        {\n            string_t key;\n            if (len != static_cast<std::size_t>(-1))\n            {\n                for (std::size_t i = 0; i < len; ++i)\n                {\n                    get();\n                    if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n\n                    if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n            else\n            {\n                while (get() != 0xFF)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n\n                    if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n        }\n\n        return sax->end_object();\n    }\n\n    /////////////\n    // MsgPack //\n    /////////////\n\n    /*!\n    @return whether a valid MessagePack value was passed to the SAX parser\n    */\n    bool parse_msgpack_internal()\n    {\n        switch (get())\n        {\n            // EOF\n            case std::char_traits<char_type>::eof():\n                return unexpect_eof(input_format_t::msgpack, \"value\");\n\n            // positive fixint\n            case 0x00:\n            case 0x01:\n            case 0x02:\n            case 0x03:\n            case 0x04:\n            case 0x05:\n            case 0x06:\n            case 0x07:\n            case 0x08:\n            case 0x09:\n            case 0x0A:\n            case 0x0B:\n            case 0x0C:\n            case 0x0D:\n            case 0x0E:\n            case 0x0F:\n            case 0x10:\n            case 0x11:\n            case 0x12:\n            case 0x13:\n            case 0x14:\n            case 0x15:\n            case 0x16:\n            case 0x17:\n            case 0x18:\n            case 0x19:\n            case 0x1A:\n            case 0x1B:\n            case 0x1C:\n            case 0x1D:\n            case 0x1E:\n            case 0x1F:\n            case 0x20:\n            case 0x21:\n            case 0x22:\n            case 0x23:\n            case 0x24:\n            case 0x25:\n            case 0x26:\n            case 0x27:\n            case 0x28:\n            case 0x29:\n            case 0x2A:\n            case 0x2B:\n            case 0x2C:\n            case 0x2D:\n            case 0x2E:\n            case 0x2F:\n            case 0x30:\n            case 0x31:\n            case 0x32:\n            case 0x33:\n            case 0x34:\n            case 0x35:\n            case 0x36:\n            case 0x37:\n            case 0x38:\n            case 0x39:\n            case 0x3A:\n            case 0x3B:\n            case 0x3C:\n            case 0x3D:\n            case 0x3E:\n            case 0x3F:\n            case 0x40:\n            case 0x41:\n            case 0x42:\n            case 0x43:\n            case 0x44:\n            case 0x45:\n            case 0x46:\n            case 0x47:\n            case 0x48:\n            case 0x49:\n            case 0x4A:\n            case 0x4B:\n            case 0x4C:\n            case 0x4D:\n            case 0x4E:\n            case 0x4F:\n            case 0x50:\n            case 0x51:\n            case 0x52:\n            case 0x53:\n            case 0x54:\n            case 0x55:\n            case 0x56:\n            case 0x57:\n            case 0x58:\n            case 0x59:\n            case 0x5A:\n            case 0x5B:\n            case 0x5C:\n            case 0x5D:\n            case 0x5E:\n            case 0x5F:\n            case 0x60:\n            case 0x61:\n            case 0x62:\n            case 0x63:\n            case 0x64:\n            case 0x65:\n            case 0x66:\n            case 0x67:\n            case 0x68:\n            case 0x69:\n            case 0x6A:\n            case 0x6B:\n            case 0x6C:\n            case 0x6D:\n            case 0x6E:\n            case 0x6F:\n            case 0x70:\n            case 0x71:\n            case 0x72:\n            case 0x73:\n            case 0x74:\n            case 0x75:\n            case 0x76:\n            case 0x77:\n            case 0x78:\n            case 0x79:\n            case 0x7A:\n            case 0x7B:\n            case 0x7C:\n            case 0x7D:\n            case 0x7E:\n            case 0x7F:\n                return sax->number_unsigned(static_cast<number_unsigned_t>(current));\n\n            // fixmap\n            case 0x80:\n            case 0x81:\n            case 0x82:\n            case 0x83:\n            case 0x84:\n            case 0x85:\n            case 0x86:\n            case 0x87:\n            case 0x88:\n            case 0x89:\n            case 0x8A:\n            case 0x8B:\n            case 0x8C:\n            case 0x8D:\n            case 0x8E:\n            case 0x8F:\n                return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));\n\n            // fixarray\n            case 0x90:\n            case 0x91:\n            case 0x92:\n            case 0x93:\n            case 0x94:\n            case 0x95:\n            case 0x96:\n            case 0x97:\n            case 0x98:\n            case 0x99:\n            case 0x9A:\n            case 0x9B:\n            case 0x9C:\n            case 0x9D:\n            case 0x9E:\n            case 0x9F:\n                return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));\n\n            // fixstr\n            case 0xA0:\n            case 0xA1:\n            case 0xA2:\n            case 0xA3:\n            case 0xA4:\n            case 0xA5:\n            case 0xA6:\n            case 0xA7:\n            case 0xA8:\n            case 0xA9:\n            case 0xAA:\n            case 0xAB:\n            case 0xAC:\n            case 0xAD:\n            case 0xAE:\n            case 0xAF:\n            case 0xB0:\n            case 0xB1:\n            case 0xB2:\n            case 0xB3:\n            case 0xB4:\n            case 0xB5:\n            case 0xB6:\n            case 0xB7:\n            case 0xB8:\n            case 0xB9:\n            case 0xBA:\n            case 0xBB:\n            case 0xBC:\n            case 0xBD:\n            case 0xBE:\n            case 0xBF:\n            case 0xD9: // str 8\n            case 0xDA: // str 16\n            case 0xDB: // str 32\n            {\n                string_t s;\n                return get_msgpack_string(s) && sax->string(s);\n            }\n\n            case 0xC0: // nil\n                return sax->null();\n\n            case 0xC2: // false\n                return sax->boolean(false);\n\n            case 0xC3: // true\n                return sax->boolean(true);\n\n            case 0xC4: // bin 8\n            case 0xC5: // bin 16\n            case 0xC6: // bin 32\n            case 0xC7: // ext 8\n            case 0xC8: // ext 16\n            case 0xC9: // ext 32\n            case 0xD4: // fixext 1\n            case 0xD5: // fixext 2\n            case 0xD6: // fixext 4\n            case 0xD7: // fixext 8\n            case 0xD8: // fixext 16\n            {\n                binary_t b;\n                return get_msgpack_binary(b) && sax->binary(b);\n            }\n\n            case 0xCA: // float 32\n            {\n                float number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0xCB: // float 64\n            {\n                double number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 0xCC: // uint 8\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xCD: // uint 16\n            {\n                std::uint16_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xCE: // uint 32\n            {\n                std::uint32_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xCF: // uint 64\n            {\n                std::uint64_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);\n            }\n\n            case 0xD0: // int 8\n            {\n                std::int8_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xD1: // int 16\n            {\n                std::int16_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xD2: // int 32\n            {\n                std::int32_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xD3: // int 64\n            {\n                std::int64_t number{};\n                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);\n            }\n\n            case 0xDC: // array 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));\n            }\n\n            case 0xDD: // array 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));\n            }\n\n            case 0xDE: // map 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));\n            }\n\n            case 0xDF: // map 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));\n            }\n\n            // negative fixint\n            case 0xE0:\n            case 0xE1:\n            case 0xE2:\n            case 0xE3:\n            case 0xE4:\n            case 0xE5:\n            case 0xE6:\n            case 0xE7:\n            case 0xE8:\n            case 0xE9:\n            case 0xEA:\n            case 0xEB:\n            case 0xEC:\n            case 0xED:\n            case 0xEE:\n            case 0xEF:\n            case 0xF0:\n            case 0xF1:\n            case 0xF2:\n            case 0xF3:\n            case 0xF4:\n            case 0xF5:\n            case 0xF6:\n            case 0xF7:\n            case 0xF8:\n            case 0xF9:\n            case 0xFA:\n            case 0xFB:\n            case 0xFC:\n            case 0xFD:\n            case 0xFE:\n            case 0xFF:\n                return sax->number_integer(static_cast<std::int8_t>(current));\n\n            default: // anything else\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a MessagePack string\n\n    This function first reads starting bytes to determine the expected\n    string length and then copies this number of bytes into a string.\n\n    @param[out] result  created string\n\n    @return whether string creation completed\n    */\n    bool get_msgpack_string(string_t& result)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, \"string\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            // fixstr\n            case 0xA0:\n            case 0xA1:\n            case 0xA2:\n            case 0xA3:\n            case 0xA4:\n            case 0xA5:\n            case 0xA6:\n            case 0xA7:\n            case 0xA8:\n            case 0xA9:\n            case 0xAA:\n            case 0xAB:\n            case 0xAC:\n            case 0xAD:\n            case 0xAE:\n            case 0xAF:\n            case 0xB0:\n            case 0xB1:\n            case 0xB2:\n            case 0xB3:\n            case 0xB4:\n            case 0xB5:\n            case 0xB6:\n            case 0xB7:\n            case 0xB8:\n            case 0xB9:\n            case 0xBA:\n            case 0xBB:\n            case 0xBC:\n            case 0xBD:\n            case 0xBE:\n            case 0xBF:\n            {\n                return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);\n            }\n\n            case 0xD9: // str 8\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);\n            }\n\n            case 0xDA: // str 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);\n            }\n\n            case 0xDB: // str 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, \"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x\" + last_token, \"string\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief reads a MessagePack byte array\n\n    This function first reads starting bytes to determine the expected\n    byte array length and then copies this number of bytes into a byte array.\n\n    @param[out] result  created byte array\n\n    @return whether byte array creation completed\n    */\n    bool get_msgpack_binary(binary_t& result)\n    {\n        // helper function to set the subtype\n        auto assign_and_return_true = [&result](std::int8_t subtype)\n        {\n            result.set_subtype(static_cast<std::uint8_t>(subtype));\n            return true;\n        };\n\n        switch (current)\n        {\n            case 0xC4: // bin 8\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_binary(input_format_t::msgpack, len, result);\n            }\n\n            case 0xC5: // bin 16\n            {\n                std::uint16_t len{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_binary(input_format_t::msgpack, len, result);\n            }\n\n            case 0xC6: // bin 32\n            {\n                std::uint32_t len{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_binary(input_format_t::msgpack, len, result);\n            }\n\n            case 0xC7: // ext 8\n            {\n                std::uint8_t len{};\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, len, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xC8: // ext 16\n            {\n                std::uint16_t len{};\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, len, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xC9: // ext 32\n            {\n                std::uint32_t len{};\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, len) &&\n                       get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, len, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD4: // fixext 1\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 1, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD5: // fixext 2\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 2, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD6: // fixext 4\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 4, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD7: // fixext 8\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 8, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            case 0xD8: // fixext 16\n            {\n                std::int8_t subtype{};\n                return get_number(input_format_t::msgpack, subtype) &&\n                       get_binary(input_format_t::msgpack, 16, result) &&\n                       assign_and_return_true(subtype);\n            }\n\n            default:           // LCOV_EXCL_LINE\n                return false;  // LCOV_EXCL_LINE\n        }\n    }\n\n    /*!\n    @param[in] len  the length of the array\n    @return whether array creation completed\n    */\n    bool get_msgpack_array(const std::size_t len)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))\n        {\n            return false;\n        }\n\n        for (std::size_t i = 0; i < len; ++i)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))\n            {\n                return false;\n            }\n        }\n\n        return sax->end_array();\n    }\n\n    /*!\n    @param[in] len  the length of the object\n    @return whether object creation completed\n    */\n    bool get_msgpack_object(const std::size_t len)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))\n        {\n            return false;\n        }\n\n        string_t key;\n        for (std::size_t i = 0; i < len; ++i)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))\n            {\n                return false;\n            }\n\n            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))\n            {\n                return false;\n            }\n            key.clear();\n        }\n\n        return sax->end_object();\n    }\n\n    ////////////\n    // UBJSON //\n    ////////////\n\n    /*!\n    @param[in] get_char  whether a new character should be retrieved from the\n                         input (true, default) or whether the last read\n                         character should be considered instead\n\n    @return whether a valid UBJSON value was passed to the SAX parser\n    */\n    bool parse_ubjson_internal(const bool get_char = true)\n    {\n        return get_ubjson_value(get_char ? get_ignore_noop() : current);\n    }\n\n    /*!\n    @brief reads a UBJSON string\n\n    This function is either called after reading the 'S' byte explicitly\n    indicating a string, or in case of an object key where the 'S' byte can be\n    left out.\n\n    @param[out] result   created string\n    @param[in] get_char  whether a new character should be retrieved from the\n                         input (true, default) or whether the last read\n                         character should be considered instead\n\n    @return whether string creation completed\n    */\n    bool get_ubjson_string(string_t& result, const bool get_char = true)\n    {\n        if (get_char)\n        {\n            get();  // TODO(niels): may we ignore N here?\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"value\")))\n        {\n            return false;\n        }\n\n        switch (current)\n        {\n            case 'U':\n            {\n                std::uint8_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'i':\n            {\n                std::int8_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'I':\n            {\n                std::int16_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'l':\n            {\n                std::int32_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            case 'L':\n            {\n                std::int64_t len{};\n                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);\n            }\n\n            default:\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, \"expected length type specification (U, i, I, l, L); last byte: 0x\" + last_token, \"string\"), BasicJsonType()));\n        }\n    }\n\n    /*!\n    @param[out] result  determined size\n    @return whether size determination completed\n    */\n    bool get_ubjson_size_value(std::size_t& result)\n    {\n        switch (get_ignore_noop())\n        {\n            case 'U':\n            {\n                std::uint8_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            case 'i':\n            {\n                std::int8_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char\n                return true;\n            }\n\n            case 'I':\n            {\n                std::int16_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            case 'l':\n            {\n                std::int32_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            case 'L':\n            {\n                std::int64_t number{};\n                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))\n                {\n                    return false;\n                }\n                result = static_cast<std::size_t>(number);\n                return true;\n            }\n\n            default:\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, \"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x\" + last_token, \"size\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @brief determine the type and size for a container\n\n    In the optimized UBJSON format, a type and a size can be provided to allow\n    for a more compact representation.\n\n    @param[out] result  pair of the size and the type\n\n    @return whether pair creation completed\n    */\n    bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)\n    {\n        result.first = string_t::npos; // size\n        result.second = 0; // type\n\n        get_ignore_noop();\n\n        if (current == '$')\n        {\n            result.second = get();  // must not ignore 'N', because 'N' maybe the type\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"type\")))\n            {\n                return false;\n            }\n\n            get_ignore_noop();\n            if (JSON_HEDLEY_UNLIKELY(current != '#'))\n            {\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"value\")))\n                {\n                    return false;\n                }\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, \"expected '#' after type information; last byte: 0x\" + last_token, \"size\"), BasicJsonType()));\n            }\n\n            return get_ubjson_size_value(result.first);\n        }\n\n        if (current == '#')\n        {\n            return get_ubjson_size_value(result.first);\n        }\n\n        return true;\n    }\n\n    /*!\n    @param prefix  the previously read or set type prefix\n    @return whether value creation completed\n    */\n    bool get_ubjson_value(const char_int_type prefix)\n    {\n        switch (prefix)\n        {\n            case std::char_traits<char_type>::eof():  // EOF\n                return unexpect_eof(input_format_t::ubjson, \"value\");\n\n            case 'T':  // true\n                return sax->boolean(true);\n            case 'F':  // false\n                return sax->boolean(false);\n\n            case 'Z':  // null\n                return sax->null();\n\n            case 'U':\n            {\n                std::uint8_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);\n            }\n\n            case 'i':\n            {\n                std::int8_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'I':\n            {\n                std::int16_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'l':\n            {\n                std::int32_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'L':\n            {\n                std::int64_t number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);\n            }\n\n            case 'd':\n            {\n                float number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 'D':\n            {\n                double number{};\n                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), \"\");\n            }\n\n            case 'H':\n            {\n                return get_ubjson_high_precision_number();\n            }\n\n            case 'C':  // char\n            {\n                get();\n                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"char\")))\n                {\n                    return false;\n                }\n                if (JSON_HEDLEY_UNLIKELY(current > 127))\n                {\n                    auto last_token = get_token_string();\n                    return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, \"byte after 'C' must be in range 0x00..0x7F; last byte: 0x\" + last_token, \"char\"), BasicJsonType()));\n                }\n                string_t s(1, static_cast<typename string_t::value_type>(current));\n                return sax->string(s);\n            }\n\n            case 'S':  // string\n            {\n                string_t s;\n                return get_ubjson_string(s) && sax->string(s);\n            }\n\n            case '[':  // array\n                return get_ubjson_array();\n\n            case '{':  // object\n                return get_ubjson_object();\n\n            default: // anything else\n            {\n                auto last_token = get_token_string();\n                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, \"invalid byte: 0x\" + last_token, \"value\"), BasicJsonType()));\n            }\n        }\n    }\n\n    /*!\n    @return whether array creation completed\n    */\n    bool get_ubjson_array()\n    {\n        std::pair<std::size_t, char_int_type> size_and_type;\n        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))\n        {\n            return false;\n        }\n\n        if (size_and_type.first != string_t::npos)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))\n            {\n                return false;\n            }\n\n            if (size_and_type.second != 0)\n            {\n                if (size_and_type.second != 'N')\n                {\n                    for (std::size_t i = 0; i < size_and_type.first; ++i)\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))\n                        {\n                            return false;\n                        }\n                    }\n                }\n            }\n            else\n            {\n                for (std::size_t i = 0; i < size_and_type.first; ++i)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))\n                    {\n                        return false;\n                    }\n                }\n            }\n        }\n        else\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))\n            {\n                return false;\n            }\n\n            while (current != ']')\n            {\n                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))\n                {\n                    return false;\n                }\n                get_ignore_noop();\n            }\n        }\n\n        return sax->end_array();\n    }\n\n    /*!\n    @return whether object creation completed\n    */\n    bool get_ubjson_object()\n    {\n        std::pair<std::size_t, char_int_type> size_and_type;\n        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))\n        {\n            return false;\n        }\n\n        string_t key;\n        if (size_and_type.first != string_t::npos)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))\n            {\n                return false;\n            }\n\n            if (size_and_type.second != 0)\n            {\n                for (std::size_t i = 0; i < size_and_type.first; ++i)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n            else\n            {\n                for (std::size_t i = 0; i < size_and_type.first; ++i)\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))\n                    {\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))\n                    {\n                        return false;\n                    }\n                    key.clear();\n                }\n            }\n        }\n        else\n        {\n            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))\n            {\n                return false;\n            }\n\n            while (current != '}')\n            {\n                if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))\n                {\n                    return false;\n                }\n                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))\n                {\n                    return false;\n                }\n                get_ignore_noop();\n                key.clear();\n            }\n        }\n\n        return sax->end_object();\n    }\n\n    // Note, no reader for UBJSON binary types is implemented because they do\n    // not exist\n\n    bool get_ubjson_high_precision_number()\n    {\n        // get size of following number string\n        std::size_t size{};\n        auto res = get_ubjson_size_value(size);\n        if (JSON_HEDLEY_UNLIKELY(!res))\n        {\n            return res;\n        }\n\n        // get number string\n        std::vector<char> number_vector;\n        for (std::size_t i = 0; i < size; ++i)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, \"number\")))\n            {\n                return false;\n            }\n            number_vector.push_back(static_cast<char>(current));\n        }\n\n        // parse number string\n        using ia_type = decltype(detail::input_adapter(number_vector));\n        auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);\n        const auto result_number = number_lexer.scan();\n        const auto number_string = number_lexer.get_token_string();\n        const auto result_remainder = number_lexer.scan();\n\n        using token_type = typename detail::lexer_base<BasicJsonType>::token_type;\n\n        if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))\n        {\n            return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, \"invalid number text: \" + number_lexer.get_token_string(), \"high-precision number\"), BasicJsonType()));\n        }\n\n        switch (result_number)\n        {\n            case token_type::value_integer:\n                return sax->number_integer(number_lexer.get_number_integer());\n            case token_type::value_unsigned:\n                return sax->number_unsigned(number_lexer.get_number_unsigned());\n            case token_type::value_float:\n                return sax->number_float(number_lexer.get_number_float(), std::move(number_string));\n            case token_type::uninitialized:\n            case token_type::literal_true:\n            case token_type::literal_false:\n            case token_type::literal_null:\n            case token_type::value_string:\n            case token_type::begin_array:\n            case token_type::begin_object:\n            case token_type::end_array:\n            case token_type::end_object:\n            case token_type::name_separator:\n            case token_type::value_separator:\n            case token_type::parse_error:\n            case token_type::end_of_input:\n            case token_type::literal_or_value:\n            default:\n                return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, \"invalid number text: \" + number_lexer.get_token_string(), \"high-precision number\"), BasicJsonType()));\n        }\n    }\n\n    ///////////////////////\n    // Utility functions //\n    ///////////////////////\n\n    /*!\n    @brief get next character from the input\n\n    This function provides the interface to the used input adapter. It does\n    not throw in case the input reached EOF, but returns a -'ve valued\n    `std::char_traits<char_type>::eof()` in that case.\n\n    @return character read from the input\n    */\n    char_int_type get()\n    {\n        ++chars_read;\n        return current = ia.get_character();\n    }\n\n    /*!\n    @return character read from the input after ignoring all 'N' entries\n    */\n    char_int_type get_ignore_noop()\n    {\n        do\n        {\n            get();\n        }\n        while (current == 'N');\n\n        return current;\n    }\n\n    /*\n    @brief read a number from the input\n\n    @tparam NumberType the type of the number\n    @param[in] format   the current format (for diagnostics)\n    @param[out] result  number of type @a NumberType\n\n    @return whether conversion completed\n\n    @note This function needs to respect the system's endianness, because\n          bytes in CBOR, MessagePack, and UBJSON are stored in network order\n          (big endian) and therefore need reordering on little endian systems.\n    */\n    template<typename NumberType, bool InputIsLittleEndian = false>\n    bool get_number(const input_format_t format, NumberType& result)\n    {\n        // step 1: read input into array with system's byte order\n        std::array<std::uint8_t, sizeof(NumberType)> vec{};\n        for (std::size_t i = 0; i < sizeof(NumberType); ++i)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, \"number\")))\n            {\n                return false;\n            }\n\n            // reverse byte order prior to conversion if necessary\n            if (is_little_endian != InputIsLittleEndian)\n            {\n                vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);\n            }\n            else\n            {\n                vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE\n            }\n        }\n\n        // step 2: convert array into number of type T and return\n        std::memcpy(&result, vec.data(), sizeof(NumberType));\n        return true;\n    }\n\n    /*!\n    @brief create a string by reading characters from the input\n\n    @tparam NumberType the type of the number\n    @param[in] format the current format (for diagnostics)\n    @param[in] len number of characters to read\n    @param[out] result string created by reading @a len bytes\n\n    @return whether string creation completed\n\n    @note We can not reserve @a len bytes for the result, because @a len\n          may be too large. Usually, @ref unexpect_eof() detects the end of\n          the input before we run out of string memory.\n    */\n    template<typename NumberType>\n    bool get_string(const input_format_t format,\n                    const NumberType len,\n                    string_t& result)\n    {\n        bool success = true;\n        for (NumberType i = 0; i < len; i++)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, \"string\")))\n            {\n                success = false;\n                break;\n            }\n            result.push_back(static_cast<typename string_t::value_type>(current));\n        }\n        return success;\n    }\n\n    /*!\n    @brief create a byte array by reading bytes from the input\n\n    @tparam NumberType the type of the number\n    @param[in] format the current format (for diagnostics)\n    @param[in] len number of bytes to read\n    @param[out] result byte array created by reading @a len bytes\n\n    @return whether byte array creation completed\n\n    @note We can not reserve @a len bytes for the result, because @a len\n          may be too large. Usually, @ref unexpect_eof() detects the end of\n          the input before we run out of memory.\n    */\n    template<typename NumberType>\n    bool get_binary(const input_format_t format,\n                    const NumberType len,\n                    binary_t& result)\n    {\n        bool success = true;\n        for (NumberType i = 0; i < len; i++)\n        {\n            get();\n            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, \"binary\")))\n            {\n                success = false;\n                break;\n            }\n            result.push_back(static_cast<std::uint8_t>(current));\n        }\n        return success;\n    }\n\n    /*!\n    @param[in] format   the current format (for diagnostics)\n    @param[in] context  further context information (for diagnostics)\n    @return whether the last read character is not EOF\n    */\n    JSON_HEDLEY_NON_NULL(3)\n    bool unexpect_eof(const input_format_t format, const char* context) const\n    {\n        if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))\n        {\n            return sax->parse_error(chars_read, \"<end of file>\",\n                                    parse_error::create(110, chars_read, exception_message(format, \"unexpected end of input\", context), BasicJsonType()));\n        }\n        return true;\n    }\n\n    /*!\n    @return a string representation of the last read byte\n    */\n    std::string get_token_string() const\n    {\n        std::array<char, 3> cr{{}};\n        static_cast<void>((std::snprintf)(cr.data(), cr.size(), \"%.2hhX\", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n        return std::string{cr.data()};\n    }\n\n    /*!\n    @param[in] format   the current format\n    @param[in] detail   a detailed error message\n    @param[in] context  further context information\n    @return a message string to use in the parse_error exceptions\n    */\n    std::string exception_message(const input_format_t format,\n                                  const std::string& detail,\n                                  const std::string& context) const\n    {\n        std::string error_msg = \"syntax error while parsing \";\n\n        switch (format)\n        {\n            case input_format_t::cbor:\n                error_msg += \"CBOR\";\n                break;\n\n            case input_format_t::msgpack:\n                error_msg += \"MessagePack\";\n                break;\n\n            case input_format_t::ubjson:\n                error_msg += \"UBJSON\";\n                break;\n\n            case input_format_t::bson:\n                error_msg += \"BSON\";\n                break;\n\n            case input_format_t::json: // LCOV_EXCL_LINE\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n\n        return error_msg + \" \" + context + \": \" + detail;\n    }\n\n  private:\n    /// input adapter\n    InputAdapterType ia;\n\n    /// the current character\n    char_int_type current = std::char_traits<char_type>::eof();\n\n    /// the number of characters read\n    std::size_t chars_read = 0;\n\n    /// whether we can assume little endianness\n    const bool is_little_endian = little_endianness();\n\n    /// the SAX parser\n    json_sax_t* sax = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/input/input_adapters.hpp>\n\n// #include <nlohmann/detail/input/lexer.hpp>\n\n// #include <nlohmann/detail/input/parser.hpp>\n\n\n#include <cmath> // isfinite\n#include <cstdint> // uint8_t\n#include <functional> // function\n#include <string> // string\n#include <utility> // move\n#include <vector> // vector\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n// #include <nlohmann/detail/input/input_adapters.hpp>\n\n// #include <nlohmann/detail/input/json_sax.hpp>\n\n// #include <nlohmann/detail/input/lexer.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/meta/is_sax.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n////////////\n// parser //\n////////////\n\nenum class parse_event_t : std::uint8_t\n{\n    /// the parser read `{` and started to process a JSON object\n    object_start,\n    /// the parser read `}` and finished processing a JSON object\n    object_end,\n    /// the parser read `[` and started to process a JSON array\n    array_start,\n    /// the parser read `]` and finished processing a JSON array\n    array_end,\n    /// the parser read a key of a value in an object\n    key,\n    /// the parser finished reading a JSON value\n    value\n};\n\ntemplate<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;\n\n/*!\n@brief syntax analysis\n\nThis class implements a recursive descent parser.\n*/\ntemplate<typename BasicJsonType, typename InputAdapterType>\nclass parser\n{\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using string_t = typename BasicJsonType::string_t;\n    using lexer_t = lexer<BasicJsonType, InputAdapterType>;\n    using token_type = typename lexer_t::token_type;\n\n  public:\n    /// a parser reading from an input adapter\n    explicit parser(InputAdapterType&& adapter,\n                    const parser_callback_t<BasicJsonType> cb = nullptr,\n                    const bool allow_exceptions_ = true,\n                    const bool skip_comments = false)\n        : callback(cb)\n        , m_lexer(std::move(adapter), skip_comments)\n        , allow_exceptions(allow_exceptions_)\n    {\n        // read first token\n        get_token();\n    }\n\n    /*!\n    @brief public parser interface\n\n    @param[in] strict      whether to expect the last token to be EOF\n    @param[in,out] result  parsed JSON value\n\n    @throw parse_error.101 in case of an unexpected token\n    @throw parse_error.102 if to_unicode fails or surrogate error\n    @throw parse_error.103 if to_unicode fails\n    */\n    void parse(const bool strict, BasicJsonType& result)\n    {\n        if (callback)\n        {\n            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);\n            sax_parse_internal(&sdp);\n\n            // in strict mode, input must be completely read\n            if (strict && (get_token() != token_type::end_of_input))\n            {\n                sdp.parse_error(m_lexer.get_position(),\n                                m_lexer.get_token_string(),\n                                parse_error::create(101, m_lexer.get_position(),\n                                                    exception_message(token_type::end_of_input, \"value\"), BasicJsonType()));\n            }\n\n            // in case of an error, return discarded value\n            if (sdp.is_errored())\n            {\n                result = value_t::discarded;\n                return;\n            }\n\n            // set top-level value to null if it was discarded by the callback\n            // function\n            if (result.is_discarded())\n            {\n                result = nullptr;\n            }\n        }\n        else\n        {\n            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);\n            sax_parse_internal(&sdp);\n\n            // in strict mode, input must be completely read\n            if (strict && (get_token() != token_type::end_of_input))\n            {\n                sdp.parse_error(m_lexer.get_position(),\n                                m_lexer.get_token_string(),\n                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, \"value\"), BasicJsonType()));\n            }\n\n            // in case of an error, return discarded value\n            if (sdp.is_errored())\n            {\n                result = value_t::discarded;\n                return;\n            }\n        }\n\n        result.assert_invariant();\n    }\n\n    /*!\n    @brief public accept interface\n\n    @param[in] strict  whether to expect the last token to be EOF\n    @return whether the input is a proper JSON text\n    */\n    bool accept(const bool strict = true)\n    {\n        json_sax_acceptor<BasicJsonType> sax_acceptor;\n        return sax_parse(&sax_acceptor, strict);\n    }\n\n    template<typename SAX>\n    JSON_HEDLEY_NON_NULL(2)\n    bool sax_parse(SAX* sax, const bool strict = true)\n    {\n        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};\n        const bool result = sax_parse_internal(sax);\n\n        // strict mode: next byte must be EOF\n        if (result && strict && (get_token() != token_type::end_of_input))\n        {\n            return sax->parse_error(m_lexer.get_position(),\n                                    m_lexer.get_token_string(),\n                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, \"value\"), BasicJsonType()));\n        }\n\n        return result;\n    }\n\n  private:\n    template<typename SAX>\n    JSON_HEDLEY_NON_NULL(2)\n    bool sax_parse_internal(SAX* sax)\n    {\n        // stack to remember the hierarchy of structured values we are parsing\n        // true = array; false = object\n        std::vector<bool> states;\n        // value to avoid a goto (see comment where set to true)\n        bool skip_to_state_evaluation = false;\n\n        while (true)\n        {\n            if (!skip_to_state_evaluation)\n            {\n                // invariant: get_token() was called before each iteration\n                switch (last_token)\n                {\n                    case token_type::begin_object:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))\n                        {\n                            return false;\n                        }\n\n                        // closing } -> we are done\n                        if (get_token() == token_type::end_object)\n                        {\n                            if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))\n                            {\n                                return false;\n                            }\n                            break;\n                        }\n\n                        // parse key\n                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))\n                        {\n                            return sax->parse_error(m_lexer.get_position(),\n                                                    m_lexer.get_token_string(),\n                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, \"object key\"), BasicJsonType()));\n                        }\n                        if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))\n                        {\n                            return false;\n                        }\n\n                        // parse separator (:)\n                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))\n                        {\n                            return sax->parse_error(m_lexer.get_position(),\n                                                    m_lexer.get_token_string(),\n                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, \"object separator\"), BasicJsonType()));\n                        }\n\n                        // remember we are now inside an object\n                        states.push_back(false);\n\n                        // parse values\n                        get_token();\n                        continue;\n                    }\n\n                    case token_type::begin_array:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))\n                        {\n                            return false;\n                        }\n\n                        // closing ] -> we are done\n                        if (get_token() == token_type::end_array)\n                        {\n                            if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))\n                            {\n                                return false;\n                            }\n                            break;\n                        }\n\n                        // remember we are now inside an array\n                        states.push_back(true);\n\n                        // parse values (no need to call get_token)\n                        continue;\n                    }\n\n                    case token_type::value_float:\n                    {\n                        const auto res = m_lexer.get_number_float();\n\n                        if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))\n                        {\n                            return sax->parse_error(m_lexer.get_position(),\n                                                    m_lexer.get_token_string(),\n                                                    out_of_range::create(406, \"number overflow parsing '\" + m_lexer.get_token_string() + \"'\", BasicJsonType()));\n                        }\n\n                        if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))\n                        {\n                            return false;\n                        }\n\n                        break;\n                    }\n\n                    case token_type::literal_false:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::literal_null:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->null()))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::literal_true:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::value_integer:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::value_string:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::value_unsigned:\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))\n                        {\n                            return false;\n                        }\n                        break;\n                    }\n\n                    case token_type::parse_error:\n                    {\n                        // using \"uninitialized\" to avoid \"expected\" message\n                        return sax->parse_error(m_lexer.get_position(),\n                                                m_lexer.get_token_string(),\n                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, \"value\"), BasicJsonType()));\n                    }\n\n                    case token_type::uninitialized:\n                    case token_type::end_array:\n                    case token_type::end_object:\n                    case token_type::name_separator:\n                    case token_type::value_separator:\n                    case token_type::end_of_input:\n                    case token_type::literal_or_value:\n                    default: // the last token was unexpected\n                    {\n                        return sax->parse_error(m_lexer.get_position(),\n                                                m_lexer.get_token_string(),\n                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, \"value\"), BasicJsonType()));\n                    }\n                }\n            }\n            else\n            {\n                skip_to_state_evaluation = false;\n            }\n\n            // we reached this line after we successfully parsed a value\n            if (states.empty())\n            {\n                // empty stack: we reached the end of the hierarchy: done\n                return true;\n            }\n\n            if (states.back())  // array\n            {\n                // comma -> next value\n                if (get_token() == token_type::value_separator)\n                {\n                    // parse a new value\n                    get_token();\n                    continue;\n                }\n\n                // closing ]\n                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))\n                {\n                    if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))\n                    {\n                        return false;\n                    }\n\n                    // We are done with this array. Before we can parse a\n                    // new value, we need to evaluate the new state first.\n                    // By setting skip_to_state_evaluation to false, we\n                    // are effectively jumping to the beginning of this if.\n                    JSON_ASSERT(!states.empty());\n                    states.pop_back();\n                    skip_to_state_evaluation = true;\n                    continue;\n                }\n\n                return sax->parse_error(m_lexer.get_position(),\n                                        m_lexer.get_token_string(),\n                                        parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, \"array\"), BasicJsonType()));\n            }\n\n            // states.back() is false -> object\n\n            // comma -> next value\n            if (get_token() == token_type::value_separator)\n            {\n                // parse key\n                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))\n                {\n                    return sax->parse_error(m_lexer.get_position(),\n                                            m_lexer.get_token_string(),\n                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, \"object key\"), BasicJsonType()));\n                }\n\n                if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))\n                {\n                    return false;\n                }\n\n                // parse separator (:)\n                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))\n                {\n                    return sax->parse_error(m_lexer.get_position(),\n                                            m_lexer.get_token_string(),\n                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, \"object separator\"), BasicJsonType()));\n                }\n\n                // parse values\n                get_token();\n                continue;\n            }\n\n            // closing }\n            if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))\n            {\n                if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))\n                {\n                    return false;\n                }\n\n                // We are done with this object. Before we can parse a\n                // new value, we need to evaluate the new state first.\n                // By setting skip_to_state_evaluation to false, we\n                // are effectively jumping to the beginning of this if.\n                JSON_ASSERT(!states.empty());\n                states.pop_back();\n                skip_to_state_evaluation = true;\n                continue;\n            }\n\n            return sax->parse_error(m_lexer.get_position(),\n                                    m_lexer.get_token_string(),\n                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, \"object\"), BasicJsonType()));\n        }\n    }\n\n    /// get next token from lexer\n    token_type get_token()\n    {\n        return last_token = m_lexer.scan();\n    }\n\n    std::string exception_message(const token_type expected, const std::string& context)\n    {\n        std::string error_msg = \"syntax error \";\n\n        if (!context.empty())\n        {\n            error_msg += \"while parsing \" + context + \" \";\n        }\n\n        error_msg += \"- \";\n\n        if (last_token == token_type::parse_error)\n        {\n            error_msg += std::string(m_lexer.get_error_message()) + \"; last read: '\" +\n                         m_lexer.get_token_string() + \"'\";\n        }\n        else\n        {\n            error_msg += \"unexpected \" + std::string(lexer_t::token_type_name(last_token));\n        }\n\n        if (expected != token_type::uninitialized)\n        {\n            error_msg += \"; expected \" + std::string(lexer_t::token_type_name(expected));\n        }\n\n        return error_msg;\n    }\n\n  private:\n    /// callback function\n    const parser_callback_t<BasicJsonType> callback = nullptr;\n    /// the type of the last read token\n    token_type last_token = token_type::uninitialized;\n    /// the lexer\n    lexer_t m_lexer;\n    /// whether to throw exceptions in case of errors\n    const bool allow_exceptions = true;\n};\n\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/iterators/internal_iterator.hpp>\n\n\n// #include <nlohmann/detail/iterators/primitive_iterator.hpp>\n\n\n#include <cstddef> // ptrdiff_t\n#include <limits>  // numeric_limits\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/*\n@brief an iterator for primitive JSON types\n\nThis class models an iterator for primitive JSON types (boolean, number,\nstring). It's only purpose is to allow the iterator/const_iterator classes\nto \"iterate\" over primitive values. Internally, the iterator is modeled by\na `difference_type` variable. Value begin_value (`0`) models the begin,\nend_value (`1`) models past the end.\n*/\nclass primitive_iterator_t\n{\n  private:\n    using difference_type = std::ptrdiff_t;\n    static constexpr difference_type begin_value = 0;\n    static constexpr difference_type end_value = begin_value + 1;\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /// iterator as signed integer type\n    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();\n\n  public:\n    constexpr difference_type get_value() const noexcept\n    {\n        return m_it;\n    }\n\n    /// set iterator to a defined beginning\n    void set_begin() noexcept\n    {\n        m_it = begin_value;\n    }\n\n    /// set iterator to a defined past the end\n    void set_end() noexcept\n    {\n        m_it = end_value;\n    }\n\n    /// return whether the iterator can be dereferenced\n    constexpr bool is_begin() const noexcept\n    {\n        return m_it == begin_value;\n    }\n\n    /// return whether the iterator is at end\n    constexpr bool is_end() const noexcept\n    {\n        return m_it == end_value;\n    }\n\n    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept\n    {\n        return lhs.m_it == rhs.m_it;\n    }\n\n    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept\n    {\n        return lhs.m_it < rhs.m_it;\n    }\n\n    primitive_iterator_t operator+(difference_type n) noexcept\n    {\n        auto result = *this;\n        result += n;\n        return result;\n    }\n\n    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept\n    {\n        return lhs.m_it - rhs.m_it;\n    }\n\n    primitive_iterator_t& operator++() noexcept\n    {\n        ++m_it;\n        return *this;\n    }\n\n    primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        ++m_it;\n        return result;\n    }\n\n    primitive_iterator_t& operator--() noexcept\n    {\n        --m_it;\n        return *this;\n    }\n\n    primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        --m_it;\n        return result;\n    }\n\n    primitive_iterator_t& operator+=(difference_type n) noexcept\n    {\n        m_it += n;\n        return *this;\n    }\n\n    primitive_iterator_t& operator-=(difference_type n) noexcept\n    {\n        m_it -= n;\n        return *this;\n    }\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/*!\n@brief an iterator value\n\n@note This structure could easily be a union, but MSVC currently does not allow\nunions members with complex constructors, see https://github.com/nlohmann/json/pull/105.\n*/\ntemplate<typename BasicJsonType> struct internal_iterator\n{\n    /// iterator for JSON objects\n    typename BasicJsonType::object_t::iterator object_iterator {};\n    /// iterator for JSON arrays\n    typename BasicJsonType::array_t::iterator array_iterator {};\n    /// generic iterator for all other types\n    primitive_iterator_t primitive_iterator {};\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/iterators/iter_impl.hpp>\n\n\n#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next\n#include <type_traits> // conditional, is_const, remove_const\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n// #include <nlohmann/detail/iterators/internal_iterator.hpp>\n\n// #include <nlohmann/detail/iterators/primitive_iterator.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/meta/cpp_future.hpp>\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n// forward declare, to be able to friend it later on\ntemplate<typename IteratorType> class iteration_proxy;\ntemplate<typename IteratorType> class iteration_proxy_value;\n\n/*!\n@brief a template for a bidirectional iterator for the @ref basic_json class\nThis class implements a both iterators (iterator and const_iterator) for the\n@ref basic_json class.\n@note An iterator is called *initialized* when a pointer to a JSON value has\n      been set (e.g., by a constructor or a copy assignment). If the iterator is\n      default-constructed, it is *uninitialized* and most methods are undefined.\n      **The library uses assertions to detect calls on uninitialized iterators.**\n@requirement The class satisfies the following concept requirements:\n-\n[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):\n  The iterator that can be moved can be moved in both directions (i.e.\n  incremented and decremented).\n@since version 1.0.0, simplified in version 2.0.9, change to bidirectional\n       iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)\n*/\ntemplate<typename BasicJsonType>\nclass iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)\n{\n    /// the iterator with BasicJsonType of different const-ness\n    using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;\n    /// allow basic_json to access private members\n    friend other_iter_impl;\n    friend BasicJsonType;\n    friend iteration_proxy<iter_impl>;\n    friend iteration_proxy_value<iter_impl>;\n\n    using object_t = typename BasicJsonType::object_t;\n    using array_t = typename BasicJsonType::array_t;\n    // make sure BasicJsonType is basic_json or const basic_json\n    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,\n                  \"iter_impl only accepts (const) basic_json\");\n\n  public:\n\n    /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.\n    /// The C++ Standard has never required user-defined iterators to derive from std::iterator.\n    /// A user-defined iterator should provide publicly accessible typedefs named\n    /// iterator_category, value_type, difference_type, pointer, and reference.\n    /// Note that value_type is required to be non-const, even for constant iterators.\n    using iterator_category = std::bidirectional_iterator_tag;\n\n    /// the type of the values when the iterator is dereferenced\n    using value_type = typename BasicJsonType::value_type;\n    /// a type to represent differences between iterators\n    using difference_type = typename BasicJsonType::difference_type;\n    /// defines a pointer to the type iterated over (value_type)\n    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,\n          typename BasicJsonType::const_pointer,\n          typename BasicJsonType::pointer>::type;\n    /// defines a reference to the type iterated over (value_type)\n    using reference =\n        typename std::conditional<std::is_const<BasicJsonType>::value,\n        typename BasicJsonType::const_reference,\n        typename BasicJsonType::reference>::type;\n\n    iter_impl() = default;\n    ~iter_impl() = default;\n    iter_impl(iter_impl&&) noexcept = default;\n    iter_impl& operator=(iter_impl&&) noexcept = default;\n\n    /*!\n    @brief constructor for a given JSON instance\n    @param[in] object  pointer to a JSON object for this iterator\n    @pre object != nullptr\n    @post The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    explicit iter_impl(pointer object) noexcept : m_object(object)\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                m_it.object_iterator = typename object_t::iterator();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_it.array_iterator = typename array_t::iterator();\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator = primitive_iterator_t();\n                break;\n            }\n        }\n    }\n\n    /*!\n    @note The conventional copy constructor and copy assignment are implicitly\n          defined. Combined with the following converting constructor and\n          assignment, they support: (1) copy from iterator to iterator, (2)\n          copy from const iterator to const iterator, and (3) conversion from\n          iterator to const iterator. However conversion from const iterator\n          to iterator is not defined.\n    */\n\n    /*!\n    @brief const copy constructor\n    @param[in] other const iterator to copy from\n    @note This copy constructor had to be defined explicitly to circumvent a bug\n          occurring on msvc v19.0 compiler (VS 2015) debug build. For more\n          information refer to: https://github.com/nlohmann/json/issues/1608\n    */\n    iter_impl(const iter_impl<const BasicJsonType>& other) noexcept\n        : m_object(other.m_object), m_it(other.m_it)\n    {}\n\n    /*!\n    @brief converting assignment\n    @param[in] other const iterator to copy from\n    @return const/non-const iterator\n    @note It is not checked whether @a other is initialized.\n    */\n    iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept\n    {\n        if (&other != this)\n        {\n            m_object = other.m_object;\n            m_it = other.m_it;\n        }\n        return *this;\n    }\n\n    /*!\n    @brief converting constructor\n    @param[in] other  non-const iterator to copy from\n    @note It is not checked whether @a other is initialized.\n    */\n    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept\n        : m_object(other.m_object), m_it(other.m_it)\n    {}\n\n    /*!\n    @brief converting assignment\n    @param[in] other  non-const iterator to copy from\n    @return const/non-const iterator\n    @note It is not checked whether @a other is initialized.\n    */\n    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)\n    {\n        m_object = other.m_object;\n        m_it = other.m_it;\n        return *this;\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /*!\n    @brief set the iterator to the first value\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    void set_begin() noexcept\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                m_it.object_iterator = m_object->m_value.object->begin();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_it.array_iterator = m_object->m_value.array->begin();\n                break;\n            }\n\n            case value_t::null:\n            {\n                // set to end so begin()==end() is true: null is empty\n                m_it.primitive_iterator.set_end();\n                break;\n            }\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator.set_begin();\n                break;\n            }\n        }\n    }\n\n    /*!\n    @brief set the iterator past the last value\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    void set_end() noexcept\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                m_it.object_iterator = m_object->m_value.object->end();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_it.array_iterator = m_object->m_value.array->end();\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator.set_end();\n                break;\n            }\n        }\n    }\n\n  public:\n    /*!\n    @brief return a reference to the value pointed to by the iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    reference operator*() const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());\n                return m_it.object_iterator->second;\n            }\n\n            case value_t::array:\n            {\n                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());\n                return *m_it.array_iterator;\n            }\n\n            case value_t::null:\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))\n                {\n                    return *m_object;\n                }\n\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n            }\n        }\n    }\n\n    /*!\n    @brief dereference the iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    pointer operator->() const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());\n                return &(m_it.object_iterator->second);\n            }\n\n            case value_t::array:\n            {\n                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());\n                return &*m_it.array_iterator;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))\n                {\n                    return m_object;\n                }\n\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n            }\n        }\n    }\n\n    /*!\n    @brief post-increment (it++)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl const operator++(int) // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        ++(*this);\n        return result;\n    }\n\n    /*!\n    @brief pre-increment (++it)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator++()\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                std::advance(m_it.object_iterator, 1);\n                break;\n            }\n\n            case value_t::array:\n            {\n                std::advance(m_it.array_iterator, 1);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                ++m_it.primitive_iterator;\n                break;\n            }\n        }\n\n        return *this;\n    }\n\n    /*!\n    @brief post-decrement (it--)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl const operator--(int) // NOLINT(readability-const-return-type)\n    {\n        auto result = *this;\n        --(*this);\n        return result;\n    }\n\n    /*!\n    @brief pre-decrement (--it)\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator--()\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n            {\n                std::advance(m_it.object_iterator, -1);\n                break;\n            }\n\n            case value_t::array:\n            {\n                std::advance(m_it.array_iterator, -1);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                --m_it.primitive_iterator;\n                break;\n            }\n        }\n\n        return *this;\n    }\n\n    /*!\n    @brief comparison: equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >\n    bool operator==(const IterImpl& other) const\n    {\n        // if objects are not the same, the comparison is undefined\n        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(212, \"cannot compare iterators of different containers\", *m_object));\n        }\n\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                return (m_it.object_iterator == other.m_it.object_iterator);\n\n            case value_t::array:\n                return (m_it.array_iterator == other.m_it.array_iterator);\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return (m_it.primitive_iterator == other.m_it.primitive_iterator);\n        }\n    }\n\n    /*!\n    @brief comparison: not equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >\n    bool operator!=(const IterImpl& other) const\n    {\n        return !operator==(other);\n    }\n\n    /*!\n    @brief comparison: smaller\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator<(const iter_impl& other) const\n    {\n        // if objects are not the same, the comparison is undefined\n        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(212, \"cannot compare iterators of different containers\", *m_object));\n        }\n\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(213, \"cannot compare order of object iterators\", *m_object));\n\n            case value_t::array:\n                return (m_it.array_iterator < other.m_it.array_iterator);\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return (m_it.primitive_iterator < other.m_it.primitive_iterator);\n        }\n    }\n\n    /*!\n    @brief comparison: less than or equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator<=(const iter_impl& other) const\n    {\n        return !other.operator < (*this);\n    }\n\n    /*!\n    @brief comparison: greater than\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator>(const iter_impl& other) const\n    {\n        return !operator<=(other);\n    }\n\n    /*!\n    @brief comparison: greater than or equal\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    bool operator>=(const iter_impl& other) const\n    {\n        return !operator<(other);\n    }\n\n    /*!\n    @brief add to iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator+=(difference_type i)\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(209, \"cannot use offsets with object iterators\", *m_object));\n\n            case value_t::array:\n            {\n                std::advance(m_it.array_iterator, i);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                m_it.primitive_iterator += i;\n                break;\n            }\n        }\n\n        return *this;\n    }\n\n    /*!\n    @brief subtract from iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl& operator-=(difference_type i)\n    {\n        return operator+=(-i);\n    }\n\n    /*!\n    @brief add to iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl operator+(difference_type i) const\n    {\n        auto result = *this;\n        result += i;\n        return result;\n    }\n\n    /*!\n    @brief addition of distance and iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    friend iter_impl operator+(difference_type i, const iter_impl& it)\n    {\n        auto result = it;\n        result += i;\n        return result;\n    }\n\n    /*!\n    @brief subtract from iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    iter_impl operator-(difference_type i) const\n    {\n        auto result = *this;\n        result -= i;\n        return result;\n    }\n\n    /*!\n    @brief return difference\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    difference_type operator-(const iter_impl& other) const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(209, \"cannot use offsets with object iterators\", *m_object));\n\n            case value_t::array:\n                return m_it.array_iterator - other.m_it.array_iterator;\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                return m_it.primitive_iterator - other.m_it.primitive_iterator;\n        }\n    }\n\n    /*!\n    @brief access to successor\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    reference operator[](difference_type n) const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        switch (m_object->m_type)\n        {\n            case value_t::object:\n                JSON_THROW(invalid_iterator::create(208, \"cannot use operator[] for object iterators\", *m_object));\n\n            case value_t::array:\n                return *std::next(m_it.array_iterator, n);\n\n            case value_t::null:\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))\n                {\n                    return *m_object;\n                }\n\n                JSON_THROW(invalid_iterator::create(214, \"cannot get value\", *m_object));\n            }\n        }\n    }\n\n    /*!\n    @brief return the key of an object iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    const typename object_t::key_type& key() const\n    {\n        JSON_ASSERT(m_object != nullptr);\n\n        if (JSON_HEDLEY_LIKELY(m_object->is_object()))\n        {\n            return m_it.object_iterator->first;\n        }\n\n        JSON_THROW(invalid_iterator::create(207, \"cannot use key() for non-object iterators\", *m_object));\n    }\n\n    /*!\n    @brief return the value of an iterator\n    @pre The iterator is initialized; i.e. `m_object != nullptr`.\n    */\n    reference value() const\n    {\n        return operator*();\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /// associated JSON instance\n    pointer m_object = nullptr;\n    /// the actual iterator of the associated instance\n    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};\n};\n} // namespace detail\n} // namespace nlohmann\n\n// #include <nlohmann/detail/iterators/iteration_proxy.hpp>\n\n// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>\n\n\n#include <cstddef> // ptrdiff_t\n#include <iterator> // reverse_iterator\n#include <utility> // declval\n\nnamespace nlohmann\n{\nnamespace detail\n{\n//////////////////////\n// reverse_iterator //\n//////////////////////\n\n/*!\n@brief a template for a reverse iterator class\n\n@tparam Base the base iterator type to reverse. Valid types are @ref\niterator (to create @ref reverse_iterator) and @ref const_iterator (to\ncreate @ref const_reverse_iterator).\n\n@requirement The class satisfies the following concept requirements:\n-\n[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):\n  The iterator that can be moved can be moved in both directions (i.e.\n  incremented and decremented).\n- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):\n  It is possible to write to the pointed-to element (only if @a Base is\n  @ref iterator).\n\n@since version 1.0.0\n*/\ntemplate<typename Base>\nclass json_reverse_iterator : public std::reverse_iterator<Base>\n{\n  public:\n    using difference_type = std::ptrdiff_t;\n    /// shortcut to the reverse iterator adapter\n    using base_iterator = std::reverse_iterator<Base>;\n    /// the reference type for the pointed-to element\n    using reference = typename Base::reference;\n\n    /// create reverse iterator from iterator\n    explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept\n        : base_iterator(it) {}\n\n    /// create reverse iterator from base class\n    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}\n\n    /// post-increment (it++)\n    json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));\n    }\n\n    /// pre-increment (++it)\n    json_reverse_iterator& operator++()\n    {\n        return static_cast<json_reverse_iterator&>(base_iterator::operator++());\n    }\n\n    /// post-decrement (it--)\n    json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));\n    }\n\n    /// pre-decrement (--it)\n    json_reverse_iterator& operator--()\n    {\n        return static_cast<json_reverse_iterator&>(base_iterator::operator--());\n    }\n\n    /// add to iterator\n    json_reverse_iterator& operator+=(difference_type i)\n    {\n        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));\n    }\n\n    /// add to iterator\n    json_reverse_iterator operator+(difference_type i) const\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));\n    }\n\n    /// subtract from iterator\n    json_reverse_iterator operator-(difference_type i) const\n    {\n        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));\n    }\n\n    /// return difference\n    difference_type operator-(const json_reverse_iterator& other) const\n    {\n        return base_iterator(*this) - base_iterator(other);\n    }\n\n    /// access to successor\n    reference operator[](difference_type n) const\n    {\n        return *(this->operator+(n));\n    }\n\n    /// return the key of an object iterator\n    auto key() const -> decltype(std::declval<Base>().key())\n    {\n        auto it = --this->base();\n        return it.key();\n    }\n\n    /// return the value of an iterator\n    reference value() const\n    {\n        auto it = --this->base();\n        return it.operator * ();\n    }\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/iterators/primitive_iterator.hpp>\n\n// #include <nlohmann/detail/json_pointer.hpp>\n\n\n#include <algorithm> // all_of\n#include <cctype> // isdigit\n#include <limits> // max\n#include <numeric> // accumulate\n#include <string> // string\n#include <utility> // move\n#include <vector> // vector\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/string_escape.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\nnamespace nlohmann\n{\n\n/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document\n/// @sa https://json.nlohmann.me/api/json_pointer/\ntemplate<typename BasicJsonType>\nclass json_pointer\n{\n    // allow basic_json to access private members\n    NLOHMANN_BASIC_JSON_TPL_DECLARATION\n    friend class basic_json;\n\n  public:\n    /// @brief create JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/\n    explicit json_pointer(const std::string& s = \"\")\n        : reference_tokens(split(s))\n    {}\n\n    /// @brief return a string representation of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/to_string/\n    std::string to_string() const\n    {\n        return std::accumulate(reference_tokens.begin(), reference_tokens.end(),\n                               std::string{},\n                               [](const std::string & a, const std::string & b)\n        {\n            return a + \"/\" + detail::escape(b);\n        });\n    }\n\n    /// @brief return a string representation of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/\n    operator std::string() const\n    {\n        return to_string();\n    }\n\n    /// @brief append another JSON pointer at the end of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/\n    json_pointer& operator/=(const json_pointer& ptr)\n    {\n        reference_tokens.insert(reference_tokens.end(),\n                                ptr.reference_tokens.begin(),\n                                ptr.reference_tokens.end());\n        return *this;\n    }\n\n    /// @brief append an unescaped reference token at the end of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/\n    json_pointer& operator/=(std::string token)\n    {\n        push_back(std::move(token));\n        return *this;\n    }\n\n    /// @brief append an array index at the end of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/\n    json_pointer& operator/=(std::size_t array_idx)\n    {\n        return *this /= std::to_string(array_idx);\n    }\n\n    /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/\n    friend json_pointer operator/(const json_pointer& lhs,\n                                  const json_pointer& rhs)\n    {\n        return json_pointer(lhs) /= rhs;\n    }\n\n    /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/\n    friend json_pointer operator/(const json_pointer& lhs, std::string token) // NOLINT(performance-unnecessary-value-param)\n    {\n        return json_pointer(lhs) /= std::move(token);\n    }\n\n    /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/\n    friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)\n    {\n        return json_pointer(lhs) /= array_idx;\n    }\n\n    /// @brief returns the parent of this JSON pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/\n    json_pointer parent_pointer() const\n    {\n        if (empty())\n        {\n            return *this;\n        }\n\n        json_pointer res = *this;\n        res.pop_back();\n        return res;\n    }\n\n    /// @brief remove last reference token\n    /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/\n    void pop_back()\n    {\n        if (JSON_HEDLEY_UNLIKELY(empty()))\n        {\n            JSON_THROW(detail::out_of_range::create(405, \"JSON pointer has no parent\", BasicJsonType()));\n        }\n\n        reference_tokens.pop_back();\n    }\n\n    /// @brief return last reference token\n    /// @sa https://json.nlohmann.me/api/json_pointer/back/\n    const std::string& back() const\n    {\n        if (JSON_HEDLEY_UNLIKELY(empty()))\n        {\n            JSON_THROW(detail::out_of_range::create(405, \"JSON pointer has no parent\", BasicJsonType()));\n        }\n\n        return reference_tokens.back();\n    }\n\n    /// @brief append an unescaped token at the end of the reference pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/push_back/\n    void push_back(const std::string& token)\n    {\n        reference_tokens.push_back(token);\n    }\n\n    /// @brief append an unescaped token at the end of the reference pointer\n    /// @sa https://json.nlohmann.me/api/json_pointer/push_back/\n    void push_back(std::string&& token)\n    {\n        reference_tokens.push_back(std::move(token));\n    }\n\n    /// @brief return whether pointer points to the root document\n    /// @sa https://json.nlohmann.me/api/json_pointer/empty/\n    bool empty() const noexcept\n    {\n        return reference_tokens.empty();\n    }\n\n  private:\n    /*!\n    @param[in] s  reference token to be converted into an array index\n\n    @return integer representation of @a s\n\n    @throw parse_error.106  if an array index begins with '0'\n    @throw parse_error.109  if an array index begins not with a digit\n    @throw out_of_range.404 if string @a s could not be converted to an integer\n    @throw out_of_range.410 if an array index exceeds size_type\n    */\n    static typename BasicJsonType::size_type array_index(const std::string& s)\n    {\n        using size_type = typename BasicJsonType::size_type;\n\n        // error condition (cf. RFC 6901, Sect. 4)\n        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))\n        {\n            JSON_THROW(detail::parse_error::create(106, 0, \"array index '\" + s + \"' must not begin with '0'\", BasicJsonType()));\n        }\n\n        // error condition (cf. RFC 6901, Sect. 4)\n        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))\n        {\n            JSON_THROW(detail::parse_error::create(109, 0, \"array index '\" + s + \"' is not a number\", BasicJsonType()));\n        }\n\n        std::size_t processed_chars = 0;\n        unsigned long long res = 0;  // NOLINT(runtime/int)\n        JSON_TRY\n        {\n            res = std::stoull(s, &processed_chars);\n        }\n        JSON_CATCH(std::out_of_range&)\n        {\n            JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + s + \"'\", BasicJsonType()));\n        }\n\n        // check if the string was completely read\n        if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))\n        {\n            JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + s + \"'\", BasicJsonType()));\n        }\n\n        // only triggered on special platforms (like 32bit), see also\n        // https://github.com/nlohmann/json/pull/2203\n        if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))  // NOLINT(runtime/int)\n        {\n            JSON_THROW(detail::out_of_range::create(410, \"array index \" + s + \" exceeds size_type\", BasicJsonType())); // LCOV_EXCL_LINE\n        }\n\n        return static_cast<size_type>(res);\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    json_pointer top() const\n    {\n        if (JSON_HEDLEY_UNLIKELY(empty()))\n        {\n            JSON_THROW(detail::out_of_range::create(405, \"JSON pointer has no parent\", BasicJsonType()));\n        }\n\n        json_pointer result = *this;\n        result.reference_tokens = {reference_tokens[0]};\n        return result;\n    }\n\n  private:\n    /*!\n    @brief create and return a reference to the pointed to value\n\n    @complexity Linear in the number of reference tokens.\n\n    @throw parse_error.109 if array index is not a number\n    @throw type_error.313 if value cannot be unflattened\n    */\n    BasicJsonType& get_and_create(BasicJsonType& j) const\n    {\n        auto* result = &j;\n\n        // in case no reference tokens exist, return a reference to the JSON value\n        // j which will be overwritten by a primitive value\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (result->type())\n            {\n                case detail::value_t::null:\n                {\n                    if (reference_token == \"0\")\n                    {\n                        // start a new array if reference token is 0\n                        result = &result->operator[](0);\n                    }\n                    else\n                    {\n                        // start a new object otherwise\n                        result = &result->operator[](reference_token);\n                    }\n                    break;\n                }\n\n                case detail::value_t::object:\n                {\n                    // create an entry in the object\n                    result = &result->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    // create an entry in the array\n                    result = &result->operator[](array_index(reference_token));\n                    break;\n                }\n\n                /*\n                The following code is only reached if there exists a reference\n                token _and_ the current value is primitive. In this case, we have\n                an error situation, because primitive values may only occur as\n                single value; that is, with an empty list of reference tokens.\n                */\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::type_error::create(313, \"invalid value to unflatten\", j));\n            }\n        }\n\n        return *result;\n    }\n\n    /*!\n    @brief return a reference to the pointed to value\n\n    @note This version does not throw if a value is not present, but tries to\n          create nested values instead. For instance, calling this function\n          with pointer `\"/this/that\"` on a null value is equivalent to calling\n          `operator[](\"this\").operator[](\"that\")` on that value, effectively\n          changing the null value to an object.\n\n    @param[in] ptr  a JSON value\n\n    @return reference to the JSON value pointed to by the JSON pointer\n\n    @complexity Linear in the length of the JSON pointer.\n\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    BasicJsonType& get_unchecked(BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            // convert null values to arrays or objects before continuing\n            if (ptr->is_null())\n            {\n                // check if reference token is a number\n                const bool nums =\n                    std::all_of(reference_token.begin(), reference_token.end(),\n                                [](const unsigned char x)\n                {\n                    return std::isdigit(x);\n                });\n\n                // change value to array for numbers or \"-\" or to object otherwise\n                *ptr = (nums || reference_token == \"-\")\n                       ? detail::value_t::array\n                       : detail::value_t::object;\n            }\n\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // use unchecked object access\n                    ptr = &ptr->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (reference_token == \"-\")\n                    {\n                        // explicitly treat \"-\" as index beyond the end\n                        ptr = &ptr->operator[](ptr->m_value.array->size());\n                    }\n                    else\n                    {\n                        // convert array index to number; unchecked access\n                        ptr = &ptr->operator[](array_index(reference_token));\n                    }\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.402  if the array index '-' is used\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    BasicJsonType& get_checked(BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // note: at performs range check\n                    ptr = &ptr->at(reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" always fails the range check\n                        JSON_THROW(detail::out_of_range::create(402,\n                                                                \"array index '-' (\" + std::to_string(ptr->m_value.array->size()) +\n                                                                \") is out of range\", *ptr));\n                    }\n\n                    // note: at performs range check\n                    ptr = &ptr->at(array_index(reference_token));\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @brief return a const reference to the pointed to value\n\n    @param[in] ptr  a JSON value\n\n    @return const reference to the JSON value pointed to by the JSON\n    pointer\n\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.402  if the array index '-' is used\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // use unchecked object access\n                    ptr = &ptr->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" cannot be used for const access\n                        JSON_THROW(detail::out_of_range::create(402, \"array index '-' (\" + std::to_string(ptr->m_value.array->size()) + \") is out of range\", *ptr));\n                    }\n\n                    // use unchecked array access\n                    ptr = &ptr->operator[](array_index(reference_token));\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    @throw out_of_range.402  if the array index '-' is used\n    @throw out_of_range.404  if the JSON pointer can not be resolved\n    */\n    const BasicJsonType& get_checked(const BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    // note: at performs range check\n                    ptr = &ptr->at(reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" always fails the range check\n                        JSON_THROW(detail::out_of_range::create(402,\n                                                                \"array index '-' (\" + std::to_string(ptr->m_value.array->size()) +\n                                                                \") is out of range\", *ptr));\n                    }\n\n                    // note: at performs range check\n                    ptr = &ptr->at(array_index(reference_token));\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                    JSON_THROW(detail::out_of_range::create(404, \"unresolved reference token '\" + reference_token + \"'\", *ptr));\n            }\n        }\n\n        return *ptr;\n    }\n\n    /*!\n    @throw parse_error.106   if an array index begins with '0'\n    @throw parse_error.109   if an array index was not a number\n    */\n    bool contains(const BasicJsonType* ptr) const\n    {\n        for (const auto& reference_token : reference_tokens)\n        {\n            switch (ptr->type())\n            {\n                case detail::value_t::object:\n                {\n                    if (!ptr->contains(reference_token))\n                    {\n                        // we did not find the key in the object\n                        return false;\n                    }\n\n                    ptr = &ptr->operator[](reference_token);\n                    break;\n                }\n\n                case detail::value_t::array:\n                {\n                    if (JSON_HEDLEY_UNLIKELY(reference_token == \"-\"))\n                    {\n                        // \"-\" always fails the range check\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !(\"0\" <= reference_token && reference_token <= \"9\")))\n                    {\n                        // invalid char\n                        return false;\n                    }\n                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))\n                    {\n                        if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))\n                        {\n                            // first char should be between '1' and '9'\n                            return false;\n                        }\n                        for (std::size_t i = 1; i < reference_token.size(); i++)\n                        {\n                            if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))\n                            {\n                                // other char should be between '0' and '9'\n                                return false;\n                            }\n                        }\n                    }\n\n                    const auto idx = array_index(reference_token);\n                    if (idx >= ptr->size())\n                    {\n                        // index out of range\n                        return false;\n                    }\n\n                    ptr = &ptr->operator[](idx);\n                    break;\n                }\n\n                case detail::value_t::null:\n                case detail::value_t::string:\n                case detail::value_t::boolean:\n                case detail::value_t::number_integer:\n                case detail::value_t::number_unsigned:\n                case detail::value_t::number_float:\n                case detail::value_t::binary:\n                case detail::value_t::discarded:\n                default:\n                {\n                    // we do not expect primitive values if there is still a\n                    // reference token to process\n                    return false;\n                }\n            }\n        }\n\n        // no reference token left means we found a primitive value\n        return true;\n    }\n\n    /*!\n    @brief split the string input to reference tokens\n\n    @note This function is only called by the json_pointer constructor.\n          All exceptions below are documented there.\n\n    @throw parse_error.107  if the pointer is not empty or begins with '/'\n    @throw parse_error.108  if character '~' is not followed by '0' or '1'\n    */\n    static std::vector<std::string> split(const std::string& reference_string)\n    {\n        std::vector<std::string> result;\n\n        // special case: empty reference string -> no reference tokens\n        if (reference_string.empty())\n        {\n            return result;\n        }\n\n        // check if nonempty reference string begins with slash\n        if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))\n        {\n            JSON_THROW(detail::parse_error::create(107, 1, \"JSON pointer must be empty or begin with '/' - was: '\" + reference_string + \"'\", BasicJsonType()));\n        }\n\n        // extract the reference tokens:\n        // - slash: position of the last read slash (or end of string)\n        // - start: position after the previous slash\n        for (\n            // search for the first slash after the first character\n            std::size_t slash = reference_string.find_first_of('/', 1),\n            // set the beginning of the first reference token\n            start = 1;\n            // we can stop if start == 0 (if slash == std::string::npos)\n            start != 0;\n            // set the beginning of the next reference token\n            // (will eventually be 0 if slash == std::string::npos)\n            start = (slash == std::string::npos) ? 0 : slash + 1,\n            // find next slash\n            slash = reference_string.find_first_of('/', start))\n        {\n            // use the text between the beginning of the reference token\n            // (start) and the last slash (slash).\n            auto reference_token = reference_string.substr(start, slash - start);\n\n            // check reference tokens are properly escaped\n            for (std::size_t pos = reference_token.find_first_of('~');\n                    pos != std::string::npos;\n                    pos = reference_token.find_first_of('~', pos + 1))\n            {\n                JSON_ASSERT(reference_token[pos] == '~');\n\n                // ~ must be followed by 0 or 1\n                if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||\n                                         (reference_token[pos + 1] != '0' &&\n                                          reference_token[pos + 1] != '1')))\n                {\n                    JSON_THROW(detail::parse_error::create(108, 0, \"escape character '~' must be followed with '0' or '1'\", BasicJsonType()));\n                }\n            }\n\n            // finally, store the reference token\n            detail::unescape(reference_token);\n            result.push_back(reference_token);\n        }\n\n        return result;\n    }\n\n  private:\n    /*!\n    @param[in] reference_string  the reference string to the current value\n    @param[in] value             the value to consider\n    @param[in,out] result        the result object to insert values to\n\n    @note Empty objects or arrays are flattened to `null`.\n    */\n    static void flatten(const std::string& reference_string,\n                        const BasicJsonType& value,\n                        BasicJsonType& result)\n    {\n        switch (value.type())\n        {\n            case detail::value_t::array:\n            {\n                if (value.m_value.array->empty())\n                {\n                    // flatten empty array as null\n                    result[reference_string] = nullptr;\n                }\n                else\n                {\n                    // iterate array and use index as reference string\n                    for (std::size_t i = 0; i < value.m_value.array->size(); ++i)\n                    {\n                        flatten(reference_string + \"/\" + std::to_string(i),\n                                value.m_value.array->operator[](i), result);\n                    }\n                }\n                break;\n            }\n\n            case detail::value_t::object:\n            {\n                if (value.m_value.object->empty())\n                {\n                    // flatten empty object as null\n                    result[reference_string] = nullptr;\n                }\n                else\n                {\n                    // iterate object and use keys as reference string\n                    for (const auto& element : *value.m_value.object)\n                    {\n                        flatten(reference_string + \"/\" + detail::escape(element.first), element.second, result);\n                    }\n                }\n                break;\n            }\n\n            case detail::value_t::null:\n            case detail::value_t::string:\n            case detail::value_t::boolean:\n            case detail::value_t::number_integer:\n            case detail::value_t::number_unsigned:\n            case detail::value_t::number_float:\n            case detail::value_t::binary:\n            case detail::value_t::discarded:\n            default:\n            {\n                // add primitive value with its reference string\n                result[reference_string] = value;\n                break;\n            }\n        }\n    }\n\n    /*!\n    @param[in] value  flattened JSON\n\n    @return unflattened JSON\n\n    @throw parse_error.109 if array index is not a number\n    @throw type_error.314  if value is not an object\n    @throw type_error.315  if object values are not primitive\n    @throw type_error.313  if value cannot be unflattened\n    */\n    static BasicJsonType\n    unflatten(const BasicJsonType& value)\n    {\n        if (JSON_HEDLEY_UNLIKELY(!value.is_object()))\n        {\n            JSON_THROW(detail::type_error::create(314, \"only objects can be unflattened\", value));\n        }\n\n        BasicJsonType result;\n\n        // iterate the JSON object values\n        for (const auto& element : *value.m_value.object)\n        {\n            if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))\n            {\n                JSON_THROW(detail::type_error::create(315, \"values in object must be primitive\", element.second));\n            }\n\n            // assign value to reference pointed to by JSON pointer; Note that if\n            // the JSON pointer is \"\" (i.e., points to the whole value), function\n            // get_and_create returns a reference to result itself. An assignment\n            // will then create a primitive value.\n            json_pointer(element.first).get_and_create(result) = element.second;\n        }\n\n        return result;\n    }\n\n    /*!\n    @brief compares two JSON pointers for equality\n\n    @param[in] lhs  JSON pointer to compare\n    @param[in] rhs  JSON pointer to compare\n    @return whether @a lhs is equal to @a rhs\n\n    @complexity Linear in the length of the JSON pointer\n\n    @exceptionsafety No-throw guarantee: this function never throws exceptions.\n    */\n    friend bool operator==(json_pointer const& lhs,\n                           json_pointer const& rhs) noexcept\n    {\n        return lhs.reference_tokens == rhs.reference_tokens;\n    }\n\n    /*!\n    @brief compares two JSON pointers for inequality\n\n    @param[in] lhs  JSON pointer to compare\n    @param[in] rhs  JSON pointer to compare\n    @return whether @a lhs is not equal @a rhs\n\n    @complexity Linear in the length of the JSON pointer\n\n    @exceptionsafety No-throw guarantee: this function never throws exceptions.\n    */\n    friend bool operator!=(json_pointer const& lhs,\n                           json_pointer const& rhs) noexcept\n    {\n        return !(lhs == rhs);\n    }\n\n    /// the reference tokens\n    std::vector<std::string> reference_tokens;\n};\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/json_ref.hpp>\n\n\n#include <initializer_list>\n#include <utility>\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\ntemplate<typename BasicJsonType>\nclass json_ref\n{\n  public:\n    using value_type = BasicJsonType;\n\n    json_ref(value_type&& value)\n        : owned_value(std::move(value))\n    {}\n\n    json_ref(const value_type& value)\n        : value_ref(&value)\n    {}\n\n    json_ref(std::initializer_list<json_ref> init)\n        : owned_value(init)\n    {}\n\n    template <\n        class... Args,\n        enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >\n    json_ref(Args && ... args)\n        : owned_value(std::forward<Args>(args)...)\n    {}\n\n    // class should be movable only\n    json_ref(json_ref&&) noexcept = default;\n    json_ref(const json_ref&) = delete;\n    json_ref& operator=(const json_ref&) = delete;\n    json_ref& operator=(json_ref&&) = delete;\n    ~json_ref() = default;\n\n    value_type moved_or_copied() const\n    {\n        if (value_ref == nullptr)\n        {\n            return std::move(owned_value);\n        }\n        return *value_ref;\n    }\n\n    value_type const& operator*() const\n    {\n        return value_ref ? *value_ref : owned_value;\n    }\n\n    value_type const* operator->() const\n    {\n        return &** this;\n    }\n\n  private:\n    mutable value_type owned_value = nullptr;\n    value_type const* value_ref = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/string_escape.hpp>\n\n// #include <nlohmann/detail/meta/cpp_future.hpp>\n\n// #include <nlohmann/detail/meta/type_traits.hpp>\n\n// #include <nlohmann/detail/output/binary_writer.hpp>\n\n\n#include <algorithm> // reverse\n#include <array> // array\n#include <cmath> // isnan, isinf\n#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t\n#include <cstring> // memcpy\n#include <limits> // numeric_limits\n#include <string> // string\n#include <utility> // move\n\n// #include <nlohmann/detail/input/binary_reader.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/output/output_adapters.hpp>\n\n\n#include <algorithm> // copy\n#include <cstddef> // size_t\n#include <iterator> // back_inserter\n#include <memory> // shared_ptr, make_shared\n#include <string> // basic_string\n#include <vector> // vector\n\n#ifndef JSON_NO_IO\n    #include <ios>      // streamsize\n    #include <ostream>  // basic_ostream\n#endif  // JSON_NO_IO\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n/// abstract output adapter interface\ntemplate<typename CharType> struct output_adapter_protocol\n{\n    virtual void write_character(CharType c) = 0;\n    virtual void write_characters(const CharType* s, std::size_t length) = 0;\n    virtual ~output_adapter_protocol() = default;\n\n    output_adapter_protocol() = default;\n    output_adapter_protocol(const output_adapter_protocol&) = default;\n    output_adapter_protocol(output_adapter_protocol&&) noexcept = default;\n    output_adapter_protocol& operator=(const output_adapter_protocol&) = default;\n    output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;\n};\n\n/// a type to simplify interfaces\ntemplate<typename CharType>\nusing output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;\n\n/// output adapter for byte vectors\ntemplate<typename CharType, typename AllocatorType = std::allocator<CharType>>\nclass output_vector_adapter : public output_adapter_protocol<CharType>\n{\n  public:\n    explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept\n        : v(vec)\n    {}\n\n    void write_character(CharType c) override\n    {\n        v.push_back(c);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    void write_characters(const CharType* s, std::size_t length) override\n    {\n        std::copy(s, s + length, std::back_inserter(v));\n    }\n\n  private:\n    std::vector<CharType, AllocatorType>& v;\n};\n\n#ifndef JSON_NO_IO\n/// output adapter for output streams\ntemplate<typename CharType>\nclass output_stream_adapter : public output_adapter_protocol<CharType>\n{\n  public:\n    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept\n        : stream(s)\n    {}\n\n    void write_character(CharType c) override\n    {\n        stream.put(c);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    void write_characters(const CharType* s, std::size_t length) override\n    {\n        stream.write(s, static_cast<std::streamsize>(length));\n    }\n\n  private:\n    std::basic_ostream<CharType>& stream;\n};\n#endif  // JSON_NO_IO\n\n/// output adapter for basic_string\ntemplate<typename CharType, typename StringType = std::basic_string<CharType>>\nclass output_string_adapter : public output_adapter_protocol<CharType>\n{\n  public:\n    explicit output_string_adapter(StringType& s) noexcept\n        : str(s)\n    {}\n\n    void write_character(CharType c) override\n    {\n        str.push_back(c);\n    }\n\n    JSON_HEDLEY_NON_NULL(2)\n    void write_characters(const CharType* s, std::size_t length) override\n    {\n        str.append(s, length);\n    }\n\n  private:\n    StringType& str;\n};\n\ntemplate<typename CharType, typename StringType = std::basic_string<CharType>>\nclass output_adapter\n{\n  public:\n    template<typename AllocatorType = std::allocator<CharType>>\n    output_adapter(std::vector<CharType, AllocatorType>& vec)\n        : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}\n\n#ifndef JSON_NO_IO\n    output_adapter(std::basic_ostream<CharType>& s)\n        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}\n#endif  // JSON_NO_IO\n\n    output_adapter(StringType& s)\n        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}\n\n    operator output_adapter_t<CharType>()\n    {\n        return oa;\n    }\n\n  private:\n    output_adapter_t<CharType> oa = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////////////\n// binary writer //\n///////////////////\n\n/*!\n@brief serialization to CBOR and MessagePack values\n*/\ntemplate<typename BasicJsonType, typename CharType>\nclass binary_writer\n{\n    using string_t = typename BasicJsonType::string_t;\n    using binary_t = typename BasicJsonType::binary_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n\n  public:\n    /*!\n    @brief create a binary writer\n\n    @param[in] adapter  output adapter to write to\n    */\n    explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))\n    {\n        JSON_ASSERT(oa);\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    @pre       j.type() == value_t::object\n    */\n    void write_bson(const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::object:\n            {\n                write_bson_object(*j.m_value.object);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::array:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                JSON_THROW(type_error::create(317, \"to serialize to BSON, top-level type must be object, but is \" + std::string(j.type_name()), j));\n            }\n        }\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    */\n    void write_cbor(const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::null:\n            {\n                oa->write_character(to_char_type(0xF6));\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                oa->write_character(j.m_value.boolean\n                                    ? to_char_type(0xF5)\n                                    : to_char_type(0xF4));\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                if (j.m_value.number_integer >= 0)\n                {\n                    // CBOR does not differentiate between positive signed\n                    // integers and unsigned integers. Therefore, we used the\n                    // code from the value_t::number_unsigned case here.\n                    if (j.m_value.number_integer <= 0x17)\n                    {\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x18));\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x19));\n                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x1A));\n                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));\n                    }\n                    else\n                    {\n                        oa->write_character(to_char_type(0x1B));\n                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));\n                    }\n                }\n                else\n                {\n                    // The conversions below encode the sign in the first\n                    // byte, and the value is converted to a positive number.\n                    const auto positive_number = -1 - j.m_value.number_integer;\n                    if (j.m_value.number_integer >= -24)\n                    {\n                        write_number(static_cast<std::uint8_t>(0x20 + positive_number));\n                    }\n                    else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x38));\n                        write_number(static_cast<std::uint8_t>(positive_number));\n                    }\n                    else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x39));\n                        write_number(static_cast<std::uint16_t>(positive_number));\n                    }\n                    else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        oa->write_character(to_char_type(0x3A));\n                        write_number(static_cast<std::uint32_t>(positive_number));\n                    }\n                    else\n                    {\n                        oa->write_character(to_char_type(0x3B));\n                        write_number(static_cast<std::uint64_t>(positive_number));\n                    }\n                }\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                if (j.m_value.number_unsigned <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x18));\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x19));\n                    write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x1A));\n                    write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));\n                }\n                else\n                {\n                    oa->write_character(to_char_type(0x1B));\n                    write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));\n                }\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                if (std::isnan(j.m_value.number_float))\n                {\n                    // NaN is 0xf97e00 in CBOR\n                    oa->write_character(to_char_type(0xF9));\n                    oa->write_character(to_char_type(0x7E));\n                    oa->write_character(to_char_type(0x00));\n                }\n                else if (std::isinf(j.m_value.number_float))\n                {\n                    // Infinity is 0xf97c00, -Infinity is 0xf9fc00\n                    oa->write_character(to_char_type(0xf9));\n                    oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));\n                    oa->write_character(to_char_type(0x00));\n                }\n                else\n                {\n                    write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);\n                }\n                break;\n            }\n\n            case value_t::string:\n            {\n                // step 1: write control byte and the string length\n                const auto N = j.m_value.string->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0x60 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x78));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x79));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x7A));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x7B));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write the string\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),\n                    j.m_value.string->size());\n                break;\n            }\n\n            case value_t::array:\n            {\n                // step 1: write control byte and the array size\n                const auto N = j.m_value.array->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0x80 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x98));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x99));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x9A));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x9B));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.array)\n                {\n                    write_cbor(el);\n                }\n                break;\n            }\n\n            case value_t::binary:\n            {\n                if (j.m_value.binary->has_subtype())\n                {\n                    if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xd8));\n                        write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));\n                    }\n                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xd9));\n                        write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));\n                    }\n                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xda));\n                        write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));\n                    }\n                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())\n                    {\n                        write_number(static_cast<std::uint8_t>(0xdb));\n                        write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));\n                    }\n                }\n\n                // step 1: write control byte and the binary array size\n                const auto N = j.m_value.binary->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0x40 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x58));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x59));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x5A));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0x5B));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write each element\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),\n                    N);\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                // step 1: write control byte and the object size\n                const auto N = j.m_value.object->size();\n                if (N <= 0x17)\n                {\n                    write_number(static_cast<std::uint8_t>(0xA0 + N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xB8));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xB9));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xBA));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n                // LCOV_EXCL_START\n                else if (N <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    oa->write_character(to_char_type(0xBB));\n                    write_number(static_cast<std::uint64_t>(N));\n                }\n                // LCOV_EXCL_STOP\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.object)\n                {\n                    write_cbor(el.first);\n                    write_cbor(el.second);\n                }\n                break;\n            }\n\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    */\n    void write_msgpack(const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::null: // nil\n            {\n                oa->write_character(to_char_type(0xC0));\n                break;\n            }\n\n            case value_t::boolean: // true and false\n            {\n                oa->write_character(j.m_value.boolean\n                                    ? to_char_type(0xC3)\n                                    : to_char_type(0xC2));\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                if (j.m_value.number_integer >= 0)\n                {\n                    // MessagePack does not differentiate between positive\n                    // signed integers and unsigned integers. Therefore, we used\n                    // the code from the value_t::number_unsigned case here.\n                    if (j.m_value.number_unsigned < 128)\n                    {\n                        // positive fixnum\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())\n                    {\n                        // uint 8\n                        oa->write_character(to_char_type(0xCC));\n                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())\n                    {\n                        // uint 16\n                        oa->write_character(to_char_type(0xCD));\n                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())\n                    {\n                        // uint 32\n                        oa->write_character(to_char_type(0xCE));\n                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())\n                    {\n                        // uint 64\n                        oa->write_character(to_char_type(0xCF));\n                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));\n                    }\n                }\n                else\n                {\n                    if (j.m_value.number_integer >= -32)\n                    {\n                        // negative fixnum\n                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())\n                    {\n                        // int 8\n                        oa->write_character(to_char_type(0xD0));\n                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())\n                    {\n                        // int 16\n                        oa->write_character(to_char_type(0xD1));\n                        write_number(static_cast<std::int16_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())\n                    {\n                        // int 32\n                        oa->write_character(to_char_type(0xD2));\n                        write_number(static_cast<std::int32_t>(j.m_value.number_integer));\n                    }\n                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&\n                             j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())\n                    {\n                        // int 64\n                        oa->write_character(to_char_type(0xD3));\n                        write_number(static_cast<std::int64_t>(j.m_value.number_integer));\n                    }\n                }\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                if (j.m_value.number_unsigned < 128)\n                {\n                    // positive fixnum\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    // uint 8\n                    oa->write_character(to_char_type(0xCC));\n                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // uint 16\n                    oa->write_character(to_char_type(0xCD));\n                    write_number(static_cast<std::uint16_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // uint 32\n                    oa->write_character(to_char_type(0xCE));\n                    write_number(static_cast<std::uint32_t>(j.m_value.number_integer));\n                }\n                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())\n                {\n                    // uint 64\n                    oa->write_character(to_char_type(0xCF));\n                    write_number(static_cast<std::uint64_t>(j.m_value.number_integer));\n                }\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);\n                break;\n            }\n\n            case value_t::string:\n            {\n                // step 1: write control byte and the string length\n                const auto N = j.m_value.string->size();\n                if (N <= 31)\n                {\n                    // fixstr\n                    write_number(static_cast<std::uint8_t>(0xA0 | N));\n                }\n                else if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    // str 8\n                    oa->write_character(to_char_type(0xD9));\n                    write_number(static_cast<std::uint8_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // str 16\n                    oa->write_character(to_char_type(0xDA));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // str 32\n                    oa->write_character(to_char_type(0xDB));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 2: write the string\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),\n                    j.m_value.string->size());\n                break;\n            }\n\n            case value_t::array:\n            {\n                // step 1: write control byte and the array size\n                const auto N = j.m_value.array->size();\n                if (N <= 15)\n                {\n                    // fixarray\n                    write_number(static_cast<std::uint8_t>(0x90 | N));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // array 16\n                    oa->write_character(to_char_type(0xDC));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // array 32\n                    oa->write_character(to_char_type(0xDD));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.array)\n                {\n                    write_msgpack(el);\n                }\n                break;\n            }\n\n            case value_t::binary:\n            {\n                // step 0: determine if the binary type has a set subtype to\n                // determine whether or not to use the ext or fixext types\n                const bool use_ext = j.m_value.binary->has_subtype();\n\n                // step 1: write control byte and the byte string length\n                const auto N = j.m_value.binary->size();\n                if (N <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    std::uint8_t output_type{};\n                    bool fixed = true;\n                    if (use_ext)\n                    {\n                        switch (N)\n                        {\n                            case 1:\n                                output_type = 0xD4; // fixext 1\n                                break;\n                            case 2:\n                                output_type = 0xD5; // fixext 2\n                                break;\n                            case 4:\n                                output_type = 0xD6; // fixext 4\n                                break;\n                            case 8:\n                                output_type = 0xD7; // fixext 8\n                                break;\n                            case 16:\n                                output_type = 0xD8; // fixext 16\n                                break;\n                            default:\n                                output_type = 0xC7; // ext 8\n                                fixed = false;\n                                break;\n                        }\n\n                    }\n                    else\n                    {\n                        output_type = 0xC4; // bin 8\n                        fixed = false;\n                    }\n\n                    oa->write_character(to_char_type(output_type));\n                    if (!fixed)\n                    {\n                        write_number(static_cast<std::uint8_t>(N));\n                    }\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    std::uint8_t output_type = use_ext\n                                               ? 0xC8 // ext 16\n                                               : 0xC5; // bin 16\n\n                    oa->write_character(to_char_type(output_type));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    std::uint8_t output_type = use_ext\n                                               ? 0xC9 // ext 32\n                                               : 0xC6; // bin 32\n\n                    oa->write_character(to_char_type(output_type));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 1.5: if this is an ext type, write the subtype\n                if (use_ext)\n                {\n                    write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));\n                }\n\n                // step 2: write the byte string\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),\n                    N);\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                // step 1: write control byte and the object size\n                const auto N = j.m_value.object->size();\n                if (N <= 15)\n                {\n                    // fixmap\n                    write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));\n                }\n                else if (N <= (std::numeric_limits<std::uint16_t>::max)())\n                {\n                    // map 16\n                    oa->write_character(to_char_type(0xDE));\n                    write_number(static_cast<std::uint16_t>(N));\n                }\n                else if (N <= (std::numeric_limits<std::uint32_t>::max)())\n                {\n                    // map 32\n                    oa->write_character(to_char_type(0xDF));\n                    write_number(static_cast<std::uint32_t>(N));\n                }\n\n                // step 2: write each element\n                for (const auto& el : *j.m_value.object)\n                {\n                    write_msgpack(el.first);\n                    write_msgpack(el.second);\n                }\n                break;\n            }\n\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n    /*!\n    @param[in] j  JSON value to serialize\n    @param[in] use_count   whether to use '#' prefixes (optimized format)\n    @param[in] use_type    whether to use '$' prefixes (optimized format)\n    @param[in] add_prefix  whether prefixes need to be used for this value\n    */\n    void write_ubjson(const BasicJsonType& j, const bool use_count,\n                      const bool use_type, const bool add_prefix = true)\n    {\n        switch (j.type())\n        {\n            case value_t::null:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('Z'));\n                }\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(j.m_value.boolean\n                                        ? to_char_type('T')\n                                        : to_char_type('F'));\n                }\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);\n                break;\n            }\n\n            case value_t::string:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('S'));\n                }\n                write_number_with_ubjson_prefix(j.m_value.string->size(), true);\n                oa->write_characters(\n                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),\n                    j.m_value.string->size());\n                break;\n            }\n\n            case value_t::array:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('['));\n                }\n\n                bool prefix_required = true;\n                if (use_type && !j.m_value.array->empty())\n                {\n                    JSON_ASSERT(use_count);\n                    const CharType first_prefix = ubjson_prefix(j.front());\n                    const bool same_prefix = std::all_of(j.begin() + 1, j.end(),\n                                                         [this, first_prefix](const BasicJsonType & v)\n                    {\n                        return ubjson_prefix(v) == first_prefix;\n                    });\n\n                    if (same_prefix)\n                    {\n                        prefix_required = false;\n                        oa->write_character(to_char_type('$'));\n                        oa->write_character(first_prefix);\n                    }\n                }\n\n                if (use_count)\n                {\n                    oa->write_character(to_char_type('#'));\n                    write_number_with_ubjson_prefix(j.m_value.array->size(), true);\n                }\n\n                for (const auto& el : *j.m_value.array)\n                {\n                    write_ubjson(el, use_count, use_type, prefix_required);\n                }\n\n                if (!use_count)\n                {\n                    oa->write_character(to_char_type(']'));\n                }\n\n                break;\n            }\n\n            case value_t::binary:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('['));\n                }\n\n                if (use_type && !j.m_value.binary->empty())\n                {\n                    JSON_ASSERT(use_count);\n                    oa->write_character(to_char_type('$'));\n                    oa->write_character('U');\n                }\n\n                if (use_count)\n                {\n                    oa->write_character(to_char_type('#'));\n                    write_number_with_ubjson_prefix(j.m_value.binary->size(), true);\n                }\n\n                if (use_type)\n                {\n                    oa->write_characters(\n                        reinterpret_cast<const CharType*>(j.m_value.binary->data()),\n                        j.m_value.binary->size());\n                }\n                else\n                {\n                    for (size_t i = 0; i < j.m_value.binary->size(); ++i)\n                    {\n                        oa->write_character(to_char_type('U'));\n                        oa->write_character(j.m_value.binary->data()[i]);\n                    }\n                }\n\n                if (!use_count)\n                {\n                    oa->write_character(to_char_type(']'));\n                }\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                if (add_prefix)\n                {\n                    oa->write_character(to_char_type('{'));\n                }\n\n                bool prefix_required = true;\n                if (use_type && !j.m_value.object->empty())\n                {\n                    JSON_ASSERT(use_count);\n                    const CharType first_prefix = ubjson_prefix(j.front());\n                    const bool same_prefix = std::all_of(j.begin(), j.end(),\n                                                         [this, first_prefix](const BasicJsonType & v)\n                    {\n                        return ubjson_prefix(v) == first_prefix;\n                    });\n\n                    if (same_prefix)\n                    {\n                        prefix_required = false;\n                        oa->write_character(to_char_type('$'));\n                        oa->write_character(first_prefix);\n                    }\n                }\n\n                if (use_count)\n                {\n                    oa->write_character(to_char_type('#'));\n                    write_number_with_ubjson_prefix(j.m_value.object->size(), true);\n                }\n\n                for (const auto& el : *j.m_value.object)\n                {\n                    write_number_with_ubjson_prefix(el.first.size(), true);\n                    oa->write_characters(\n                        reinterpret_cast<const CharType*>(el.first.c_str()),\n                        el.first.size());\n                    write_ubjson(el.second, use_count, use_type, prefix_required);\n                }\n\n                if (!use_count)\n                {\n                    oa->write_character(to_char_type('}'));\n                }\n\n                break;\n            }\n\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n  private:\n    //////////\n    // BSON //\n    //////////\n\n    /*!\n    @return The size of a BSON document entry header, including the id marker\n            and the entry name size (and its null-terminator).\n    */\n    static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)\n    {\n        const auto it = name.find(static_cast<typename string_t::value_type>(0));\n        if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))\n        {\n            JSON_THROW(out_of_range::create(409, \"BSON key cannot contain code point U+0000 (at byte \" + std::to_string(it) + \")\", j));\n            static_cast<void>(j);\n        }\n\n        return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;\n    }\n\n    /*!\n    @brief Writes the given @a element_type and @a name to the output adapter\n    */\n    void write_bson_entry_header(const string_t& name,\n                                 const std::uint8_t element_type)\n    {\n        oa->write_character(to_char_type(element_type)); // boolean\n        oa->write_characters(\n            reinterpret_cast<const CharType*>(name.c_str()),\n            name.size() + 1u);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and boolean value @a value\n    */\n    void write_bson_boolean(const string_t& name,\n                            const bool value)\n    {\n        write_bson_entry_header(name, 0x08);\n        oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and double value @a value\n    */\n    void write_bson_double(const string_t& name,\n                           const double value)\n    {\n        write_bson_entry_header(name, 0x01);\n        write_number<double, true>(value);\n    }\n\n    /*!\n    @return The size of the BSON-encoded string in @a value\n    */\n    static std::size_t calc_bson_string_size(const string_t& value)\n    {\n        return sizeof(std::int32_t) + value.size() + 1ul;\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and string value @a value\n    */\n    void write_bson_string(const string_t& name,\n                           const string_t& value)\n    {\n        write_bson_entry_header(name, 0x02);\n\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));\n        oa->write_characters(\n            reinterpret_cast<const CharType*>(value.c_str()),\n            value.size() + 1);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and null value\n    */\n    void write_bson_null(const string_t& name)\n    {\n        write_bson_entry_header(name, 0x0A);\n    }\n\n    /*!\n    @return The size of the BSON-encoded integer @a value\n    */\n    static std::size_t calc_bson_integer_size(const std::int64_t value)\n    {\n        return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()\n               ? sizeof(std::int32_t)\n               : sizeof(std::int64_t);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and integer @a value\n    */\n    void write_bson_integer(const string_t& name,\n                            const std::int64_t value)\n    {\n        if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())\n        {\n            write_bson_entry_header(name, 0x10); // int32\n            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));\n        }\n        else\n        {\n            write_bson_entry_header(name, 0x12); // int64\n            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));\n        }\n    }\n\n    /*!\n    @return The size of the BSON-encoded unsigned integer in @a j\n    */\n    static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept\n    {\n        return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n               ? sizeof(std::int32_t)\n               : sizeof(std::int64_t);\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and unsigned @a value\n    */\n    void write_bson_unsigned(const string_t& name,\n                             const BasicJsonType& j)\n    {\n        if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n        {\n            write_bson_entry_header(name, 0x10 /* int32 */);\n            write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));\n        }\n        else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))\n        {\n            write_bson_entry_header(name, 0x12 /* int64 */);\n            write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));\n        }\n        else\n        {\n            JSON_THROW(out_of_range::create(407, \"integer number \" + std::to_string(j.m_value.number_unsigned) + \" cannot be represented by BSON as it does not fit int64\", j));\n        }\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and object @a value\n    */\n    void write_bson_object_entry(const string_t& name,\n                                 const typename BasicJsonType::object_t& value)\n    {\n        write_bson_entry_header(name, 0x03); // object\n        write_bson_object(value);\n    }\n\n    /*!\n    @return The size of the BSON-encoded array @a value\n    */\n    static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)\n    {\n        std::size_t array_index = 0ul;\n\n        const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)\n        {\n            return result + calc_bson_element_size(std::to_string(array_index++), el);\n        });\n\n        return sizeof(std::int32_t) + embedded_document_size + 1ul;\n    }\n\n    /*!\n    @return The size of the BSON-encoded binary array @a value\n    */\n    static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)\n    {\n        return sizeof(std::int32_t) + value.size() + 1ul;\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and array @a value\n    */\n    void write_bson_array(const string_t& name,\n                          const typename BasicJsonType::array_t& value)\n    {\n        write_bson_entry_header(name, 0x04); // array\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));\n\n        std::size_t array_index = 0ul;\n\n        for (const auto& el : value)\n        {\n            write_bson_element(std::to_string(array_index++), el);\n        }\n\n        oa->write_character(to_char_type(0x00));\n    }\n\n    /*!\n    @brief Writes a BSON element with key @a name and binary value @a value\n    */\n    void write_bson_binary(const string_t& name,\n                           const binary_t& value)\n    {\n        write_bson_entry_header(name, 0x05);\n\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));\n        write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));\n\n        oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());\n    }\n\n    /*!\n    @brief Calculates the size necessary to serialize the JSON value @a j with its @a name\n    @return The calculated size for the BSON document entry for @a j with the given @a name.\n    */\n    static std::size_t calc_bson_element_size(const string_t& name,\n            const BasicJsonType& j)\n    {\n        const auto header_size = calc_bson_entry_header_size(name, j);\n        switch (j.type())\n        {\n            case value_t::object:\n                return header_size + calc_bson_object_size(*j.m_value.object);\n\n            case value_t::array:\n                return header_size + calc_bson_array_size(*j.m_value.array);\n\n            case value_t::binary:\n                return header_size + calc_bson_binary_size(*j.m_value.binary);\n\n            case value_t::boolean:\n                return header_size + 1ul;\n\n            case value_t::number_float:\n                return header_size + 8ul;\n\n            case value_t::number_integer:\n                return header_size + calc_bson_integer_size(j.m_value.number_integer);\n\n            case value_t::number_unsigned:\n                return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);\n\n            case value_t::string:\n                return header_size + calc_bson_string_size(*j.m_value.string);\n\n            case value_t::null:\n                return header_size + 0ul;\n\n            // LCOV_EXCL_START\n            case value_t::discarded:\n            default:\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)\n                return 0ul;\n                // LCOV_EXCL_STOP\n        }\n    }\n\n    /*!\n    @brief Serializes the JSON value @a j to BSON and associates it with the\n           key @a name.\n    @param name The name to associate with the JSON entity @a j within the\n                current BSON document\n    */\n    void write_bson_element(const string_t& name,\n                            const BasicJsonType& j)\n    {\n        switch (j.type())\n        {\n            case value_t::object:\n                return write_bson_object_entry(name, *j.m_value.object);\n\n            case value_t::array:\n                return write_bson_array(name, *j.m_value.array);\n\n            case value_t::binary:\n                return write_bson_binary(name, *j.m_value.binary);\n\n            case value_t::boolean:\n                return write_bson_boolean(name, j.m_value.boolean);\n\n            case value_t::number_float:\n                return write_bson_double(name, j.m_value.number_float);\n\n            case value_t::number_integer:\n                return write_bson_integer(name, j.m_value.number_integer);\n\n            case value_t::number_unsigned:\n                return write_bson_unsigned(name, j);\n\n            case value_t::string:\n                return write_bson_string(name, *j.m_value.string);\n\n            case value_t::null:\n                return write_bson_null(name);\n\n            // LCOV_EXCL_START\n            case value_t::discarded:\n            default:\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)\n                return;\n                // LCOV_EXCL_STOP\n        }\n    }\n\n    /*!\n    @brief Calculates the size of the BSON serialization of the given\n           JSON-object @a j.\n    @param[in] value  JSON value to serialize\n    @pre       value.type() == value_t::object\n    */\n    static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)\n    {\n        std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),\n                                    [](size_t result, const typename BasicJsonType::object_t::value_type & el)\n        {\n            return result += calc_bson_element_size(el.first, el.second);\n        });\n\n        return sizeof(std::int32_t) + document_size + 1ul;\n    }\n\n    /*!\n    @param[in] value  JSON value to serialize\n    @pre       value.type() == value_t::object\n    */\n    void write_bson_object(const typename BasicJsonType::object_t& value)\n    {\n        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));\n\n        for (const auto& el : value)\n        {\n            write_bson_element(el.first, el.second);\n        }\n\n        oa->write_character(to_char_type(0x00));\n    }\n\n    //////////\n    // CBOR //\n    //////////\n\n    static constexpr CharType get_cbor_float_prefix(float /*unused*/)\n    {\n        return to_char_type(0xFA);  // Single-Precision Float\n    }\n\n    static constexpr CharType get_cbor_float_prefix(double /*unused*/)\n    {\n        return to_char_type(0xFB);  // Double-Precision Float\n    }\n\n    /////////////\n    // MsgPack //\n    /////////////\n\n    static constexpr CharType get_msgpack_float_prefix(float /*unused*/)\n    {\n        return to_char_type(0xCA);  // float 32\n    }\n\n    static constexpr CharType get_msgpack_float_prefix(double /*unused*/)\n    {\n        return to_char_type(0xCB);  // float 64\n    }\n\n    ////////////\n    // UBJSON //\n    ////////////\n\n    // UBJSON: write number (floating point)\n    template<typename NumberType, typename std::enable_if<\n                 std::is_floating_point<NumberType>::value, int>::type = 0>\n    void write_number_with_ubjson_prefix(const NumberType n,\n                                         const bool add_prefix)\n    {\n        if (add_prefix)\n        {\n            oa->write_character(get_ubjson_float_prefix(n));\n        }\n        write_number(n);\n    }\n\n    // UBJSON: write number (unsigned integer)\n    template<typename NumberType, typename std::enable_if<\n                 std::is_unsigned<NumberType>::value, int>::type = 0>\n    void write_number_with_ubjson_prefix(const NumberType n,\n                                         const bool add_prefix)\n    {\n        if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('i'));  // int8\n            }\n            write_number(static_cast<std::uint8_t>(n));\n        }\n        else if (n <= (std::numeric_limits<std::uint8_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('U'));  // uint8\n            }\n            write_number(static_cast<std::uint8_t>(n));\n        }\n        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('I'));  // int16\n            }\n            write_number(static_cast<std::int16_t>(n));\n        }\n        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('l'));  // int32\n            }\n            write_number(static_cast<std::int32_t>(n));\n        }\n        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('L'));  // int64\n            }\n            write_number(static_cast<std::int64_t>(n));\n        }\n        else\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('H'));  // high-precision number\n            }\n\n            const auto number = BasicJsonType(n).dump();\n            write_number_with_ubjson_prefix(number.size(), true);\n            for (std::size_t i = 0; i < number.size(); ++i)\n            {\n                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));\n            }\n        }\n    }\n\n    // UBJSON: write number (signed integer)\n    template < typename NumberType, typename std::enable_if <\n                   std::is_signed<NumberType>::value&&\n                   !std::is_floating_point<NumberType>::value, int >::type = 0 >\n    void write_number_with_ubjson_prefix(const NumberType n,\n                                         const bool add_prefix)\n    {\n        if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('i'));  // int8\n            }\n            write_number(static_cast<std::int8_t>(n));\n        }\n        else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('U'));  // uint8\n            }\n            write_number(static_cast<std::uint8_t>(n));\n        }\n        else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('I'));  // int16\n            }\n            write_number(static_cast<std::int16_t>(n));\n        }\n        else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('l'));  // int32\n            }\n            write_number(static_cast<std::int32_t>(n));\n        }\n        else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('L'));  // int64\n            }\n            write_number(static_cast<std::int64_t>(n));\n        }\n        // LCOV_EXCL_START\n        else\n        {\n            if (add_prefix)\n            {\n                oa->write_character(to_char_type('H'));  // high-precision number\n            }\n\n            const auto number = BasicJsonType(n).dump();\n            write_number_with_ubjson_prefix(number.size(), true);\n            for (std::size_t i = 0; i < number.size(); ++i)\n            {\n                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));\n            }\n        }\n        // LCOV_EXCL_STOP\n    }\n\n    /*!\n    @brief determine the type prefix of container values\n    */\n    CharType ubjson_prefix(const BasicJsonType& j) const noexcept\n    {\n        switch (j.type())\n        {\n            case value_t::null:\n                return 'Z';\n\n            case value_t::boolean:\n                return j.m_value.boolean ? 'T' : 'F';\n\n            case value_t::number_integer:\n            {\n                if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())\n                {\n                    return 'i';\n                }\n                if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())\n                {\n                    return 'U';\n                }\n                if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())\n                {\n                    return 'I';\n                }\n                if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())\n                {\n                    return 'l';\n                }\n                if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())\n                {\n                    return 'L';\n                }\n                // anything else is treated as high-precision number\n                return 'H'; // LCOV_EXCL_LINE\n            }\n\n            case value_t::number_unsigned:\n            {\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))\n                {\n                    return 'i';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))\n                {\n                    return 'U';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))\n                {\n                    return 'I';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))\n                {\n                    return 'l';\n                }\n                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))\n                {\n                    return 'L';\n                }\n                // anything else is treated as high-precision number\n                return 'H'; // LCOV_EXCL_LINE\n            }\n\n            case value_t::number_float:\n                return get_ubjson_float_prefix(j.m_value.number_float);\n\n            case value_t::string:\n                return 'S';\n\n            case value_t::array: // fallthrough\n            case value_t::binary:\n                return '[';\n\n            case value_t::object:\n                return '{';\n\n            case value_t::discarded:\n            default:  // discarded values\n                return 'N';\n        }\n    }\n\n    static constexpr CharType get_ubjson_float_prefix(float /*unused*/)\n    {\n        return 'd';  // float 32\n    }\n\n    static constexpr CharType get_ubjson_float_prefix(double /*unused*/)\n    {\n        return 'D';  // float 64\n    }\n\n    ///////////////////////\n    // Utility functions //\n    ///////////////////////\n\n    /*\n    @brief write a number to output input\n    @param[in] n number of type @a NumberType\n    @tparam NumberType the type of the number\n    @tparam OutputIsLittleEndian Set to true if output data is\n                                 required to be little endian\n\n    @note This function needs to respect the system's endianness, because bytes\n          in CBOR, MessagePack, and UBJSON are stored in network order (big\n          endian) and therefore need reordering on little endian systems.\n    */\n    template<typename NumberType, bool OutputIsLittleEndian = false>\n    void write_number(const NumberType n)\n    {\n        // step 1: write number to array of length NumberType\n        std::array<CharType, sizeof(NumberType)> vec{};\n        std::memcpy(vec.data(), &n, sizeof(NumberType));\n\n        // step 2: write array to output (with possible reordering)\n        if (is_little_endian != OutputIsLittleEndian)\n        {\n            // reverse byte order prior to conversion if necessary\n            std::reverse(vec.begin(), vec.end());\n        }\n\n        oa->write_characters(vec.data(), sizeof(NumberType));\n    }\n\n    void write_compact_float(const number_float_t n, detail::input_format_t format)\n    {\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n        if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&\n                static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&\n                static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))\n        {\n            oa->write_character(format == detail::input_format_t::cbor\n                                ? get_cbor_float_prefix(static_cast<float>(n))\n                                : get_msgpack_float_prefix(static_cast<float>(n)));\n            write_number(static_cast<float>(n));\n        }\n        else\n        {\n            oa->write_character(format == detail::input_format_t::cbor\n                                ? get_cbor_float_prefix(n)\n                                : get_msgpack_float_prefix(n));\n            write_number(n);\n        }\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n    }\n\n  public:\n    // The following to_char_type functions are implement the conversion\n    // between uint8_t and CharType. In case CharType is not unsigned,\n    // such a conversion is required to allow values greater than 128.\n    // See <https://github.com/nlohmann/json/issues/1286> for a discussion.\n    template < typename C = CharType,\n               enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >\n    static constexpr CharType to_char_type(std::uint8_t x) noexcept\n    {\n        return *reinterpret_cast<char*>(&x);\n    }\n\n    template < typename C = CharType,\n               enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >\n    static CharType to_char_type(std::uint8_t x) noexcept\n    {\n        static_assert(sizeof(std::uint8_t) == sizeof(CharType), \"size of CharType must be equal to std::uint8_t\");\n        static_assert(std::is_trivial<CharType>::value, \"CharType must be trivial\");\n        CharType result;\n        std::memcpy(&result, &x, sizeof(x));\n        return result;\n    }\n\n    template<typename C = CharType,\n             enable_if_t<std::is_unsigned<C>::value>* = nullptr>\n    static constexpr CharType to_char_type(std::uint8_t x) noexcept\n    {\n        return x;\n    }\n\n    template < typename InputCharType, typename C = CharType,\n               enable_if_t <\n                   std::is_signed<C>::value &&\n                   std::is_signed<char>::value &&\n                   std::is_same<char, typename std::remove_cv<InputCharType>::type>::value\n                   > * = nullptr >\n    static constexpr CharType to_char_type(InputCharType x) noexcept\n    {\n        return x;\n    }\n\n  private:\n    /// whether we can assume little endianness\n    const bool is_little_endian = little_endianness();\n\n    /// the output\n    output_adapter_t<CharType> oa = nullptr;\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/output/output_adapters.hpp>\n\n// #include <nlohmann/detail/output/serializer.hpp>\n\n\n#include <algorithm> // reverse, remove, fill, find, none_of\n#include <array> // array\n#include <clocale> // localeconv, lconv\n#include <cmath> // labs, isfinite, isnan, signbit\n#include <cstddef> // size_t, ptrdiff_t\n#include <cstdint> // uint8_t\n#include <cstdio> // snprintf\n#include <limits> // numeric_limits\n#include <string> // string, char_traits\n#include <iomanip> // setfill, setw\n#include <sstream> // stringstream\n#include <type_traits> // is_same\n#include <utility> // move\n\n// #include <nlohmann/detail/conversions/to_chars.hpp>\n\n\n#include <array> // array\n#include <cmath>   // signbit, isfinite\n#include <cstdint> // intN_t, uintN_t\n#include <cstring> // memcpy, memmove\n#include <limits> // numeric_limits\n#include <type_traits> // conditional\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n\n/*!\n@brief implements the Grisu2 algorithm for binary to decimal floating-point\nconversion.\n\nThis implementation is a slightly modified version of the reference\nimplementation which may be obtained from\nhttp://florian.loitsch.com/publications (bench.tar.gz).\n\nThe code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.\n\nFor a detailed description of the algorithm see:\n\n[1] Loitsch, \"Printing Floating-Point Numbers Quickly and Accurately with\n    Integers\", Proceedings of the ACM SIGPLAN 2010 Conference on Programming\n    Language Design and Implementation, PLDI 2010\n[2] Burger, Dybvig, \"Printing Floating-Point Numbers Quickly and Accurately\",\n    Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language\n    Design and Implementation, PLDI 1996\n*/\nnamespace dtoa_impl\n{\n\ntemplate<typename Target, typename Source>\nTarget reinterpret_bits(const Source source)\n{\n    static_assert(sizeof(Target) == sizeof(Source), \"size mismatch\");\n\n    Target target;\n    std::memcpy(&target, &source, sizeof(Source));\n    return target;\n}\n\nstruct diyfp // f * 2^e\n{\n    static constexpr int kPrecision = 64; // = q\n\n    std::uint64_t f = 0;\n    int e = 0;\n\n    constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}\n\n    /*!\n    @brief returns x - y\n    @pre x.e == y.e and x.f >= y.f\n    */\n    static diyfp sub(const diyfp& x, const diyfp& y) noexcept\n    {\n        JSON_ASSERT(x.e == y.e);\n        JSON_ASSERT(x.f >= y.f);\n\n        return {x.f - y.f, x.e};\n    }\n\n    /*!\n    @brief returns x * y\n    @note The result is rounded. (Only the upper q bits are returned.)\n    */\n    static diyfp mul(const diyfp& x, const diyfp& y) noexcept\n    {\n        static_assert(kPrecision == 64, \"internal error\");\n\n        // Computes:\n        //  f = round((x.f * y.f) / 2^q)\n        //  e = x.e + y.e + q\n\n        // Emulate the 64-bit * 64-bit multiplication:\n        //\n        // p = u * v\n        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)\n        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )\n        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )\n        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )\n        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)\n        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )\n        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )\n        //\n        // (Since Q might be larger than 2^32 - 1)\n        //\n        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)\n        //\n        // (Q_hi + H does not overflow a 64-bit int)\n        //\n        //   = p_lo + 2^64 p_hi\n\n        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;\n        const std::uint64_t u_hi = x.f >> 32u;\n        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;\n        const std::uint64_t v_hi = y.f >> 32u;\n\n        const std::uint64_t p0 = u_lo * v_lo;\n        const std::uint64_t p1 = u_lo * v_hi;\n        const std::uint64_t p2 = u_hi * v_lo;\n        const std::uint64_t p3 = u_hi * v_hi;\n\n        const std::uint64_t p0_hi = p0 >> 32u;\n        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;\n        const std::uint64_t p1_hi = p1 >> 32u;\n        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;\n        const std::uint64_t p2_hi = p2 >> 32u;\n\n        std::uint64_t Q = p0_hi + p1_lo + p2_lo;\n\n        // The full product might now be computed as\n        //\n        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)\n        // p_lo = p0_lo + (Q << 32)\n        //\n        // But in this particular case here, the full p_lo is not required.\n        // Effectively we only need to add the highest bit in p_lo to p_hi (and\n        // Q_hi + 1 does not overflow).\n\n        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up\n\n        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);\n\n        return {h, x.e + y.e + 64};\n    }\n\n    /*!\n    @brief normalize x such that the significand is >= 2^(q-1)\n    @pre x.f != 0\n    */\n    static diyfp normalize(diyfp x) noexcept\n    {\n        JSON_ASSERT(x.f != 0);\n\n        while ((x.f >> 63u) == 0)\n        {\n            x.f <<= 1u;\n            x.e--;\n        }\n\n        return x;\n    }\n\n    /*!\n    @brief normalize x such that the result has the exponent E\n    @pre e >= x.e and the upper e - x.e bits of x.f must be zero.\n    */\n    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept\n    {\n        const int delta = x.e - target_exponent;\n\n        JSON_ASSERT(delta >= 0);\n        JSON_ASSERT(((x.f << delta) >> delta) == x.f);\n\n        return {x.f << delta, target_exponent};\n    }\n};\n\nstruct boundaries\n{\n    diyfp w;\n    diyfp minus;\n    diyfp plus;\n};\n\n/*!\nCompute the (normalized) diyfp representing the input number 'value' and its\nboundaries.\n\n@pre value must be finite and positive\n*/\ntemplate<typename FloatType>\nboundaries compute_boundaries(FloatType value)\n{\n    JSON_ASSERT(std::isfinite(value));\n    JSON_ASSERT(value > 0);\n\n    // Convert the IEEE representation into a diyfp.\n    //\n    // If v is denormal:\n    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))\n    // If v is normalized:\n    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))\n\n    static_assert(std::numeric_limits<FloatType>::is_iec559,\n                  \"internal error: dtoa_short requires an IEEE-754 floating-point implementation\");\n\n    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)\n    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);\n    constexpr int      kMinExp    = 1 - kBias;\n    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)\n\n    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;\n\n    const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));\n    const std::uint64_t E = bits >> (kPrecision - 1);\n    const std::uint64_t F = bits & (kHiddenBit - 1);\n\n    const bool is_denormal = E == 0;\n    const diyfp v = is_denormal\n                    ? diyfp(F, kMinExp)\n                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);\n\n    // Compute the boundaries m- and m+ of the floating-point value\n    // v = f * 2^e.\n    //\n    // Determine v- and v+, the floating-point predecessor and successor if v,\n    // respectively.\n    //\n    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)\n    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)\n    //\n    //      v+ = v + 2^e\n    //\n    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_\n    // between m- and m+ round to v, regardless of how the input rounding\n    // algorithm breaks ties.\n    //\n    //      ---+-------------+-------------+-------------+-------------+---  (A)\n    //         v-            m-            v             m+            v+\n    //\n    //      -----------------+------+------+-------------+-------------+---  (B)\n    //                       v-     m-     v             m+            v+\n\n    const bool lower_boundary_is_closer = F == 0 && E > 1;\n    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);\n    const diyfp m_minus = lower_boundary_is_closer\n                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)\n                          : diyfp(2 * v.f - 1, v.e - 1); // (A)\n\n    // Determine the normalized w+ = m+.\n    const diyfp w_plus = diyfp::normalize(m_plus);\n\n    // Determine w- = m- such that e_(w-) = e_(w+).\n    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);\n\n    return {diyfp::normalize(v), w_minus, w_plus};\n}\n\n// Given normalized diyfp w, Grisu needs to find a (normalized) cached\n// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies\n// within a certain range [alpha, gamma] (Definition 3.2 from [1])\n//\n//      alpha <= e = e_c + e_w + q <= gamma\n//\n// or\n//\n//      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q\n//                          <= f_c * f_w * 2^gamma\n//\n// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies\n//\n//      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma\n//\n// or\n//\n//      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)\n//\n// The choice of (alpha,gamma) determines the size of the table and the form of\n// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well\n// in practice:\n//\n// The idea is to cut the number c * w = f * 2^e into two parts, which can be\n// processed independently: An integral part p1, and a fractional part p2:\n//\n//      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e\n//              = (f div 2^-e) + (f mod 2^-e) * 2^e\n//              = p1 + p2 * 2^e\n//\n// The conversion of p1 into decimal form requires a series of divisions and\n// modulos by (a power of) 10. These operations are faster for 32-bit than for\n// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be\n// achieved by choosing\n//\n//      -e >= 32   or   e <= -32 := gamma\n//\n// In order to convert the fractional part\n//\n//      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...\n//\n// into decimal form, the fraction is repeatedly multiplied by 10 and the digits\n// d[-i] are extracted in order:\n//\n//      (10 * p2) div 2^-e = d[-1]\n//      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...\n//\n// The multiplication by 10 must not overflow. It is sufficient to choose\n//\n//      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.\n//\n// Since p2 = f mod 2^-e < 2^-e,\n//\n//      -e <= 60   or   e >= -60 := alpha\n\nconstexpr int kAlpha = -60;\nconstexpr int kGamma = -32;\n\nstruct cached_power // c = f * 2^e ~= 10^k\n{\n    std::uint64_t f;\n    int e;\n    int k;\n};\n\n/*!\nFor a normalized diyfp w = f * 2^e, this function returns a (normalized) cached\npower-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c\nsatisfies (Definition 3.2 from [1])\n\n     alpha <= e_c + e + q <= gamma.\n*/\ninline cached_power get_cached_power_for_binary_exponent(int e)\n{\n    // Now\n    //\n    //      alpha <= e_c + e + q <= gamma                                    (1)\n    //      ==> f_c * 2^alpha <= c * 2^e * 2^q\n    //\n    // and since the c's are normalized, 2^(q-1) <= f_c,\n    //\n    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)\n    //      ==> 2^(alpha - e - 1) <= c\n    //\n    // If c were an exact power of ten, i.e. c = 10^k, one may determine k as\n    //\n    //      k = ceil( log_10( 2^(alpha - e - 1) ) )\n    //        = ceil( (alpha - e - 1) * log_10(2) )\n    //\n    // From the paper:\n    // \"In theory the result of the procedure could be wrong since c is rounded,\n    //  and the computation itself is approximated [...]. In practice, however,\n    //  this simple function is sufficient.\"\n    //\n    // For IEEE double precision floating-point numbers converted into\n    // normalized diyfp's w = f * 2^e, with q = 64,\n    //\n    //      e >= -1022      (min IEEE exponent)\n    //           -52        (p - 1)\n    //           -52        (p - 1, possibly normalize denormal IEEE numbers)\n    //           -11        (normalize the diyfp)\n    //         = -1137\n    //\n    // and\n    //\n    //      e <= +1023      (max IEEE exponent)\n    //           -52        (p - 1)\n    //           -11        (normalize the diyfp)\n    //         = 960\n    //\n    // This binary exponent range [-1137,960] results in a decimal exponent\n    // range [-307,324]. One does not need to store a cached power for each\n    // k in this range. For each such k it suffices to find a cached power\n    // such that the exponent of the product lies in [alpha,gamma].\n    // This implies that the difference of the decimal exponents of adjacent\n    // table entries must be less than or equal to\n    //\n    //      floor( (gamma - alpha) * log_10(2) ) = 8.\n    //\n    // (A smaller distance gamma-alpha would require a larger table.)\n\n    // NB:\n    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.\n\n    constexpr int kCachedPowersMinDecExp = -300;\n    constexpr int kCachedPowersDecStep = 8;\n\n    static constexpr std::array<cached_power, 79> kCachedPowers =\n    {\n        {\n            { 0xAB70FE17C79AC6CA, -1060, -300 },\n            { 0xFF77B1FCBEBCDC4F, -1034, -292 },\n            { 0xBE5691EF416BD60C, -1007, -284 },\n            { 0x8DD01FAD907FFC3C,  -980, -276 },\n            { 0xD3515C2831559A83,  -954, -268 },\n            { 0x9D71AC8FADA6C9B5,  -927, -260 },\n            { 0xEA9C227723EE8BCB,  -901, -252 },\n            { 0xAECC49914078536D,  -874, -244 },\n            { 0x823C12795DB6CE57,  -847, -236 },\n            { 0xC21094364DFB5637,  -821, -228 },\n            { 0x9096EA6F3848984F,  -794, -220 },\n            { 0xD77485CB25823AC7,  -768, -212 },\n            { 0xA086CFCD97BF97F4,  -741, -204 },\n            { 0xEF340A98172AACE5,  -715, -196 },\n            { 0xB23867FB2A35B28E,  -688, -188 },\n            { 0x84C8D4DFD2C63F3B,  -661, -180 },\n            { 0xC5DD44271AD3CDBA,  -635, -172 },\n            { 0x936B9FCEBB25C996,  -608, -164 },\n            { 0xDBAC6C247D62A584,  -582, -156 },\n            { 0xA3AB66580D5FDAF6,  -555, -148 },\n            { 0xF3E2F893DEC3F126,  -529, -140 },\n            { 0xB5B5ADA8AAFF80B8,  -502, -132 },\n            { 0x87625F056C7C4A8B,  -475, -124 },\n            { 0xC9BCFF6034C13053,  -449, -116 },\n            { 0x964E858C91BA2655,  -422, -108 },\n            { 0xDFF9772470297EBD,  -396, -100 },\n            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },\n            { 0xF8A95FCF88747D94,  -343,  -84 },\n            { 0xB94470938FA89BCF,  -316,  -76 },\n            { 0x8A08F0F8BF0F156B,  -289,  -68 },\n            { 0xCDB02555653131B6,  -263,  -60 },\n            { 0x993FE2C6D07B7FAC,  -236,  -52 },\n            { 0xE45C10C42A2B3B06,  -210,  -44 },\n            { 0xAA242499697392D3,  -183,  -36 },\n            { 0xFD87B5F28300CA0E,  -157,  -28 },\n            { 0xBCE5086492111AEB,  -130,  -20 },\n            { 0x8CBCCC096F5088CC,  -103,  -12 },\n            { 0xD1B71758E219652C,   -77,   -4 },\n            { 0x9C40000000000000,   -50,    4 },\n            { 0xE8D4A51000000000,   -24,   12 },\n            { 0xAD78EBC5AC620000,     3,   20 },\n            { 0x813F3978F8940984,    30,   28 },\n            { 0xC097CE7BC90715B3,    56,   36 },\n            { 0x8F7E32CE7BEA5C70,    83,   44 },\n            { 0xD5D238A4ABE98068,   109,   52 },\n            { 0x9F4F2726179A2245,   136,   60 },\n            { 0xED63A231D4C4FB27,   162,   68 },\n            { 0xB0DE65388CC8ADA8,   189,   76 },\n            { 0x83C7088E1AAB65DB,   216,   84 },\n            { 0xC45D1DF942711D9A,   242,   92 },\n            { 0x924D692CA61BE758,   269,  100 },\n            { 0xDA01EE641A708DEA,   295,  108 },\n            { 0xA26DA3999AEF774A,   322,  116 },\n            { 0xF209787BB47D6B85,   348,  124 },\n            { 0xB454E4A179DD1877,   375,  132 },\n            { 0x865B86925B9BC5C2,   402,  140 },\n            { 0xC83553C5C8965D3D,   428,  148 },\n            { 0x952AB45CFA97A0B3,   455,  156 },\n            { 0xDE469FBD99A05FE3,   481,  164 },\n            { 0xA59BC234DB398C25,   508,  172 },\n            { 0xF6C69A72A3989F5C,   534,  180 },\n            { 0xB7DCBF5354E9BECE,   561,  188 },\n            { 0x88FCF317F22241E2,   588,  196 },\n            { 0xCC20CE9BD35C78A5,   614,  204 },\n            { 0x98165AF37B2153DF,   641,  212 },\n            { 0xE2A0B5DC971F303A,   667,  220 },\n            { 0xA8D9D1535CE3B396,   694,  228 },\n            { 0xFB9B7CD9A4A7443C,   720,  236 },\n            { 0xBB764C4CA7A44410,   747,  244 },\n            { 0x8BAB8EEFB6409C1A,   774,  252 },\n            { 0xD01FEF10A657842C,   800,  260 },\n            { 0x9B10A4E5E9913129,   827,  268 },\n            { 0xE7109BFBA19C0C9D,   853,  276 },\n            { 0xAC2820D9623BF429,   880,  284 },\n            { 0x80444B5E7AA7CF85,   907,  292 },\n            { 0xBF21E44003ACDD2D,   933,  300 },\n            { 0x8E679C2F5E44FF8F,   960,  308 },\n            { 0xD433179D9C8CB841,   986,  316 },\n            { 0x9E19DB92B4E31BA9,  1013,  324 },\n        }\n    };\n\n    // This computation gives exactly the same results for k as\n    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)\n    // for |e| <= 1500, but doesn't require floating-point operations.\n    // NB: log_10(2) ~= 78913 / 2^18\n    JSON_ASSERT(e >= -1500);\n    JSON_ASSERT(e <=  1500);\n    const int f = kAlpha - e - 1;\n    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);\n\n    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;\n    JSON_ASSERT(index >= 0);\n    JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());\n\n    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];\n    JSON_ASSERT(kAlpha <= cached.e + e + 64);\n    JSON_ASSERT(kGamma >= cached.e + e + 64);\n\n    return cached;\n}\n\n/*!\nFor n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.\nFor n == 0, returns 1 and sets pow10 := 1.\n*/\ninline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)\n{\n    // LCOV_EXCL_START\n    if (n >= 1000000000)\n    {\n        pow10 = 1000000000;\n        return 10;\n    }\n    // LCOV_EXCL_STOP\n    if (n >= 100000000)\n    {\n        pow10 = 100000000;\n        return  9;\n    }\n    if (n >= 10000000)\n    {\n        pow10 = 10000000;\n        return  8;\n    }\n    if (n >= 1000000)\n    {\n        pow10 = 1000000;\n        return  7;\n    }\n    if (n >= 100000)\n    {\n        pow10 = 100000;\n        return  6;\n    }\n    if (n >= 10000)\n    {\n        pow10 = 10000;\n        return  5;\n    }\n    if (n >= 1000)\n    {\n        pow10 = 1000;\n        return  4;\n    }\n    if (n >= 100)\n    {\n        pow10 = 100;\n        return  3;\n    }\n    if (n >= 10)\n    {\n        pow10 = 10;\n        return  2;\n    }\n\n    pow10 = 1;\n    return 1;\n}\n\ninline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,\n                         std::uint64_t rest, std::uint64_t ten_k)\n{\n    JSON_ASSERT(len >= 1);\n    JSON_ASSERT(dist <= delta);\n    JSON_ASSERT(rest <= delta);\n    JSON_ASSERT(ten_k > 0);\n\n    //               <--------------------------- delta ---->\n    //                                  <---- dist --------->\n    // --------------[------------------+-------------------]--------------\n    //               M-                 w                   M+\n    //\n    //                                  ten_k\n    //                                <------>\n    //                                       <---- rest ---->\n    // --------------[------------------+----+--------------]--------------\n    //                                  w    V\n    //                                       = buf * 10^k\n    //\n    // ten_k represents a unit-in-the-last-place in the decimal representation\n    // stored in buf.\n    // Decrement buf by ten_k while this takes buf closer to w.\n\n    // The tests are written in this order to avoid overflow in unsigned\n    // integer arithmetic.\n\n    while (rest < dist\n            && delta - rest >= ten_k\n            && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))\n    {\n        JSON_ASSERT(buf[len - 1] != '0');\n        buf[len - 1]--;\n        rest += ten_k;\n    }\n}\n\n/*!\nGenerates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.\nM- and M+ must be normalized and share the same exponent -60 <= e <= -32.\n*/\ninline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,\n                             diyfp M_minus, diyfp w, diyfp M_plus)\n{\n    static_assert(kAlpha >= -60, \"internal error\");\n    static_assert(kGamma <= -32, \"internal error\");\n\n    // Generates the digits (and the exponent) of a decimal floating-point\n    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's\n    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.\n    //\n    //               <--------------------------- delta ---->\n    //                                  <---- dist --------->\n    // --------------[------------------+-------------------]--------------\n    //               M-                 w                   M+\n    //\n    // Grisu2 generates the digits of M+ from left to right and stops as soon as\n    // V is in [M-,M+].\n\n    JSON_ASSERT(M_plus.e >= kAlpha);\n    JSON_ASSERT(M_plus.e <= kGamma);\n\n    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)\n    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)\n\n    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):\n    //\n    //      M+ = f * 2^e\n    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e\n    //         = ((p1        ) * 2^-e + (p2        )) * 2^e\n    //         = p1 + p2 * 2^e\n\n    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);\n\n    auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)\n    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e\n\n    // 1)\n    //\n    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]\n\n    JSON_ASSERT(p1 > 0);\n\n    std::uint32_t pow10{};\n    const int k = find_largest_pow10(p1, pow10);\n\n    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)\n    //\n    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))\n    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))\n    //\n    //      M+ = p1                                             + p2 * 2^e\n    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e\n    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e\n    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e\n    //\n    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)\n    //\n    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]\n    //\n    // but stop as soon as\n    //\n    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e\n\n    int n = k;\n    while (n > 0)\n    {\n        // Invariants:\n        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)\n        //      pow10 = 10^(n-1) <= p1 < 10^n\n        //\n        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)\n        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)\n        //\n        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e\n        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)\n        //\n        JSON_ASSERT(d <= 9);\n        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d\n        //\n        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)\n        //\n        p1 = r;\n        n--;\n        //\n        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)\n        //      pow10 = 10^n\n        //\n\n        // Now check if enough digits have been generated.\n        // Compute\n        //\n        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e\n        //\n        // Note:\n        // Since rest and delta share the same exponent e, it suffices to\n        // compare the significands.\n        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;\n        if (rest <= delta)\n        {\n            // V = buffer * 10^n, with M- <= V <= M+.\n\n            decimal_exponent += n;\n\n            // We may now just stop. But instead look if the buffer could be\n            // decremented to bring V closer to w.\n            //\n            // pow10 = 10^n is now 1 ulp in the decimal representation V.\n            // The rounding procedure works with diyfp's with an implicit\n            // exponent of e.\n            //\n            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e\n            //\n            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;\n            grisu2_round(buffer, length, dist, delta, rest, ten_n);\n\n            return;\n        }\n\n        pow10 /= 10;\n        //\n        //      pow10 = 10^(n-1) <= p1 < 10^n\n        // Invariants restored.\n    }\n\n    // 2)\n    //\n    // The digits of the integral part have been generated:\n    //\n    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e\n    //         = buffer            + p2 * 2^e\n    //\n    // Now generate the digits of the fractional part p2 * 2^e.\n    //\n    // Note:\n    // No decimal point is generated: the exponent is adjusted instead.\n    //\n    // p2 actually represents the fraction\n    //\n    //      p2 * 2^e\n    //          = p2 / 2^-e\n    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...\n    //\n    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)\n    //\n    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m\n    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)\n    //\n    // using\n    //\n    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)\n    //                = (                   d) * 2^-e + (                   r)\n    //\n    // or\n    //      10^m * p2 * 2^e = d + r * 2^e\n    //\n    // i.e.\n    //\n    //      M+ = buffer + p2 * 2^e\n    //         = buffer + 10^-m * (d + r * 2^e)\n    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e\n    //\n    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e\n\n    JSON_ASSERT(p2 > delta);\n\n    int m = 0;\n    for (;;)\n    {\n        // Invariant:\n        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e\n        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e\n        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e\n        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e\n        //\n        JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);\n        p2 *= 10;\n        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e\n        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e\n        //\n        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e\n        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))\n        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e\n        //\n        JSON_ASSERT(d <= 9);\n        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d\n        //\n        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e\n        //\n        p2 = r;\n        m++;\n        //\n        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e\n        // Invariant restored.\n\n        // Check if enough digits have been generated.\n        //\n        //      10^-m * p2 * 2^e <= delta * 2^e\n        //              p2 * 2^e <= 10^m * delta * 2^e\n        //                    p2 <= 10^m * delta\n        delta *= 10;\n        dist  *= 10;\n        if (p2 <= delta)\n        {\n            break;\n        }\n    }\n\n    // V = buffer * 10^-m, with M- <= V <= M+.\n\n    decimal_exponent -= m;\n\n    // 1 ulp in the decimal representation is now 10^-m.\n    // Since delta and dist are now scaled by 10^m, we need to do the\n    // same with ulp in order to keep the units in sync.\n    //\n    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e\n    //\n    const std::uint64_t ten_m = one.f;\n    grisu2_round(buffer, length, dist, delta, p2, ten_m);\n\n    // By construction this algorithm generates the shortest possible decimal\n    // number (Loitsch, Theorem 6.2) which rounds back to w.\n    // For an input number of precision p, at least\n    //\n    //      N = 1 + ceil(p * log_10(2))\n    //\n    // decimal digits are sufficient to identify all binary floating-point\n    // numbers (Matula, \"In-and-Out conversions\").\n    // This implies that the algorithm does not produce more than N decimal\n    // digits.\n    //\n    //      N = 17 for p = 53 (IEEE double precision)\n    //      N = 9  for p = 24 (IEEE single precision)\n}\n\n/*!\nv = buf * 10^decimal_exponent\nlen is the length of the buffer (number of decimal digits)\nThe buffer must be large enough, i.e. >= max_digits10.\n*/\nJSON_HEDLEY_NON_NULL(1)\ninline void grisu2(char* buf, int& len, int& decimal_exponent,\n                   diyfp m_minus, diyfp v, diyfp m_plus)\n{\n    JSON_ASSERT(m_plus.e == m_minus.e);\n    JSON_ASSERT(m_plus.e == v.e);\n\n    //  --------(-----------------------+-----------------------)--------    (A)\n    //          m-                      v                       m+\n    //\n    //  --------------------(-----------+-----------------------)--------    (B)\n    //                      m-          v                       m+\n    //\n    // First scale v (and m- and m+) such that the exponent is in the range\n    // [alpha, gamma].\n\n    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);\n\n    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k\n\n    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]\n    const diyfp w       = diyfp::mul(v,       c_minus_k);\n    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);\n    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);\n\n    //  ----(---+---)---------------(---+---)---------------(---+---)----\n    //          w-                      w                       w+\n    //          = c*m-                  = c*v                   = c*m+\n    //\n    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and\n    // w+ are now off by a small amount.\n    // In fact:\n    //\n    //      w - v * 10^k < 1 ulp\n    //\n    // To account for this inaccuracy, add resp. subtract 1 ulp.\n    //\n    //  --------+---[---------------(---+---)---------------]---+--------\n    //          w-  M-                  w                   M+  w+\n    //\n    // Now any number in [M-, M+] (bounds included) will round to w when input,\n    // regardless of how the input rounding algorithm breaks ties.\n    //\n    // And digit_gen generates the shortest possible such number in [M-, M+].\n    // Note that this does not mean that Grisu2 always generates the shortest\n    // possible number in the interval (m-, m+).\n    const diyfp M_minus(w_minus.f + 1, w_minus.e);\n    const diyfp M_plus (w_plus.f  - 1, w_plus.e );\n\n    decimal_exponent = -cached.k; // = -(-k) = k\n\n    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);\n}\n\n/*!\nv = buf * 10^decimal_exponent\nlen is the length of the buffer (number of decimal digits)\nThe buffer must be large enough, i.e. >= max_digits10.\n*/\ntemplate<typename FloatType>\nJSON_HEDLEY_NON_NULL(1)\nvoid grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)\n{\n    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,\n                  \"internal error: not enough precision\");\n\n    JSON_ASSERT(std::isfinite(value));\n    JSON_ASSERT(value > 0);\n\n    // If the neighbors (and boundaries) of 'value' are always computed for double-precision\n    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting\n    // decimal representations are not exactly \"short\".\n    //\n    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)\n    // says \"value is converted to a string as if by std::sprintf in the default (\"C\") locale\"\n    // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'\n    // does.\n    // On the other hand, the documentation for 'std::to_chars' requires that \"parsing the\n    // representation using the corresponding std::from_chars function recovers value exactly\". That\n    // indicates that single precision floating-point numbers should be recovered using\n    // 'std::strtof'.\n    //\n    // NB: If the neighbors are computed for single-precision numbers, there is a single float\n    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision\n    //     value is off by 1 ulp.\n#if 0\n    const boundaries w = compute_boundaries(static_cast<double>(value));\n#else\n    const boundaries w = compute_boundaries(value);\n#endif\n\n    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);\n}\n\n/*!\n@brief appends a decimal representation of e to buf\n@return a pointer to the element following the exponent.\n@pre -1000 < e < 1000\n*/\nJSON_HEDLEY_NON_NULL(1)\nJSON_HEDLEY_RETURNS_NON_NULL\ninline char* append_exponent(char* buf, int e)\n{\n    JSON_ASSERT(e > -1000);\n    JSON_ASSERT(e <  1000);\n\n    if (e < 0)\n    {\n        e = -e;\n        *buf++ = '-';\n    }\n    else\n    {\n        *buf++ = '+';\n    }\n\n    auto k = static_cast<std::uint32_t>(e);\n    if (k < 10)\n    {\n        // Always print at least two digits in the exponent.\n        // This is for compatibility with printf(\"%g\").\n        *buf++ = '0';\n        *buf++ = static_cast<char>('0' + k);\n    }\n    else if (k < 100)\n    {\n        *buf++ = static_cast<char>('0' + k / 10);\n        k %= 10;\n        *buf++ = static_cast<char>('0' + k);\n    }\n    else\n    {\n        *buf++ = static_cast<char>('0' + k / 100);\n        k %= 100;\n        *buf++ = static_cast<char>('0' + k / 10);\n        k %= 10;\n        *buf++ = static_cast<char>('0' + k);\n    }\n\n    return buf;\n}\n\n/*!\n@brief prettify v = buf * 10^decimal_exponent\n\nIf v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point\nnotation. Otherwise it will be printed in exponential notation.\n\n@pre min_exp < 0\n@pre max_exp > 0\n*/\nJSON_HEDLEY_NON_NULL(1)\nJSON_HEDLEY_RETURNS_NON_NULL\ninline char* format_buffer(char* buf, int len, int decimal_exponent,\n                           int min_exp, int max_exp)\n{\n    JSON_ASSERT(min_exp < 0);\n    JSON_ASSERT(max_exp > 0);\n\n    const int k = len;\n    const int n = len + decimal_exponent;\n\n    // v = buf * 10^(n-k)\n    // k is the length of the buffer (number of decimal digits)\n    // n is the position of the decimal point relative to the start of the buffer.\n\n    if (k <= n && n <= max_exp)\n    {\n        // digits[000]\n        // len <= max_exp + 2\n\n        std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));\n        // Make it look like a floating-point number (#362, #378)\n        buf[n + 0] = '.';\n        buf[n + 1] = '0';\n        return buf + (static_cast<size_t>(n) + 2);\n    }\n\n    if (0 < n && n <= max_exp)\n    {\n        // dig.its\n        // len <= max_digits10 + 1\n\n        JSON_ASSERT(k > n);\n\n        std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));\n        buf[n] = '.';\n        return buf + (static_cast<size_t>(k) + 1U);\n    }\n\n    if (min_exp < n && n <= 0)\n    {\n        // 0.[000]digits\n        // len <= 2 + (-min_exp - 1) + max_digits10\n\n        std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));\n        buf[0] = '0';\n        buf[1] = '.';\n        std::memset(buf + 2, '0', static_cast<size_t>(-n));\n        return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));\n    }\n\n    if (k == 1)\n    {\n        // dE+123\n        // len <= 1 + 5\n\n        buf += 1;\n    }\n    else\n    {\n        // d.igitsE+123\n        // len <= max_digits10 + 1 + 5\n\n        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);\n        buf[1] = '.';\n        buf += 1 + static_cast<size_t>(k);\n    }\n\n    *buf++ = 'e';\n    return append_exponent(buf, n - 1);\n}\n\n} // namespace dtoa_impl\n\n/*!\n@brief generates a decimal representation of the floating-point number value in [first, last).\n\nThe format of the resulting decimal representation is similar to printf's %g\nformat. Returns an iterator pointing past-the-end of the decimal representation.\n\n@note The input number must be finite, i.e. NaN's and Inf's are not supported.\n@note The buffer must be large enough.\n@note The result is NOT null-terminated.\n*/\ntemplate<typename FloatType>\nJSON_HEDLEY_NON_NULL(1, 2)\nJSON_HEDLEY_RETURNS_NON_NULL\nchar* to_chars(char* first, const char* last, FloatType value)\n{\n    static_cast<void>(last); // maybe unused - fix warning\n    JSON_ASSERT(std::isfinite(value));\n\n    // Use signbit(value) instead of (value < 0) since signbit works for -0.\n    if (std::signbit(value))\n    {\n        value = -value;\n        *first++ = '-';\n    }\n\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n    if (value == 0) // +-0\n    {\n        *first++ = '0';\n        // Make it look like a floating-point number (#362, #378)\n        *first++ = '.';\n        *first++ = '0';\n        return first;\n    }\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n\n    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);\n\n    // Compute v = buffer * 10^decimal_exponent.\n    // The decimal digits are stored in the buffer, which needs to be interpreted\n    // as an unsigned decimal integer.\n    // len is the length of the buffer, i.e. the number of decimal digits.\n    int len = 0;\n    int decimal_exponent = 0;\n    dtoa_impl::grisu2(first, len, decimal_exponent, value);\n\n    JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);\n\n    // Format the buffer like printf(\"%.*g\", prec, value)\n    constexpr int kMinExp = -4;\n    // Use digits10 here to increase compatibility with version 2.\n    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;\n\n    JSON_ASSERT(last - first >= kMaxExp + 2);\n    JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);\n    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);\n\n    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);\n}\n\n} // namespace detail\n} // namespace nlohmann\n\n// #include <nlohmann/detail/exceptions.hpp>\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n// #include <nlohmann/detail/meta/cpp_future.hpp>\n\n// #include <nlohmann/detail/output/binary_writer.hpp>\n\n// #include <nlohmann/detail/output/output_adapters.hpp>\n\n// #include <nlohmann/detail/value_t.hpp>\n\n\nnamespace nlohmann\n{\nnamespace detail\n{\n///////////////////\n// serialization //\n///////////////////\n\n/// how to treat decoding errors\nenum class error_handler_t\n{\n    strict,  ///< throw a type_error exception in case of invalid UTF-8\n    replace, ///< replace invalid UTF-8 sequences with U+FFFD\n    ignore   ///< ignore invalid UTF-8 sequences\n};\n\ntemplate<typename BasicJsonType>\nclass serializer\n{\n    using string_t = typename BasicJsonType::string_t;\n    using number_float_t = typename BasicJsonType::number_float_t;\n    using number_integer_t = typename BasicJsonType::number_integer_t;\n    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n    using binary_char_t = typename BasicJsonType::binary_t::value_type;\n    static constexpr std::uint8_t UTF8_ACCEPT = 0;\n    static constexpr std::uint8_t UTF8_REJECT = 1;\n\n  public:\n    /*!\n    @param[in] s  output stream to serialize to\n    @param[in] ichar  indentation character to use\n    @param[in] error_handler_  how to react on decoding errors\n    */\n    serializer(output_adapter_t<char> s, const char ichar,\n               error_handler_t error_handler_ = error_handler_t::strict)\n        : o(std::move(s))\n        , loc(std::localeconv())\n        , thousands_sep(loc->thousands_sep == nullptr ? '\\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))\n        , decimal_point(loc->decimal_point == nullptr ? '\\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))\n        , indent_char(ichar)\n        , indent_string(512, indent_char)\n        , error_handler(error_handler_)\n    {}\n\n    // delete because of pointer members\n    serializer(const serializer&) = delete;\n    serializer& operator=(const serializer&) = delete;\n    serializer(serializer&&) = delete;\n    serializer& operator=(serializer&&) = delete;\n    ~serializer() = default;\n\n    /*!\n    @brief internal implementation of the serialization function\n\n    This function is called by the public member function dump and organizes\n    the serialization internally. The indentation level is propagated as\n    additional parameter. In case of arrays and objects, the function is\n    called recursively.\n\n    - strings and object keys are escaped using `escape_string()`\n    - integer numbers are converted implicitly via `operator<<`\n    - floating-point numbers are converted to a string using `\"%g\"` format\n    - binary values are serialized as objects containing the subtype and the\n      byte array\n\n    @param[in] val               value to serialize\n    @param[in] pretty_print      whether the output shall be pretty-printed\n    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters\n    in the output are escaped with `\\uXXXX` sequences, and the result consists\n    of ASCII characters only.\n    @param[in] indent_step       the indent level\n    @param[in] current_indent    the current indent level (only used internally)\n    */\n    void dump(const BasicJsonType& val,\n              const bool pretty_print,\n              const bool ensure_ascii,\n              const unsigned int indent_step,\n              const unsigned int current_indent = 0)\n    {\n        switch (val.m_type)\n        {\n            case value_t::object:\n            {\n                if (val.m_value.object->empty())\n                {\n                    o->write_characters(\"{}\", 2);\n                    return;\n                }\n\n                if (pretty_print)\n                {\n                    o->write_characters(\"{\\n\", 2);\n\n                    // variable to hold indentation for recursive calls\n                    const auto new_indent = current_indent + indent_step;\n                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))\n                    {\n                        indent_string.resize(indent_string.size() * 2, ' ');\n                    }\n\n                    // first n-1 elements\n                    auto i = val.m_value.object->cbegin();\n                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)\n                    {\n                        o->write_characters(indent_string.c_str(), new_indent);\n                        o->write_character('\\\"');\n                        dump_escaped(i->first, ensure_ascii);\n                        o->write_characters(\"\\\": \", 3);\n                        dump(i->second, true, ensure_ascii, indent_step, new_indent);\n                        o->write_characters(\",\\n\", 2);\n                    }\n\n                    // last element\n                    JSON_ASSERT(i != val.m_value.object->cend());\n                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());\n                    o->write_characters(indent_string.c_str(), new_indent);\n                    o->write_character('\\\"');\n                    dump_escaped(i->first, ensure_ascii);\n                    o->write_characters(\"\\\": \", 3);\n                    dump(i->second, true, ensure_ascii, indent_step, new_indent);\n\n                    o->write_character('\\n');\n                    o->write_characters(indent_string.c_str(), current_indent);\n                    o->write_character('}');\n                }\n                else\n                {\n                    o->write_character('{');\n\n                    // first n-1 elements\n                    auto i = val.m_value.object->cbegin();\n                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)\n                    {\n                        o->write_character('\\\"');\n                        dump_escaped(i->first, ensure_ascii);\n                        o->write_characters(\"\\\":\", 2);\n                        dump(i->second, false, ensure_ascii, indent_step, current_indent);\n                        o->write_character(',');\n                    }\n\n                    // last element\n                    JSON_ASSERT(i != val.m_value.object->cend());\n                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());\n                    o->write_character('\\\"');\n                    dump_escaped(i->first, ensure_ascii);\n                    o->write_characters(\"\\\":\", 2);\n                    dump(i->second, false, ensure_ascii, indent_step, current_indent);\n\n                    o->write_character('}');\n                }\n\n                return;\n            }\n\n            case value_t::array:\n            {\n                if (val.m_value.array->empty())\n                {\n                    o->write_characters(\"[]\", 2);\n                    return;\n                }\n\n                if (pretty_print)\n                {\n                    o->write_characters(\"[\\n\", 2);\n\n                    // variable to hold indentation for recursive calls\n                    const auto new_indent = current_indent + indent_step;\n                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))\n                    {\n                        indent_string.resize(indent_string.size() * 2, ' ');\n                    }\n\n                    // first n-1 elements\n                    for (auto i = val.m_value.array->cbegin();\n                            i != val.m_value.array->cend() - 1; ++i)\n                    {\n                        o->write_characters(indent_string.c_str(), new_indent);\n                        dump(*i, true, ensure_ascii, indent_step, new_indent);\n                        o->write_characters(\",\\n\", 2);\n                    }\n\n                    // last element\n                    JSON_ASSERT(!val.m_value.array->empty());\n                    o->write_characters(indent_string.c_str(), new_indent);\n                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);\n\n                    o->write_character('\\n');\n                    o->write_characters(indent_string.c_str(), current_indent);\n                    o->write_character(']');\n                }\n                else\n                {\n                    o->write_character('[');\n\n                    // first n-1 elements\n                    for (auto i = val.m_value.array->cbegin();\n                            i != val.m_value.array->cend() - 1; ++i)\n                    {\n                        dump(*i, false, ensure_ascii, indent_step, current_indent);\n                        o->write_character(',');\n                    }\n\n                    // last element\n                    JSON_ASSERT(!val.m_value.array->empty());\n                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);\n\n                    o->write_character(']');\n                }\n\n                return;\n            }\n\n            case value_t::string:\n            {\n                o->write_character('\\\"');\n                dump_escaped(*val.m_value.string, ensure_ascii);\n                o->write_character('\\\"');\n                return;\n            }\n\n            case value_t::binary:\n            {\n                if (pretty_print)\n                {\n                    o->write_characters(\"{\\n\", 2);\n\n                    // variable to hold indentation for recursive calls\n                    const auto new_indent = current_indent + indent_step;\n                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))\n                    {\n                        indent_string.resize(indent_string.size() * 2, ' ');\n                    }\n\n                    o->write_characters(indent_string.c_str(), new_indent);\n\n                    o->write_characters(\"\\\"bytes\\\": [\", 10);\n\n                    if (!val.m_value.binary->empty())\n                    {\n                        for (auto i = val.m_value.binary->cbegin();\n                                i != val.m_value.binary->cend() - 1; ++i)\n                        {\n                            dump_integer(*i);\n                            o->write_characters(\", \", 2);\n                        }\n                        dump_integer(val.m_value.binary->back());\n                    }\n\n                    o->write_characters(\"],\\n\", 3);\n                    o->write_characters(indent_string.c_str(), new_indent);\n\n                    o->write_characters(\"\\\"subtype\\\": \", 11);\n                    if (val.m_value.binary->has_subtype())\n                    {\n                        dump_integer(val.m_value.binary->subtype());\n                    }\n                    else\n                    {\n                        o->write_characters(\"null\", 4);\n                    }\n                    o->write_character('\\n');\n                    o->write_characters(indent_string.c_str(), current_indent);\n                    o->write_character('}');\n                }\n                else\n                {\n                    o->write_characters(\"{\\\"bytes\\\":[\", 10);\n\n                    if (!val.m_value.binary->empty())\n                    {\n                        for (auto i = val.m_value.binary->cbegin();\n                                i != val.m_value.binary->cend() - 1; ++i)\n                        {\n                            dump_integer(*i);\n                            o->write_character(',');\n                        }\n                        dump_integer(val.m_value.binary->back());\n                    }\n\n                    o->write_characters(\"],\\\"subtype\\\":\", 12);\n                    if (val.m_value.binary->has_subtype())\n                    {\n                        dump_integer(val.m_value.binary->subtype());\n                        o->write_character('}');\n                    }\n                    else\n                    {\n                        o->write_characters(\"null}\", 5);\n                    }\n                }\n                return;\n            }\n\n            case value_t::boolean:\n            {\n                if (val.m_value.boolean)\n                {\n                    o->write_characters(\"true\", 4);\n                }\n                else\n                {\n                    o->write_characters(\"false\", 5);\n                }\n                return;\n            }\n\n            case value_t::number_integer:\n            {\n                dump_integer(val.m_value.number_integer);\n                return;\n            }\n\n            case value_t::number_unsigned:\n            {\n                dump_integer(val.m_value.number_unsigned);\n                return;\n            }\n\n            case value_t::number_float:\n            {\n                dump_float(val.m_value.number_float);\n                return;\n            }\n\n            case value_t::discarded:\n            {\n                o->write_characters(\"<discarded>\", 11);\n                return;\n            }\n\n            case value_t::null:\n            {\n                o->write_characters(\"null\", 4);\n                return;\n            }\n\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n    }\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /*!\n    @brief dump escaped string\n\n    Escape a string by replacing certain special characters by a sequence of an\n    escape character (backslash) and another character and other control\n    characters by a sequence of \"\\u\" followed by a four-digit hex\n    representation. The escaped string is written to output stream @a o.\n\n    @param[in] s  the string to escape\n    @param[in] ensure_ascii  whether to escape non-ASCII characters with\n                             \\uXXXX sequences\n\n    @complexity Linear in the length of string @a s.\n    */\n    void dump_escaped(const string_t& s, const bool ensure_ascii)\n    {\n        std::uint32_t codepoint{};\n        std::uint8_t state = UTF8_ACCEPT;\n        std::size_t bytes = 0;  // number of bytes written to string_buffer\n\n        // number of bytes written at the point of the last valid byte\n        std::size_t bytes_after_last_accept = 0;\n        std::size_t undumped_chars = 0;\n\n        for (std::size_t i = 0; i < s.size(); ++i)\n        {\n            const auto byte = static_cast<std::uint8_t>(s[i]);\n\n            switch (decode(state, codepoint, byte))\n            {\n                case UTF8_ACCEPT:  // decode found a new code point\n                {\n                    switch (codepoint)\n                    {\n                        case 0x08: // backspace\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'b';\n                            break;\n                        }\n\n                        case 0x09: // horizontal tab\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 't';\n                            break;\n                        }\n\n                        case 0x0A: // newline\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'n';\n                            break;\n                        }\n\n                        case 0x0C: // formfeed\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'f';\n                            break;\n                        }\n\n                        case 0x0D: // carriage return\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = 'r';\n                            break;\n                        }\n\n                        case 0x22: // quotation mark\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = '\\\"';\n                            break;\n                        }\n\n                        case 0x5C: // reverse solidus\n                        {\n                            string_buffer[bytes++] = '\\\\';\n                            string_buffer[bytes++] = '\\\\';\n                            break;\n                        }\n\n                        default:\n                        {\n                            // escape control characters (0x00..0x1F) or, if\n                            // ensure_ascii parameter is used, non-ASCII characters\n                            if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))\n                            {\n                                if (codepoint <= 0xFFFF)\n                                {\n                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                                    static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, \"\\\\u%04x\",\n                                                                      static_cast<std::uint16_t>(codepoint)));\n                                    bytes += 6;\n                                }\n                                else\n                                {\n                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n                                    static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, \"\\\\u%04x\\\\u%04x\",\n                                                                      static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),\n                                                                      static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));\n                                    bytes += 12;\n                                }\n                            }\n                            else\n                            {\n                                // copy byte to buffer (all previous bytes\n                                // been copied have in default case above)\n                                string_buffer[bytes++] = s[i];\n                            }\n                            break;\n                        }\n                    }\n\n                    // write buffer and reset index; there must be 13 bytes\n                    // left, as this is the maximal number of bytes to be\n                    // written (\"\\uxxxx\\uxxxx\\0\") for one code point\n                    if (string_buffer.size() - bytes < 13)\n                    {\n                        o->write_characters(string_buffer.data(), bytes);\n                        bytes = 0;\n                    }\n\n                    // remember the byte position of this accept\n                    bytes_after_last_accept = bytes;\n                    undumped_chars = 0;\n                    break;\n                }\n\n                case UTF8_REJECT:  // decode found invalid UTF-8 byte\n                {\n                    switch (error_handler)\n                    {\n                        case error_handler_t::strict:\n                        {\n                            std::stringstream ss;\n                            ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (byte | 0);\n                            JSON_THROW(type_error::create(316, \"invalid UTF-8 byte at index \" + std::to_string(i) + \": 0x\" + ss.str(), BasicJsonType()));\n                        }\n\n                        case error_handler_t::ignore:\n                        case error_handler_t::replace:\n                        {\n                            // in case we saw this character the first time, we\n                            // would like to read it again, because the byte\n                            // may be OK for itself, but just not OK for the\n                            // previous sequence\n                            if (undumped_chars > 0)\n                            {\n                                --i;\n                            }\n\n                            // reset length buffer to the last accepted index;\n                            // thus removing/ignoring the invalid characters\n                            bytes = bytes_after_last_accept;\n\n                            if (error_handler == error_handler_t::replace)\n                            {\n                                // add a replacement character\n                                if (ensure_ascii)\n                                {\n                                    string_buffer[bytes++] = '\\\\';\n                                    string_buffer[bytes++] = 'u';\n                                    string_buffer[bytes++] = 'f';\n                                    string_buffer[bytes++] = 'f';\n                                    string_buffer[bytes++] = 'f';\n                                    string_buffer[bytes++] = 'd';\n                                }\n                                else\n                                {\n                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\\xEF');\n                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\\xBF');\n                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\\xBD');\n                                }\n\n                                // write buffer and reset index; there must be 13 bytes\n                                // left, as this is the maximal number of bytes to be\n                                // written (\"\\uxxxx\\uxxxx\\0\") for one code point\n                                if (string_buffer.size() - bytes < 13)\n                                {\n                                    o->write_characters(string_buffer.data(), bytes);\n                                    bytes = 0;\n                                }\n\n                                bytes_after_last_accept = bytes;\n                            }\n\n                            undumped_chars = 0;\n\n                            // continue processing the string\n                            state = UTF8_ACCEPT;\n                            break;\n                        }\n\n                        default:            // LCOV_EXCL_LINE\n                            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n                    }\n                    break;\n                }\n\n                default:  // decode found yet incomplete multi-byte code point\n                {\n                    if (!ensure_ascii)\n                    {\n                        // code point will not be escaped - copy byte to buffer\n                        string_buffer[bytes++] = s[i];\n                    }\n                    ++undumped_chars;\n                    break;\n                }\n            }\n        }\n\n        // we finished processing the string\n        if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))\n        {\n            // write buffer\n            if (bytes > 0)\n            {\n                o->write_characters(string_buffer.data(), bytes);\n            }\n        }\n        else\n        {\n            // we finish reading, but do not accept: string was incomplete\n            switch (error_handler)\n            {\n                case error_handler_t::strict:\n                {\n                    std::stringstream ss;\n                    ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (static_cast<std::uint8_t>(s.back()) | 0);\n                    JSON_THROW(type_error::create(316, \"incomplete UTF-8 string; last byte: 0x\" + ss.str(), BasicJsonType()));\n                }\n\n                case error_handler_t::ignore:\n                {\n                    // write all accepted bytes\n                    o->write_characters(string_buffer.data(), bytes_after_last_accept);\n                    break;\n                }\n\n                case error_handler_t::replace:\n                {\n                    // write all accepted bytes\n                    o->write_characters(string_buffer.data(), bytes_after_last_accept);\n                    // add a replacement character\n                    if (ensure_ascii)\n                    {\n                        o->write_characters(\"\\\\ufffd\", 6);\n                    }\n                    else\n                    {\n                        o->write_characters(\"\\xEF\\xBF\\xBD\", 3);\n                    }\n                    break;\n                }\n\n                default:            // LCOV_EXCL_LINE\n                    JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n            }\n        }\n    }\n\n  private:\n    /*!\n    @brief count digits\n\n    Count the number of decimal (base 10) digits for an input unsigned integer.\n\n    @param[in] x  unsigned integer number to count its digits\n    @return    number of decimal digits\n    */\n    inline unsigned int count_digits(number_unsigned_t x) noexcept\n    {\n        unsigned int n_digits = 1;\n        for (;;)\n        {\n            if (x < 10)\n            {\n                return n_digits;\n            }\n            if (x < 100)\n            {\n                return n_digits + 1;\n            }\n            if (x < 1000)\n            {\n                return n_digits + 2;\n            }\n            if (x < 10000)\n            {\n                return n_digits + 3;\n            }\n            x = x / 10000u;\n            n_digits += 4;\n        }\n    }\n\n    // templates to avoid warnings about useless casts\n    template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>\n    bool is_negative_number(NumberType x)\n    {\n        return x < 0;\n    }\n\n    template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >\n    bool is_negative_number(NumberType /*unused*/)\n    {\n        return false;\n    }\n\n    /*!\n    @brief dump an integer\n\n    Dump a given integer to output stream @a o. Works internally with\n    @a number_buffer.\n\n    @param[in] x  integer number (signed or unsigned) to dump\n    @tparam NumberType either @a number_integer_t or @a number_unsigned_t\n    */\n    template < typename NumberType, detail::enable_if_t <\n                   std::is_integral<NumberType>::value ||\n                   std::is_same<NumberType, number_unsigned_t>::value ||\n                   std::is_same<NumberType, number_integer_t>::value ||\n                   std::is_same<NumberType, binary_char_t>::value,\n                   int > = 0 >\n    void dump_integer(NumberType x)\n    {\n        static constexpr std::array<std::array<char, 2>, 100> digits_to_99\n        {\n            {\n                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},\n                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},\n                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},\n                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},\n                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},\n                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},\n                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},\n                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},\n                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},\n                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},\n            }\n        };\n\n        // special case for \"0\"\n        if (x == 0)\n        {\n            o->write_character('0');\n            return;\n        }\n\n        // use a pointer to fill the buffer\n        auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n\n        number_unsigned_t abs_value;\n\n        unsigned int n_chars{};\n\n        if (is_negative_number(x))\n        {\n            *buffer_ptr = '-';\n            abs_value = remove_sign(static_cast<number_integer_t>(x));\n\n            // account one more byte for the minus sign\n            n_chars = 1 + count_digits(abs_value);\n        }\n        else\n        {\n            abs_value = static_cast<number_unsigned_t>(x);\n            n_chars = count_digits(abs_value);\n        }\n\n        // spare 1 byte for '\\0'\n        JSON_ASSERT(n_chars < number_buffer.size() - 1);\n\n        // jump to the end to generate the string from backward,\n        // so we later avoid reversing the result\n        buffer_ptr += n_chars;\n\n        // Fast int2ascii implementation inspired by \"Fastware\" talk by Andrei Alexandrescu\n        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg\n        while (abs_value >= 100)\n        {\n            const auto digits_index = static_cast<unsigned>((abs_value % 100));\n            abs_value /= 100;\n            *(--buffer_ptr) = digits_to_99[digits_index][1];\n            *(--buffer_ptr) = digits_to_99[digits_index][0];\n        }\n\n        if (abs_value >= 10)\n        {\n            const auto digits_index = static_cast<unsigned>(abs_value);\n            *(--buffer_ptr) = digits_to_99[digits_index][1];\n            *(--buffer_ptr) = digits_to_99[digits_index][0];\n        }\n        else\n        {\n            *(--buffer_ptr) = static_cast<char>('0' + abs_value);\n        }\n\n        o->write_characters(number_buffer.data(), n_chars);\n    }\n\n    /*!\n    @brief dump a floating-point number\n\n    Dump a given floating-point number to output stream @a o. Works internally\n    with @a number_buffer.\n\n    @param[in] x  floating-point number to dump\n    */\n    void dump_float(number_float_t x)\n    {\n        // NaN / inf\n        if (!std::isfinite(x))\n        {\n            o->write_characters(\"null\", 4);\n            return;\n        }\n\n        // If number_float_t is an IEEE-754 single or double precision number,\n        // use the Grisu2 algorithm to produce short numbers which are\n        // guaranteed to round-trip, using strtof and strtod, resp.\n        //\n        // NB: The test below works if <long double> == <double>.\n        static constexpr bool is_ieee_single_or_double\n            = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||\n              (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);\n\n        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());\n    }\n\n    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)\n    {\n        auto* begin = number_buffer.data();\n        auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);\n\n        o->write_characters(begin, static_cast<size_t>(end - begin));\n    }\n\n    void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)\n    {\n        // get number of digits for a float -> text -> float round-trip\n        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;\n\n        // the actual conversion\n        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), \"%.*g\", d, x);\n\n        // negative value indicates an error\n        JSON_ASSERT(len > 0);\n        // check if buffer was large enough\n        JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());\n\n        // erase thousands separator\n        if (thousands_sep != '\\0')\n        {\n            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081\n            const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);\n            std::fill(end, number_buffer.end(), '\\0');\n            JSON_ASSERT((end - number_buffer.begin()) <= len);\n            len = (end - number_buffer.begin());\n        }\n\n        // convert decimal point to '.'\n        if (decimal_point != '\\0' && decimal_point != '.')\n        {\n            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081\n            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);\n            if (dec_pos != number_buffer.end())\n            {\n                *dec_pos = '.';\n            }\n        }\n\n        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));\n\n        // determine if we need to append \".0\"\n        const bool value_is_int_like =\n            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,\n                         [](char c)\n        {\n            return c == '.' || c == 'e';\n        });\n\n        if (value_is_int_like)\n        {\n            o->write_characters(\".0\", 2);\n        }\n    }\n\n    /*!\n    @brief check whether a string is UTF-8 encoded\n\n    The function checks each byte of a string whether it is UTF-8 encoded. The\n    result of the check is stored in the @a state parameter. The function must\n    be called initially with state 0 (accept). State 1 means the string must\n    be rejected, because the current byte is not allowed. If the string is\n    completely processed, but the state is non-zero, the string ended\n    prematurely; that is, the last byte indicated more bytes should have\n    followed.\n\n    @param[in,out] state  the state of the decoding\n    @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)\n    @param[in] byte       next byte to decode\n    @return               new state\n\n    @note The function has been edited: a std::array is used.\n\n    @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>\n    @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/\n    */\n    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept\n    {\n        static const std::array<std::uint8_t, 400> utf8d =\n        {\n            {\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F\n                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F\n                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F\n                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF\n                8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF\n                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF\n                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF\n                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0\n                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2\n                1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4\n                1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6\n                1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8\n            }\n        };\n\n        JSON_ASSERT(byte < utf8d.size());\n        const std::uint8_t type = utf8d[byte];\n\n        codep = (state != UTF8_ACCEPT)\n                ? (byte & 0x3fu) | (codep << 6u)\n                : (0xFFu >> type) & (byte);\n\n        std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);\n        JSON_ASSERT(index < 400);\n        state = utf8d[index];\n        return state;\n    }\n\n    /*\n     * Overload to make the compiler happy while it is instantiating\n     * dump_integer for number_unsigned_t.\n     * Must never be called.\n     */\n    number_unsigned_t remove_sign(number_unsigned_t x)\n    {\n        JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        return x; // LCOV_EXCL_LINE\n    }\n\n    /*\n     * Helper function for dump_integer\n     *\n     * This function takes a negative signed integer and returns its absolute\n     * value as unsigned integer. The plus/minus shuffling is necessary as we can\n     * not directly remove the sign of an arbitrary signed integer as the\n     * absolute values of INT_MIN and INT_MAX are usually not the same. See\n     * #1708 for details.\n     */\n    inline number_unsigned_t remove_sign(number_integer_t x) noexcept\n    {\n        JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)\n        return static_cast<number_unsigned_t>(-(x + 1)) + 1;\n    }\n\n  private:\n    /// the output of the serializer\n    output_adapter_t<char> o = nullptr;\n\n    /// a (hopefully) large enough character buffer\n    std::array<char, 64> number_buffer{{}};\n\n    /// the locale\n    const std::lconv* loc = nullptr;\n    /// the locale's thousand separator character\n    const char thousands_sep = '\\0';\n    /// the locale's decimal point character\n    const char decimal_point = '\\0';\n\n    /// string buffer\n    std::array<char, 512> string_buffer{{}};\n\n    /// the indentation character\n    const char indent_char;\n    /// the indentation string\n    string_t indent_string;\n\n    /// error_handler how to react on decoding errors\n    const error_handler_t error_handler;\n};\n}  // namespace detail\n}  // namespace nlohmann\n\n// #include <nlohmann/detail/value_t.hpp>\n\n// #include <nlohmann/json_fwd.hpp>\n\n// #include <nlohmann/ordered_map.hpp>\n\n\n#include <functional> // less\n#include <initializer_list> // initializer_list\n#include <iterator> // input_iterator_tag, iterator_traits\n#include <memory> // allocator\n#include <stdexcept> // for out_of_range\n#include <type_traits> // enable_if, is_convertible\n#include <utility> // pair\n#include <vector> // vector\n\n// #include <nlohmann/detail/macro_scope.hpp>\n\n\nnamespace nlohmann\n{\n\n/// ordered_map: a minimal map-like container that preserves insertion order\n/// for use within nlohmann::basic_json<ordered_map>\ntemplate <class Key, class T, class IgnoredLess = std::less<Key>,\n          class Allocator = std::allocator<std::pair<const Key, T>>>\n                  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>\n{\n    using key_type = Key;\n    using mapped_type = T;\n    using Container = std::vector<std::pair<const Key, T>, Allocator>;\n    using iterator = typename Container::iterator;\n    using const_iterator = typename Container::const_iterator;\n    using size_type = typename Container::size_type;\n    using value_type = typename Container::value_type;\n\n    // Explicit constructors instead of `using Container::Container`\n    // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)\n    ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}\n    template <class It>\n    ordered_map(It first, It last, const Allocator& alloc = Allocator())\n        : Container{first, last, alloc} {}\n    ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )\n        : Container{init, alloc} {}\n\n    std::pair<iterator, bool> emplace(const key_type& key, T&& t)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return {it, false};\n            }\n        }\n        Container::emplace_back(key, t);\n        return {--this->end(), true};\n    }\n\n    T& operator[](const Key& key)\n    {\n        return emplace(key, T{}).first->second;\n    }\n\n    const T& operator[](const Key& key) const\n    {\n        return at(key);\n    }\n\n    T& at(const Key& key)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it->second;\n            }\n        }\n\n        JSON_THROW(std::out_of_range(\"key not found\"));\n    }\n\n    const T& at(const Key& key) const\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it->second;\n            }\n        }\n\n        JSON_THROW(std::out_of_range(\"key not found\"));\n    }\n\n    size_type erase(const Key& key)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                // Since we cannot move const Keys, re-construct them in place\n                for (auto next = it; ++next != this->end(); ++it)\n                {\n                    it->~value_type(); // Destroy but keep allocation\n                    new (&*it) value_type{std::move(*next)};\n                }\n                Container::pop_back();\n                return 1;\n            }\n        }\n        return 0;\n    }\n\n    iterator erase(iterator pos)\n    {\n        return erase(pos, std::next(pos));\n    }\n\n    iterator erase(iterator first, iterator last)\n    {\n        const auto elements_affected = std::distance(first, last);\n        const auto offset = std::distance(Container::begin(), first);\n\n        // This is the start situation. We need to delete elements_affected\n        // elements (3 in this example: e, f, g), and need to return an\n        // iterator past the last deleted element (h in this example).\n        // Note that offset is the distance from the start of the vector\n        // to first. We will need this later.\n\n        // [ a, b, c, d, e, f, g, h, i, j ]\n        //               ^        ^\n        //             first    last\n\n        // Since we cannot move const Keys, we re-construct them in place.\n        // We start at first and re-construct (viz. copy) the elements from\n        // the back of the vector. Example for first iteration:\n\n        //               ,--------.\n        //               v        |   destroy e and re-construct with h\n        // [ a, b, c, d, e, f, g, h, i, j ]\n        //               ^        ^\n        //               it       it + elements_affected\n\n        for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)\n        {\n            it->~value_type(); // destroy but keep allocation\n            new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // \"move\" next element to it\n        }\n\n        // [ a, b, c, d, h, i, j, h, i, j ]\n        //               ^        ^\n        //             first    last\n\n        // remove the unneeded elements at the end of the vector\n        Container::resize(this->size() - static_cast<size_type>(elements_affected));\n\n        // [ a, b, c, d, h, i, j ]\n        //               ^        ^\n        //             first    last\n\n        // first is now pointing past the last deleted element, but we cannot\n        // use this iterator, because it may have been invalidated by the\n        // resize call. Instead, we can return begin() + offset.\n        return Container::begin() + offset;\n    }\n\n    size_type count(const Key& key) const\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return 1;\n            }\n        }\n        return 0;\n    }\n\n    iterator find(const Key& key)\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it;\n            }\n        }\n        return Container::end();\n    }\n\n    const_iterator find(const Key& key) const\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == key)\n            {\n                return it;\n            }\n        }\n        return Container::end();\n    }\n\n    std::pair<iterator, bool> insert( value_type&& value )\n    {\n        return emplace(value.first, std::move(value.second));\n    }\n\n    std::pair<iterator, bool> insert( const value_type& value )\n    {\n        for (auto it = this->begin(); it != this->end(); ++it)\n        {\n            if (it->first == value.first)\n            {\n                return {it, false};\n            }\n        }\n        Container::push_back(value);\n        return {--this->end(), true};\n    }\n\n    template<typename InputIt>\n    using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,\n            std::input_iterator_tag>::value>::type;\n\n    template<typename InputIt, typename = require_input_iter<InputIt>>\n    void insert(InputIt first, InputIt last)\n    {\n        for (auto it = first; it != last; ++it)\n        {\n            insert(*it);\n        }\n    }\n};\n\n}  // namespace nlohmann\n\n\n#if defined(JSON_HAS_CPP_17)\n    #include <string_view>\n#endif\n\n/*!\n@brief namespace for Niels Lohmann\n@see https://github.com/nlohmann\n@since version 1.0.0\n*/\nnamespace nlohmann\n{\n\n/*!\n@brief a class to store JSON values\n\n@internal\n@invariant The member variables @a m_value and @a m_type have the following\nrelationship:\n- If `m_type == value_t::object`, then `m_value.object != nullptr`.\n- If `m_type == value_t::array`, then `m_value.array != nullptr`.\n- If `m_type == value_t::string`, then `m_value.string != nullptr`.\nThe invariants are checked by member function assert_invariant().\n\n@note ObjectType trick from https://stackoverflow.com/a/9860911\n@endinternal\n\n@since version 1.0.0\n\n@nosubgrouping\n*/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nclass basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)\n{\n  private:\n    template<detail::value_t> friend struct detail::external_constructor;\n    friend ::nlohmann::json_pointer<basic_json>;\n\n    template<typename BasicJsonType, typename InputType>\n    friend class ::nlohmann::detail::parser;\n    friend ::nlohmann::detail::serializer<basic_json>;\n    template<typename BasicJsonType>\n    friend class ::nlohmann::detail::iter_impl;\n    template<typename BasicJsonType, typename CharType>\n    friend class ::nlohmann::detail::binary_writer;\n    template<typename BasicJsonType, typename InputType, typename SAX>\n    friend class ::nlohmann::detail::binary_reader;\n    template<typename BasicJsonType>\n    friend class ::nlohmann::detail::json_sax_dom_parser;\n    template<typename BasicJsonType>\n    friend class ::nlohmann::detail::json_sax_dom_callback_parser;\n    friend class ::nlohmann::detail::exception;\n\n    /// workaround type for MSVC\n    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    // convenience aliases for types residing in namespace detail;\n    using lexer = ::nlohmann::detail::lexer_base<basic_json>;\n\n    template<typename InputAdapterType>\n    static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(\n        InputAdapterType adapter,\n        detail::parser_callback_t<basic_json>cb = nullptr,\n        const bool allow_exceptions = true,\n        const bool ignore_comments = false\n                                 )\n    {\n        return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),\n                std::move(cb), allow_exceptions, ignore_comments);\n    }\n\n  private:\n    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;\n    template<typename BasicJsonType>\n    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;\n    template<typename BasicJsonType>\n    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;\n    template<typename Iterator>\n    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;\n    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;\n\n    template<typename CharType>\n    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;\n\n    template<typename InputType>\n    using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;\n    template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    using serializer = ::nlohmann::detail::serializer<basic_json>;\n\n  public:\n    using value_t = detail::value_t;\n    /// JSON Pointer, see @ref nlohmann::json_pointer\n    using json_pointer = ::nlohmann::json_pointer<basic_json>;\n    template<typename T, typename SFINAE>\n    using json_serializer = JSONSerializer<T, SFINAE>;\n    /// how to treat decoding errors\n    using error_handler_t = detail::error_handler_t;\n    /// how to treat CBOR tags\n    using cbor_tag_handler_t = detail::cbor_tag_handler_t;\n    /// helper type for initializer lists of basic_json values\n    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;\n\n    using input_format_t = detail::input_format_t;\n    /// SAX interface type, see @ref nlohmann::json_sax\n    using json_sax_t = json_sax<basic_json>;\n\n    ////////////////\n    // exceptions //\n    ////////////////\n\n    /// @name exceptions\n    /// Classes to implement user-defined exceptions.\n    /// @{\n\n    using exception = detail::exception;\n    using parse_error = detail::parse_error;\n    using invalid_iterator = detail::invalid_iterator;\n    using type_error = detail::type_error;\n    using out_of_range = detail::out_of_range;\n    using other_error = detail::other_error;\n\n    /// @}\n\n\n    /////////////////////\n    // container types //\n    /////////////////////\n\n    /// @name container types\n    /// The canonic container types to use @ref basic_json like any other STL\n    /// container.\n    /// @{\n\n    /// the type of elements in a basic_json container\n    using value_type = basic_json;\n\n    /// the type of an element reference\n    using reference = value_type&;\n    /// the type of an element const reference\n    using const_reference = const value_type&;\n\n    /// a type to represent differences between iterators\n    using difference_type = std::ptrdiff_t;\n    /// a type to represent container sizes\n    using size_type = std::size_t;\n\n    /// the allocator type\n    using allocator_type = AllocatorType<basic_json>;\n\n    /// the type of an element pointer\n    using pointer = typename std::allocator_traits<allocator_type>::pointer;\n    /// the type of an element const pointer\n    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;\n\n    /// an iterator for a basic_json container\n    using iterator = iter_impl<basic_json>;\n    /// a const iterator for a basic_json container\n    using const_iterator = iter_impl<const basic_json>;\n    /// a reverse iterator for a basic_json container\n    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;\n    /// a const reverse iterator for a basic_json container\n    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;\n\n    /// @}\n\n\n    /// @brief returns the allocator associated with the container\n    /// @sa https://json.nlohmann.me/api/basic_json/get_allocator/\n    static allocator_type get_allocator()\n    {\n        return allocator_type();\n    }\n\n    /// @brief returns version information on the library\n    /// @sa https://json.nlohmann.me/api/basic_json/meta/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json meta()\n    {\n        basic_json result;\n\n        result[\"copyright\"] = \"(C) 2013-2022 Niels Lohmann\";\n        result[\"name\"] = \"JSON for Modern C++\";\n        result[\"url\"] = \"https://github.com/nlohmann/json\";\n        result[\"version\"][\"string\"] =\n            std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + \".\" +\n            std::to_string(NLOHMANN_JSON_VERSION_MINOR) + \".\" +\n            std::to_string(NLOHMANN_JSON_VERSION_PATCH);\n        result[\"version\"][\"major\"] = NLOHMANN_JSON_VERSION_MAJOR;\n        result[\"version\"][\"minor\"] = NLOHMANN_JSON_VERSION_MINOR;\n        result[\"version\"][\"patch\"] = NLOHMANN_JSON_VERSION_PATCH;\n\n#ifdef _WIN32\n        result[\"platform\"] = \"win32\";\n#elif defined __linux__\n        result[\"platform\"] = \"linux\";\n#elif defined __APPLE__\n        result[\"platform\"] = \"apple\";\n#elif defined __unix__\n        result[\"platform\"] = \"unix\";\n#else\n        result[\"platform\"] = \"unknown\";\n#endif\n\n#if defined(__ICC) || defined(__INTEL_COMPILER)\n        result[\"compiler\"] = {{\"family\", \"icc\"}, {\"version\", __INTEL_COMPILER}};\n#elif defined(__clang__)\n        result[\"compiler\"] = {{\"family\", \"clang\"}, {\"version\", __clang_version__}};\n#elif defined(__GNUC__) || defined(__GNUG__)\n        result[\"compiler\"] = {{\"family\", \"gcc\"}, {\"version\", std::to_string(__GNUC__) + \".\" + std::to_string(__GNUC_MINOR__) + \".\" + std::to_string(__GNUC_PATCHLEVEL__)}};\n#elif defined(__HP_cc) || defined(__HP_aCC)\n        result[\"compiler\"] = \"hp\"\n#elif defined(__IBMCPP__)\n        result[\"compiler\"] = {{\"family\", \"ilecpp\"}, {\"version\", __IBMCPP__}};\n#elif defined(_MSC_VER)\n        result[\"compiler\"] = {{\"family\", \"msvc\"}, {\"version\", _MSC_VER}};\n#elif defined(__PGI)\n        result[\"compiler\"] = {{\"family\", \"pgcpp\"}, {\"version\", __PGI}};\n#elif defined(__SUNPRO_CC)\n        result[\"compiler\"] = {{\"family\", \"sunpro\"}, {\"version\", __SUNPRO_CC}};\n#else\n        result[\"compiler\"] = {{\"family\", \"unknown\"}, {\"version\", \"unknown\"}};\n#endif\n\n#ifdef __cplusplus\n        result[\"compiler\"][\"c++\"] = std::to_string(__cplusplus);\n#else\n        result[\"compiler\"][\"c++\"] = \"unknown\";\n#endif\n        return result;\n    }\n\n\n    ///////////////////////////\n    // JSON value data types //\n    ///////////////////////////\n\n    /// @name JSON value data types\n    /// The data types to store a JSON value. These types are derived from\n    /// the template arguments passed to class @ref basic_json.\n    /// @{\n\n    /// @brief object key comparator type\n    /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/\n#if defined(JSON_HAS_CPP_14)\n    // Use transparent comparator if possible, combined with perfect forwarding\n    // on find() and count() calls prevents unnecessary string construction.\n    using object_comparator_t = std::less<>;\n#else\n    using object_comparator_t = std::less<StringType>;\n#endif\n\n    /// @brief a type for an object\n    /// @sa https://json.nlohmann.me/api/basic_json/object_t/\n    using object_t = ObjectType<StringType,\n          basic_json,\n          object_comparator_t,\n          AllocatorType<std::pair<const StringType,\n          basic_json>>>;\n\n    /// @brief a type for an array\n    /// @sa https://json.nlohmann.me/api/basic_json/array_t/\n    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n\n    /// @brief a type for a string\n    /// @sa https://json.nlohmann.me/api/basic_json/string_t/\n    using string_t = StringType;\n\n    /// @brief a type for a boolean\n    /// @sa https://json.nlohmann.me/api/basic_json/boolean_t/\n    using boolean_t = BooleanType;\n\n    /// @brief a type for a number (integer)\n    /// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/\n    using number_integer_t = NumberIntegerType;\n\n    /// @brief a type for a number (unsigned)\n    /// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/\n    using number_unsigned_t = NumberUnsignedType;\n\n    /// @brief a type for a number (floating-point)\n    /// @sa https://json.nlohmann.me/api/basic_json/number_float_t/\n    using number_float_t = NumberFloatType;\n\n    /// @brief a type for a packed binary type\n    /// @sa https://json.nlohmann.me/api/basic_json/binary_t/\n    using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;\n\n    /// @}\n\n  private:\n\n    /// helper for exception-safe object creation\n    template<typename T, typename... Args>\n    JSON_HEDLEY_RETURNS_NON_NULL\n    static T* create(Args&& ... args)\n    {\n        AllocatorType<T> alloc;\n        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;\n\n        auto deleter = [&](T * obj)\n        {\n            AllocatorTraits::deallocate(alloc, obj, 1);\n        };\n        std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);\n        AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);\n        JSON_ASSERT(obj != nullptr);\n        return obj.release();\n    }\n\n    ////////////////////////\n    // JSON value storage //\n    ////////////////////////\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    /*!\n    @brief a JSON value\n\n    The actual storage for a JSON value of the @ref basic_json class. This\n    union combines the different storage types for the JSON value types\n    defined in @ref value_t.\n\n    JSON type | value_t type    | used type\n    --------- | --------------- | ------------------------\n    object    | object          | pointer to @ref object_t\n    array     | array           | pointer to @ref array_t\n    string    | string          | pointer to @ref string_t\n    boolean   | boolean         | @ref boolean_t\n    number    | number_integer  | @ref number_integer_t\n    number    | number_unsigned | @ref number_unsigned_t\n    number    | number_float    | @ref number_float_t\n    binary    | binary          | pointer to @ref binary_t\n    null      | null            | *no value is stored*\n\n    @note Variable-length types (objects, arrays, and strings) are stored as\n    pointers. The size of the union should not exceed 64 bits if the default\n    value types are used.\n\n    @since version 1.0.0\n    */\n    union json_value\n    {\n        /// object (stored with pointer to save storage)\n        object_t* object;\n        /// array (stored with pointer to save storage)\n        array_t* array;\n        /// string (stored with pointer to save storage)\n        string_t* string;\n        /// binary (stored with pointer to save storage)\n        binary_t* binary;\n        /// boolean\n        boolean_t boolean;\n        /// number (integer)\n        number_integer_t number_integer;\n        /// number (unsigned integer)\n        number_unsigned_t number_unsigned;\n        /// number (floating-point)\n        number_float_t number_float;\n\n        /// default constructor (for null values)\n        json_value() = default;\n        /// constructor for booleans\n        json_value(boolean_t v) noexcept : boolean(v) {}\n        /// constructor for numbers (integer)\n        json_value(number_integer_t v) noexcept : number_integer(v) {}\n        /// constructor for numbers (unsigned)\n        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}\n        /// constructor for numbers (floating-point)\n        json_value(number_float_t v) noexcept : number_float(v) {}\n        /// constructor for empty values of a given type\n        json_value(value_t t)\n        {\n            switch (t)\n            {\n                case value_t::object:\n                {\n                    object = create<object_t>();\n                    break;\n                }\n\n                case value_t::array:\n                {\n                    array = create<array_t>();\n                    break;\n                }\n\n                case value_t::string:\n                {\n                    string = create<string_t>(\"\");\n                    break;\n                }\n\n                case value_t::binary:\n                {\n                    binary = create<binary_t>();\n                    break;\n                }\n\n                case value_t::boolean:\n                {\n                    boolean = static_cast<boolean_t>(false);\n                    break;\n                }\n\n                case value_t::number_integer:\n                {\n                    number_integer = static_cast<number_integer_t>(0);\n                    break;\n                }\n\n                case value_t::number_unsigned:\n                {\n                    number_unsigned = static_cast<number_unsigned_t>(0);\n                    break;\n                }\n\n                case value_t::number_float:\n                {\n                    number_float = static_cast<number_float_t>(0.0);\n                    break;\n                }\n\n                case value_t::null:\n                {\n                    object = nullptr;  // silence warning, see #821\n                    break;\n                }\n\n                case value_t::discarded:\n                default:\n                {\n                    object = nullptr;  // silence warning, see #821\n                    if (JSON_HEDLEY_UNLIKELY(t == value_t::null))\n                    {\n                        JSON_THROW(other_error::create(500, \"961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5\", basic_json())); // LCOV_EXCL_LINE\n                    }\n                    break;\n                }\n            }\n        }\n\n        /// constructor for strings\n        json_value(const string_t& value) : string(create<string_t>(value)) {}\n\n        /// constructor for rvalue strings\n        json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}\n\n        /// constructor for objects\n        json_value(const object_t& value) : object(create<object_t>(value)) {}\n\n        /// constructor for rvalue objects\n        json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}\n\n        /// constructor for arrays\n        json_value(const array_t& value) : array(create<array_t>(value)) {}\n\n        /// constructor for rvalue arrays\n        json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}\n\n        /// constructor for binary arrays\n        json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}\n\n        /// constructor for rvalue binary arrays\n        json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}\n\n        /// constructor for binary arrays (internal type)\n        json_value(const binary_t& value) : binary(create<binary_t>(value)) {}\n\n        /// constructor for rvalue binary arrays (internal type)\n        json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}\n\n        void destroy(value_t t)\n        {\n            if (t == value_t::array || t == value_t::object)\n            {\n                // flatten the current json_value to a heap-allocated stack\n                std::vector<basic_json> stack;\n\n                // move the top-level items to stack\n                if (t == value_t::array)\n                {\n                    stack.reserve(array->size());\n                    std::move(array->begin(), array->end(), std::back_inserter(stack));\n                }\n                else\n                {\n                    stack.reserve(object->size());\n                    for (auto&& it : *object)\n                    {\n                        stack.push_back(std::move(it.second));\n                    }\n                }\n\n                while (!stack.empty())\n                {\n                    // move the last item to local variable to be processed\n                    basic_json current_item(std::move(stack.back()));\n                    stack.pop_back();\n\n                    // if current_item is array/object, move\n                    // its children to the stack to be processed later\n                    if (current_item.is_array())\n                    {\n                        std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));\n\n                        current_item.m_value.array->clear();\n                    }\n                    else if (current_item.is_object())\n                    {\n                        for (auto&& it : *current_item.m_value.object)\n                        {\n                            stack.push_back(std::move(it.second));\n                        }\n\n                        current_item.m_value.object->clear();\n                    }\n\n                    // it's now safe that current_item get destructed\n                    // since it doesn't have any children\n                }\n            }\n\n            switch (t)\n            {\n                case value_t::object:\n                {\n                    AllocatorType<object_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, object);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);\n                    break;\n                }\n\n                case value_t::array:\n                {\n                    AllocatorType<array_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, array);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);\n                    break;\n                }\n\n                case value_t::string:\n                {\n                    AllocatorType<string_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, string);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);\n                    break;\n                }\n\n                case value_t::binary:\n                {\n                    AllocatorType<binary_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);\n                    break;\n                }\n\n                case value_t::null:\n                case value_t::boolean:\n                case value_t::number_integer:\n                case value_t::number_unsigned:\n                case value_t::number_float:\n                case value_t::discarded:\n                default:\n                {\n                    break;\n                }\n            }\n        }\n    };\n\n  private:\n    /*!\n    @brief checks the class invariants\n\n    This function asserts the class invariants. It needs to be called at the\n    end of every constructor to make sure that created objects respect the\n    invariant. Furthermore, it has to be called each time the type of a JSON\n    value is changed, because the invariant expresses a relationship between\n    @a m_type and @a m_value.\n\n    Furthermore, the parent relation is checked for arrays and objects: If\n    @a check_parents true and the value is an array or object, then the\n    container's elements must have the current value as parent.\n\n    @param[in] check_parents  whether the parent relation should be checked.\n               The value is true by default and should only be set to false\n               during destruction of objects when the invariant does not\n               need to hold.\n    */\n    void assert_invariant(bool check_parents = true) const noexcept\n    {\n        JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);\n        JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);\n        JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);\n        JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);\n\n#if JSON_DIAGNOSTICS\n        JSON_TRY\n        {\n            // cppcheck-suppress assertWithSideEffect\n            JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)\n            {\n                return j.m_parent == this;\n            }));\n        }\n        JSON_CATCH(...) {} // LCOV_EXCL_LINE\n#endif\n        static_cast<void>(check_parents);\n    }\n\n    void set_parents()\n    {\n#if JSON_DIAGNOSTICS\n        switch (m_type)\n        {\n            case value_t::array:\n            {\n                for (auto& element : *m_value.array)\n                {\n                    element.m_parent = this;\n                }\n                break;\n            }\n\n            case value_t::object:\n            {\n                for (auto& element : *m_value.object)\n                {\n                    element.second.m_parent = this;\n                }\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                break;\n        }\n#endif\n    }\n\n    iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)\n    {\n#if JSON_DIAGNOSTICS\n        for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)\n        {\n            (it + i)->m_parent = this;\n        }\n#else\n        static_cast<void>(count_set_parents);\n#endif\n        return it;\n    }\n\n    reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))\n    {\n#if JSON_DIAGNOSTICS\n        if (old_capacity != static_cast<std::size_t>(-1))\n        {\n            // see https://github.com/nlohmann/json/issues/2838\n            JSON_ASSERT(type() == value_t::array);\n            if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))\n            {\n                // capacity has changed: update all parents\n                set_parents();\n                return j;\n            }\n        }\n\n        // ordered_json uses a vector internally, so pointers could have\n        // been invalidated; see https://github.com/nlohmann/json/issues/2962\n#ifdef JSON_HEDLEY_MSVC_VERSION\n#pragma warning(push )\n#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr\n#endif\n        if (detail::is_ordered_map<object_t>::value)\n        {\n            set_parents();\n            return j;\n        }\n#ifdef JSON_HEDLEY_MSVC_VERSION\n#pragma warning( pop )\n#endif\n\n        j.m_parent = this;\n#else\n        static_cast<void>(j);\n        static_cast<void>(old_capacity);\n#endif\n        return j;\n    }\n\n  public:\n    //////////////////////////\n    // JSON parser callback //\n    //////////////////////////\n\n    /// @brief parser event types\n    /// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/\n    using parse_event_t = detail::parse_event_t;\n\n    /// @brief per-element parser callback type\n    /// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/\n    using parser_callback_t = detail::parser_callback_t<basic_json>;\n\n    //////////////////\n    // constructors //\n    //////////////////\n\n    /// @name constructors and destructors\n    /// Constructors of class @ref basic_json, copy/move constructor, copy\n    /// assignment, static functions creating objects, and the destructor.\n    /// @{\n\n    /// @brief create an empty value with a given type\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(const value_t v)\n        : m_type(v), m_value(v)\n    {\n        assert_invariant();\n    }\n\n    /// @brief create a null object\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(std::nullptr_t = nullptr) noexcept\n        : basic_json(value_t::null)\n    {\n        assert_invariant();\n    }\n\n    /// @brief create a JSON value from compatible types\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    template < typename CompatibleType,\n               typename U = detail::uncvref_t<CompatibleType>,\n               detail::enable_if_t <\n                   !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >\n    basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)\n                JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),\n                                           std::forward<CompatibleType>(val))))\n    {\n        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief create a JSON value from an existing one\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    template < typename BasicJsonType,\n               detail::enable_if_t <\n                   detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >\n    basic_json(const BasicJsonType& val)\n    {\n        using other_boolean_t = typename BasicJsonType::boolean_t;\n        using other_number_float_t = typename BasicJsonType::number_float_t;\n        using other_number_integer_t = typename BasicJsonType::number_integer_t;\n        using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;\n        using other_string_t = typename BasicJsonType::string_t;\n        using other_object_t = typename BasicJsonType::object_t;\n        using other_array_t = typename BasicJsonType::array_t;\n        using other_binary_t = typename BasicJsonType::binary_t;\n\n        switch (val.type())\n        {\n            case value_t::boolean:\n                JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());\n                break;\n            case value_t::number_float:\n                JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());\n                break;\n            case value_t::number_integer:\n                JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());\n                break;\n            case value_t::number_unsigned:\n                JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());\n                break;\n            case value_t::string:\n                JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());\n                break;\n            case value_t::object:\n                JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());\n                break;\n            case value_t::array:\n                JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());\n                break;\n            case value_t::binary:\n                JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());\n                break;\n            case value_t::null:\n                *this = nullptr;\n                break;\n            case value_t::discarded:\n                m_type = value_t::discarded;\n                break;\n            default:            // LCOV_EXCL_LINE\n                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n        }\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief create a container (array or object) from an initializer list\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(initializer_list_t init,\n               bool type_deduction = true,\n               value_t manual_type = value_t::array)\n    {\n        // check if each element is an array with two elements whose first\n        // element is a string\n        bool is_an_object = std::all_of(init.begin(), init.end(),\n                                        [](const detail::json_ref<basic_json>& element_ref)\n        {\n            return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();\n        });\n\n        // adjust type if type deduction is not wanted\n        if (!type_deduction)\n        {\n            // if array is wanted, do not create an object though possible\n            if (manual_type == value_t::array)\n            {\n                is_an_object = false;\n            }\n\n            // if object is wanted but impossible, throw an exception\n            if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))\n            {\n                JSON_THROW(type_error::create(301, \"cannot create object from initializer list\", basic_json()));\n            }\n        }\n\n        if (is_an_object)\n        {\n            // the initializer list is a list of pairs -> create object\n            m_type = value_t::object;\n            m_value = value_t::object;\n\n            for (auto& element_ref : init)\n            {\n                auto element = element_ref.moved_or_copied();\n                m_value.object->emplace(\n                    std::move(*((*element.m_value.array)[0].m_value.string)),\n                    std::move((*element.m_value.array)[1]));\n            }\n        }\n        else\n        {\n            // the initializer list describes an array -> create array\n            m_type = value_t::array;\n            m_value.array = create<array_t>(init.begin(), init.end());\n        }\n\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief explicitly create a binary array (without subtype)\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(const typename binary_t::container_type& init)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = init;\n        return res;\n    }\n\n    /// @brief explicitly create a binary array (with subtype)\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = binary_t(init, subtype);\n        return res;\n    }\n\n    /// @brief explicitly create a binary array\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(typename binary_t::container_type&& init)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = std::move(init);\n        return res;\n    }\n\n    /// @brief explicitly create a binary array (with subtype)\n    /// @sa https://json.nlohmann.me/api/basic_json/binary/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)\n    {\n        auto res = basic_json();\n        res.m_type = value_t::binary;\n        res.m_value = binary_t(std::move(init), subtype);\n        return res;\n    }\n\n    /// @brief explicitly create an array from an initializer list\n    /// @sa https://json.nlohmann.me/api/basic_json/array/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json array(initializer_list_t init = {})\n    {\n        return basic_json(init, false, value_t::array);\n    }\n\n    /// @brief explicitly create an object from an initializer list\n    /// @sa https://json.nlohmann.me/api/basic_json/object/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json object(initializer_list_t init = {})\n    {\n        return basic_json(init, false, value_t::object);\n    }\n\n    /// @brief construct an array with count copies of given value\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(size_type cnt, const basic_json& val)\n        : m_type(value_t::array)\n    {\n        m_value.array = create<array_t>(cnt, val);\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief construct a JSON container given an iterator range\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    template < class InputIT, typename std::enable_if <\n                   std::is_same<InputIT, typename basic_json_t::iterator>::value ||\n                   std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >\n    basic_json(InputIT first, InputIT last)\n    {\n        JSON_ASSERT(first.m_object != nullptr);\n        JSON_ASSERT(last.m_object != nullptr);\n\n        // make sure iterator fits the current value\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(201, \"iterators are not compatible\", basic_json()));\n        }\n\n        // copy type from first iterator\n        m_type = first.m_object->m_type;\n\n        // check if iterator range is complete for primitive values\n        switch (m_type)\n        {\n            case value_t::boolean:\n            case value_t::number_float:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::string:\n            {\n                if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()\n                                         || !last.m_it.primitive_iterator.is_end()))\n                {\n                    JSON_THROW(invalid_iterator::create(204, \"iterators out of range\", *first.m_object));\n                }\n                break;\n            }\n\n            case value_t::null:\n            case value_t::object:\n            case value_t::array:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n                break;\n        }\n\n        switch (m_type)\n        {\n            case value_t::number_integer:\n            {\n                m_value.number_integer = first.m_object->m_value.number_integer;\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                m_value.number_unsigned = first.m_object->m_value.number_unsigned;\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                m_value.number_float = first.m_object->m_value.number_float;\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                m_value.boolean = first.m_object->m_value.boolean;\n                break;\n            }\n\n            case value_t::string:\n            {\n                m_value = *first.m_object->m_value.string;\n                break;\n            }\n\n            case value_t::object:\n            {\n                m_value.object = create<object_t>(first.m_it.object_iterator,\n                                                  last.m_it.object_iterator);\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_value.array = create<array_t>(first.m_it.array_iterator,\n                                                last.m_it.array_iterator);\n                break;\n            }\n\n            case value_t::binary:\n            {\n                m_value = *first.m_object->m_value.binary;\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                JSON_THROW(invalid_iterator::create(206, \"cannot construct with iterators from \" + std::string(first.m_object->type_name()), *first.m_object));\n        }\n\n        set_parents();\n        assert_invariant();\n    }\n\n\n    ///////////////////////////////////////\n    // other constructors and destructor //\n    ///////////////////////////////////////\n\n    template<typename JsonRef,\n             detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,\n                                 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >\n    basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}\n\n    /// @brief copy constructor\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(const basic_json& other)\n        : m_type(other.m_type)\n    {\n        // check of passed value is valid\n        other.assert_invariant();\n\n        switch (m_type)\n        {\n            case value_t::object:\n            {\n                m_value = *other.m_value.object;\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_value = *other.m_value.array;\n                break;\n            }\n\n            case value_t::string:\n            {\n                m_value = *other.m_value.string;\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                m_value = other.m_value.boolean;\n                break;\n            }\n\n            case value_t::number_integer:\n            {\n                m_value = other.m_value.number_integer;\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                m_value = other.m_value.number_unsigned;\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                m_value = other.m_value.number_float;\n                break;\n            }\n\n            case value_t::binary:\n            {\n                m_value = *other.m_value.binary;\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                break;\n        }\n\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief move constructor\n    /// @sa https://json.nlohmann.me/api/basic_json/basic_json/\n    basic_json(basic_json&& other) noexcept\n        : m_type(std::move(other.m_type)),\n          m_value(std::move(other.m_value))\n    {\n        // check that passed value is valid\n        other.assert_invariant(false);\n\n        // invalidate payload\n        other.m_type = value_t::null;\n        other.m_value = {};\n\n        set_parents();\n        assert_invariant();\n    }\n\n    /// @brief copy assignment\n    /// @sa https://json.nlohmann.me/api/basic_json/operator=/\n    basic_json& operator=(basic_json other) noexcept (\n        std::is_nothrow_move_constructible<value_t>::value&&\n        std::is_nothrow_move_assignable<value_t>::value&&\n        std::is_nothrow_move_constructible<json_value>::value&&\n        std::is_nothrow_move_assignable<json_value>::value\n    )\n    {\n        // check that passed value is valid\n        other.assert_invariant();\n\n        using std::swap;\n        swap(m_type, other.m_type);\n        swap(m_value, other.m_value);\n\n        set_parents();\n        assert_invariant();\n        return *this;\n    }\n\n    /// @brief destructor\n    /// @sa https://json.nlohmann.me/api/basic_json/~basic_json/\n    ~basic_json() noexcept\n    {\n        assert_invariant(false);\n        m_value.destroy(m_type);\n    }\n\n    /// @}\n\n  public:\n    ///////////////////////\n    // object inspection //\n    ///////////////////////\n\n    /// @name object inspection\n    /// Functions to inspect the type of a JSON value.\n    /// @{\n\n    /// @brief serialization\n    /// @sa https://json.nlohmann.me/api/basic_json/dump/\n    string_t dump(const int indent = -1,\n                  const char indent_char = ' ',\n                  const bool ensure_ascii = false,\n                  const error_handler_t error_handler = error_handler_t::strict) const\n    {\n        string_t result;\n        serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);\n\n        if (indent >= 0)\n        {\n            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));\n        }\n        else\n        {\n            s.dump(*this, false, ensure_ascii, 0);\n        }\n\n        return result;\n    }\n\n    /// @brief return the type of the JSON value (explicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/type/\n    constexpr value_t type() const noexcept\n    {\n        return m_type;\n    }\n\n    /// @brief return whether type is primitive\n    /// @sa https://json.nlohmann.me/api/basic_json/is_primitive/\n    constexpr bool is_primitive() const noexcept\n    {\n        return is_null() || is_string() || is_boolean() || is_number() || is_binary();\n    }\n\n    /// @brief return whether type is structured\n    /// @sa https://json.nlohmann.me/api/basic_json/is_structured/\n    constexpr bool is_structured() const noexcept\n    {\n        return is_array() || is_object();\n    }\n\n    /// @brief return whether value is null\n    /// @sa https://json.nlohmann.me/api/basic_json/is_null/\n    constexpr bool is_null() const noexcept\n    {\n        return m_type == value_t::null;\n    }\n\n    /// @brief return whether value is a boolean\n    /// @sa https://json.nlohmann.me/api/basic_json/is_boolean/\n    constexpr bool is_boolean() const noexcept\n    {\n        return m_type == value_t::boolean;\n    }\n\n    /// @brief return whether value is a number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number/\n    constexpr bool is_number() const noexcept\n    {\n        return is_number_integer() || is_number_float();\n    }\n\n    /// @brief return whether value is an integer number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/\n    constexpr bool is_number_integer() const noexcept\n    {\n        return m_type == value_t::number_integer || m_type == value_t::number_unsigned;\n    }\n\n    /// @brief return whether value is an unsigned integer number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/\n    constexpr bool is_number_unsigned() const noexcept\n    {\n        return m_type == value_t::number_unsigned;\n    }\n\n    /// @brief return whether value is a floating-point number\n    /// @sa https://json.nlohmann.me/api/basic_json/is_number_float/\n    constexpr bool is_number_float() const noexcept\n    {\n        return m_type == value_t::number_float;\n    }\n\n    /// @brief return whether value is an object\n    /// @sa https://json.nlohmann.me/api/basic_json/is_object/\n    constexpr bool is_object() const noexcept\n    {\n        return m_type == value_t::object;\n    }\n\n    /// @brief return whether value is an array\n    /// @sa https://json.nlohmann.me/api/basic_json/is_array/\n    constexpr bool is_array() const noexcept\n    {\n        return m_type == value_t::array;\n    }\n\n    /// @brief return whether value is a string\n    /// @sa https://json.nlohmann.me/api/basic_json/is_string/\n    constexpr bool is_string() const noexcept\n    {\n        return m_type == value_t::string;\n    }\n\n    /// @brief return whether value is a binary array\n    /// @sa https://json.nlohmann.me/api/basic_json/is_binary/\n    constexpr bool is_binary() const noexcept\n    {\n        return m_type == value_t::binary;\n    }\n\n    /// @brief return whether value is discarded\n    /// @sa https://json.nlohmann.me/api/basic_json/is_discarded/\n    constexpr bool is_discarded() const noexcept\n    {\n        return m_type == value_t::discarded;\n    }\n\n    /// @brief return the type of the JSON value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/\n    constexpr operator value_t() const noexcept\n    {\n        return m_type;\n    }\n\n    /// @}\n\n  private:\n    //////////////////\n    // value access //\n    //////////////////\n\n    /// get a boolean (explicit)\n    boolean_t get_impl(boolean_t* /*unused*/) const\n    {\n        if (JSON_HEDLEY_LIKELY(is_boolean()))\n        {\n            return m_value.boolean;\n        }\n\n        JSON_THROW(type_error::create(302, \"type must be boolean, but is \" + std::string(type_name()), *this));\n    }\n\n    /// get a pointer to the value (object)\n    object_t* get_impl_ptr(object_t* /*unused*/) noexcept\n    {\n        return is_object() ? m_value.object : nullptr;\n    }\n\n    /// get a pointer to the value (object)\n    constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept\n    {\n        return is_object() ? m_value.object : nullptr;\n    }\n\n    /// get a pointer to the value (array)\n    array_t* get_impl_ptr(array_t* /*unused*/) noexcept\n    {\n        return is_array() ? m_value.array : nullptr;\n    }\n\n    /// get a pointer to the value (array)\n    constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept\n    {\n        return is_array() ? m_value.array : nullptr;\n    }\n\n    /// get a pointer to the value (string)\n    string_t* get_impl_ptr(string_t* /*unused*/) noexcept\n    {\n        return is_string() ? m_value.string : nullptr;\n    }\n\n    /// get a pointer to the value (string)\n    constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept\n    {\n        return is_string() ? m_value.string : nullptr;\n    }\n\n    /// get a pointer to the value (boolean)\n    boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept\n    {\n        return is_boolean() ? &m_value.boolean : nullptr;\n    }\n\n    /// get a pointer to the value (boolean)\n    constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept\n    {\n        return is_boolean() ? &m_value.boolean : nullptr;\n    }\n\n    /// get a pointer to the value (integer number)\n    number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept\n    {\n        return is_number_integer() ? &m_value.number_integer : nullptr;\n    }\n\n    /// get a pointer to the value (integer number)\n    constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept\n    {\n        return is_number_integer() ? &m_value.number_integer : nullptr;\n    }\n\n    /// get a pointer to the value (unsigned number)\n    number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept\n    {\n        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;\n    }\n\n    /// get a pointer to the value (unsigned number)\n    constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept\n    {\n        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;\n    }\n\n    /// get a pointer to the value (floating-point number)\n    number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept\n    {\n        return is_number_float() ? &m_value.number_float : nullptr;\n    }\n\n    /// get a pointer to the value (floating-point number)\n    constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept\n    {\n        return is_number_float() ? &m_value.number_float : nullptr;\n    }\n\n    /// get a pointer to the value (binary)\n    binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept\n    {\n        return is_binary() ? m_value.binary : nullptr;\n    }\n\n    /// get a pointer to the value (binary)\n    constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept\n    {\n        return is_binary() ? m_value.binary : nullptr;\n    }\n\n    /*!\n    @brief helper function to implement get_ref()\n\n    This function helps to implement get_ref() without code duplication for\n    const and non-const overloads\n\n    @tparam ThisType will be deduced as `basic_json` or `const basic_json`\n\n    @throw type_error.303 if ReferenceType does not match underlying value\n    type of the current JSON\n    */\n    template<typename ReferenceType, typename ThisType>\n    static ReferenceType get_ref_impl(ThisType& obj)\n    {\n        // delegate the call to get_ptr<>()\n        auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();\n\n        if (JSON_HEDLEY_LIKELY(ptr != nullptr))\n        {\n            return *ptr;\n        }\n\n        JSON_THROW(type_error::create(303, \"incompatible ReferenceType for get_ref, actual type is \" + std::string(obj.type_name()), obj));\n    }\n\n  public:\n    /// @name value access\n    /// Direct access to the stored value of a JSON value.\n    /// @{\n\n    /// @brief get a pointer value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/\n    template<typename PointerType, typename std::enable_if<\n                 std::is_pointer<PointerType>::value, int>::type = 0>\n    auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))\n    {\n        // delegate the call to get_impl_ptr<>()\n        return get_impl_ptr(static_cast<PointerType>(nullptr));\n    }\n\n    /// @brief get a pointer value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/\n    template < typename PointerType, typename std::enable_if <\n                   std::is_pointer<PointerType>::value&&\n                   std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >\n    constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))\n    {\n        // delegate the call to get_impl_ptr<>() const\n        return get_impl_ptr(static_cast<PointerType>(nullptr));\n    }\n\n  private:\n    /*!\n    @brief get a value (explicit)\n\n    Explicit type conversion between the JSON value and a compatible value\n    which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)\n    and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).\n    The value is converted by calling the @ref json_serializer<ValueType>\n    `from_json()` method.\n\n    The function is equivalent to executing\n    @code {.cpp}\n    ValueType ret;\n    JSONSerializer<ValueType>::from_json(*this, ret);\n    return ret;\n    @endcode\n\n    This overloads is chosen if:\n    - @a ValueType is not @ref basic_json,\n    - @ref json_serializer<ValueType> has a `from_json()` method of the form\n      `void from_json(const basic_json&, ValueType&)`, and\n    - @ref json_serializer<ValueType> does not have a `from_json()` method of\n      the form `ValueType from_json(const basic_json&)`\n\n    @tparam ValueType the returned value type\n\n    @return copy of the JSON value, converted to @a ValueType\n\n    @throw what @ref json_serializer<ValueType> `from_json()` method throws\n\n    @liveexample{The example below shows several conversions from JSON values\n    to other types. There a few things to note: (1) Floating-point numbers can\n    be converted to integers\\, (2) A JSON array can be converted to a standard\n    `std::vector<short>`\\, (3) A JSON object can be converted to C++\n    associative containers such as `std::unordered_map<std::string\\,\n    json>`.,get__ValueType_const}\n\n    @since version 2.1.0\n    */\n    template < typename ValueType,\n               detail::enable_if_t <\n                   detail::is_default_constructible<ValueType>::value&&\n                   detail::has_from_json<basic_json_t, ValueType>::value,\n                   int > = 0 >\n    ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(\n                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))\n    {\n        auto ret = ValueType();\n        JSONSerializer<ValueType>::from_json(*this, ret);\n        return ret;\n    }\n\n    /*!\n    @brief get a value (explicit); special case\n\n    Explicit type conversion between the JSON value and a compatible value\n    which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)\n    and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).\n    The value is converted by calling the @ref json_serializer<ValueType>\n    `from_json()` method.\n\n    The function is equivalent to executing\n    @code {.cpp}\n    return JSONSerializer<ValueType>::from_json(*this);\n    @endcode\n\n    This overloads is chosen if:\n    - @a ValueType is not @ref basic_json and\n    - @ref json_serializer<ValueType> has a `from_json()` method of the form\n      `ValueType from_json(const basic_json&)`\n\n    @note If @ref json_serializer<ValueType> has both overloads of\n    `from_json()`, this one is chosen.\n\n    @tparam ValueType the returned value type\n\n    @return copy of the JSON value, converted to @a ValueType\n\n    @throw what @ref json_serializer<ValueType> `from_json()` method throws\n\n    @since version 2.1.0\n    */\n    template < typename ValueType,\n               detail::enable_if_t <\n                   detail::has_non_default_from_json<basic_json_t, ValueType>::value,\n                   int > = 0 >\n    ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(\n                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))\n    {\n        return JSONSerializer<ValueType>::from_json(*this);\n    }\n\n    /*!\n    @brief get special-case overload\n\n    This overloads converts the current @ref basic_json in a different\n    @ref basic_json type\n\n    @tparam BasicJsonType == @ref basic_json\n\n    @return a copy of *this, converted into @a BasicJsonType\n\n    @complexity Depending on the implementation of the called `from_json()`\n                method.\n\n    @since version 3.2.0\n    */\n    template < typename BasicJsonType,\n               detail::enable_if_t <\n                   detail::is_basic_json<BasicJsonType>::value,\n                   int > = 0 >\n    BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const\n    {\n        return *this;\n    }\n\n    /*!\n    @brief get special-case overload\n\n    This overloads avoids a lot of template boilerplate, it can be seen as the\n    identity method\n\n    @tparam BasicJsonType == @ref basic_json\n\n    @return a copy of *this\n\n    @complexity Constant.\n\n    @since version 2.1.0\n    */\n    template<typename BasicJsonType,\n             detail::enable_if_t<\n                 std::is_same<BasicJsonType, basic_json_t>::value,\n                 int> = 0>\n    basic_json get_impl(detail::priority_tag<3> /*unused*/) const\n    {\n        return *this;\n    }\n\n    /*!\n    @brief get a pointer value (explicit)\n    @copydoc get()\n    */\n    template<typename PointerType,\n             detail::enable_if_t<\n                 std::is_pointer<PointerType>::value,\n                 int> = 0>\n    constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept\n    -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())\n    {\n        // delegate the call to get_ptr\n        return get_ptr<PointerType>();\n    }\n\n  public:\n    /*!\n    @brief get a (pointer) value (explicit)\n\n    Performs explicit type conversion between the JSON value and a compatible value if required.\n\n    - If the requested type is a pointer to the internally stored JSON value that pointer is returned.\n    No copies are made.\n\n    - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible\n    from the current @ref basic_json.\n\n    - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`\n    method.\n\n    @tparam ValueTypeCV the provided value type\n    @tparam ValueType the returned value type\n\n    @return copy of the JSON value, converted to @tparam ValueType if necessary\n\n    @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required\n\n    @since version 2.1.0\n    */\n    template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>\n#if defined(JSON_HAS_CPP_14)\n    constexpr\n#endif\n    auto get() const noexcept(\n    noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))\n    -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))\n    {\n        // we cannot static_assert on ValueTypeCV being non-const, because\n        // there is support for get<const basic_json_t>(), which is why we\n        // still need the uncvref\n        static_assert(!std::is_reference<ValueTypeCV>::value,\n                      \"get() cannot be used with reference types, you might want to use get_ref()\");\n        return get_impl<ValueType>(detail::priority_tag<4> {});\n    }\n\n    /*!\n    @brief get a pointer value (explicit)\n\n    Explicit pointer access to the internally stored JSON value. No copies are\n    made.\n\n    @warning The pointer becomes invalid if the underlying JSON object\n    changes.\n\n    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref\n    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,\n    @ref number_unsigned_t, or @ref number_float_t.\n\n    @return pointer to the internally stored JSON value if the requested\n    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise\n\n    @complexity Constant.\n\n    @liveexample{The example below shows how pointers to internal values of a\n    JSON value can be requested. Note that no type conversions are made and a\n    `nullptr` is returned if the value and the requested pointer type does not\n    match.,get__PointerType}\n\n    @sa see @ref get_ptr() for explicit pointer-member access\n\n    @since version 1.0.0\n    */\n    template<typename PointerType, typename std::enable_if<\n                 std::is_pointer<PointerType>::value, int>::type = 0>\n    auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())\n    {\n        // delegate the call to get_ptr\n        return get_ptr<PointerType>();\n    }\n\n    /// @brief get a value (explicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_to/\n    template < typename ValueType,\n               detail::enable_if_t <\n                   !detail::is_basic_json<ValueType>::value&&\n                   detail::has_from_json<basic_json_t, ValueType>::value,\n                   int > = 0 >\n    ValueType & get_to(ValueType& v) const noexcept(noexcept(\n                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))\n    {\n        JSONSerializer<ValueType>::from_json(*this, v);\n        return v;\n    }\n\n    // specialization to allow calling get_to with a basic_json value\n    // see https://github.com/nlohmann/json/issues/2175\n    template<typename ValueType,\n             detail::enable_if_t <\n                 detail::is_basic_json<ValueType>::value,\n                 int> = 0>\n    ValueType & get_to(ValueType& v) const\n    {\n        v = *this;\n        return v;\n    }\n\n    template <\n        typename T, std::size_t N,\n        typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n        detail::enable_if_t <\n            detail::has_from_json<basic_json_t, Array>::value, int > = 0 >\n    Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n    noexcept(noexcept(JSONSerializer<Array>::from_json(\n                          std::declval<const basic_json_t&>(), v)))\n    {\n        JSONSerializer<Array>::from_json(*this, v);\n        return v;\n    }\n\n    /// @brief get a reference value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ref/\n    template<typename ReferenceType, typename std::enable_if<\n                 std::is_reference<ReferenceType>::value, int>::type = 0>\n    ReferenceType get_ref()\n    {\n        // delegate call to get_ref_impl\n        return get_ref_impl<ReferenceType>(*this);\n    }\n\n    /// @brief get a reference value (implicit)\n    /// @sa https://json.nlohmann.me/api/basic_json/get_ref/\n    template < typename ReferenceType, typename std::enable_if <\n                   std::is_reference<ReferenceType>::value&&\n                   std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >\n    ReferenceType get_ref() const\n    {\n        // delegate call to get_ref_impl\n        return get_ref_impl<ReferenceType>(*this);\n    }\n\n    /*!\n    @brief get a value (implicit)\n\n    Implicit type conversion between the JSON value and a compatible value.\n    The call is realized by calling @ref get() const.\n\n    @tparam ValueType non-pointer type compatible to the JSON value, for\n    instance `int` for JSON integer numbers, `bool` for JSON booleans, or\n    `std::vector` types for JSON arrays. The character type of @ref string_t\n    as well as an initializer list of this type is excluded to avoid\n    ambiguities as these types implicitly convert to `std::string`.\n\n    @return copy of the JSON value, converted to type @a ValueType\n\n    @throw type_error.302 in case passed type @a ValueType is incompatible\n    to the JSON value type (e.g., the JSON value is of type boolean, but a\n    string is requested); see example below\n\n    @complexity Linear in the size of the JSON value.\n\n    @liveexample{The example below shows several conversions from JSON values\n    to other types. There a few things to note: (1) Floating-point numbers can\n    be converted to integers\\, (2) A JSON array can be converted to a standard\n    `std::vector<short>`\\, (3) A JSON object can be converted to C++\n    associative containers such as `std::unordered_map<std::string\\,\n    json>`.,operator__ValueType}\n\n    @since version 1.0.0\n    */\n    template < typename ValueType, typename std::enable_if <\n                   detail::conjunction <\n                       detail::negation<std::is_pointer<ValueType>>,\n                       detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,\n                                        detail::negation<std::is_same<ValueType, typename string_t::value_type>>,\n                                        detail::negation<detail::is_basic_json<ValueType>>,\n                                        detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,\n\n#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))\n                                                detail::negation<std::is_same<ValueType, std::string_view>>,\n#endif\n                                                detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>\n                                                >::value, int >::type = 0 >\n                                        JSON_EXPLICIT operator ValueType() const\n    {\n        // delegate the call to get<>() const\n        return get<ValueType>();\n    }\n\n    /// @brief get a binary value\n    /// @sa https://json.nlohmann.me/api/basic_json/get_binary/\n    binary_t& get_binary()\n    {\n        if (!is_binary())\n        {\n            JSON_THROW(type_error::create(302, \"type must be binary, but is \" + std::string(type_name()), *this));\n        }\n\n        return *get_ptr<binary_t*>();\n    }\n\n    /// @brief get a binary value\n    /// @sa https://json.nlohmann.me/api/basic_json/get_binary/\n    const binary_t& get_binary() const\n    {\n        if (!is_binary())\n        {\n            JSON_THROW(type_error::create(302, \"type must be binary, but is \" + std::string(type_name()), *this));\n        }\n\n        return *get_ptr<const binary_t*>();\n    }\n\n    /// @}\n\n\n    ////////////////////\n    // element access //\n    ////////////////////\n\n    /// @name element access\n    /// Access to the JSON value.\n    /// @{\n\n    /// @brief access specified array element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    reference at(size_type idx)\n    {\n        // at only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            JSON_TRY\n            {\n                return set_parent(m_value.array->at(idx));\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified array element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    const_reference at(size_type idx) const\n    {\n        // at only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            JSON_TRY\n            {\n                return m_value.array->at(idx);\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified object element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    reference at(const typename object_t::key_type& key)\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_TRY\n            {\n                return set_parent(m_value.object->at(key));\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(403, \"key '\" + key + \"' not found\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified object element with bounds checking\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    const_reference at(const typename object_t::key_type& key) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_TRY\n            {\n                return m_value.object->at(key);\n            }\n            JSON_CATCH (std::out_of_range&)\n            {\n                // create better exception explanation\n                JSON_THROW(out_of_range::create(403, \"key '\" + key + \"' not found\", *this));\n            }\n        }\n        else\n        {\n            JSON_THROW(type_error::create(304, \"cannot use at() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief access specified array element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    reference operator[](size_type idx)\n    {\n        // implicitly convert null value to an empty array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value.array = create<array_t>();\n            assert_invariant();\n        }\n\n        // operator[] only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            // fill up array with null values if given idx is outside range\n            if (idx >= m_value.array->size())\n            {\n#if JSON_DIAGNOSTICS\n                // remember array size & capacity before resizing\n                const auto old_size = m_value.array->size();\n                const auto old_capacity = m_value.array->capacity();\n#endif\n                m_value.array->resize(idx + 1);\n\n#if JSON_DIAGNOSTICS\n                if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))\n                {\n                    // capacity has changed: update all parents\n                    set_parents();\n                }\n                else\n                {\n                    // set parent for values added above\n                    set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));\n                }\n#endif\n                assert_invariant();\n            }\n\n            return m_value.array->operator[](idx);\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a numeric argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified array element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    const_reference operator[](size_type idx) const\n    {\n        // const operator[] only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            return m_value.array->operator[](idx);\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a numeric argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    reference operator[](const typename object_t::key_type& key)\n    {\n        // implicitly convert null value to an empty object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value.object = create<object_t>();\n            assert_invariant();\n        }\n\n        // operator[] only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            return set_parent(m_value.object->operator[](key));\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    const_reference operator[](const typename object_t::key_type& key) const\n    {\n        // const operator[] only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());\n            return m_value.object->find(key)->second;\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    template<typename T>\n    JSON_HEDLEY_NON_NULL(2)\n    reference operator[](T* key)\n    {\n        // implicitly convert null to object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value = value_t::object;\n            assert_invariant();\n        }\n\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            return set_parent(m_value.object->operator[](key));\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    template<typename T>\n    JSON_HEDLEY_NON_NULL(2)\n    const_reference operator[](T* key) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());\n            return m_value.object->find(key)->second;\n        }\n\n        JSON_THROW(type_error::create(305, \"cannot use operator[] with a string argument with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    /// using std::is_convertible in a std::enable_if will fail when using explicit conversions\n    template < class ValueType, typename std::enable_if <\n                   detail::is_getable<basic_json_t, ValueType>::value\n                   && !std::is_same<value_t, ValueType>::value, int >::type = 0 >\n    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            // if key is found, return value and given default value otherwise\n            const auto it = find(key);\n            if (it != end())\n            {\n                return it->template get<ValueType>();\n            }\n\n            return default_value;\n        }\n\n        JSON_THROW(type_error::create(306, \"cannot use value() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    /// overload for a default value of type const char*\n    string_t value(const typename object_t::key_type& key, const char* default_value) const\n    {\n        return value(key, string_t(default_value));\n    }\n\n    /// @brief access specified object element via JSON Pointer with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    template<class ValueType, typename std::enable_if<\n                 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>\n    ValueType value(const json_pointer& ptr, const ValueType& default_value) const\n    {\n        // at only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            // if pointer resolves a value, return it or use default value\n            JSON_TRY\n            {\n                return ptr.get_checked(this).template get<ValueType>();\n            }\n            JSON_INTERNAL_CATCH (out_of_range&)\n            {\n                return default_value;\n            }\n        }\n\n        JSON_THROW(type_error::create(306, \"cannot use value() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief access specified object element via JSON Pointer with default value\n    /// @sa https://json.nlohmann.me/api/basic_json/value/\n    /// overload for a default value of type const char*\n    JSON_HEDLEY_NON_NULL(3)\n    string_t value(const json_pointer& ptr, const char* default_value) const\n    {\n        return value(ptr, string_t(default_value));\n    }\n\n    /// @brief access the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/front/\n    reference front()\n    {\n        return *begin();\n    }\n\n    /// @brief access the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/front/\n    const_reference front() const\n    {\n        return *cbegin();\n    }\n\n    /// @brief access the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/back/\n    reference back()\n    {\n        auto tmp = end();\n        --tmp;\n        return *tmp;\n    }\n\n    /// @brief access the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/back/\n    const_reference back() const\n    {\n        auto tmp = cend();\n        --tmp;\n        return *tmp;\n    }\n\n    /// @brief remove element given an iterator\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    template < class IteratorType, typename std::enable_if <\n                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||\n                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type\n               = 0 >\n    IteratorType erase(IteratorType pos)\n    {\n        // make sure iterator fits the current value\n        if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n        }\n\n        IteratorType result = end();\n\n        switch (m_type)\n        {\n            case value_t::boolean:\n            case value_t::number_float:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::string:\n            case value_t::binary:\n            {\n                if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))\n                {\n                    JSON_THROW(invalid_iterator::create(205, \"iterator out of range\", *this));\n                }\n\n                if (is_string())\n                {\n                    AllocatorType<string_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);\n                    m_value.string = nullptr;\n                }\n                else if (is_binary())\n                {\n                    AllocatorType<binary_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);\n                    m_value.binary = nullptr;\n                }\n\n                m_type = value_t::null;\n                assert_invariant();\n                break;\n            }\n\n            case value_t::object:\n            {\n                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);\n                break;\n            }\n\n            case value_t::array:\n            {\n                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n        }\n\n        return result;\n    }\n\n    /// @brief remove elements given an iterator range\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    template < class IteratorType, typename std::enable_if <\n                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||\n                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type\n               = 0 >\n    IteratorType erase(IteratorType first, IteratorType last)\n    {\n        // make sure iterator fits the current value\n        if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(203, \"iterators do not fit current value\", *this));\n        }\n\n        IteratorType result = end();\n\n        switch (m_type)\n        {\n            case value_t::boolean:\n            case value_t::number_float:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::string:\n            case value_t::binary:\n            {\n                if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()\n                                       || !last.m_it.primitive_iterator.is_end()))\n                {\n                    JSON_THROW(invalid_iterator::create(204, \"iterators out of range\", *this));\n                }\n\n                if (is_string())\n                {\n                    AllocatorType<string_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);\n                    m_value.string = nullptr;\n                }\n                else if (is_binary())\n                {\n                    AllocatorType<binary_t> alloc;\n                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);\n                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);\n                    m_value.binary = nullptr;\n                }\n\n                m_type = value_t::null;\n                assert_invariant();\n                break;\n            }\n\n            case value_t::object:\n            {\n                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,\n                                              last.m_it.object_iterator);\n                break;\n            }\n\n            case value_t::array:\n            {\n                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,\n                                             last.m_it.array_iterator);\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n        }\n\n        return result;\n    }\n\n    /// @brief remove element from a JSON object given a key\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    size_type erase(const typename object_t::key_type& key)\n    {\n        // this erase only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            return m_value.object->erase(key);\n        }\n\n        JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief remove element from a JSON array given an index\n    /// @sa https://json.nlohmann.me/api/basic_json/erase/\n    void erase(const size_type idx)\n    {\n        // this erase only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            if (JSON_HEDLEY_UNLIKELY(idx >= size()))\n            {\n                JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", *this));\n            }\n\n            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));\n        }\n        else\n        {\n            JSON_THROW(type_error::create(307, \"cannot use erase() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @}\n\n\n    ////////////\n    // lookup //\n    ////////////\n\n    /// @name lookup\n    /// @{\n\n    /// @brief find an element in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/find/\n    template<typename KeyT>\n    iterator find(KeyT&& key)\n    {\n        auto result = end();\n\n        if (is_object())\n        {\n            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));\n        }\n\n        return result;\n    }\n\n    /// @brief find an element in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/find/\n    template<typename KeyT>\n    const_iterator find(KeyT&& key) const\n    {\n        auto result = cend();\n\n        if (is_object())\n        {\n            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));\n        }\n\n        return result;\n    }\n\n    /// @brief returns the number of occurrences of a key in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/count/\n    template<typename KeyT>\n    size_type count(KeyT&& key) const\n    {\n        // return 0 for all nonobject types\n        return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;\n    }\n\n    /// @brief check the existence of an element in a JSON object\n    /// @sa https://json.nlohmann.me/api/basic_json/contains/\n    template < typename KeyT, typename std::enable_if <\n                   !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >\n    bool contains(KeyT && key) const\n    {\n        return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();\n    }\n\n    /// @brief check the existence of an element in a JSON object given a JSON pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/contains/\n    bool contains(const json_pointer& ptr) const\n    {\n        return ptr.contains(this);\n    }\n\n    /// @}\n\n\n    ///////////////\n    // iterators //\n    ///////////////\n\n    /// @name iterators\n    /// @{\n\n    /// @brief returns an iterator to the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/begin/\n    iterator begin() noexcept\n    {\n        iterator result(this);\n        result.set_begin();\n        return result;\n    }\n\n    /// @brief returns an iterator to the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/begin/\n    const_iterator begin() const noexcept\n    {\n        return cbegin();\n    }\n\n    /// @brief returns a const iterator to the first element\n    /// @sa https://json.nlohmann.me/api/basic_json/cbegin/\n    const_iterator cbegin() const noexcept\n    {\n        const_iterator result(this);\n        result.set_begin();\n        return result;\n    }\n\n    /// @brief returns an iterator to one past the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/end/\n    iterator end() noexcept\n    {\n        iterator result(this);\n        result.set_end();\n        return result;\n    }\n\n    /// @brief returns an iterator to one past the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/end/\n    const_iterator end() const noexcept\n    {\n        return cend();\n    }\n\n    /// @brief returns an iterator to one past the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/cend/\n    const_iterator cend() const noexcept\n    {\n        const_iterator result(this);\n        result.set_end();\n        return result;\n    }\n\n    /// @brief returns an iterator to the reverse-beginning\n    /// @sa https://json.nlohmann.me/api/basic_json/rbegin/\n    reverse_iterator rbegin() noexcept\n    {\n        return reverse_iterator(end());\n    }\n\n    /// @brief returns an iterator to the reverse-beginning\n    /// @sa https://json.nlohmann.me/api/basic_json/rbegin/\n    const_reverse_iterator rbegin() const noexcept\n    {\n        return crbegin();\n    }\n\n    /// @brief returns an iterator to the reverse-end\n    /// @sa https://json.nlohmann.me/api/basic_json/rend/\n    reverse_iterator rend() noexcept\n    {\n        return reverse_iterator(begin());\n    }\n\n    /// @brief returns an iterator to the reverse-end\n    /// @sa https://json.nlohmann.me/api/basic_json/rend/\n    const_reverse_iterator rend() const noexcept\n    {\n        return crend();\n    }\n\n    /// @brief returns a const reverse iterator to the last element\n    /// @sa https://json.nlohmann.me/api/basic_json/crbegin/\n    const_reverse_iterator crbegin() const noexcept\n    {\n        return const_reverse_iterator(cend());\n    }\n\n    /// @brief returns a const reverse iterator to one before the first\n    /// @sa https://json.nlohmann.me/api/basic_json/crend/\n    const_reverse_iterator crend() const noexcept\n    {\n        return const_reverse_iterator(cbegin());\n    }\n\n  public:\n    /// @brief wrapper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    /// @deprecated This function is deprecated since 3.1.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use @ref items() instead;\n    ///             that is, replace `json::iterator_wrapper(j)` with `j.items()`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())\n    static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept\n    {\n        return ref.items();\n    }\n\n    /// @brief wrapper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    /// @deprecated This function is deprecated since 3.1.0 and will be removed in\n    ///         version 4.0.0 of the library. Please use @ref items() instead;\n    ///         that is, replace `json::iterator_wrapper(j)` with `j.items()`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())\n    static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept\n    {\n        return ref.items();\n    }\n\n    /// @brief helper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    iteration_proxy<iterator> items() noexcept\n    {\n        return iteration_proxy<iterator>(*this);\n    }\n\n    /// @brief helper to access iterator member functions in range-based for\n    /// @sa https://json.nlohmann.me/api/basic_json/items/\n    iteration_proxy<const_iterator> items() const noexcept\n    {\n        return iteration_proxy<const_iterator>(*this);\n    }\n\n    /// @}\n\n\n    //////////////\n    // capacity //\n    //////////////\n\n    /// @name capacity\n    /// @{\n\n    /// @brief checks whether the container is empty.\n    /// @sa https://json.nlohmann.me/api/basic_json/empty/\n    bool empty() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::null:\n            {\n                // null values are empty\n                return true;\n            }\n\n            case value_t::array:\n            {\n                // delegate call to array_t::empty()\n                return m_value.array->empty();\n            }\n\n            case value_t::object:\n            {\n                // delegate call to object_t::empty()\n                return m_value.object->empty();\n            }\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // all other types are nonempty\n                return false;\n            }\n        }\n    }\n\n    /// @brief returns the number of elements\n    /// @sa https://json.nlohmann.me/api/basic_json/size/\n    size_type size() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::null:\n            {\n                // null values are empty\n                return 0;\n            }\n\n            case value_t::array:\n            {\n                // delegate call to array_t::size()\n                return m_value.array->size();\n            }\n\n            case value_t::object:\n            {\n                // delegate call to object_t::size()\n                return m_value.object->size();\n            }\n\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // all other types have size 1\n                return 1;\n            }\n        }\n    }\n\n    /// @brief returns the maximum possible number of elements\n    /// @sa https://json.nlohmann.me/api/basic_json/max_size/\n    size_type max_size() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::array:\n            {\n                // delegate call to array_t::max_size()\n                return m_value.array->max_size();\n            }\n\n            case value_t::object:\n            {\n                // delegate call to object_t::max_size()\n                return m_value.object->max_size();\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // all other types have max_size() == size()\n                return size();\n            }\n        }\n    }\n\n    /// @}\n\n\n    ///////////////\n    // modifiers //\n    ///////////////\n\n    /// @name modifiers\n    /// @{\n\n    /// @brief clears the contents\n    /// @sa https://json.nlohmann.me/api/basic_json/clear/\n    void clear() noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::number_integer:\n            {\n                m_value.number_integer = 0;\n                break;\n            }\n\n            case value_t::number_unsigned:\n            {\n                m_value.number_unsigned = 0;\n                break;\n            }\n\n            case value_t::number_float:\n            {\n                m_value.number_float = 0.0;\n                break;\n            }\n\n            case value_t::boolean:\n            {\n                m_value.boolean = false;\n                break;\n            }\n\n            case value_t::string:\n            {\n                m_value.string->clear();\n                break;\n            }\n\n            case value_t::binary:\n            {\n                m_value.binary->clear();\n                break;\n            }\n\n            case value_t::array:\n            {\n                m_value.array->clear();\n                break;\n            }\n\n            case value_t::object:\n            {\n                m_value.object->clear();\n                break;\n            }\n\n            case value_t::null:\n            case value_t::discarded:\n            default:\n                break;\n        }\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(basic_json&& val)\n    {\n        // push_back only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))\n        {\n            JSON_THROW(type_error::create(308, \"cannot use push_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value = value_t::array;\n            assert_invariant();\n        }\n\n        // add element to array (move semantics)\n        const auto old_capacity = m_value.array->capacity();\n        m_value.array->push_back(std::move(val));\n        set_parent(m_value.array->back(), old_capacity);\n        // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(basic_json&& val)\n    {\n        push_back(std::move(val));\n        return *this;\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(const basic_json& val)\n    {\n        // push_back only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))\n        {\n            JSON_THROW(type_error::create(308, \"cannot use push_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value = value_t::array;\n            assert_invariant();\n        }\n\n        // add element to array\n        const auto old_capacity = m_value.array->capacity();\n        m_value.array->push_back(val);\n        set_parent(m_value.array->back(), old_capacity);\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(const basic_json& val)\n    {\n        push_back(val);\n        return *this;\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(const typename object_t::value_type& val)\n    {\n        // push_back only works for null objects or objects\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))\n        {\n            JSON_THROW(type_error::create(308, \"cannot use push_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value = value_t::object;\n            assert_invariant();\n        }\n\n        // add element to object\n        auto res = m_value.object->insert(val);\n        set_parent(res.first->second);\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(const typename object_t::value_type& val)\n    {\n        push_back(val);\n        return *this;\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/push_back/\n    void push_back(initializer_list_t init)\n    {\n        if (is_object() && init.size() == 2 && (*init.begin())->is_string())\n        {\n            basic_json&& key = init.begin()->moved_or_copied();\n            push_back(typename object_t::value_type(\n                          std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));\n        }\n        else\n        {\n            push_back(basic_json(init));\n        }\n    }\n\n    /// @brief add an object to an object\n    /// @sa https://json.nlohmann.me/api/basic_json/operator+=/\n    reference operator+=(initializer_list_t init)\n    {\n        push_back(init);\n        return *this;\n    }\n\n    /// @brief add an object to an array\n    /// @sa https://json.nlohmann.me/api/basic_json/emplace_back/\n    template<class... Args>\n    reference emplace_back(Args&& ... args)\n    {\n        // emplace_back only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))\n        {\n            JSON_THROW(type_error::create(311, \"cannot use emplace_back() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an array\n        if (is_null())\n        {\n            m_type = value_t::array;\n            m_value = value_t::array;\n            assert_invariant();\n        }\n\n        // add element to array (perfect forwarding)\n        const auto old_capacity = m_value.array->capacity();\n        m_value.array->emplace_back(std::forward<Args>(args)...);\n        return set_parent(m_value.array->back(), old_capacity);\n    }\n\n    /// @brief add an object to an object if key does not exist\n    /// @sa https://json.nlohmann.me/api/basic_json/emplace/\n    template<class... Args>\n    std::pair<iterator, bool> emplace(Args&& ... args)\n    {\n        // emplace only works for null objects or arrays\n        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))\n        {\n            JSON_THROW(type_error::create(311, \"cannot use emplace() with \" + std::string(type_name()), *this));\n        }\n\n        // transform null object into an object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value = value_t::object;\n            assert_invariant();\n        }\n\n        // add element to array (perfect forwarding)\n        auto res = m_value.object->emplace(std::forward<Args>(args)...);\n        set_parent(res.first->second);\n\n        // create result iterator and set iterator to the result of emplace\n        auto it = begin();\n        it.m_it.object_iterator = res.first;\n\n        // return pair of iterator and boolean\n        return {it, res.second};\n    }\n\n    /// Helper for insertion of an iterator\n    /// @note: This uses std::distance to support GCC 4.8,\n    ///        see https://github.com/nlohmann/json/pull/1257\n    template<typename... Args>\n    iterator insert_iterator(const_iterator pos, Args&& ... args)\n    {\n        iterator result(this);\n        JSON_ASSERT(m_value.array != nullptr);\n\n        auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);\n        m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);\n        result.m_it.array_iterator = m_value.array->begin() + insert_pos;\n\n        // This could have been written as:\n        // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);\n        // but the return value of insert is missing in GCC 4.8, so it is written this way instead.\n\n        set_parents();\n        return result;\n    }\n\n    /// @brief inserts element into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, const basic_json& val)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            // check if iterator pos fits to this JSON value\n            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n            {\n                JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n            }\n\n            // insert to array and return iterator\n            return insert_iterator(pos, val);\n        }\n\n        JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief inserts element into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, basic_json&& val)\n    {\n        return insert(pos, val);\n    }\n\n    /// @brief inserts copies of element into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, size_type cnt, const basic_json& val)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            // check if iterator pos fits to this JSON value\n            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n            {\n                JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n            }\n\n            // insert to array and return iterator\n            return insert_iterator(pos, cnt, val);\n        }\n\n        JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n    }\n\n    /// @brief inserts range of elements into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, const_iterator first, const_iterator last)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_UNLIKELY(!is_array()))\n        {\n            JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n        }\n\n        // check if iterator pos fits to this JSON value\n        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n        }\n\n        // check if range iterators belong to the same JSON object\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(210, \"iterators do not fit\", *this));\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(first.m_object == this))\n        {\n            JSON_THROW(invalid_iterator::create(211, \"passed iterators may not belong to container\", *this));\n        }\n\n        // insert to array and return iterator\n        return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);\n    }\n\n    /// @brief inserts elements from initializer list into array\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    iterator insert(const_iterator pos, initializer_list_t ilist)\n    {\n        // insert only works for arrays\n        if (JSON_HEDLEY_UNLIKELY(!is_array()))\n        {\n            JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n        }\n\n        // check if iterator pos fits to this JSON value\n        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterator does not fit current value\", *this));\n        }\n\n        // insert to array and return iterator\n        return insert_iterator(pos, ilist.begin(), ilist.end());\n    }\n\n    /// @brief inserts range of elements into object\n    /// @sa https://json.nlohmann.me/api/basic_json/insert/\n    void insert(const_iterator first, const_iterator last)\n    {\n        // insert only works for objects\n        if (JSON_HEDLEY_UNLIKELY(!is_object()))\n        {\n            JSON_THROW(type_error::create(309, \"cannot use insert() with \" + std::string(type_name()), *this));\n        }\n\n        // check if range iterators belong to the same JSON object\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(210, \"iterators do not fit\", *this));\n        }\n\n        // passed iterators must belong to objects\n        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))\n        {\n            JSON_THROW(invalid_iterator::create(202, \"iterators first and last must point to objects\", *this));\n        }\n\n        m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);\n    }\n\n    /// @brief updates a JSON object from another object, overwriting existing keys\n    /// @sa https://json.nlohmann.me/api/basic_json/update/\n    void update(const_reference j, bool merge_objects = false)\n    {\n        update(j.begin(), j.end(), merge_objects);\n    }\n\n    /// @brief updates a JSON object from another object, overwriting existing keys\n    /// @sa https://json.nlohmann.me/api/basic_json/update/\n    void update(const_iterator first, const_iterator last, bool merge_objects = false)\n    {\n        // implicitly convert null value to an empty object\n        if (is_null())\n        {\n            m_type = value_t::object;\n            m_value.object = create<object_t>();\n            assert_invariant();\n        }\n\n        if (JSON_HEDLEY_UNLIKELY(!is_object()))\n        {\n            JSON_THROW(type_error::create(312, \"cannot use update() with \" + std::string(type_name()), *this));\n        }\n\n        // check if range iterators belong to the same JSON object\n        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))\n        {\n            JSON_THROW(invalid_iterator::create(210, \"iterators do not fit\", *this));\n        }\n\n        // passed iterators must belong to objects\n        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))\n        {\n            JSON_THROW(type_error::create(312, \"cannot use update() with \" + std::string(first.m_object->type_name()), *first.m_object));\n        }\n\n        for (auto it = first; it != last; ++it)\n        {\n            if (merge_objects && it.value().is_object())\n            {\n                auto it2 = m_value.object->find(it.key());\n                if (it2 != m_value.object->end())\n                {\n                    it2->second.update(it.value(), true);\n                    continue;\n                }\n            }\n            m_value.object->operator[](it.key()) = it.value();\n#if JSON_DIAGNOSTICS\n            m_value.object->operator[](it.key()).m_parent = this;\n#endif\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(reference other) noexcept (\n        std::is_nothrow_move_constructible<value_t>::value&&\n        std::is_nothrow_move_assignable<value_t>::value&&\n        std::is_nothrow_move_constructible<json_value>::value&&\n        std::is_nothrow_move_assignable<json_value>::value\n    )\n    {\n        std::swap(m_type, other.m_type);\n        std::swap(m_value, other.m_value);\n\n        set_parents();\n        other.set_parents();\n        assert_invariant();\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    friend void swap(reference left, reference right) noexcept (\n        std::is_nothrow_move_constructible<value_t>::value&&\n        std::is_nothrow_move_assignable<value_t>::value&&\n        std::is_nothrow_move_constructible<json_value>::value&&\n        std::is_nothrow_move_assignable<json_value>::value\n    )\n    {\n        left.swap(right);\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(array_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for arrays\n        if (JSON_HEDLEY_LIKELY(is_array()))\n        {\n            std::swap(*(m_value.array), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(object_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for objects\n        if (JSON_HEDLEY_LIKELY(is_object()))\n        {\n            std::swap(*(m_value.object), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(string_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for strings\n        if (JSON_HEDLEY_LIKELY(is_string()))\n        {\n            std::swap(*(m_value.string), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(binary_t& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for strings\n        if (JSON_HEDLEY_LIKELY(is_binary()))\n        {\n            std::swap(*(m_value.binary), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @brief exchanges the values\n    /// @sa https://json.nlohmann.me/api/basic_json/swap/\n    void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)\n    {\n        // swap only works for strings\n        if (JSON_HEDLEY_LIKELY(is_binary()))\n        {\n            std::swap(*(m_value.binary), other);\n        }\n        else\n        {\n            JSON_THROW(type_error::create(310, \"cannot use swap() with \" + std::string(type_name()), *this));\n        }\n    }\n\n    /// @}\n\n  public:\n    //////////////////////////////////////////\n    // lexicographical comparison operators //\n    //////////////////////////////////////////\n\n    /// @name lexicographical comparison operators\n    /// @{\n\n    /// @brief comparison: equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/\n    friend bool operator==(const_reference lhs, const_reference rhs) noexcept\n    {\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n        const auto lhs_type = lhs.type();\n        const auto rhs_type = rhs.type();\n\n        if (lhs_type == rhs_type)\n        {\n            switch (lhs_type)\n            {\n                case value_t::array:\n                    return *lhs.m_value.array == *rhs.m_value.array;\n\n                case value_t::object:\n                    return *lhs.m_value.object == *rhs.m_value.object;\n\n                case value_t::null:\n                    return true;\n\n                case value_t::string:\n                    return *lhs.m_value.string == *rhs.m_value.string;\n\n                case value_t::boolean:\n                    return lhs.m_value.boolean == rhs.m_value.boolean;\n\n                case value_t::number_integer:\n                    return lhs.m_value.number_integer == rhs.m_value.number_integer;\n\n                case value_t::number_unsigned:\n                    return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;\n\n                case value_t::number_float:\n                    return lhs.m_value.number_float == rhs.m_value.number_float;\n\n                case value_t::binary:\n                    return *lhs.m_value.binary == *rhs.m_value.binary;\n\n                case value_t::discarded:\n                default:\n                    return false;\n            }\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)\n        {\n            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)\n        {\n            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);\n        }\n\n        return false;\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n    }\n\n    /// @brief comparison: equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator==(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs == basic_json(rhs);\n    }\n\n    /// @brief comparison: equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator==(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) == rhs;\n    }\n\n    /// @brief comparison: not equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/\n    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(lhs == rhs);\n    }\n\n    /// @brief comparison: not equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs != basic_json(rhs);\n    }\n\n    /// @brief comparison: not equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) != rhs;\n    }\n\n    /// @brief comparison: less than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/\n    friend bool operator<(const_reference lhs, const_reference rhs) noexcept\n    {\n        const auto lhs_type = lhs.type();\n        const auto rhs_type = rhs.type();\n\n        if (lhs_type == rhs_type)\n        {\n            switch (lhs_type)\n            {\n                case value_t::array:\n                    // note parentheses are necessary, see\n                    // https://github.com/nlohmann/json/issues/1530\n                    return (*lhs.m_value.array) < (*rhs.m_value.array);\n\n                case value_t::object:\n                    return (*lhs.m_value.object) < (*rhs.m_value.object);\n\n                case value_t::null:\n                    return false;\n\n                case value_t::string:\n                    return (*lhs.m_value.string) < (*rhs.m_value.string);\n\n                case value_t::boolean:\n                    return (lhs.m_value.boolean) < (rhs.m_value.boolean);\n\n                case value_t::number_integer:\n                    return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);\n\n                case value_t::number_unsigned:\n                    return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);\n\n                case value_t::number_float:\n                    return (lhs.m_value.number_float) < (rhs.m_value.number_float);\n\n                case value_t::binary:\n                    return (*lhs.m_value.binary) < (*rhs.m_value.binary);\n\n                case value_t::discarded:\n                default:\n                    return false;\n            }\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)\n        {\n            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)\n        {\n            return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;\n        }\n        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);\n        }\n        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)\n        {\n            return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);\n        }\n        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)\n        {\n            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;\n        }\n\n        // We only reach this line if we cannot compare values. In that case,\n        // we compare types. Note we have to call the operator explicitly,\n        // because MSVC has problems otherwise.\n        return operator<(lhs_type, rhs_type);\n    }\n\n    /// @brief comparison: less than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs < basic_json(rhs);\n    }\n\n    /// @brief comparison: less than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) < rhs;\n    }\n\n    /// @brief comparison: less than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_le/\n    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(rhs < lhs);\n    }\n\n    /// @brief comparison: less than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_le/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs <= basic_json(rhs);\n    }\n\n    /// @brief comparison: less than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_le/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) <= rhs;\n    }\n\n    /// @brief comparison: greater than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/\n    friend bool operator>(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(lhs <= rhs);\n    }\n\n    /// @brief comparison: greater than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs > basic_json(rhs);\n    }\n\n    /// @brief comparison: greater than\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) > rhs;\n    }\n\n    /// @brief comparison: greater than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/\n    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept\n    {\n        return !(lhs < rhs);\n    }\n\n    /// @brief comparison: greater than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept\n    {\n        return lhs >= basic_json(rhs);\n    }\n\n    /// @brief comparison: greater than or equal\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/\n    template<typename ScalarType, typename std::enable_if<\n                 std::is_scalar<ScalarType>::value, int>::type = 0>\n    friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept\n    {\n        return basic_json(lhs) >= rhs;\n    }\n\n    /// @}\n\n    ///////////////////\n    // serialization //\n    ///////////////////\n\n    /// @name serialization\n    /// @{\n#ifndef JSON_NO_IO\n    /// @brief serialize to stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/\n    friend std::ostream& operator<<(std::ostream& o, const basic_json& j)\n    {\n        // read width member and use it as indentation parameter if nonzero\n        const bool pretty_print = o.width() > 0;\n        const auto indentation = pretty_print ? o.width() : 0;\n\n        // reset width to 0 for subsequent calls to this stream\n        o.width(0);\n\n        // do the actual serialization\n        serializer s(detail::output_adapter<char>(o), o.fill());\n        s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));\n        return o;\n    }\n\n    /// @brief serialize to stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/\n    /// @deprecated This function is deprecated since 3.0.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use\n    ///             operator<<(std::ostream&, const basic_json&) instead; that is,\n    ///             replace calls like `j >> o;` with `o << j;`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))\n    friend std::ostream& operator>>(const basic_json& j, std::ostream& o)\n    {\n        return o << j;\n    }\n#endif  // JSON_NO_IO\n    /// @}\n\n\n    /////////////////////\n    // deserialization //\n    /////////////////////\n\n    /// @name deserialization\n    /// @{\n\n    /// @brief deserialize from a compatible input\n    /// @sa https://json.nlohmann.me/api/basic_json/parse/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json parse(InputType&& i,\n                            const parser_callback_t cb = nullptr,\n                            const bool allow_exceptions = true,\n                            const bool ignore_comments = false)\n    {\n        basic_json result;\n        parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);\n        return result;\n    }\n\n    /// @brief deserialize from a pair of character iterators\n    /// @sa https://json.nlohmann.me/api/basic_json/parse/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json parse(IteratorType first,\n                            IteratorType last,\n                            const parser_callback_t cb = nullptr,\n                            const bool allow_exceptions = true,\n                            const bool ignore_comments = false)\n    {\n        basic_json result;\n        parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);\n        return result;\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))\n    static basic_json parse(detail::span_input_adapter&& i,\n                            const parser_callback_t cb = nullptr,\n                            const bool allow_exceptions = true,\n                            const bool ignore_comments = false)\n    {\n        basic_json result;\n        parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);\n        return result;\n    }\n\n    /// @brief check if the input is valid JSON\n    /// @sa https://json.nlohmann.me/api/basic_json/accept/\n    template<typename InputType>\n    static bool accept(InputType&& i,\n                       const bool ignore_comments = false)\n    {\n        return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);\n    }\n\n    /// @brief check if the input is valid JSON\n    /// @sa https://json.nlohmann.me/api/basic_json/accept/\n    template<typename IteratorType>\n    static bool accept(IteratorType first, IteratorType last,\n                       const bool ignore_comments = false)\n    {\n        return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))\n    static bool accept(detail::span_input_adapter&& i,\n                       const bool ignore_comments = false)\n    {\n        return parser(i.get(), nullptr, false, ignore_comments).accept(true);\n    }\n\n    /// @brief generate SAX events\n    /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/\n    template <typename InputType, typename SAX>\n    JSON_HEDLEY_NON_NULL(2)\n    static bool sax_parse(InputType&& i, SAX* sax,\n                          input_format_t format = input_format_t::json,\n                          const bool strict = true,\n                          const bool ignore_comments = false)\n    {\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        return format == input_format_t::json\n               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)\n               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);\n    }\n\n    /// @brief generate SAX events\n    /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/\n    template<class IteratorType, class SAX>\n    JSON_HEDLEY_NON_NULL(3)\n    static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,\n                          input_format_t format = input_format_t::json,\n                          const bool strict = true,\n                          const bool ignore_comments = false)\n    {\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        return format == input_format_t::json\n               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)\n               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);\n    }\n\n    /// @brief generate SAX events\n    /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/\n    /// @deprecated This function is deprecated since 3.8.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use\n    ///             sax_parse(ptr, ptr + len) instead.\n    template <typename SAX>\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))\n    JSON_HEDLEY_NON_NULL(2)\n    static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,\n                          input_format_t format = input_format_t::json,\n                          const bool strict = true,\n                          const bool ignore_comments = false)\n    {\n        auto ia = i.get();\n        return format == input_format_t::json\n               // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)\n               // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);\n    }\n#ifndef JSON_NO_IO\n    /// @brief deserialize from stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/\n    /// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in\n    ///             version 4.0.0 of the library. Please use\n    ///             operator>>(std::istream&, basic_json&) instead; that is,\n    ///             replace calls like `j << i;` with `i >> j;`.\n    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))\n    friend std::istream& operator<<(basic_json& j, std::istream& i)\n    {\n        return operator>>(i, j);\n    }\n\n    /// @brief deserialize from stream\n    /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/\n    friend std::istream& operator>>(std::istream& i, basic_json& j)\n    {\n        parser(detail::input_adapter(i)).parse(false, j);\n        return i;\n    }\n#endif  // JSON_NO_IO\n    /// @}\n\n    ///////////////////////////\n    // convenience functions //\n    ///////////////////////////\n\n    /// @brief return the type as string\n    /// @sa https://json.nlohmann.me/api/basic_json/type_name/\n    JSON_HEDLEY_RETURNS_NON_NULL\n    const char* type_name() const noexcept\n    {\n        switch (m_type)\n        {\n            case value_t::null:\n                return \"null\";\n            case value_t::object:\n                return \"object\";\n            case value_t::array:\n                return \"array\";\n            case value_t::string:\n                return \"string\";\n            case value_t::boolean:\n                return \"boolean\";\n            case value_t::binary:\n                return \"binary\";\n            case value_t::discarded:\n                return \"discarded\";\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            default:\n                return \"number\";\n        }\n    }\n\n\n  JSON_PRIVATE_UNLESS_TESTED:\n    //////////////////////\n    // member variables //\n    //////////////////////\n\n    /// the type of the current element\n    value_t m_type = value_t::null;\n\n    /// the value of the current element\n    json_value m_value = {};\n\n#if JSON_DIAGNOSTICS\n    /// a pointer to a parent value (for debugging purposes)\n    basic_json* m_parent = nullptr;\n#endif\n\n    //////////////////////////////////////////\n    // binary serialization/deserialization //\n    //////////////////////////////////////////\n\n    /// @name binary serialization/deserialization support\n    /// @{\n\n  public:\n    /// @brief create a CBOR serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/\n    static std::vector<std::uint8_t> to_cbor(const basic_json& j)\n    {\n        std::vector<std::uint8_t> result;\n        to_cbor(j, result);\n        return result;\n    }\n\n    /// @brief create a CBOR serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/\n    static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)\n    {\n        binary_writer<std::uint8_t>(o).write_cbor(j);\n    }\n\n    /// @brief create a CBOR serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/\n    static void to_cbor(const basic_json& j, detail::output_adapter<char> o)\n    {\n        binary_writer<char>(o).write_cbor(j);\n    }\n\n    /// @brief create a MessagePack serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/\n    static std::vector<std::uint8_t> to_msgpack(const basic_json& j)\n    {\n        std::vector<std::uint8_t> result;\n        to_msgpack(j, result);\n        return result;\n    }\n\n    /// @brief create a MessagePack serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/\n    static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)\n    {\n        binary_writer<std::uint8_t>(o).write_msgpack(j);\n    }\n\n    /// @brief create a MessagePack serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/\n    static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)\n    {\n        binary_writer<char>(o).write_msgpack(j);\n    }\n\n    /// @brief create a UBJSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/\n    static std::vector<std::uint8_t> to_ubjson(const basic_json& j,\n            const bool use_size = false,\n            const bool use_type = false)\n    {\n        std::vector<std::uint8_t> result;\n        to_ubjson(j, result, use_size, use_type);\n        return result;\n    }\n\n    /// @brief create a UBJSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/\n    static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                          const bool use_size = false, const bool use_type = false)\n    {\n        binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);\n    }\n\n    /// @brief create a UBJSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/\n    static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,\n                          const bool use_size = false, const bool use_type = false)\n    {\n        binary_writer<char>(o).write_ubjson(j, use_size, use_type);\n    }\n\n    /// @brief create a BSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_bson/\n    static std::vector<std::uint8_t> to_bson(const basic_json& j)\n    {\n        std::vector<std::uint8_t> result;\n        to_bson(j, result);\n        return result;\n    }\n\n    /// @brief create a BSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_bson/\n    static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)\n    {\n        binary_writer<std::uint8_t>(o).write_bson(j);\n    }\n\n    /// @brief create a BSON serialization of a given JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/to_bson/\n    static void to_bson(const basic_json& j, detail::output_adapter<char> o)\n    {\n        binary_writer<char>(o).write_bson(j);\n    }\n\n    /// @brief create a JSON value from an input in CBOR format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_cbor(InputType&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in CBOR format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_cbor(IteratorType first, IteratorType last,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))\n    static basic_json from_cbor(const T* ptr, std::size_t len,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);\n    }\n\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))\n    static basic_json from_cbor(detail::span_input_adapter&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true,\n                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in MessagePack format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_msgpack(InputType&& i,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in MessagePack format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_msgpack(IteratorType first, IteratorType last,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))\n    static basic_json from_msgpack(const T* ptr, std::size_t len,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        return from_msgpack(ptr, ptr + len, strict, allow_exceptions);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))\n    static basic_json from_msgpack(detail::span_input_adapter&& i,\n                                   const bool strict = true,\n                                   const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in UBJSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_ubjson(InputType&& i,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in UBJSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_ubjson(IteratorType first, IteratorType last,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))\n    static basic_json from_ubjson(const T* ptr, std::size_t len,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        return from_ubjson(ptr, ptr + len, strict, allow_exceptions);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))\n    static basic_json from_ubjson(detail::span_input_adapter&& i,\n                                  const bool strict = true,\n                                  const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in BSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_bson/\n    template<typename InputType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_bson(InputType&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::forward<InputType>(i));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    /// @brief create a JSON value from an input in BSON format\n    /// @sa https://json.nlohmann.me/api/basic_json/from_bson/\n    template<typename IteratorType>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json from_bson(IteratorType first, IteratorType last,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = detail::input_adapter(std::move(first), std::move(last));\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n\n    template<typename T>\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))\n    static basic_json from_bson(const T* ptr, std::size_t len,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        return from_bson(ptr, ptr + len, strict, allow_exceptions);\n    }\n\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))\n    static basic_json from_bson(detail::span_input_adapter&& i,\n                                const bool strict = true,\n                                const bool allow_exceptions = true)\n    {\n        basic_json result;\n        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);\n        auto ia = i.get();\n        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)\n        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);\n        return res ? result : basic_json(value_t::discarded);\n    }\n    /// @}\n\n    //////////////////////////\n    // JSON Pointer support //\n    //////////////////////////\n\n    /// @name JSON Pointer functions\n    /// @{\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    reference operator[](const json_pointer& ptr)\n    {\n        return ptr.get_unchecked(this);\n    }\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/\n    const_reference operator[](const json_pointer& ptr) const\n    {\n        return ptr.get_unchecked(this);\n    }\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    reference at(const json_pointer& ptr)\n    {\n        return ptr.get_checked(this);\n    }\n\n    /// @brief access specified element via JSON Pointer\n    /// @sa https://json.nlohmann.me/api/basic_json/at/\n    const_reference at(const json_pointer& ptr) const\n    {\n        return ptr.get_checked(this);\n    }\n\n    /// @brief return flattened JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/flatten/\n    basic_json flatten() const\n    {\n        basic_json result(value_t::object);\n        json_pointer::flatten(\"\", *this, result);\n        return result;\n    }\n\n    /// @brief unflatten a previously flattened JSON value\n    /// @sa https://json.nlohmann.me/api/basic_json/unflatten/\n    basic_json unflatten() const\n    {\n        return json_pointer::unflatten(*this);\n    }\n\n    /// @}\n\n    //////////////////////////\n    // JSON Patch functions //\n    //////////////////////////\n\n    /// @name JSON Patch functions\n    /// @{\n\n    /// @brief applies a JSON patch\n    /// @sa https://json.nlohmann.me/api/basic_json/patch/\n    basic_json patch(const basic_json& json_patch) const\n    {\n        // make a working copy to apply the patch to\n        basic_json result = *this;\n\n        // the valid JSON Patch operations\n        enum class patch_operations {add, remove, replace, move, copy, test, invalid};\n\n        const auto get_op = [](const std::string & op)\n        {\n            if (op == \"add\")\n            {\n                return patch_operations::add;\n            }\n            if (op == \"remove\")\n            {\n                return patch_operations::remove;\n            }\n            if (op == \"replace\")\n            {\n                return patch_operations::replace;\n            }\n            if (op == \"move\")\n            {\n                return patch_operations::move;\n            }\n            if (op == \"copy\")\n            {\n                return patch_operations::copy;\n            }\n            if (op == \"test\")\n            {\n                return patch_operations::test;\n            }\n\n            return patch_operations::invalid;\n        };\n\n        // wrapper for \"add\" operation; add value at ptr\n        const auto operation_add = [&result](json_pointer & ptr, basic_json val)\n        {\n            // adding to the root of the target document means replacing it\n            if (ptr.empty())\n            {\n                result = val;\n                return;\n            }\n\n            // make sure the top element of the pointer exists\n            json_pointer top_pointer = ptr.top();\n            if (top_pointer != ptr)\n            {\n                result.at(top_pointer);\n            }\n\n            // get reference to parent of JSON pointer ptr\n            const auto last_path = ptr.back();\n            ptr.pop_back();\n            basic_json& parent = result[ptr];\n\n            switch (parent.m_type)\n            {\n                case value_t::null:\n                case value_t::object:\n                {\n                    // use operator[] to add value\n                    parent[last_path] = val;\n                    break;\n                }\n\n                case value_t::array:\n                {\n                    if (last_path == \"-\")\n                    {\n                        // special case: append to back\n                        parent.push_back(val);\n                    }\n                    else\n                    {\n                        const auto idx = json_pointer::array_index(last_path);\n                        if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))\n                        {\n                            // avoid undefined behavior\n                            JSON_THROW(out_of_range::create(401, \"array index \" + std::to_string(idx) + \" is out of range\", parent));\n                        }\n\n                        // default case: insert add offset\n                        parent.insert(parent.begin() + static_cast<difference_type>(idx), val);\n                    }\n                    break;\n                }\n\n                // if there exists a parent it cannot be primitive\n                case value_t::string: // LCOV_EXCL_LINE\n                case value_t::boolean: // LCOV_EXCL_LINE\n                case value_t::number_integer: // LCOV_EXCL_LINE\n                case value_t::number_unsigned: // LCOV_EXCL_LINE\n                case value_t::number_float: // LCOV_EXCL_LINE\n                case value_t::binary: // LCOV_EXCL_LINE\n                case value_t::discarded: // LCOV_EXCL_LINE\n                default:            // LCOV_EXCL_LINE\n                    JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE\n            }\n        };\n\n        // wrapper for \"remove\" operation; remove value at ptr\n        const auto operation_remove = [this, &result](json_pointer & ptr)\n        {\n            // get reference to parent of JSON pointer ptr\n            const auto last_path = ptr.back();\n            ptr.pop_back();\n            basic_json& parent = result.at(ptr);\n\n            // remove child\n            if (parent.is_object())\n            {\n                // perform range check\n                auto it = parent.find(last_path);\n                if (JSON_HEDLEY_LIKELY(it != parent.end()))\n                {\n                    parent.erase(it);\n                }\n                else\n                {\n                    JSON_THROW(out_of_range::create(403, \"key '\" + last_path + \"' not found\", *this));\n                }\n            }\n            else if (parent.is_array())\n            {\n                // note erase performs range check\n                parent.erase(json_pointer::array_index(last_path));\n            }\n        };\n\n        // type check: top level value must be an array\n        if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))\n        {\n            JSON_THROW(parse_error::create(104, 0, \"JSON patch must be an array of objects\", json_patch));\n        }\n\n        // iterate and apply the operations\n        for (const auto& val : json_patch)\n        {\n            // wrapper to get a value for an operation\n            const auto get_value = [&val](const std::string & op,\n                                          const std::string & member,\n                                          bool string_type) -> basic_json &\n            {\n                // find value\n                auto it = val.m_value.object->find(member);\n\n                // context-sensitive error message\n                const auto error_msg = (op == \"op\") ? \"operation\" : \"operation '\" + op + \"'\";\n\n                // check if desired value is present\n                if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))\n                {\n                    // NOLINTNEXTLINE(performance-inefficient-string-concatenation)\n                    JSON_THROW(parse_error::create(105, 0, error_msg + \" must have member '\" + member + \"'\", val));\n                }\n\n                // check if result is of type string\n                if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))\n                {\n                    // NOLINTNEXTLINE(performance-inefficient-string-concatenation)\n                    JSON_THROW(parse_error::create(105, 0, error_msg + \" must have string member '\" + member + \"'\", val));\n                }\n\n                // no error: return value\n                return it->second;\n            };\n\n            // type check: every element of the array must be an object\n            if (JSON_HEDLEY_UNLIKELY(!val.is_object()))\n            {\n                JSON_THROW(parse_error::create(104, 0, \"JSON patch must be an array of objects\", val));\n            }\n\n            // collect mandatory members\n            const auto op = get_value(\"op\", \"op\", true).template get<std::string>();\n            const auto path = get_value(op, \"path\", true).template get<std::string>();\n            json_pointer ptr(path);\n\n            switch (get_op(op))\n            {\n                case patch_operations::add:\n                {\n                    operation_add(ptr, get_value(\"add\", \"value\", false));\n                    break;\n                }\n\n                case patch_operations::remove:\n                {\n                    operation_remove(ptr);\n                    break;\n                }\n\n                case patch_operations::replace:\n                {\n                    // the \"path\" location must exist - use at()\n                    result.at(ptr) = get_value(\"replace\", \"value\", false);\n                    break;\n                }\n\n                case patch_operations::move:\n                {\n                    const auto from_path = get_value(\"move\", \"from\", true).template get<std::string>();\n                    json_pointer from_ptr(from_path);\n\n                    // the \"from\" location must exist - use at()\n                    basic_json v = result.at(from_ptr);\n\n                    // The move operation is functionally identical to a\n                    // \"remove\" operation on the \"from\" location, followed\n                    // immediately by an \"add\" operation at the target\n                    // location with the value that was just removed.\n                    operation_remove(from_ptr);\n                    operation_add(ptr, v);\n                    break;\n                }\n\n                case patch_operations::copy:\n                {\n                    const auto from_path = get_value(\"copy\", \"from\", true).template get<std::string>();\n                    const json_pointer from_ptr(from_path);\n\n                    // the \"from\" location must exist - use at()\n                    basic_json v = result.at(from_ptr);\n\n                    // The copy is functionally identical to an \"add\"\n                    // operation at the target location using the value\n                    // specified in the \"from\" member.\n                    operation_add(ptr, v);\n                    break;\n                }\n\n                case patch_operations::test:\n                {\n                    bool success = false;\n                    JSON_TRY\n                    {\n                        // check if \"value\" matches the one at \"path\"\n                        // the \"path\" location must exist - use at()\n                        success = (result.at(ptr) == get_value(\"test\", \"value\", false));\n                    }\n                    JSON_INTERNAL_CATCH (out_of_range&)\n                    {\n                        // ignore out of range errors: success remains false\n                    }\n\n                    // throw an exception if test fails\n                    if (JSON_HEDLEY_UNLIKELY(!success))\n                    {\n                        JSON_THROW(other_error::create(501, \"unsuccessful: \" + val.dump(), val));\n                    }\n\n                    break;\n                }\n\n                case patch_operations::invalid:\n                default:\n                {\n                    // op must be \"add\", \"remove\", \"replace\", \"move\", \"copy\", or\n                    // \"test\"\n                    JSON_THROW(parse_error::create(105, 0, \"operation value '\" + op + \"' is invalid\", val));\n                }\n            }\n        }\n\n        return result;\n    }\n\n    /// @brief creates a diff as a JSON patch\n    /// @sa https://json.nlohmann.me/api/basic_json/diff/\n    JSON_HEDLEY_WARN_UNUSED_RESULT\n    static basic_json diff(const basic_json& source, const basic_json& target,\n                           const std::string& path = \"\")\n    {\n        // the patch\n        basic_json result(value_t::array);\n\n        // if the values are the same, return empty patch\n        if (source == target)\n        {\n            return result;\n        }\n\n        if (source.type() != target.type())\n        {\n            // different types: replace value\n            result.push_back(\n            {\n                {\"op\", \"replace\"}, {\"path\", path}, {\"value\", target}\n            });\n            return result;\n        }\n\n        switch (source.type())\n        {\n            case value_t::array:\n            {\n                // first pass: traverse common elements\n                std::size_t i = 0;\n                while (i < source.size() && i < target.size())\n                {\n                    // recursive call to compare array values at index i\n                    auto temp_diff = diff(source[i], target[i], path + \"/\" + std::to_string(i));\n                    result.insert(result.end(), temp_diff.begin(), temp_diff.end());\n                    ++i;\n                }\n\n                // We now reached the end of at least one array\n                // in a second pass, traverse the remaining elements\n\n                // remove my remaining elements\n                const auto end_index = static_cast<difference_type>(result.size());\n                while (i < source.size())\n                {\n                    // add operations in reverse order to avoid invalid\n                    // indices\n                    result.insert(result.begin() + end_index, object(\n                    {\n                        {\"op\", \"remove\"},\n                        {\"path\", path + \"/\" + std::to_string(i)}\n                    }));\n                    ++i;\n                }\n\n                // add other remaining elements\n                while (i < target.size())\n                {\n                    result.push_back(\n                    {\n                        {\"op\", \"add\"},\n                        {\"path\", path + \"/-\"},\n                        {\"value\", target[i]}\n                    });\n                    ++i;\n                }\n\n                break;\n            }\n\n            case value_t::object:\n            {\n                // first pass: traverse this object's elements\n                for (auto it = source.cbegin(); it != source.cend(); ++it)\n                {\n                    // escape the key name to be used in a JSON patch\n                    const auto path_key = path + \"/\" + detail::escape(it.key());\n\n                    if (target.find(it.key()) != target.end())\n                    {\n                        // recursive call to compare object values at key it\n                        auto temp_diff = diff(it.value(), target[it.key()], path_key);\n                        result.insert(result.end(), temp_diff.begin(), temp_diff.end());\n                    }\n                    else\n                    {\n                        // found a key that is not in o -> remove it\n                        result.push_back(object(\n                        {\n                            {\"op\", \"remove\"}, {\"path\", path_key}\n                        }));\n                    }\n                }\n\n                // second pass: traverse other object's elements\n                for (auto it = target.cbegin(); it != target.cend(); ++it)\n                {\n                    if (source.find(it.key()) == source.end())\n                    {\n                        // found a key that is not in this -> add it\n                        const auto path_key = path + \"/\" + detail::escape(it.key());\n                        result.push_back(\n                        {\n                            {\"op\", \"add\"}, {\"path\", path_key},\n                            {\"value\", it.value()}\n                        });\n                    }\n                }\n\n                break;\n            }\n\n            case value_t::null:\n            case value_t::string:\n            case value_t::boolean:\n            case value_t::number_integer:\n            case value_t::number_unsigned:\n            case value_t::number_float:\n            case value_t::binary:\n            case value_t::discarded:\n            default:\n            {\n                // both primitive type: replace value\n                result.push_back(\n                {\n                    {\"op\", \"replace\"}, {\"path\", path}, {\"value\", target}\n                });\n                break;\n            }\n        }\n\n        return result;\n    }\n\n    /// @}\n\n    ////////////////////////////////\n    // JSON Merge Patch functions //\n    ////////////////////////////////\n\n    /// @name JSON Merge Patch functions\n    /// @{\n\n    /// @brief applies a JSON Merge Patch\n    /// @sa https://json.nlohmann.me/api/basic_json/merge_patch/\n    void merge_patch(const basic_json& apply_patch)\n    {\n        if (apply_patch.is_object())\n        {\n            if (!is_object())\n            {\n                *this = object();\n            }\n            for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)\n            {\n                if (it.value().is_null())\n                {\n                    erase(it.key());\n                }\n                else\n                {\n                    operator[](it.key()).merge_patch(it.value());\n                }\n            }\n        }\n        else\n        {\n            *this = apply_patch;\n        }\n    }\n\n    /// @}\n};\n\n/// @brief user-defined to_string function for JSON values\n/// @sa https://json.nlohmann.me/api/basic_json/to_string/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nstd::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)\n{\n    return j.dump();\n}\n\n} // namespace nlohmann\n\n///////////////////////\n// nonmember support //\n///////////////////////\n\nnamespace std // NOLINT(cert-dcl58-cpp)\n{\n\n/// @brief hash value for JSON objects\n/// @sa https://json.nlohmann.me/api/basic_json/std_hash/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\nstruct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>\n{\n    std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const\n    {\n        return nlohmann::detail::hash(j);\n    }\n};\n\n// specialization for std::less<value_t>\ntemplate<>\nstruct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679\n{\n    /*!\n    @brief compare two value_t enum values\n    @since version 3.0.0\n    */\n    bool operator()(nlohmann::detail::value_t lhs,\n                    nlohmann::detail::value_t rhs) const noexcept\n    {\n        return nlohmann::detail::operator<(lhs, rhs);\n    }\n};\n\n// C++20 prohibit function specialization in the std namespace.\n#ifndef JSON_HAS_CPP_20\n\n/// @brief exchanges the values of two JSON objects\n/// @sa https://json.nlohmann.me/api/basic_json/std_swap/\nNLOHMANN_BASIC_JSON_TPL_DECLARATION\ninline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept(  // NOLINT(readability-inconsistent-declaration-parameter-name)\n    is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&&                          // NOLINT(misc-redundant-expression)\n    is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)\n{\n    j1.swap(j2);\n}\n\n#endif\n\n} // namespace std\n\n/// @brief user-defined string literal for JSON values\n/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/\nJSON_HEDLEY_NON_NULL(1)\ninline nlohmann::json operator \"\" _json(const char* s, std::size_t n)\n{\n    return nlohmann::json::parse(s, s + n);\n}\n\n/// @brief user-defined string literal for JSON pointer\n/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/\nJSON_HEDLEY_NON_NULL(1)\ninline nlohmann::json::json_pointer operator \"\" _json_pointer(const char* s, std::size_t n)\n{\n    return nlohmann::json::json_pointer(std::string(s, n));\n}\n\n// #include <nlohmann/detail/macro_unscope.hpp>\n\n\n// restore clang diagnostic settings\n#if defined(__clang__)\n    #pragma clang diagnostic pop\n#endif\n\n// clean up\n#undef JSON_ASSERT\n#undef JSON_INTERNAL_CATCH\n#undef JSON_CATCH\n#undef JSON_THROW\n#undef JSON_TRY\n#undef JSON_PRIVATE_UNLESS_TESTED\n#undef JSON_HAS_CPP_11\n#undef JSON_HAS_CPP_14\n#undef JSON_HAS_CPP_17\n#undef JSON_HAS_CPP_20\n#undef JSON_HAS_FILESYSTEM\n#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION\n#undef NLOHMANN_BASIC_JSON_TPL\n#undef JSON_EXPLICIT\n#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL\n\n// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>\n\n\n#undef JSON_HEDLEY_ALWAYS_INLINE\n#undef JSON_HEDLEY_ARM_VERSION\n#undef JSON_HEDLEY_ARM_VERSION_CHECK\n#undef JSON_HEDLEY_ARRAY_PARAM\n#undef JSON_HEDLEY_ASSUME\n#undef JSON_HEDLEY_BEGIN_C_DECLS\n#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_CLANG_HAS_BUILTIN\n#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_CLANG_HAS_EXTENSION\n#undef JSON_HEDLEY_CLANG_HAS_FEATURE\n#undef JSON_HEDLEY_CLANG_HAS_WARNING\n#undef JSON_HEDLEY_COMPCERT_VERSION\n#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK\n#undef JSON_HEDLEY_CONCAT\n#undef JSON_HEDLEY_CONCAT3\n#undef JSON_HEDLEY_CONCAT3_EX\n#undef JSON_HEDLEY_CONCAT_EX\n#undef JSON_HEDLEY_CONST\n#undef JSON_HEDLEY_CONSTEXPR\n#undef JSON_HEDLEY_CONST_CAST\n#undef JSON_HEDLEY_CPP_CAST\n#undef JSON_HEDLEY_CRAY_VERSION\n#undef JSON_HEDLEY_CRAY_VERSION_CHECK\n#undef JSON_HEDLEY_C_DECL\n#undef JSON_HEDLEY_DEPRECATED\n#undef JSON_HEDLEY_DEPRECATED_FOR\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS\n#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION\n#undef JSON_HEDLEY_DIAGNOSTIC_POP\n#undef JSON_HEDLEY_DIAGNOSTIC_PUSH\n#undef JSON_HEDLEY_DMC_VERSION\n#undef JSON_HEDLEY_DMC_VERSION_CHECK\n#undef JSON_HEDLEY_EMPTY_BASES\n#undef JSON_HEDLEY_EMSCRIPTEN_VERSION\n#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK\n#undef JSON_HEDLEY_END_C_DECLS\n#undef JSON_HEDLEY_FLAGS\n#undef JSON_HEDLEY_FLAGS_CAST\n#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_GCC_HAS_BUILTIN\n#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_GCC_HAS_EXTENSION\n#undef JSON_HEDLEY_GCC_HAS_FEATURE\n#undef JSON_HEDLEY_GCC_HAS_WARNING\n#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK\n#undef JSON_HEDLEY_GCC_VERSION\n#undef JSON_HEDLEY_GCC_VERSION_CHECK\n#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_GNUC_HAS_BUILTIN\n#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_GNUC_HAS_EXTENSION\n#undef JSON_HEDLEY_GNUC_HAS_FEATURE\n#undef JSON_HEDLEY_GNUC_HAS_WARNING\n#undef JSON_HEDLEY_GNUC_VERSION\n#undef JSON_HEDLEY_GNUC_VERSION_CHECK\n#undef JSON_HEDLEY_HAS_ATTRIBUTE\n#undef JSON_HEDLEY_HAS_BUILTIN\n#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE\n#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS\n#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE\n#undef JSON_HEDLEY_HAS_EXTENSION\n#undef JSON_HEDLEY_HAS_FEATURE\n#undef JSON_HEDLEY_HAS_WARNING\n#undef JSON_HEDLEY_IAR_VERSION\n#undef JSON_HEDLEY_IAR_VERSION_CHECK\n#undef JSON_HEDLEY_IBM_VERSION\n#undef JSON_HEDLEY_IBM_VERSION_CHECK\n#undef JSON_HEDLEY_IMPORT\n#undef JSON_HEDLEY_INLINE\n#undef JSON_HEDLEY_INTEL_CL_VERSION\n#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK\n#undef JSON_HEDLEY_INTEL_VERSION\n#undef JSON_HEDLEY_INTEL_VERSION_CHECK\n#undef JSON_HEDLEY_IS_CONSTANT\n#undef JSON_HEDLEY_IS_CONSTEXPR_\n#undef JSON_HEDLEY_LIKELY\n#undef JSON_HEDLEY_MALLOC\n#undef JSON_HEDLEY_MCST_LCC_VERSION\n#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK\n#undef JSON_HEDLEY_MESSAGE\n#undef JSON_HEDLEY_MSVC_VERSION\n#undef JSON_HEDLEY_MSVC_VERSION_CHECK\n#undef JSON_HEDLEY_NEVER_INLINE\n#undef JSON_HEDLEY_NON_NULL\n#undef JSON_HEDLEY_NO_ESCAPE\n#undef JSON_HEDLEY_NO_RETURN\n#undef JSON_HEDLEY_NO_THROW\n#undef JSON_HEDLEY_NULL\n#undef JSON_HEDLEY_PELLES_VERSION\n#undef JSON_HEDLEY_PELLES_VERSION_CHECK\n#undef JSON_HEDLEY_PGI_VERSION\n#undef JSON_HEDLEY_PGI_VERSION_CHECK\n#undef JSON_HEDLEY_PREDICT\n#undef JSON_HEDLEY_PRINTF_FORMAT\n#undef JSON_HEDLEY_PRIVATE\n#undef JSON_HEDLEY_PUBLIC\n#undef JSON_HEDLEY_PURE\n#undef JSON_HEDLEY_REINTERPRET_CAST\n#undef JSON_HEDLEY_REQUIRE\n#undef JSON_HEDLEY_REQUIRE_CONSTEXPR\n#undef JSON_HEDLEY_REQUIRE_MSG\n#undef JSON_HEDLEY_RESTRICT\n#undef JSON_HEDLEY_RETURNS_NON_NULL\n#undef JSON_HEDLEY_SENTINEL\n#undef JSON_HEDLEY_STATIC_ASSERT\n#undef JSON_HEDLEY_STATIC_CAST\n#undef JSON_HEDLEY_STRINGIFY\n#undef JSON_HEDLEY_STRINGIFY_EX\n#undef JSON_HEDLEY_SUNPRO_VERSION\n#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK\n#undef JSON_HEDLEY_TINYC_VERSION\n#undef JSON_HEDLEY_TINYC_VERSION_CHECK\n#undef JSON_HEDLEY_TI_ARMCL_VERSION\n#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL2000_VERSION\n#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL430_VERSION\n#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL6X_VERSION\n#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CL7X_VERSION\n#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK\n#undef JSON_HEDLEY_TI_CLPRU_VERSION\n#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK\n#undef JSON_HEDLEY_TI_VERSION\n#undef JSON_HEDLEY_TI_VERSION_CHECK\n#undef JSON_HEDLEY_UNAVAILABLE\n#undef JSON_HEDLEY_UNLIKELY\n#undef JSON_HEDLEY_UNPREDICTABLE\n#undef JSON_HEDLEY_UNREACHABLE\n#undef JSON_HEDLEY_UNREACHABLE_RETURN\n#undef JSON_HEDLEY_VERSION\n#undef JSON_HEDLEY_VERSION_DECODE_MAJOR\n#undef JSON_HEDLEY_VERSION_DECODE_MINOR\n#undef JSON_HEDLEY_VERSION_DECODE_REVISION\n#undef JSON_HEDLEY_VERSION_ENCODE\n#undef JSON_HEDLEY_WARNING\n#undef JSON_HEDLEY_WARN_UNUSED_RESULT\n#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG\n#undef JSON_HEDLEY_FALL_THROUGH\n\n\n\n#endif  // INCLUDE_NLOHMANN_JSON_HPP_\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/CMakeLists.txt",
    "content": "option(JSON_Valgrind    \"Execute test suite with Valgrind.\" OFF)\noption(JSON_FastTests   \"Skip expensive/slow tests.\" OFF)\n\n# download test data\ninclude(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/download_test_data.cmake)\n\n# test fixture to download test data\nadd_test(NAME \"download_test_data\" COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target download_test_data)\nset_tests_properties(download_test_data PROPERTIES FIXTURES_SETUP TEST_DATA)\n\nif(JSON_Valgrind)\n    find_program(CMAKE_MEMORYCHECK_COMMAND valgrind)\n    message(STATUS \"Executing test suite with Valgrind (${CMAKE_MEMORYCHECK_COMMAND})\")\n    set(memcheck_command \"${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1 --leak-check=full\")\n    separate_arguments(memcheck_command)\nendif()\n\n#############################################################################\n# doctest library with the main function to speed up build\n#############################################################################\n\nadd_library(doctest_main OBJECT src/unit.cpp)\nset_target_properties(doctest_main PROPERTIES\n    COMPILE_DEFINITIONS \"$<$<CXX_COMPILER_ID:MSVC>:_SCL_SECURE_NO_WARNINGS>\"\n    COMPILE_OPTIONS \"$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>\"\n)\nif (${CMAKE_VERSION} VERSION_LESS \"3.8.0\")\n    target_compile_features(doctest_main PUBLIC cxx_range_for)\nelse()\n    target_compile_features(doctest_main PUBLIC cxx_std_11)\nendif()\ntarget_include_directories(doctest_main PRIVATE \"thirdparty/doctest\")\n\n# https://stackoverflow.com/questions/2368811/how-to-set-warning-level-in-cmake\nif(MSVC)\n    # Force to always compile with W4\n    if(CMAKE_CXX_FLAGS MATCHES \"/W[0-4]\")\n        string(REGEX REPLACE \"/W[0-4]\" \"/W4\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\n    else()\n        set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /W4\")\n    endif()\n\n\t# Disable warning C4566: character represented by universal-character-name '\\uFF01' cannot be represented in the current code page (1252)\n\t# Disable warning C4996: 'nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::operator <<': was declared deprecated\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /wd4566 /wd4996\")\n\n\t# https://github.com/nlohmann/json/issues/1114\n\tset(CMAKE_CXX_FLAGS_DEBUG \"${CMAKE_CXX_FLAGS_DEBUG} /bigobj\")\nendif()\n\n#############################################################################\n# one executable for each unit test file\n#############################################################################\n\n# check if compiler supports C++17\nforeach(feature ${CMAKE_CXX_COMPILE_FEATURES})\n    if (${feature} STREQUAL cxx_std_17)\n        set(compiler_supports_cpp_17 TRUE)\n    endif()\nendforeach()\n# Clang only supports C++17 starting from Clang 5.0\nif (\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)\n    unset(compiler_supports_cpp_17)\nendif()\n# MSVC 2015 (14.0) does not support C++17\nif (\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"MSVC\" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.1)\n    unset(compiler_supports_cpp_17)\nendif()\n\nfile(GLOB files src/unit-*.cpp)\n\nforeach(file ${files})\n    get_filename_component(file_basename ${file} NAME_WE)\n    string(REGEX REPLACE \"unit-([^$]+)\" \"test-\\\\1\" testcase ${file_basename})\n\n    add_executable(${testcase} $<TARGET_OBJECTS:doctest_main> ${file})\n    target_compile_definitions(${testcase} PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)\n    target_compile_options(${testcase} PRIVATE\n        $<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>\n        $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>\n        $<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>\n    )\n    target_include_directories(${testcase} PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)\n    target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME})\n\n    # add a copy with C++17 compilation\n    if (compiler_supports_cpp_17)\n        file(READ ${file} FILE_CONTENT)\n        string(FIND \"${FILE_CONTENT}\" \"JSON_HAS_CPP_17\" CPP_17_FOUND)\n        if(NOT ${CPP_17_FOUND} EQUAL -1)\n            add_executable(${testcase}_cpp17 $<TARGET_OBJECTS:doctest_main> ${file})\n            target_compile_definitions(${testcase}_cpp17 PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)\n            target_compile_options(${testcase}_cpp17 PRIVATE\n                $<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>\n                $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>\n                $<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>\n            )\n            target_include_directories(${testcase}_cpp17 PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)\n            target_link_libraries(${testcase}_cpp17 PRIVATE ${NLOHMANN_JSON_TARGET_NAME})\n            target_compile_features(${testcase}_cpp17 PRIVATE cxx_std_17)\n\n            if (CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0 AND NOT MINGW)\n                # fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90050\n                target_link_libraries(${testcase}_cpp17 PRIVATE stdc++fs)\n            endif()\n\n            if (JSON_FastTests)\n                add_test(NAME \"${testcase}_cpp17\"\n                    COMMAND ${testcase}_cpp17 ${DOCTEST_TEST_FILTER}\n                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}\n                )\n            else()\n                add_test(NAME \"${testcase}_cpp17\"\n                    COMMAND ${testcase}_cpp17 ${DOCTEST_TEST_FILTER} --no-skip\n                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}\n                )\n            endif()\n            set_tests_properties(\"${testcase}_cpp17\" PROPERTIES LABELS \"all\" FIXTURES_REQUIRED TEST_DATA)\n        endif()\n    endif()\n\n    if (JSON_FastTests)\n        add_test(NAME \"${testcase}\"\n            COMMAND ${testcase} ${DOCTEST_TEST_FILTER}\n            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}\n        )\n    else()\n        add_test(NAME \"${testcase}\"\n            COMMAND ${testcase} ${DOCTEST_TEST_FILTER} --no-skip\n            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}\n        )\n    endif()\n    set_tests_properties(\"${testcase}\" PROPERTIES LABELS \"all\" FIXTURES_REQUIRED TEST_DATA)\n\n    if(JSON_Valgrind)\n        add_test(NAME \"${testcase}_valgrind\"\n            COMMAND ${memcheck_command} ${CMAKE_CURRENT_BINARY_DIR}/${testcase} ${DOCTEST_TEST_FILTER}\n            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}\n        )\n        set_tests_properties(\"${testcase}_valgrind\" PROPERTIES LABELS \"valgrind\" FIXTURES_REQUIRED TEST_DATA)\n    endif()\nendforeach()\n\n# disable exceptions for test-disabled_exceptions\ntarget_compile_definitions(test-disabled_exceptions PUBLIC JSON_NOEXCEPTION)\nif (CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\" OR CMAKE_CXX_COMPILER_ID STREQUAL \"AppleClang\" OR CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\")\n    target_compile_options(test-disabled_exceptions PUBLIC -fno-exceptions)\nelseif (CMAKE_CXX_COMPILER_ID STREQUAL \"MSVC\")\n    # disabled due to https://github.com/nlohmann/json/discussions/2824\n    #target_compile_options(test-disabled_exceptions PUBLIC /EH)\n    #target_compile_definitions(test-disabled_exceptions PUBLIC _HAS_EXCEPTIONS=0)\nendif()\n\n# avoid stack overflow, see https://github.com/nlohmann/json/issues/2955\nif (CMAKE_CXX_COMPILER_ID STREQUAL \"MSVC\")\n    set_property(TARGET test-cbor APPEND_STRING PROPERTY LINK_FLAGS \" /STACK:4000000\")\n    set_property(TARGET test-msgpack APPEND_STRING PROPERTY LINK_FLAGS \" /STACK:4000000\")\n    set_property(TARGET test-ubjson APPEND_STRING PROPERTY LINK_FLAGS \" /STACK:4000000\")\nendif()\n\n#############################################################################\n# Test the generated build configs\n#############################################################################\n\n# these tests depend on the generated file nlohmann_jsonConfig.cmake\nif (JSON_Install)\n    add_subdirectory(cmake_import)\n    add_subdirectory(cmake_import_minver)\nendif()\n\nadd_subdirectory(cmake_add_subdirectory)\nadd_subdirectory(cmake_fetch_content)\nadd_subdirectory(cmake_target_include_directories)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/Makefile",
    "content": "##############################################################################\n# OSS-Fuzz\n##############################################################################\n\n# The following targets realize the integration to OSS-Fuzz.\n# See <https://github.com/google/oss-fuzz/blob/master/projects/json/build.sh> for more information.\n\n# additional flags\nCXXFLAGS += -std=c++11\nCPPFLAGS += -I ../single_include\n\nFUZZER_ENGINE = src/fuzzer-driver_afl.cpp\nFUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer\nfuzzers: $(FUZZERS)\n\nparse_afl_fuzzer:\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_json.cpp -o $@\n\nparse_bson_fuzzer:\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_bson.cpp -o $@\n\nparse_cbor_fuzzer:\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_cbor.cpp -o $@\n\nparse_msgpack_fuzzer:\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_msgpack.cpp -o $@\n\nparse_ubjson_fuzzer:\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_add_subdirectory/CMakeLists.txt",
    "content": "add_test(NAME cmake_add_subdirectory_configure\n  COMMAND ${CMAKE_COMMAND}\n    -G \"${CMAKE_GENERATOR}\"\n    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\n    -Dnlohmann_json_source=${PROJECT_SOURCE_DIR}\n    ${CMAKE_CURRENT_SOURCE_DIR}/project\n)\nadd_test(NAME cmake_add_subdirectory_build\n  COMMAND ${CMAKE_COMMAND} --build .\n)\nset_tests_properties(cmake_add_subdirectory_configure PROPERTIES\n  FIXTURES_SETUP cmake_add_subdirectory\n  LABELS not_reproducible\n)\nset_tests_properties(cmake_add_subdirectory_build PROPERTIES\n  FIXTURES_REQUIRED cmake_add_subdirectory\n  LABELS not_reproducible\n)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_add_subdirectory/project/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.1)\n\nproject(DummyImport CXX)\n\nset(JSON_BuildTests OFF CACHE INTERNAL \"\")\nadd_subdirectory(${nlohmann_json_source}\n   ${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json)\n\nadd_executable(with_namespace_target main.cpp)\ntarget_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)\n\nadd_executable(without_namespace_target main.cpp)\ntarget_link_libraries(without_namespace_target nlohmann_json)\n\nif(NOT MSVC)\n    add_executable(without_exceptions main.cpp)\n    target_link_libraries(without_exceptions nlohmann_json::nlohmann_json)\n    target_compile_definitions(without_exceptions PRIVATE JSON_NOEXCEPTION)\n    target_compile_options(without_exceptions PRIVATE -fno-exceptions)\nendif()\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_add_subdirectory/project/main.cpp",
    "content": "#include <nlohmann/json.hpp>\n\nint main(int argc, char **argv)\n{\n    nlohmann::json j;\n\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_fetch_content/CMakeLists.txt",
    "content": "if (${CMAKE_VERSION} VERSION_GREATER \"3.11.0\")\n  add_test(NAME cmake_fetch_content_configure\n    COMMAND ${CMAKE_COMMAND}\n    -G \"${CMAKE_GENERATOR}\"\n    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\n    -Dnlohmann_json_source=${PROJECT_SOURCE_DIR}\n    ${CMAKE_CURRENT_SOURCE_DIR}/project\n  )\n  add_test(NAME cmake_fetch_content_build\n    COMMAND ${CMAKE_COMMAND} --build .\n  )\n  set_tests_properties(cmake_fetch_content_configure PROPERTIES\n    FIXTURES_SETUP cmake_fetch_content\n    LABELS \"git_required;not_reproducible\"\n  )\n  set_tests_properties(cmake_fetch_content_build PROPERTIES\n    FIXTURES_REQUIRED cmake_fetch_content\n    LABELS \"git_required;not_reproducible\"\n  )\nendif()\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_fetch_content/project/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.11)\n\nproject(DummyImport CXX)\n\ninclude(FetchContent)\n\nget_filename_component(GIT_REPOSITORY_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ABSOLUTE)\nFetchContent_Declare(json GIT_REPOSITORY ${GIT_REPOSITORY_DIRECTORY} GIT_TAG HEAD)\n\nFetchContent_GetProperties(json)\nif(NOT json_POPULATED)\n  FetchContent_Populate(json)\n  add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)\nendif()\n\nadd_executable(with_namespace_target main.cpp)\ntarget_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)\n\nadd_executable(without_namespace_target main.cpp)\ntarget_link_libraries(without_namespace_target nlohmann_json)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_fetch_content/project/main.cpp",
    "content": "#include <nlohmann/json.hpp>\n\nint main(int argc, char **argv)\n{\n    nlohmann::json j;\n\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_import/CMakeLists.txt",
    "content": "add_test(NAME cmake_import_configure\n  COMMAND ${CMAKE_COMMAND}\n    -G \"${CMAKE_GENERATOR}\"\n    -A \"${CMAKE_GENERATOR_PLATFORM}\"\n    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\n    -Dnlohmann_json_DIR=${PROJECT_BINARY_DIR}\n    ${CMAKE_CURRENT_SOURCE_DIR}/project\n)\nadd_test(NAME cmake_import_build\n  COMMAND ${CMAKE_COMMAND} --build .\n)\nset_tests_properties(cmake_import_configure PROPERTIES\n  FIXTURES_SETUP cmake_import\n  LABELS not_reproducible\n)\nset_tests_properties(cmake_import_build PROPERTIES\n  FIXTURES_REQUIRED cmake_import\n  LABELS not_reproducible\n)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_import/project/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.1)\n\nproject(DummyImport CXX)\n\nfind_package(nlohmann_json REQUIRED)\n\nadd_executable(with_namespace_target main.cpp)\ntarget_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)\n\nadd_executable(without_namespace_target main.cpp)\ntarget_link_libraries(without_namespace_target nlohmann_json)\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_import/project/main.cpp",
    "content": "#include <nlohmann/json.hpp>\n\nint main(int argc, char **argv)\n{\n    nlohmann::json j;\n\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_import_minver/CMakeLists.txt",
    "content": "add_test(NAME cmake_import_minver_configure\n  COMMAND ${CMAKE_COMMAND}\n    -G \"${CMAKE_GENERATOR}\"\n    -A \"${CMAKE_GENERATOR_PLATFORM}\"\n    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\n    -Dnlohmann_json_DIR=${PROJECT_BINARY_DIR}\n    ${CMAKE_CURRENT_SOURCE_DIR}/project\n)\nadd_test(NAME cmake_import_minver_build\n  COMMAND ${CMAKE_COMMAND} --build .\n)\nset_tests_properties(cmake_import_minver_configure PROPERTIES\n  FIXTURES_SETUP cmake_import_minver\n  LABELS not_reproducible\n)\nset_tests_properties(cmake_import_minver_build PROPERTIES\n  FIXTURES_REQUIRED cmake_import_minver\n  LABELS not_reproducible\n)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_import_minver/project/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.1)\n\nproject(DummyImportMinVer CXX)\n\nfind_package(nlohmann_json 3.2.0 REQUIRED)\n\nadd_executable(with_namespace_target main.cpp)\ntarget_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_import_minver/project/main.cpp",
    "content": "#include <nlohmann/json.hpp>\n\nint main(int argc, char **argv)\n{\n    nlohmann::json j;\n\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_target_include_directories/CMakeLists.txt",
    "content": "add_test(NAME cmake_target_include_directories_configure\n  COMMAND ${CMAKE_COMMAND}\n    -G \"${CMAKE_GENERATOR}\"\n    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\n    -Dnlohmann_json_source=${PROJECT_SOURCE_DIR}\n    ${CMAKE_CURRENT_SOURCE_DIR}/project\n)\nadd_test(NAME cmake_target_include_directories_build\n    COMMAND ${CMAKE_COMMAND} --build .\n)\nset_tests_properties(cmake_target_include_directories_configure PROPERTIES\n    FIXTURES_SETUP cmake_target_include_directories\n    LABELS not_reproducible\n)\nset_tests_properties(cmake_target_include_directories_build PROPERTIES\n    FIXTURES_REQUIRED cmake_target_include_directories\n    LABELS not_reproducible\n)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_target_include_directories/project/Bar.cpp",
    "content": "#include \"Bar.hpp\"\n\nclass Bar;\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_target_include_directories/project/Bar.hpp",
    "content": "#include <nlohmann/json.hpp>\n#include \"Foo.hpp\"\n\nclass Bar : public Foo{};\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_target_include_directories/project/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.1)\n\nproject(DummyImport CXX)\n\nadd_executable(with_private_target main.cpp)\ntarget_include_directories(with_private_target PRIVATE ${nlohmann_json_source}/include)\nset_target_properties(with_private_target PROPERTIES CXX_STANDARD 11)\n\nadd_executable(with_private_system_target main.cpp)\ntarget_include_directories(with_private_system_target PRIVATE SYSTEM ${nlohmann_json_source}/include)\nset_target_properties(with_private_system_target PROPERTIES CXX_STANDARD 11)\n\n# regression from https://github.com/nlohmann/json/discussions/2281\nadd_library(Foo STATIC Foo.cpp Bar.cpp)\ntarget_include_directories(Foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include)\nset_target_properties(Foo PROPERTIES CXX_STANDARD 11)\n\nadd_library(Bar STATIC Bar.cpp)\ntarget_link_libraries(Bar PRIVATE Foo)\ntarget_include_directories(Bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include)\nset_target_properties(Bar PROPERTIES CXX_STANDARD 11)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_target_include_directories/project/Foo.cpp",
    "content": "#include \"Foo.hpp\"\n\nclass Foo;\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_target_include_directories/project/Foo.hpp",
    "content": "#pragma once\n#include <nlohmann/json.hpp>\n\nclass Foo{};\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cmake_target_include_directories/project/main.cpp",
    "content": "#include <nlohmann/json.hpp>\n\nint main(int argc, char **argv)\n{\n    nlohmann::json j;\n\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cuda_example/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.18)\nproject(json_cuda LANGUAGES CUDA)\n\nadd_executable(json_cuda json_cuda.cu)\ntarget_include_directories(json_cuda PRIVATE ../../include)\ntarget_compile_features(json_cuda PUBLIC cuda_std_11)\nset_target_properties(json_cuda PROPERTIES\n    CUDA_EXTENSIONS OFF\n    CUDA_STANDARD_REQUIRED ON\n)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/cuda_example/json_cuda.cu",
    "content": "#include <nlohmann/json.hpp>\n\nint main()\n{\n    nlohmann::ordered_json json = {\"Test\"};\n    json.dump();\n\n    // regression for #3013 (ordered_json::reset() compile error with nvcc)\n    nlohmann::ordered_json metadata;\n    metadata.erase(\"key\");\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/reports/2016-08-29-fuzz/index.html",
    "content": "<table style=\"font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'\">\n<tr><td style=\"width: 18ex\"><b>Banner:</b></td><td>fuzz</td></tr>\n<tr><td><b>Directory:</b></td><td>fuzz-testing/out</td></tr>\n<tr><td><b>Generated on:</b></td><td>Mo 29 Aug 2016 22:14:22 CEST</td></tr>\n</table>\n<p>\n<img src=\"high_freq.png\" width=1000 height=300><p>\n<img src=\"low_freq.png\" width=1000 height=200><p>\n<img src=\"exec_speed.png\" width=1000 height=200>\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/reports/2016-09-09-nativejson_benchmark/README.md",
    "content": "Results of the latest benchmark from <https://github.com/miloyip/nativejson-benchmark>.\n\nSee <https://github.com/nlohmann/json/issues/307> for discussion.\n\nOriginal post at 2016-09-09 to <json@yahoogroups.com>:\n\n> Hi,\n> \n> This benchmark evaluated conformance, parse/stringify speed/memory, and\n> code size. It can also be viewed as a long list of open source C/C++ JSON\n> libraries.\n> \n> You can run the benchmark on your own machine by checkout this project.\n> \n> https://github.com/miloyip/nativejson-benchmark\n> \n> You can also view some sample results here:\n> \n> https://rawgit.com/miloyip/nativejson-benchmark/master/sample/conformance.html\n> https://rawgit.com/miloyip/nativejson-benchmark/master/sample/performance_Corei7-4980HQ@2.80GHz_mac64_clang7.0.html\n> \n> If you make a new library, you may use this for testing conformance and\n> performance. Afterwards, please submit a pull request.\n> \n> Enjoy!\n> \n> -- \n> Milo Yip\n> \n> https://github.com/miloyip/\n> http://twitter.com/miloyip/\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/reports/2016-09-09-nativejson_benchmark/conformance_Nlohmann (C++11).md",
    "content": "\n\n\n\n<!DOCTYPE html>\n<html lang=\"en\" class=\"\">\n  <head prefix=\"og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#\">\n    <meta charset='utf-8'>\n    \n\n    <link crossorigin=\"anonymous\" href=\"https://assets-cdn.github.com/assets/frameworks-3a71f36dec04358c4f2f42280fb2cf5c38856f935a3f609eab0a1ae31b1d635a.css\" media=\"all\" rel=\"stylesheet\" />\n    <link crossorigin=\"anonymous\" href=\"https://assets-cdn.github.com/assets/github-5c885e880e980dc7f119393287b84906d930ccaff83f6bff8ae2c086b87ca4d8.css\" media=\"all\" rel=\"stylesheet\" />\n    \n    \n    <link crossorigin=\"anonymous\" href=\"https://assets-cdn.github.com/assets/site-4ef7bbe907458c89cb1f7f5c5e6c4cd87e03acf66b1817325e644920d2a83330.css\" media=\"all\" rel=\"stylesheet\" />\n    \n\n    <link as=\"script\" href=\"https://assets-cdn.github.com/assets/frameworks-88471af1fec40ff9418efbe2ddd15b6896af8d772f8179004c254dffc25ea490.js\" rel=\"preload\" />\n    \n    <link as=\"script\" href=\"https://assets-cdn.github.com/assets/github-e18e11a943ff2eb9394c72d4ec8b76592c454915b5839ae177d422777a046e29.js\" rel=\"preload\" />\n\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta http-equiv=\"Content-Language\" content=\"en\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    \n    <title>nativejson-benchmark/conformance_Nlohmann (C++11).md at master · miloyip/nativejson-benchmark · GitHub</title>\n    <link rel=\"search\" type=\"application/opensearchdescription+xml\" href=\"/opensearch.xml\" title=\"GitHub\">\n    <link rel=\"fluid-icon\" href=\"https://github.com/fluidicon.png\" title=\"GitHub\">\n    <link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"57x57\" href=\"/apple-touch-icon-57x57.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"60x60\" href=\"/apple-touch-icon-60x60.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"/apple-touch-icon-72x72.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"/apple-touch-icon-76x76.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"114x114\" href=\"/apple-touch-icon-114x114.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"/apple-touch-icon-120x120.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"144x144\" href=\"/apple-touch-icon-144x144.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"/apple-touch-icon-152x152.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/apple-touch-icon-180x180.png\">\n    <meta property=\"fb:app_id\" content=\"1401488693436528\">\n\n      <meta content=\"https://avatars2.githubusercontent.com/u/1195774?v=3&amp;s=400\" name=\"twitter:image:src\" /><meta content=\"@github\" name=\"twitter:site\" /><meta content=\"summary\" name=\"twitter:card\" /><meta content=\"miloyip/nativejson-benchmark\" name=\"twitter:title\" /><meta content=\"nativejson-benchmark - C/C++ JSON parser/generator benchmark\" name=\"twitter:description\" />\n      <meta content=\"https://avatars2.githubusercontent.com/u/1195774?v=3&amp;s=400\" property=\"og:image\" /><meta content=\"GitHub\" property=\"og:site_name\" /><meta content=\"object\" property=\"og:type\" /><meta content=\"miloyip/nativejson-benchmark\" property=\"og:title\" /><meta content=\"https://github.com/miloyip/nativejson-benchmark\" property=\"og:url\" /><meta content=\"nativejson-benchmark - C/C++ JSON parser/generator benchmark\" property=\"og:description\" />\n      <meta name=\"browser-stats-url\" content=\"https://api.github.com/_private/browser/stats\">\n    <meta name=\"browser-errors-url\" content=\"https://api.github.com/_private/browser/errors\">\n    <link rel=\"assets\" href=\"https://assets-cdn.github.com/\">\n    \n    <meta name=\"pjax-timeout\" content=\"1000\">\n    \n    <meta name=\"request-id\" content=\"D4563DA7:75ED:525C921:57D6FEBB\" data-pjax-transient>\n\n    <meta name=\"msapplication-TileImage\" content=\"/windows-tile.png\">\n    <meta name=\"msapplication-TileColor\" content=\"#ffffff\">\n    <meta name=\"selected-link\" value=\"repo_source\" data-pjax-transient>\n\n    <meta name=\"google-site-verification\" content=\"KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU\">\n<meta name=\"google-site-verification\" content=\"ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA\">\n    <meta name=\"google-analytics\" content=\"UA-3769691-2\">\n\n<meta content=\"collector.githubapp.com\" name=\"octolytics-host\" /><meta content=\"github\" name=\"octolytics-app-id\" /><meta content=\"D4563DA7:75ED:525C921:57D6FEBB\" name=\"octolytics-dimension-request_id\" />\n<meta content=\"/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show\" data-pjax-transient=\"true\" name=\"analytics-location\" />\n\n\n\n  <meta class=\"js-ga-set\" name=\"dimension1\" content=\"Logged Out\">\n\n\n\n        <meta name=\"hostname\" content=\"github.com\">\n    <meta name=\"user-login\" content=\"\">\n\n        <meta name=\"expected-hostname\" content=\"github.com\">\n      <meta name=\"js-proxy-site-detection-payload\" content=\"N2RkMmY1ZjE1MTA4MzRhYTA5NDNkMjliNDU3OTA3ZTdlMGNmNDZjN2QyODBiZjM3MmYzMjFjNzY1ZjIwNjY4NHx7InJlbW90ZV9hZGRyZXNzIjoiMjEyLjg2LjYxLjE2NyIsInJlcXVlc3RfaWQiOiJENDU2M0RBNzo3NUVEOjUyNUM5MjE6NTdENkZFQkIiLCJ0aW1lc3RhbXAiOjE0NzM3MDc3MDh9\">\n\n\n      <link rel=\"mask-icon\" href=\"https://assets-cdn.github.com/pinned-octocat.svg\" color=\"#4078c0\">\n      <link rel=\"icon\" type=\"image/x-icon\" href=\"https://assets-cdn.github.com/favicon.ico\">\n\n    <meta name=\"html-safe-nonce\" content=\"deea0f406df2fb95709865c5ee80a255d8c47fa9\">\n    <meta content=\"736eea9d74cf34fe850d2180e8a5f0a1cc7bc0be\" name=\"form-nonce\" />\n\n    <meta http-equiv=\"x-pjax-version\" content=\"f302977937abe3fe1c9a4d4bed913565\">\n    \n\n      \n  <meta name=\"description\" content=\"nativejson-benchmark - C/C++ JSON parser/generator benchmark\">\n  <meta name=\"go-import\" content=\"github.com/miloyip/nativejson-benchmark git https://github.com/miloyip/nativejson-benchmark.git\">\n\n  <meta content=\"1195774\" name=\"octolytics-dimension-user_id\" /><meta content=\"miloyip\" name=\"octolytics-dimension-user_login\" /><meta content=\"22976798\" name=\"octolytics-dimension-repository_id\" /><meta content=\"miloyip/nativejson-benchmark\" name=\"octolytics-dimension-repository_nwo\" /><meta content=\"true\" name=\"octolytics-dimension-repository_public\" /><meta content=\"false\" name=\"octolytics-dimension-repository_is_fork\" /><meta content=\"22976798\" name=\"octolytics-dimension-repository_network_root_id\" /><meta content=\"miloyip/nativejson-benchmark\" name=\"octolytics-dimension-repository_network_root_nwo\" />\n  <link href=\"https://github.com/miloyip/nativejson-benchmark/commits/master.atom\" rel=\"alternate\" title=\"Recent Commits to nativejson-benchmark:master\" type=\"application/atom+xml\">\n\n\n      <link rel=\"canonical\" href=\"https://github.com/miloyip/nativejson-benchmark/blob/master/sample/conformance_Nlohmann%20(C%2B%2B11).md\" data-pjax-transient>\n  </head>\n\n\n  <body class=\"logged-out  env-production  vis-public page-blob\">\n    <div id=\"js-pjax-loader-bar\" class=\"pjax-loader-bar\"><div class=\"progress\"></div></div>\n    <a href=\"#start-of-content\" tabindex=\"1\" class=\"accessibility-aid js-skip-to-content\">Skip to content</a>\n\n    \n    \n    \n\n\n\n          <header class=\"site-header js-details-container\" role=\"banner\">\n  <div class=\"container-responsive\">\n    <a class=\"header-logo-invertocat\" href=\"https://github.com/\" aria-label=\"Homepage\" data-ga-click=\"(Logged out) Header, go to homepage, icon:logo-wordmark\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-mark-github\" height=\"32\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"32\"><path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z\"></path></svg>\n    </a>\n\n    <button class=\"btn-link float-right site-header-toggle js-details-target\" type=\"button\" aria-label=\"Toggle navigation\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-three-bars\" height=\"24\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"18\"><path d=\"M11.41 9H.59C0 9 0 8.59 0 8c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zm0-4H.59C0 5 0 4.59 0 4c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM.59 11H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1H.59C0 13 0 12.59 0 12c0-.59 0-1 .59-1z\"></path></svg>\n    </button>\n\n    <div class=\"site-header-menu\">\n      <nav class=\"site-header-nav site-header-nav-main\">\n        <a href=\"/personal\" class=\"js-selected-navigation-item nav-item nav-item-personal\" data-ga-click=\"Header, click, Nav menu - item:personal\" data-selected-links=\"/personal /personal\">\n          Personal\n</a>        <a href=\"/open-source\" class=\"js-selected-navigation-item nav-item nav-item-opensource\" data-ga-click=\"Header, click, Nav menu - item:opensource\" data-selected-links=\"/open-source /open-source\">\n          Open source\n</a>        <a href=\"/business\" class=\"js-selected-navigation-item nav-item nav-item-business\" data-ga-click=\"Header, click, Nav menu - item:business\" data-selected-links=\"/business /business/partners /business/features /business/customers /business\">\n          Business\n</a>        <a href=\"/explore\" class=\"js-selected-navigation-item nav-item nav-item-explore\" data-ga-click=\"Header, click, Nav menu - item:explore\" data-selected-links=\"/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship /explore\">\n          Explore\n</a>      </nav>\n\n      <div class=\"site-header-actions\">\n            <a class=\"btn btn-primary site-header-actions-btn\" href=\"/join?source=header-repo\" data-ga-click=\"(Logged out) Header, clicked Sign up, text:sign-up\">Sign up</a>\n          <a class=\"btn site-header-actions-btn mr-2\" href=\"/login?return_to=%2Fmiloyip%2Fnativejson-benchmark%2Fblob%2Fmaster%2Fsample%2Fconformance_Nlohmann%2520%28C%252B%252B11%29.md\" data-ga-click=\"(Logged out) Header, clicked Sign in, text:sign-in\">Sign in</a>\n      </div>\n\n        <nav class=\"site-header-nav site-header-nav-secondary\">\n          <a class=\"nav-item\" href=\"/pricing\">Pricing</a>\n          <a class=\"nav-item\" href=\"/blog\">Blog</a>\n          <a class=\"nav-item\" href=\"https://help.github.com\">Support</a>\n          <a class=\"nav-item header-search-link\" href=\"https://github.com/search\">Search GitHub</a>\n              <div class=\"header-search scoped-search site-scoped-search js-site-search\" role=\"search\">\n  <!-- </textarea> --><!-- '\"` --><form accept-charset=\"UTF-8\" action=\"/miloyip/nativejson-benchmark/search\" class=\"js-site-search-form\" data-scoped-search-url=\"/miloyip/nativejson-benchmark/search\" data-unscoped-search-url=\"/search\" method=\"get\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /></div>\n    <label class=\"form-control header-search-wrapper js-chromeless-input-container\">\n      <div class=\"header-search-scope\">This repository</div>\n      <input type=\"text\"\n        class=\"form-control header-search-input js-site-search-focus js-site-search-field is-clearable\"\n        data-hotkey=\"s\"\n        name=\"q\"\n        placeholder=\"Search\"\n        aria-label=\"Search this repository\"\n        data-unscoped-placeholder=\"Search GitHub\"\n        data-scoped-placeholder=\"Search\"\n        autocapitalize=\"off\">\n    </label>\n</form></div>\n\n        </nav>\n    </div>\n  </div>\n</header>\n\n\n\n    <div id=\"start-of-content\" class=\"accessibility-aid\"></div>\n\n      <div id=\"js-flash-container\">\n</div>\n\n\n    <div role=\"main\">\n        <div itemscope itemtype=\"http://schema.org/SoftwareSourceCode\">\n    <div id=\"js-repo-pjax-container\" data-pjax-container>\n      \n<div class=\"pagehead repohead instapaper_ignore readability-menu experiment-repo-nav\">\n  <div class=\"container repohead-details-container\">\n\n    \n\n<ul class=\"pagehead-actions\">\n\n  <li>\n      <a href=\"/login?return_to=%2Fmiloyip%2Fnativejson-benchmark\"\n    class=\"btn btn-sm btn-with-count tooltipped tooltipped-n\"\n    aria-label=\"You must be signed in to watch a repository\" rel=\"nofollow\">\n    <svg aria-hidden=\"true\" class=\"octicon octicon-eye\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z\"></path></svg>\n    Watch\n  </a>\n  <a class=\"social-count\" href=\"/miloyip/nativejson-benchmark/watchers\"\n     aria-label=\"40 users are watching this repository\">\n    40\n  </a>\n\n  </li>\n\n  <li>\n      <a href=\"/login?return_to=%2Fmiloyip%2Fnativejson-benchmark\"\n    class=\"btn btn-sm btn-with-count tooltipped tooltipped-n\"\n    aria-label=\"You must be signed in to star a repository\" rel=\"nofollow\">\n    <svg aria-hidden=\"true\" class=\"octicon octicon-star\" height=\"16\" version=\"1.1\" viewBox=\"0 0 14 16\" width=\"14\"><path d=\"M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z\"></path></svg>\n    Star\n  </a>\n\n    <a class=\"social-count js-social-count\" href=\"/miloyip/nativejson-benchmark/stargazers\"\n      aria-label=\"352 users starred this repository\">\n      352\n    </a>\n\n  </li>\n\n  <li>\n      <a href=\"/login?return_to=%2Fmiloyip%2Fnativejson-benchmark\"\n        class=\"btn btn-sm btn-with-count tooltipped tooltipped-n\"\n        aria-label=\"You must be signed in to fork a repository\" rel=\"nofollow\">\n        <svg aria-hidden=\"true\" class=\"octicon octicon-repo-forked\" height=\"16\" version=\"1.1\" viewBox=\"0 0 10 16\" width=\"10\"><path d=\"M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"></path></svg>\n        Fork\n      </a>\n\n    <a href=\"/miloyip/nativejson-benchmark/network\" class=\"social-count\"\n       aria-label=\"59 users are forked this repository\">\n      59\n    </a>\n  </li>\n</ul>\n\n    <h1 class=\"public \">\n  <svg aria-hidden=\"true\" class=\"octicon octicon-repo\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z\"></path></svg>\n  <span class=\"author\" itemprop=\"author\"><a href=\"/miloyip\" class=\"url fn\" rel=\"author\">miloyip</a></span><!--\n--><span class=\"path-divider\">/</span><!--\n--><strong itemprop=\"name\"><a href=\"/miloyip/nativejson-benchmark\" data-pjax=\"#js-repo-pjax-container\">nativejson-benchmark</a></strong>\n\n</h1>\n\n  </div>\n  <div class=\"container\">\n    \n<nav class=\"reponav js-repo-nav js-sidenav-container-pjax\"\n     itemscope\n     itemtype=\"http://schema.org/BreadcrumbList\"\n     role=\"navigation\"\n     data-pjax=\"#js-repo-pjax-container\">\n\n  <span itemscope itemtype=\"http://schema.org/ListItem\" itemprop=\"itemListElement\">\n    <a href=\"/miloyip/nativejson-benchmark\" aria-selected=\"true\" class=\"js-selected-navigation-item selected reponav-item\" data-hotkey=\"g c\" data-selected-links=\"repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /miloyip/nativejson-benchmark\" itemprop=\"url\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-code\" height=\"16\" version=\"1.1\" viewBox=\"0 0 14 16\" width=\"14\"><path d=\"M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z\"></path></svg>\n      <span itemprop=\"name\">Code</span>\n      <meta itemprop=\"position\" content=\"1\">\n</a>  </span>\n\n    <span itemscope itemtype=\"http://schema.org/ListItem\" itemprop=\"itemListElement\">\n      <a href=\"/miloyip/nativejson-benchmark/issues\" class=\"js-selected-navigation-item reponav-item\" data-hotkey=\"g i\" data-selected-links=\"repo_issues repo_labels repo_milestones /miloyip/nativejson-benchmark/issues\" itemprop=\"url\">\n        <svg aria-hidden=\"true\" class=\"octicon octicon-issue-opened\" height=\"16\" version=\"1.1\" viewBox=\"0 0 14 16\" width=\"14\"><path d=\"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z\"></path></svg>\n        <span itemprop=\"name\">Issues</span>\n        <span class=\"counter\">8</span>\n        <meta itemprop=\"position\" content=\"2\">\n</a>    </span>\n\n  <span itemscope itemtype=\"http://schema.org/ListItem\" itemprop=\"itemListElement\">\n    <a href=\"/miloyip/nativejson-benchmark/pulls\" class=\"js-selected-navigation-item reponav-item\" data-hotkey=\"g p\" data-selected-links=\"repo_pulls /miloyip/nativejson-benchmark/pulls\" itemprop=\"url\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-git-pull-request\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"></path></svg>\n      <span itemprop=\"name\">Pull requests</span>\n      <span class=\"counter\">1</span>\n      <meta itemprop=\"position\" content=\"3\">\n</a>  </span>\n\n\n\n\n  <a href=\"/miloyip/nativejson-benchmark/pulse\" class=\"js-selected-navigation-item reponav-item\" data-selected-links=\"pulse /miloyip/nativejson-benchmark/pulse\">\n    <svg aria-hidden=\"true\" class=\"octicon octicon-pulse\" height=\"16\" version=\"1.1\" viewBox=\"0 0 14 16\" width=\"14\"><path d=\"M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z\"></path></svg>\n    Pulse\n</a>\n  <a href=\"/miloyip/nativejson-benchmark/graphs\" class=\"js-selected-navigation-item reponav-item\" data-selected-links=\"repo_graphs repo_contributors /miloyip/nativejson-benchmark/graphs\">\n    <svg aria-hidden=\"true\" class=\"octicon octicon-graph\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z\"></path></svg>\n    Graphs\n</a>\n\n</nav>\n\n  </div>\n</div>\n\n<div class=\"container new-discussion-timeline experiment-repo-nav\">\n  <div class=\"repository-content\">\n\n    \n\n<a href=\"/miloyip/nativejson-benchmark/blob/95f27ebcf9a96c7ca4cee26467ed5420140090fb/sample/conformance_Nlohmann%20(C%2B%2B11).md\" class=\"d-none js-permalink-shortcut\" data-hotkey=\"y\">Permalink</a>\n\n<!-- blob contrib key: blob_contributors:v21:0bf9e3593dedd91db6c9dc69e13b7f95 -->\n\n<div class=\"file-navigation js-zeroclipboard-container\">\n  \n<div class=\"select-menu branch-select-menu js-menu-container js-select-menu float-left\">\n  <button class=\"btn btn-sm select-menu-button js-menu-target css-truncate\" data-hotkey=\"w\"\n    \n    type=\"button\" aria-label=\"Switch branches or tags\" tabindex=\"0\" aria-haspopup=\"true\">\n    <i>Branch:</i>\n    <span class=\"js-select-button css-truncate-target\">master</span>\n  </button>\n\n  <div class=\"select-menu-modal-holder js-menu-content js-navigation-container\" data-pjax aria-hidden=\"true\">\n\n    <div class=\"select-menu-modal\">\n      <div class=\"select-menu-header\">\n        <svg aria-label=\"Close\" class=\"octicon octicon-x js-menu-close\" height=\"16\" role=\"img\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z\"></path></svg>\n        <span class=\"select-menu-title\">Switch branches/tags</span>\n      </div>\n\n      <div class=\"select-menu-filters\">\n        <div class=\"select-menu-text-filter\">\n          <input type=\"text\" aria-label=\"Filter branches/tags\" id=\"context-commitish-filter-field\" class=\"form-control js-filterable-field js-navigation-enable\" placeholder=\"Filter branches/tags\">\n        </div>\n        <div class=\"select-menu-tabs\">\n          <ul>\n            <li class=\"select-menu-tab\">\n              <a href=\"#\" data-tab-filter=\"branches\" data-filter-placeholder=\"Filter branches/tags\" class=\"js-select-menu-tab\" role=\"tab\">Branches</a>\n            </li>\n            <li class=\"select-menu-tab\">\n              <a href=\"#\" data-tab-filter=\"tags\" data-filter-placeholder=\"Find a tag…\" class=\"js-select-menu-tab\" role=\"tab\">Tags</a>\n            </li>\n          </ul>\n        </div>\n      </div>\n\n      <div class=\"select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket\" data-tab-filter=\"branches\" role=\"menu\">\n\n        <div data-filterable-for=\"context-commitish-filter-field\" data-filterable-type=\"substring\">\n\n\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/Stixjson/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"Stixjson\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                Stixjson\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/ccan/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"ccan\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                ccan\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/jbson/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"jbson\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                jbson\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/jute/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"jute\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                jute\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/lastjson/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"lastjson\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                lastjson\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/libjson/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"libjson\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                libjson\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open selected\"\n               href=\"/miloyip/nativejson-benchmark/blob/master/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"master\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                master\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/qt/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"qt\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                qt\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/tunnuz/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"tunnuz\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                tunnuz\n              </span>\n            </a>\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n               href=\"/miloyip/nativejson-benchmark/blob/ujson/sample/conformance_Nlohmann%20(C++11).md\"\n               data-name=\"ujson\"\n               data-skip-pjax=\"true\"\n               rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target js-select-menu-filter-text\">\n                ujson\n              </span>\n            </a>\n        </div>\n\n          <div class=\"select-menu-no-results\">Nothing to show</div>\n      </div>\n\n      <div class=\"select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket\" data-tab-filter=\"tags\">\n        <div data-filterable-for=\"context-commitish-filter-field\" data-filterable-type=\"substring\">\n\n\n            <a class=\"select-menu-item js-navigation-item js-navigation-open \"\n              href=\"/miloyip/nativejson-benchmark/tree/v1.0.0/sample/conformance_Nlohmann%20(C%2B%2B11).md\"\n              data-name=\"v1.0.0\"\n              data-skip-pjax=\"true\"\n              rel=\"nofollow\">\n              <svg aria-hidden=\"true\" class=\"octicon octicon-check select-menu-item-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z\"></path></svg>\n              <span class=\"select-menu-item-text css-truncate-target\" title=\"v1.0.0\">\n                v1.0.0\n              </span>\n            </a>\n        </div>\n\n        <div class=\"select-menu-no-results\">Nothing to show</div>\n      </div>\n\n    </div>\n  </div>\n</div>\n\n  <div class=\"btn-group float-right\">\n    <a href=\"/miloyip/nativejson-benchmark/find/master\"\n          class=\"js-pjax-capture-input btn btn-sm\"\n          data-pjax\n          data-hotkey=\"t\">\n      Find file\n    </a>\n    <button aria-label=\"Copy file path to clipboard\" class=\"js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s\" data-copied-hint=\"Copied!\" type=\"button\">Copy path</button>\n  </div>\n  <div class=\"breadcrumb js-zeroclipboard-target\">\n    <span class=\"repo-root js-repo-root\"><span class=\"js-path-segment\"><a href=\"/miloyip/nativejson-benchmark\"><span>nativejson-benchmark</span></a></span></span><span class=\"separator\">/</span><span class=\"js-path-segment\"><a href=\"/miloyip/nativejson-benchmark/tree/master/sample\"><span>sample</span></a></span><span class=\"separator\">/</span><strong class=\"final-path\">conformance_Nlohmann (C++11).md</strong>\n  </div>\n</div>\n\n\n  <div class=\"commit-tease\">\n      <span class=\"float-right\">\n        <a class=\"commit-tease-sha\" href=\"/miloyip/nativejson-benchmark/commit/a4a9f10f41c515d6abb0f019ab9f5d021ed4bb9e\" data-pjax>\n          a4a9f10\n        </a>\n        <relative-time datetime=\"2016-09-09T03:15:21Z\">Sep 9, 2016</relative-time>\n      </span>\n      <div>\n        <img alt=\"@miloyip\" class=\"avatar\" height=\"20\" src=\"https://avatars3.githubusercontent.com/u/1195774?v=3&amp;s=40\" width=\"20\" />\n        <a href=\"/miloyip\" class=\"user-mention\" rel=\"author\">miloyip</a>\n          <a href=\"/miloyip/nativejson-benchmark/commit/a4a9f10f41c515d6abb0f019ab9f5d021ed4bb9e\" class=\"message\" data-pjax=\"true\" title=\"Update sample result for 41 libraries\n\nFixed #43\">Update sample result for 41 libraries</a>\n      </div>\n\n    <div class=\"commit-tease-contributors\">\n      <button type=\"button\" class=\"btn-link muted-link contributors-toggle\" data-facebox=\"#blob_contributors_box\">\n        <strong>1</strong>\n         contributor\n      </button>\n      \n    </div>\n\n    <div id=\"blob_contributors_box\" style=\"display:none\">\n      <h2 class=\"facebox-header\" data-facebox-id=\"facebox-header\">Users who have contributed to this file</h2>\n      <ul class=\"facebox-user-list\" data-facebox-id=\"facebox-description\">\n          <li class=\"facebox-user-list-item\">\n            <img alt=\"@miloyip\" height=\"24\" src=\"https://avatars1.githubusercontent.com/u/1195774?v=3&amp;s=48\" width=\"24\" />\n            <a href=\"/miloyip\">miloyip</a>\n          </li>\n      </ul>\n    </div>\n  </div>\n\n<div class=\"file\">\n  <div class=\"file-header\">\n  <div class=\"file-actions\">\n\n    <div class=\"btn-group\">\n      <a href=\"/miloyip/nativejson-benchmark/raw/master/sample/conformance_Nlohmann%20(C%2B%2B11).md\" class=\"btn btn-sm \" id=\"raw-url\">Raw</a>\n        <a href=\"/miloyip/nativejson-benchmark/blame/master/sample/conformance_Nlohmann%20(C%2B%2B11).md\" class=\"btn btn-sm js-update-url-with-hash\">Blame</a>\n      <a href=\"/miloyip/nativejson-benchmark/commits/master/sample/conformance_Nlohmann%20(C%2B%2B11).md\" class=\"btn btn-sm \" rel=\"nofollow\">History</a>\n    </div>\n\n\n        <button type=\"button\" class=\"btn-octicon disabled tooltipped tooltipped-nw\"\n          aria-label=\"You must be signed in to make or propose changes\">\n          <svg aria-hidden=\"true\" class=\"octicon octicon-pencil\" height=\"16\" version=\"1.1\" viewBox=\"0 0 14 16\" width=\"14\"><path d=\"M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z\"></path></svg>\n        </button>\n        <button type=\"button\" class=\"btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw\"\n          aria-label=\"You must be signed in to make or propose changes\">\n          <svg aria-hidden=\"true\" class=\"octicon octicon-trashcan\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z\"></path></svg>\n        </button>\n  </div>\n\n  <div class=\"file-info\">\n      59 lines (37 sloc)\n      <span class=\"file-info-divider\"></span>\n    545 Bytes\n  </div>\n</div>\n\n  \n  <div id=\"readme\" class=\"readme blob instapaper_body\">\n    <article class=\"markdown-body entry-content\" itemprop=\"text\"><h1><a id=\"user-content-conformance-of-nlohmann-c11\" class=\"anchor\" href=\"#conformance-of-nlohmann-c11\" aria-hidden=\"true\"><svg aria-hidden=\"true\" class=\"octicon octicon-link\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conformance of Nlohmann (C++11)</h1>\n\n<h2><a id=\"user-content-1-parse-validation\" class=\"anchor\" href=\"#1-parse-validation\" aria-hidden=\"true\"><svg aria-hidden=\"true\" class=\"octicon octicon-link\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. Parse Validation</h2>\n\n<p>Summary: 34 of 34 are correct.</p>\n\n<h2><a id=\"user-content-2-parse-double\" class=\"anchor\" href=\"#2-parse-double\" aria-hidden=\"true\"><svg aria-hidden=\"true\" class=\"octicon octicon-link\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Parse Double</h2>\n\n<p>Summary: 66 of 66 are correct.</p>\n\n<h2><a id=\"user-content-3-parse-string\" class=\"anchor\" href=\"#3-parse-string\" aria-hidden=\"true\"><svg aria-hidden=\"true\" class=\"octicon octicon-link\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Parse String</h2>\n\n<p>Summary: 9 of 9 are correct.</p>\n\n<h2><a id=\"user-content-4-roundtrip\" class=\"anchor\" href=\"#4-roundtrip\" aria-hidden=\"true\"><svg aria-hidden=\"true\" class=\"octicon octicon-link\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Roundtrip</h2>\n\n<ul>\n<li>Fail:</li>\n</ul>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">5e-324</span>]</pre></div>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">4.94065645841247e-324</span>]</pre></div>\n\n<ul>\n<li>Fail:</li>\n</ul>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">2.225073858507201e-308</span>]</pre></div>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">2.2250738585072e-308</span>]</pre></div>\n\n<ul>\n<li>Fail:</li>\n</ul>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">2.2250738585072014e-308</span>]</pre></div>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">2.2250738585072e-308</span>]</pre></div>\n\n<ul>\n<li>Fail:</li>\n</ul>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">1.7976931348623157e308</span>]</pre></div>\n\n<div class=\"highlight highlight-source-js\"><pre>[<span class=\"pl-c1\">1.79769313486232e+308</span>]</pre></div>\n\n<p>Summary: 23 of 27 are correct.</p>\n</article>\n  </div>\n\n</div>\n\n<button type=\"button\" data-facebox=\"#jump-to-line\" data-facebox-class=\"linejump\" data-hotkey=\"l\" class=\"d-none\">Jump to Line</button>\n<div id=\"jump-to-line\" style=\"display:none\">\n  <!-- </textarea> --><!-- '\"` --><form accept-charset=\"UTF-8\" action=\"\" class=\"js-jump-to-line-form\" method=\"get\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /></div>\n    <input class=\"form-control linejump-input js-jump-to-line-field\" type=\"text\" placeholder=\"Jump to line&hellip;\" aria-label=\"Jump to line\" autofocus>\n    <button type=\"submit\" class=\"btn\">Go</button>\n</form></div>\n\n  </div>\n  <div class=\"modal-backdrop js-touch-events\"></div>\n</div>\n\n\n    </div>\n  </div>\n\n    </div>\n\n        <div class=\"container site-footer-container\">\n  <div class=\"site-footer\" role=\"contentinfo\">\n    <ul class=\"site-footer-links float-right\">\n        <li><a href=\"https://github.com/contact\" data-ga-click=\"Footer, go to contact, text:contact\">Contact GitHub</a></li>\n      <li><a href=\"https://developer.github.com\" data-ga-click=\"Footer, go to api, text:api\">API</a></li>\n      <li><a href=\"https://training.github.com\" data-ga-click=\"Footer, go to training, text:training\">Training</a></li>\n      <li><a href=\"https://shop.github.com\" data-ga-click=\"Footer, go to shop, text:shop\">Shop</a></li>\n        <li><a href=\"https://github.com/blog\" data-ga-click=\"Footer, go to blog, text:blog\">Blog</a></li>\n        <li><a href=\"https://github.com/about\" data-ga-click=\"Footer, go to about, text:about\">About</a></li>\n\n    </ul>\n\n    <a href=\"https://github.com\" aria-label=\"Homepage\" class=\"site-footer-mark\" title=\"GitHub\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-mark-github\" height=\"24\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"24\"><path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z\"></path></svg>\n</a>\n    <ul class=\"site-footer-links\">\n      <li>&copy; 2016 <span title=\"0.18611s from github-fe151-cp1-prd.iad.github.net\">GitHub</span>, Inc.</li>\n        <li><a href=\"https://github.com/site/terms\" data-ga-click=\"Footer, go to terms, text:terms\">Terms</a></li>\n        <li><a href=\"https://github.com/site/privacy\" data-ga-click=\"Footer, go to privacy, text:privacy\">Privacy</a></li>\n        <li><a href=\"https://github.com/security\" data-ga-click=\"Footer, go to security, text:security\">Security</a></li>\n        <li><a href=\"https://status.github.com/\" data-ga-click=\"Footer, go to status, text:status\">Status</a></li>\n        <li><a href=\"https://help.github.com\" data-ga-click=\"Footer, go to help, text:help\">Help</a></li>\n    </ul>\n  </div>\n</div>\n\n\n\n    \n\n    <div id=\"ajax-error-message\" class=\"ajax-error-message flash flash-error\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-alert\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z\"></path></svg>\n      <button type=\"button\" class=\"flash-close js-flash-close js-ajax-error-dismiss\" aria-label=\"Dismiss error\">\n        <svg aria-hidden=\"true\" class=\"octicon octicon-x\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z\"></path></svg>\n      </button>\n      You can't perform that action at this time.\n    </div>\n\n\n      <script crossorigin=\"anonymous\" src=\"https://assets-cdn.github.com/assets/compat-40e365359d1c4db1e36a55be458e60f2b7c24d58b5a00ae13398480e7ba768e0.js\"></script>\n      <script crossorigin=\"anonymous\" src=\"https://assets-cdn.github.com/assets/frameworks-88471af1fec40ff9418efbe2ddd15b6896af8d772f8179004c254dffc25ea490.js\"></script>\n      <script async=\"async\" crossorigin=\"anonymous\" src=\"https://assets-cdn.github.com/assets/github-e18e11a943ff2eb9394c72d4ec8b76592c454915b5839ae177d422777a046e29.js\"></script>\n      \n      \n      \n      \n      \n      \n    <div class=\"js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-alert\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path d=\"M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z\"></path></svg>\n      <span class=\"signed-in-tab-flash\">You signed in with another tab or window. <a href=\"\">Reload</a> to refresh your session.</span>\n      <span class=\"signed-out-tab-flash\">You signed out in another tab or window. <a href=\"\">Reload</a> to refresh your session.</span>\n    </div>\n    <div class=\"facebox\" id=\"facebox\" style=\"display:none;\">\n  <div class=\"facebox-popup\">\n    <div class=\"facebox-content\" role=\"dialog\" aria-labelledby=\"facebox-header\" aria-describedby=\"facebox-description\">\n    </div>\n    <button type=\"button\" class=\"facebox-close js-facebox-close\" aria-label=\"Close modal\">\n      <svg aria-hidden=\"true\" class=\"octicon octicon-x\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\"><path d=\"M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z\"></path></svg>\n    </button>\n  </div>\n</div>\n\n  </body>\n</html>\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/reports/2016-10-02-fuzz/index.html",
    "content": "<table style=\"font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'\">\n<tr><td style=\"width: 18ex\"><b>Banner:</b></td><td>fuzz</td></tr>\n<tr><td><b>Directory:</b></td><td>fuzz-testing/out</td></tr>\n<tr><td><b>Generated on:</b></td><td>Sun Oct  2 08:51:02 CEST 2016</td></tr>\n</table>\n<p>\n<img src=\"high_freq.png\" width=1000 height=300><p>\n<img src=\"low_freq.png\" width=1000 height=200><p>\n<img src=\"exec_speed.png\" width=1000 height=200>\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/fuzzer-driver_afl.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nThis file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on\nan implementation of the `LLVMFuzzerTestOneInput` function which processes a\npassed byte array.\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\n*/\n\n#include <vector>    // for vector\n#include <cstdint>   // for uint8_t\n#include <iostream>  // for cin\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);\n\nint main()\n{\n#ifdef __AFL_HAVE_MANUAL_CONTROL\n    while (__AFL_LOOP(1000))\n    {\n#endif\n        // copy stdin to byte vector\n        std::vector<uint8_t> vec;\n        char c;\n        while (std::cin.get(c))\n        {\n            vec.push_back(static_cast<uint8_t>(c));\n        }\n\n        LLVMFuzzerTestOneInput(vec.data(), vec.size());\n#ifdef __AFL_HAVE_MANUAL_CONTROL\n    }\n#endif\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/fuzzer-parse_bson.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nThis file implements a parser test suitable for fuzz testing. Given a byte\narray data, it performs the following steps:\n\n- j1 = from_bson(data)\n- vec = to_bson(j1)\n- j2 = from_bson(vec)\n- assert(j1 == j2)\n\nThe provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer\ndrivers.\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\n*/\n\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// see http://llvm.org/docs/LibFuzzer.html\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)\n{\n    try\n    {\n        // step 1: parse input\n        std::vector<uint8_t> vec1(data, data + size);\n        json j1 = json::from_bson(vec1);\n\n        if (j1.is_discarded())\n        {\n            return 0;\n        }\n\n        try\n        {\n            // step 2: round trip\n            std::vector<uint8_t> vec2 = json::to_bson(j1);\n\n            // parse serialization\n            json j2 = json::from_bson(vec2);\n\n            // serializations must match\n            assert(json::to_bson(j2) == vec2);\n        }\n        catch (const json::parse_error&)\n        {\n            // parsing a BSON serialization must not fail\n            assert(false);\n        }\n    }\n    catch (const json::parse_error&)\n    {\n        // parse errors are ok, because input may be random bytes\n    }\n    catch (const json::type_error&)\n    {\n        // type errors can occur during parsing, too\n    }\n    catch (const json::out_of_range&)\n    {\n        // out of range errors can occur during parsing, too\n    }\n\n    // return 0 - non-zero return values are reserved for future use\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/fuzzer-parse_cbor.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nThis file implements a parser test suitable for fuzz testing. Given a byte\narray data, it performs the following steps:\n\n- j1 = from_cbor(data)\n- vec = to_cbor(j1)\n- j2 = from_cbor(vec)\n- assert(j1 == j2)\n\nThe provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer\ndrivers.\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\n*/\n\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// see http://llvm.org/docs/LibFuzzer.html\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)\n{\n    try\n    {\n        // step 1: parse input\n        std::vector<uint8_t> vec1(data, data + size);\n        json j1 = json::from_cbor(vec1);\n\n        try\n        {\n            // step 2: round trip\n            std::vector<uint8_t> vec2 = json::to_cbor(j1);\n\n            // parse serialization\n            json j2 = json::from_cbor(vec2);\n\n            // serializations must match\n            assert(json::to_cbor(j2) == vec2);\n        }\n        catch (const json::parse_error&)\n        {\n            // parsing a CBOR serialization must not fail\n            assert(false);\n        }\n    }\n    catch (const json::parse_error&)\n    {\n        // parse errors are ok, because input may be random bytes\n    }\n    catch (const json::type_error&)\n    {\n        // type errors can occur during parsing, too\n    }\n    catch (const json::out_of_range&)\n    {\n        // out of range errors can occur during parsing, too\n    }\n\n    // return 0 - non-zero return values are reserved for future use\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/fuzzer-parse_json.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nThis file implements a parser test suitable for fuzz testing. Given a byte\narray data, it performs the following steps:\n\n- j1 = parse(data)\n- s1 = serialize(j1)\n- j2 = parse(s1)\n- s2 = serialize(j2)\n- assert(s1 == s2)\n\nThe provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer\ndrivers.\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\n*/\n\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// see http://llvm.org/docs/LibFuzzer.html\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)\n{\n    try\n    {\n        // step 1: parse input\n        json j1 = json::parse(data, data + size);\n\n        try\n        {\n            // step 2: round trip\n\n            // first serialization\n            std::string s1 = j1.dump();\n\n            // parse serialization\n            json j2 = json::parse(s1);\n\n            // second serialization\n            std::string s2 = j2.dump();\n\n            // serializations must match\n            assert(s1 == s2);\n        }\n        catch (const json::parse_error&)\n        {\n            // parsing a JSON serialization must not fail\n            assert(false);\n        }\n    }\n    catch (const json::parse_error&)\n    {\n        // parse errors are ok, because input may be random bytes\n    }\n    catch (const json::out_of_range&)\n    {\n        // out of range errors may happen if provided sizes are excessive\n    }\n\n    // return 0 - non-zero return values are reserved for future use\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/fuzzer-parse_msgpack.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nThis file implements a parser test suitable for fuzz testing. Given a byte\narray data, it performs the following steps:\n\n- j1 = from_msgpack(data)\n- vec = to_msgpack(j1)\n- j2 = from_msgpack(vec)\n- assert(j1 == j2)\n\nThe provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer\ndrivers.\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\n*/\n\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// see http://llvm.org/docs/LibFuzzer.html\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)\n{\n    try\n    {\n        // step 1: parse input\n        std::vector<uint8_t> vec1(data, data + size);\n        json j1 = json::from_msgpack(vec1);\n\n        try\n        {\n            // step 2: round trip\n            std::vector<uint8_t> vec2 = json::to_msgpack(j1);\n\n            // parse serialization\n            json j2 = json::from_msgpack(vec2);\n\n            // serializations must match\n            assert(json::to_msgpack(j2) == vec2);\n        }\n        catch (const json::parse_error&)\n        {\n            // parsing a MessagePack serialization must not fail\n            assert(false);\n        }\n    }\n    catch (const json::parse_error&)\n    {\n        // parse errors are ok, because input may be random bytes\n    }\n    catch (const json::type_error&)\n    {\n        // type errors can occur during parsing, too\n    }\n    catch (const json::out_of_range&)\n    {\n        // out of range errors may happen if provided sizes are excessive\n    }\n\n    // return 0 - non-zero return values are reserved for future use\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/fuzzer-parse_ubjson.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nThis file implements a parser test suitable for fuzz testing. Given a byte\narray data, it performs the following steps:\n\n- j1 = from_ubjson(data)\n- vec = to_ubjson(j1)\n- j2 = from_ubjson(vec)\n- assert(j1 == j2)\n- vec2 = to_ubjson(j1, use_size = true, use_type = false)\n- j3 = from_ubjson(vec2)\n- assert(j1 == j3)\n- vec3 = to_ubjson(j1, use_size = true, use_type = true)\n- j4 = from_ubjson(vec3)\n- assert(j1 == j4)\n\nThe provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer\ndrivers.\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\n*/\n\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// see http://llvm.org/docs/LibFuzzer.html\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)\n{\n    try\n    {\n        // step 1: parse input\n        std::vector<uint8_t> vec1(data, data + size);\n        json j1 = json::from_ubjson(vec1);\n\n        try\n        {\n            // step 2.1: round trip without adding size annotations to container types\n            std::vector<uint8_t> vec2 = json::to_ubjson(j1, false, false);\n\n            // step 2.2: round trip with adding size annotations but without adding type annonations to container types\n            std::vector<uint8_t> vec3 = json::to_ubjson(j1, true, false);\n\n            // step 2.3: round trip with adding size as well as type annotations to container types\n            std::vector<uint8_t> vec4 = json::to_ubjson(j1, true, true);\n\n            // parse serialization\n            json j2 = json::from_ubjson(vec2);\n            json j3 = json::from_ubjson(vec3);\n            json j4 = json::from_ubjson(vec4);\n\n            // serializations must match\n            assert(json::to_ubjson(j2, false, false) == vec2);\n            assert(json::to_ubjson(j3, true, false) == vec3);\n            assert(json::to_ubjson(j4, true, true) == vec4);\n        }\n        catch (const json::parse_error&)\n        {\n            // parsing a UBJSON serialization must not fail\n            assert(false);\n        }\n    }\n    catch (const json::parse_error&)\n    {\n        // parse errors are ok, because input may be random bytes\n    }\n    catch (const json::type_error&)\n    {\n        // type errors can occur during parsing, too\n    }\n    catch (const json::out_of_range&)\n    {\n        // out of range errors may happen if provided sizes are excessive\n    }\n\n    // return 0 - non-zero return values are reserved for future use\n    return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/test_utils.hpp",
    "content": "#pragma once\n\n#include <cstdint> // uint8_t\n#include <fstream> // ifstream, istreambuf_iterator, ios\n#include <vector> // vector\n\nnamespace utils\n{\n\ninline std::vector<std::uint8_t> read_binary_file(const std::string& filename)\n{\n    std::ifstream file(filename, std::ios::binary);\n    file.unsetf(std::ios::skipws);\n\n    file.seekg(0, std::ios::end);\n    const auto size = file.tellg();\n    file.seekg(0, std::ios::beg);\n\n    std::vector<std::uint8_t> byte_vector;\n    byte_vector.reserve(static_cast<std::size_t>(size));\n    byte_vector.insert(byte_vector.begin(), std::istream_iterator<std::uint8_t>(file), std::istream_iterator<std::uint8_t>());\n    return byte_vector;\n}\n\n} // namespace utils\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-algorithms.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"algorithms\")\n{\n    json j_array = {13, 29, 3, {{\"one\", 1}, {\"two\", 2}}, true, false, {1, 2, 3}, \"foo\", \"baz\"};\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    SECTION(\"non-modifying sequence operations\")\n    {\n        SECTION(\"std::all_of\")\n        {\n            CHECK(std::all_of(j_array.begin(), j_array.end(), [](const json & value)\n            {\n                return !value.empty();\n            }));\n            CHECK(std::all_of(j_object.begin(), j_object.end(), [](const json & value)\n            {\n                return value.type() == json::value_t::number_integer;\n            }));\n        }\n\n        SECTION(\"std::any_of\")\n        {\n            CHECK(std::any_of(j_array.begin(), j_array.end(), [](const json & value)\n            {\n                return value.is_string() && value.get<std::string>() == \"foo\";\n            }));\n            CHECK(std::any_of(j_object.begin(), j_object.end(), [](const json & value)\n            {\n                return value.get<int>() > 1;\n            }));\n        }\n\n        SECTION(\"std::none_of\")\n        {\n            CHECK(std::none_of(j_array.begin(), j_array.end(), [](const json & value)\n            {\n                return value.empty();\n            }));\n            CHECK(std::none_of(j_object.begin(), j_object.end(), [](const json & value)\n            {\n                return value.get<int>() <= 0;\n            }));\n        }\n\n        SECTION(\"std::for_each\")\n        {\n            SECTION(\"reading\")\n            {\n                int sum = 0;\n\n                std::for_each(j_array.cbegin(), j_array.cend(), [&sum](const json & value)\n                {\n                    if (value.is_number())\n                    {\n                        sum += static_cast<int>(value);\n                    }\n                });\n\n                CHECK(sum == 45);\n            }\n\n            SECTION(\"writing\")\n            {\n                auto add17 = [](json & value)\n                {\n                    if (value.is_array())\n                    {\n                        value.push_back(17);\n                    }\n                };\n\n                std::for_each(j_array.begin(), j_array.end(), add17);\n\n                CHECK(j_array[6] == json({1, 2, 3, 17}));\n            }\n        }\n\n        SECTION(\"std::count\")\n        {\n            CHECK(std::count(j_array.begin(), j_array.end(), json(true)) == 1);\n        }\n\n        SECTION(\"std::count_if\")\n        {\n            CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json & value)\n            {\n                return (value.is_number());\n            }) == 3);\n            CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json&)\n            {\n                return true;\n            }) == 9);\n        }\n\n        SECTION(\"std::mismatch\")\n        {\n            json j_array2 = {13, 29, 3, {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}}, true, false, {1, 2, 3}, \"foo\", \"baz\"};\n            auto res = std::mismatch(j_array.begin(), j_array.end(), j_array2.begin());\n            CHECK(*res.first == json({{\"one\", 1}, {\"two\", 2}}));\n            CHECK(*res.second == json({{\"one\", 1}, {\"two\", 2}, {\"three\", 3}}));\n        }\n\n        SECTION(\"std::equal\")\n        {\n            SECTION(\"using operator==\")\n            {\n                CHECK(std::equal(j_array.begin(), j_array.end(), j_array.begin()));\n                CHECK(std::equal(j_object.begin(), j_object.end(), j_object.begin()));\n                CHECK(!std::equal(j_array.begin(), j_array.end(), j_object.begin()));\n            }\n\n            SECTION(\"using user-defined comparison\")\n            {\n                // compare objects only by size of its elements\n                json j_array2 = {13, 29, 3, {\"Hello\", \"World\"}, true, false, {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}}, \"foo\", \"baz\"};\n                CHECK(!std::equal(j_array.begin(), j_array.end(), j_array2.begin()));\n                CHECK(std::equal(j_array.begin(), j_array.end(), j_array2.begin(),\n                                 [](const json & a, const json & b)\n                {\n                    return (a.size() == b.size());\n                }));\n            }\n        }\n\n        SECTION(\"std::find\")\n        {\n            auto it = std::find(j_array.begin(), j_array.end(), json(false));\n            CHECK(std::distance(j_array.begin(), it) == 5);\n        }\n\n        SECTION(\"std::find_if\")\n        {\n            auto it = std::find_if(j_array.begin(), j_array.end(),\n                                   [](const json & value)\n            {\n                return value.is_boolean();\n            });\n            CHECK(std::distance(j_array.begin(), it) == 4);\n        }\n\n        SECTION(\"std::find_if_not\")\n        {\n            auto it = std::find_if_not(j_array.begin(), j_array.end(),\n                                       [](const json & value)\n            {\n                return value.is_number();\n            });\n            CHECK(std::distance(j_array.begin(), it) == 3);\n        }\n\n        SECTION(\"std::adjacent_find\")\n        {\n            CHECK(std::adjacent_find(j_array.begin(), j_array.end()) == j_array.end());\n            CHECK(std::adjacent_find(j_array.begin(), j_array.end(),\n                                     [](const json & v1, const json & v2)\n            {\n                return v1.type() == v2.type();\n            }) == j_array.begin());\n        }\n    }\n\n    SECTION(\"modifying sequence operations\")\n    {\n        SECTION(\"std::reverse\")\n        {\n            std::reverse(j_array.begin(), j_array.end());\n            CHECK(j_array == json({\"baz\", \"foo\", {1, 2, 3}, false, true, {{\"one\", 1}, {\"two\", 2}}, 3, 29, 13}));\n        }\n\n        SECTION(\"std::rotate\")\n        {\n            std::rotate(j_array.begin(), j_array.begin() + 1, j_array.end());\n            CHECK(j_array == json({29, 3, {{\"one\", 1}, {\"two\", 2}}, true, false, {1, 2, 3}, \"foo\", \"baz\", 13}));\n        }\n\n        SECTION(\"std::partition\")\n        {\n            auto it = std::partition(j_array.begin(), j_array.end(), [](const json & v)\n            {\n                return v.is_string();\n            });\n            CHECK(std::distance(j_array.begin(), it) == 2);\n            CHECK(!it[2].is_string());\n        }\n    }\n\n    SECTION(\"sorting operations\")\n    {\n        SECTION(\"std::sort\")\n        {\n            SECTION(\"with standard comparison\")\n            {\n                json j = {13, 29, 3, {{\"one\", 1}, {\"two\", 2}}, true, false, {1, 2, 3}, \"foo\", \"baz\", nullptr};\n                std::sort(j.begin(), j.end());\n                CHECK(j == json({nullptr, false, true, 3, 13, 29, {{\"one\", 1}, {\"two\", 2}}, {1, 2, 3}, \"baz\", \"foo\"}));\n            }\n\n            SECTION(\"with user-defined comparison\")\n            {\n                json j = {3, {{\"one\", 1}, {\"two\", 2}}, {1, 2, 3}, nullptr};\n                std::sort(j.begin(), j.end(), [](const json & a, const json & b)\n                {\n                    return a.size() < b.size();\n                });\n                CHECK(j == json({nullptr, 3, {{\"one\", 1}, {\"two\", 2}}, {1, 2, 3}}));\n            }\n\n            SECTION(\"sorting an object\")\n            {\n                json j({{\"one\", 1}, {\"two\", 2}});\n                CHECK_THROWS_AS(std::sort(j.begin(), j.end()), json::invalid_iterator&);\n                CHECK_THROWS_WITH(std::sort(j.begin(), j.end()),\n                                  \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n            }\n        }\n\n        SECTION(\"std::partial_sort\")\n        {\n            json j = {13, 29, 3, {{\"one\", 1}, {\"two\", 2}}, true, false, {1, 2, 3}, \"foo\", \"baz\", nullptr};\n            std::partial_sort(j.begin(), j.begin() + 4, j.end());\n            CHECK(j == json({nullptr, false, true, 3, {{\"one\", 1}, {\"two\", 2}}, 29, {1, 2, 3}, \"foo\", \"baz\", 13}));\n        }\n    }\n\n    SECTION(\"set operations\")\n    {\n        SECTION(\"std::merge\")\n        {\n            {\n                json j1 = {2, 4, 6, 8};\n                json j2 = {1, 2, 3, 5, 7};\n                json j3;\n\n                std::merge(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));\n                CHECK(j3 == json({1, 2, 2, 3, 4, 5, 6, 7, 8}));\n            }\n        }\n\n        SECTION(\"std::set_difference\")\n        {\n            json j1 = {1, 2, 3, 4, 5, 6, 7, 8};\n            json j2 = {1, 2, 3, 5, 7};\n            json j3;\n\n            std::set_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));\n            CHECK(j3 == json({4, 6, 8}));\n        }\n\n        SECTION(\"std::set_intersection\")\n        {\n            json j1 = {1, 2, 3, 4, 5, 6, 7, 8};\n            json j2 = {1, 2, 3, 5, 7};\n            json j3;\n\n            std::set_intersection(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));\n            CHECK(j3 == json({1, 2, 3, 5, 7}));\n        }\n\n        SECTION(\"std::set_union\")\n        {\n            json j1 = {2, 4, 6, 8};\n            json j2 = {1, 2, 3, 5, 7};\n            json j3;\n\n            std::set_union(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));\n            CHECK(j3 == json({1, 2, 3, 4, 5, 6, 7, 8}));\n        }\n\n        SECTION(\"std::set_symmetric_difference\")\n        {\n            json j1 = {2, 4, 6, 8};\n            json j2 = {1, 2, 3, 5, 7};\n            json j3;\n\n            std::set_symmetric_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));\n            CHECK(j3 == json({1, 3, 4, 5, 6, 7, 8}));\n        }\n    }\n\n    SECTION(\"heap operations\")\n    {\n        std::make_heap(j_array.begin(), j_array.end());\n        CHECK(std::is_heap(j_array.begin(), j_array.end()));\n        std::sort_heap(j_array.begin(), j_array.end());\n        CHECK(j_array == json({false, true, 3, 13, 29, {{\"one\", 1}, {\"two\", 2}}, {1, 2, 3}, \"baz\", \"foo\"}));\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-allocator.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nnamespace\n{\n// special test case to check if memory is leaked if constructor throws\ntemplate<class T>\nstruct bad_allocator : std::allocator<T>\n{\n    template<class... Args>\n    void construct(T* /*unused*/, Args&& ... /*unused*/)\n    {\n        throw std::bad_alloc();\n    }\n};\n} // namespace\n\nTEST_CASE(\"bad_alloc\")\n{\n    SECTION(\"bad_alloc\")\n    {\n        // create JSON type using the throwing allocator\n        using bad_json = nlohmann::basic_json<std::map,\n              std::vector,\n              std::string,\n              bool,\n              std::int64_t,\n              std::uint64_t,\n              double,\n              bad_allocator>;\n\n        // creating an object should throw\n        CHECK_THROWS_AS(bad_json(bad_json::value_t::object), std::bad_alloc&);\n    }\n}\n\nnamespace\n{\nbool next_construct_fails = false;\nbool next_destroy_fails = false;\nbool next_deallocate_fails = false;\n\ntemplate<class T>\nstruct my_allocator : std::allocator<T>\n{\n    using std::allocator<T>::allocator;\n\n    template<class... Args>\n    void construct(T* p, Args&& ... args)\n    {\n        if (next_construct_fails)\n        {\n            next_construct_fails = false;\n            throw std::bad_alloc();\n        }\n\n        ::new (reinterpret_cast<void*>(p)) T(std::forward<Args>(args)...);\n    }\n\n    void deallocate(T* p, std::size_t n)\n    {\n        if (next_deallocate_fails)\n        {\n            next_deallocate_fails = false;\n            throw std::bad_alloc();\n        }\n\n        std::allocator<T>::deallocate(p, n);\n    }\n\n    void destroy(T* p)\n    {\n        if (next_destroy_fails)\n        {\n            next_destroy_fails = false;\n            throw std::bad_alloc();\n        }\n\n        static_cast<void>(p); // fix MSVC's C4100 warning\n        p->~T();\n    }\n\n    template <class U>\n    struct rebind\n    {\n        using other = my_allocator<U>;\n    };\n};\n\n// allows deletion of raw pointer, usually hold by json_value\ntemplate<class T>\nvoid my_allocator_clean_up(T* p)\n{\n    assert(p != nullptr);\n    my_allocator<T> alloc;\n    alloc.destroy(p);\n    alloc.deallocate(p, 1);\n}\n} // namespace\n\nTEST_CASE(\"controlled bad_alloc\")\n{\n    // create JSON type using the throwing allocator\n    using my_json = nlohmann::basic_json<std::map,\n          std::vector,\n          std::string,\n          bool,\n          std::int64_t,\n          std::uint64_t,\n          double,\n          my_allocator>;\n\n    SECTION(\"class json_value\")\n    {\n        SECTION(\"json_value(value_t)\")\n        {\n            SECTION(\"object\")\n            {\n                next_construct_fails = false;\n                auto t = my_json::value_t::object;\n                CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(t).object));\n                next_construct_fails = true;\n                CHECK_THROWS_AS(my_json::json_value(t), std::bad_alloc&);\n                next_construct_fails = false;\n            }\n            SECTION(\"array\")\n            {\n                next_construct_fails = false;\n                auto t = my_json::value_t::array;\n                CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(t).array));\n                next_construct_fails = true;\n                CHECK_THROWS_AS(my_json::json_value(t), std::bad_alloc&);\n                next_construct_fails = false;\n            }\n            SECTION(\"string\")\n            {\n                next_construct_fails = false;\n                auto t = my_json::value_t::string;\n                CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(t).string));\n                next_construct_fails = true;\n                CHECK_THROWS_AS(my_json::json_value(t), std::bad_alloc&);\n                next_construct_fails = false;\n            }\n        }\n\n        SECTION(\"json_value(const string_t&)\")\n        {\n            next_construct_fails = false;\n            my_json::string_t v(\"foo\");\n            CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(v).string));\n            next_construct_fails = true;\n            CHECK_THROWS_AS(my_json::json_value(v), std::bad_alloc&);\n            next_construct_fails = false;\n        }\n    }\n\n    SECTION(\"class basic_json\")\n    {\n        SECTION(\"basic_json(const CompatibleObjectType&)\")\n        {\n            next_construct_fails = false;\n            std::map<std::string, std::string> v {{\"foo\", \"bar\"}};\n            CHECK_NOTHROW(my_json(v));\n            next_construct_fails = true;\n            CHECK_THROWS_AS(my_json(v), std::bad_alloc&);\n            next_construct_fails = false;\n        }\n\n        SECTION(\"basic_json(const CompatibleArrayType&)\")\n        {\n            next_construct_fails = false;\n            std::vector<std::string> v {\"foo\", \"bar\", \"baz\"};\n            CHECK_NOTHROW(my_json(v));\n            next_construct_fails = true;\n            CHECK_THROWS_AS(my_json(v), std::bad_alloc&);\n            next_construct_fails = false;\n        }\n\n        SECTION(\"basic_json(const typename string_t::value_type*)\")\n        {\n            next_construct_fails = false;\n            CHECK_NOTHROW(my_json(\"foo\"));\n            next_construct_fails = true;\n            CHECK_THROWS_AS(my_json(\"foo\"), std::bad_alloc&);\n            next_construct_fails = false;\n        }\n\n        SECTION(\"basic_json(const typename string_t::value_type*)\")\n        {\n            next_construct_fails = false;\n            std::string s(\"foo\");\n            CHECK_NOTHROW(my_json(s));\n            next_construct_fails = true;\n            CHECK_THROWS_AS(my_json(s), std::bad_alloc&);\n            next_construct_fails = false;\n        }\n    }\n}\n\nnamespace\n{\ntemplate<class T>\nstruct allocator_no_forward : std::allocator<T>\n{\n    allocator_no_forward() = default;\n    template <class U>\n    allocator_no_forward(allocator_no_forward<U> /*unused*/) {}\n\n    template <class U>\n    struct rebind\n    {\n        using other =  allocator_no_forward<U>;\n    };\n\n    template <class... Args>\n    void construct(T* p, const Args& ... args) noexcept(noexcept(::new (static_cast<void*>(p)) T(args...)))\n    {\n        // force copy even if move is available\n        ::new (static_cast<void*>(p)) T(args...);\n    }\n};\n} // namespace\n\nTEST_CASE(\"bad my_allocator::construct\")\n{\n    SECTION(\"my_allocator::construct doesn't forward\")\n    {\n        using bad_alloc_json = nlohmann::basic_json<std::map,\n              std::vector,\n              std::string,\n              bool,\n              std::int64_t,\n              std::uint64_t,\n              double,\n              allocator_no_forward>;\n\n        bad_alloc_json j;\n        j[\"test\"] = bad_alloc_json::array_t();\n        j[\"test\"].push_back(\"should not leak\");\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-alt-string.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2018 Vitaliy Manushkin <agri@akamo.info>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\n\n#include <string>\n#include <utility>\n\n\n/* forward declarations */\nclass alt_string;\nbool operator<(const char* op1, const alt_string& op2);\nvoid int_to_string(alt_string& target, std::size_t value);\n\n/*\n * This is virtually a string class.\n * It covers std::string under the hood.\n */\nclass alt_string\n{\n  public:\n    using value_type = std::string::value_type;\n\n    alt_string(const char* str): str_impl(str) {}\n    alt_string(const char* str, std::size_t count): str_impl(str, count) {}\n    alt_string(size_t count, char chr): str_impl(count, chr) {}\n    alt_string() = default;\n\n    template <typename...TParams>\n    alt_string& append(TParams&& ...params)\n    {\n        str_impl.append(std::forward<TParams>(params)...);\n        return *this;\n    }\n\n    void push_back(char c)\n    {\n        str_impl.push_back(c);\n    }\n\n    template <typename op_type>\n    bool operator==(const op_type& op) const\n    {\n        return str_impl == op;\n    }\n\n    bool operator==(const alt_string& op) const\n    {\n        return str_impl == op.str_impl;\n    }\n\n    template <typename op_type>\n    bool operator!=(const op_type& op) const\n    {\n        return str_impl != op;\n    }\n\n    bool operator!=(const alt_string& op) const\n    {\n        return str_impl != op.str_impl;\n    }\n\n    std::size_t size() const noexcept\n    {\n        return str_impl.size();\n    }\n\n    void resize (std::size_t n)\n    {\n        str_impl.resize(n);\n    }\n\n    void resize (std::size_t n, char c)\n    {\n        str_impl.resize(n, c);\n    }\n\n    template <typename op_type>\n    bool operator<(const op_type& op) const\n    {\n        return str_impl < op;\n    }\n\n    bool operator<(const alt_string& op) const\n    {\n        return str_impl < op.str_impl;\n    }\n\n    const char* c_str() const\n    {\n        return str_impl.c_str();\n    }\n\n    char& operator[](std::size_t index)\n    {\n        return str_impl[index];\n    }\n\n    const char& operator[](std::size_t index) const\n    {\n        return str_impl[index];\n    }\n\n    char& back()\n    {\n        return str_impl.back();\n    }\n\n    const char& back() const\n    {\n        return str_impl.back();\n    }\n\n    void clear()\n    {\n        str_impl.clear();\n    }\n\n    const value_type* data()\n    {\n        return str_impl.data();\n    }\n\n  private:\n    std::string str_impl {};\n\n    friend bool ::operator<(const char* /*op1*/, const alt_string& /*op2*/);\n};\n\nvoid int_to_string(alt_string& target, std::size_t value)\n{\n    target = std::to_string(value).c_str();\n}\n\nusing alt_json = nlohmann::basic_json <\n                 std::map,\n                 std::vector,\n                 alt_string,\n                 bool,\n                 std::int64_t,\n                 std::uint64_t,\n                 double,\n                 std::allocator,\n                 nlohmann::adl_serializer >;\n\n\nbool operator<(const char* op1, const alt_string& op2)\n{\n    return op1 < op2.str_impl;\n}\n\nTEST_CASE(\"alternative string type\")\n{\n    SECTION(\"dump\")\n    {\n        {\n            alt_json doc;\n            doc[\"pi\"] = 3.141;\n            alt_string dump = doc.dump();\n            CHECK(dump == R\"({\"pi\":3.141})\");\n        }\n\n        {\n            alt_json doc;\n            doc[\"happy\"] = true;\n            alt_string dump = doc.dump();\n            CHECK(dump == R\"({\"happy\":true})\");\n        }\n\n        {\n            alt_json doc;\n            doc[\"name\"] = \"I'm Batman\";\n            alt_string dump = doc.dump();\n            CHECK(dump == R\"({\"name\":\"I'm Batman\"})\");\n        }\n\n        {\n            alt_json doc;\n            doc[\"nothing\"] = nullptr;\n            alt_string dump = doc.dump();\n            CHECK(dump == R\"({\"nothing\":null})\");\n        }\n\n        {\n            alt_json doc;\n            doc[\"answer\"][\"everything\"] = 42;\n            alt_string dump = doc.dump();\n            CHECK(dump == R\"({\"answer\":{\"everything\":42}})\");\n        }\n\n        {\n            alt_json doc;\n            doc[\"list\"] = { 1, 0, 2 };\n            alt_string dump = doc.dump();\n            CHECK(dump == R\"({\"list\":[1,0,2]})\");\n        }\n\n        {\n            alt_json doc;\n            doc[\"object\"] = { {\"currency\", \"USD\"}, {\"value\", 42.99} };\n            alt_string dump = doc.dump();\n            CHECK(dump == R\"({\"object\":{\"currency\":\"USD\",\"value\":42.99}})\");\n        }\n    }\n\n    SECTION(\"parse\")\n    {\n        auto doc = alt_json::parse(R\"({\"foo\": \"bar\"})\");\n        alt_string dump = doc.dump();\n        CHECK(dump == R\"({\"foo\":\"bar\"})\");\n    }\n\n    SECTION(\"items\")\n    {\n        auto doc = alt_json::parse(R\"({\"foo\": \"bar\"})\");\n\n        for (const auto& item : doc.items())\n        {\n            CHECK(item.key() == \"foo\");\n            CHECK(item.value() == \"bar\");\n        }\n\n        auto doc_array = alt_json::parse(R\"([\"foo\", \"bar\"])\");\n\n        for (const auto& item : doc_array.items())\n        {\n            if (item.key() == \"0\" )\n            {\n                CHECK( item.value() == \"foo\" );\n            }\n            else if (item.key() == \"1\" )\n            {\n                CHECK(item.value() == \"bar\");\n            }\n            else\n            {\n                CHECK(false);\n            }\n        }\n    }\n\n    SECTION(\"equality\")\n    {\n        alt_json doc;\n        doc[\"Who are you?\"] = \"I'm Batman\";\n\n        CHECK(\"I'm Batman\" == doc[\"Who are you?\"]);\n        CHECK(doc[\"Who are you?\"]  == \"I'm Batman\");\n        CHECK_FALSE(\"I'm Batman\" != doc[\"Who are you?\"]);\n        CHECK_FALSE(doc[\"Who are you?\"]  != \"I'm Batman\");\n\n        CHECK(\"I'm Bruce Wayne\" != doc[\"Who are you?\"]);\n        CHECK(doc[\"Who are you?\"]  != \"I'm Bruce Wayne\");\n        CHECK_FALSE(\"I'm Bruce Wayne\" == doc[\"Who are you?\"]);\n        CHECK_FALSE(doc[\"Who are you?\"]  == \"I'm Bruce Wayne\");\n\n        {\n            const alt_json& const_doc = doc;\n\n            CHECK(\"I'm Batman\" == const_doc[\"Who are you?\"]);\n            CHECK(const_doc[\"Who are you?\"] == \"I'm Batman\");\n            CHECK_FALSE(\"I'm Batman\" != const_doc[\"Who are you?\"]);\n            CHECK_FALSE(const_doc[\"Who are you?\"] != \"I'm Batman\");\n\n            CHECK(\"I'm Bruce Wayne\" != const_doc[\"Who are you?\"]);\n            CHECK(const_doc[\"Who are you?\"] != \"I'm Bruce Wayne\");\n            CHECK_FALSE(\"I'm Bruce Wayne\" == const_doc[\"Who are you?\"]);\n            CHECK_FALSE(const_doc[\"Who are you?\"] == \"I'm Bruce Wayne\");\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-assert_macro.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// avoid warning when assert does not abort\nDOCTEST_GCC_SUPPRESS_WARNING_PUSH\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wstrict-overflow\")\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wstrict-overflow\")\n\n/// global variable to record side effect of assert calls\nstatic int assert_counter;\n\n/// set failure variable to true instead of calling assert(x)\n#define JSON_ASSERT(x) {if (!(x)) ++assert_counter; }\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n// the test assumes exceptions to work\n#if !defined(JSON_NOEXCEPTION)\nTEST_CASE(\"JSON_ASSERT(x)\")\n{\n    SECTION(\"basic_json(first, second)\")\n    {\n        assert_counter = 0;\n        CHECK(assert_counter == 0);\n\n        json::iterator it;\n        json j;\n\n        // in case assertions do not abort execution, an exception is thrown\n        CHECK_THROWS_WITH_AS(json(it, j.end()), \"[json.exception.invalid_iterator.201] iterators are not compatible\", json::invalid_iterator);\n\n        // check that assertion actually happened\n        CHECK(assert_counter == 1);\n    }\n}\n#endif\n\nDOCTEST_GCC_SUPPRESS_WARNING_POP\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-bson.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <test_data.hpp>\n#include \"test_utils.hpp\"\n\nTEST_CASE(\"BSON\")\n{\n    SECTION(\"individual values not supported\")\n    {\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            CHECK_THROWS_AS(json::to_bson(j), json::type_error&);\n            CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null\");\n        }\n\n        SECTION(\"boolean\")\n        {\n            SECTION(\"true\")\n            {\n                json j = true;\n                CHECK_THROWS_AS(json::to_bson(j), json::type_error&);\n                CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is boolean\");\n            }\n\n            SECTION(\"false\")\n            {\n                json j = false;\n                CHECK_THROWS_AS(json::to_bson(j), json::type_error&);\n                CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is boolean\");\n            }\n        }\n\n        SECTION(\"number\")\n        {\n            json j = 42;\n            CHECK_THROWS_AS(json::to_bson(j), json::type_error&);\n            CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is number\");\n        }\n\n        SECTION(\"float\")\n        {\n            json j = 4.2;\n            CHECK_THROWS_AS(json::to_bson(j), json::type_error&);\n            CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is number\");\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"not supported\";\n            CHECK_THROWS_AS(json::to_bson(j), json::type_error&);\n            CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is string\");\n        }\n\n        SECTION(\"array\")\n        {\n            json j = std::vector<int> {1, 2, 3, 4, 5, 6, 7};\n            CHECK_THROWS_AS(json::to_bson(j), json::type_error&);\n            CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array\");\n        }\n    }\n\n    SECTION(\"keys containing code-point U+0000 cannot be serialized to BSON\")\n    {\n        json j =\n        {\n            { std::string(\"en\\0try\", 6), true }\n        };\n        CHECK_THROWS_AS(json::to_bson(j), json::out_of_range&);\n#if JSON_DIAGNOSTICS\n        CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.out_of_range.409] (/en) BSON key cannot contain code point U+0000 (at byte 2)\");\n#else\n        CHECK_THROWS_WITH(json::to_bson(j), \"[json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)\");\n#endif\n    }\n\n    SECTION(\"string length must be at least 1\")\n    {\n        // from https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11175\n        std::vector<std::uint8_t> v =\n        {\n            0x20, 0x20, 0x20, 0x20,\n            0x02,\n            0x00,\n            0x00, 0x00, 0x00, 0x80\n        };\n        json _;\n        CHECK_THROWS_AS(_ = json::from_bson(v), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_bson(v), \"[json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648\");\n    }\n\n    SECTION(\"objects\")\n    {\n        SECTION(\"empty object\")\n        {\n            json j = json::object();\n            std::vector<std::uint8_t> expected =\n            {\n                0x05, 0x00, 0x00, 0x00, // size (little endian)\n                // no entries\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with bool\")\n        {\n            json j =\n            {\n                { \"entry\", true }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x0D, 0x00, 0x00, 0x00, // size (little endian)\n                0x08,               // entry: boolean\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x01,           // value = true\n                0x00                    // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with bool\")\n        {\n            json j =\n            {\n                { \"entry\", false }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x0D, 0x00, 0x00, 0x00, // size (little endian)\n                0x08,               // entry: boolean\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x00,           // value = false\n                0x00                    // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with double\")\n        {\n            json j =\n            {\n                { \"entry\", 4.2 }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x14, 0x00, 0x00, 0x00, // size (little endian)\n                0x01, /// entry: double\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x40,\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with string\")\n        {\n            json j =\n            {\n                { \"entry\", \"bsonstr\" }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x18, 0x00, 0x00, 0x00, // size (little endian)\n                0x02, /// entry: string (UTF-8)\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x08, 0x00, 0x00, 0x00, 'b', 's', 'o', 'n', 's', 't', 'r', '\\x00',\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with null member\")\n        {\n            json j =\n            {\n                { \"entry\", nullptr }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x0C, 0x00, 0x00, 0x00, // size (little endian)\n                0x0A, /// entry: null\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with integer (32-bit) member\")\n        {\n            json j =\n            {\n                { \"entry\", std::int32_t{0x12345678} }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x10, 0x00, 0x00, 0x00, // size (little endian)\n                0x10, /// entry: int32\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x78, 0x56, 0x34, 0x12,\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with integer (64-bit) member\")\n        {\n            json j =\n            {\n                { \"entry\", std::int64_t{0x1234567804030201} }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x14, 0x00, 0x00, 0x00, // size (little endian)\n                0x12, /// entry: int64\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x01, 0x02, 0x03, 0x04, 0x78, 0x56, 0x34, 0x12,\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with negative integer (32-bit) member\")\n        {\n            json j =\n            {\n                { \"entry\", std::int32_t{-1} }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x10, 0x00, 0x00, 0x00, // size (little endian)\n                0x10, /// entry: int32\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0xFF, 0xFF, 0xFF, 0xFF,\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with negative integer (64-bit) member\")\n        {\n            json j =\n            {\n                { \"entry\", std::int64_t{-1} }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x10, 0x00, 0x00, 0x00, // size (little endian)\n                0x10, /// entry: int32\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0xFF, 0xFF, 0xFF, 0xFF,\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with unsigned integer (64-bit) member\")\n        {\n            // directly encoding uint64 is not supported in bson (only for timestamp values)\n            json j =\n            {\n                { \"entry\", std::uint64_t{0x1234567804030201} }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x14, 0x00, 0x00, 0x00, // size (little endian)\n                0x12, /// entry: int64\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x01, 0x02, 0x03, 0x04, 0x78, 0x56, 0x34, 0x12,\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with small unsigned integer member\")\n        {\n            json j =\n            {\n                { \"entry\", std::uint64_t{0x42} }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x10, 0x00, 0x00, 0x00, // size (little endian)\n                0x10, /// entry: int32\n                'e', 'n', 't', 'r', 'y', '\\x00',\n                0x42, 0x00, 0x00, 0x00,\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with object member\")\n        {\n            json j =\n            {\n                { \"entry\", json::object() }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x11, 0x00, 0x00, 0x00, // size (little endian)\n                0x03, /// entry: embedded document\n                'e', 'n', 't', 'r', 'y', '\\x00',\n\n                0x05, 0x00, 0x00, 0x00, // size (little endian)\n                // no entries\n                0x00, // end marker (embedded document)\n\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with array member\")\n        {\n            json j =\n            {\n                { \"entry\", json::array() }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x11, 0x00, 0x00, 0x00, // size (little endian)\n                0x04, /// entry: embedded document\n                'e', 'n', 't', 'r', 'y', '\\x00',\n\n                0x05, 0x00, 0x00, 0x00, // size (little endian)\n                // no entries\n                0x00, // end marker (embedded document)\n\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with non-empty array member\")\n        {\n            json j =\n            {\n                { \"entry\", json::array({1, 2, 3, 4, 5, 6, 7, 8}) }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x49, 0x00, 0x00, 0x00, // size (little endian)\n                0x04, /// entry: embedded document\n                'e', 'n', 't', 'r', 'y', '\\x00',\n\n                0x3D, 0x00, 0x00, 0x00, // size (little endian)\n                0x10, '0', 0x00, 0x01, 0x00, 0x00, 0x00,\n                0x10, '1', 0x00, 0x02, 0x00, 0x00, 0x00,\n                0x10, '2', 0x00, 0x03, 0x00, 0x00, 0x00,\n                0x10, '3', 0x00, 0x04, 0x00, 0x00, 0x00,\n                0x10, '4', 0x00, 0x05, 0x00, 0x00, 0x00,\n                0x10, '5', 0x00, 0x06, 0x00, 0x00, 0x00,\n                0x10, '6', 0x00, 0x07, 0x00, 0x00, 0x00,\n                0x10, '7', 0x00, 0x08, 0x00, 0x00, 0x00,\n                0x00, // end marker (embedded document)\n\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with binary member\")\n        {\n            const size_t N = 10;\n            const auto s = std::vector<std::uint8_t>(N, 'x');\n            json j =\n            {\n                { \"entry\", json::binary(s, 0) }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x1B, 0x00, 0x00, 0x00, // size (little endian)\n                0x05, // entry: binary\n                'e', 'n', 't', 'r', 'y', '\\x00',\n\n                0x0A, 0x00, 0x00, 0x00, // size of binary (little endian)\n                0x00, // Generic binary subtype\n                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"non-empty object with binary member with subtype\")\n        {\n            // an MD5 hash\n            const std::vector<std::uint8_t> md5hash = {0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4};\n            json j =\n            {\n                { \"entry\", json::binary(md5hash, 5) }\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                0x21, 0x00, 0x00, 0x00, // size (little endian)\n                0x05, // entry: binary\n                'e', 'n', 't', 'r', 'y', '\\x00',\n\n                0x10, 0x00, 0x00, 0x00, // size of binary (little endian)\n                0x05, // MD5 binary subtype\n                0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4,\n\n                0x00 // end marker\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n\n        SECTION(\"Some more complex document\")\n        {\n            // directly encoding uint64 is not supported in bson (only for timestamp values)\n            json j =\n            {\n                {\"double\", 42.5},\n                {\"entry\", 4.2},\n                {\"number\", 12345},\n                {\"object\", {{ \"string\", \"value\" }}}\n            };\n\n            std::vector<std::uint8_t> expected =\n            {\n                /*size */ 0x4f, 0x00, 0x00, 0x00,\n                /*entry*/ 0x01, 'd',  'o',  'u',  'b',  'l',  'e',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x40,\n                /*entry*/ 0x01, 'e',  'n',  't',  'r',  'y',  0x00, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x40,\n                /*entry*/ 0x10, 'n',  'u',  'm',  'b',  'e',  'r',  0x00, 0x39, 0x30, 0x00, 0x00,\n                /*entry*/ 0x03, 'o',  'b',  'j',  'e',  'c',  't',  0x00,\n                /*entry: obj-size */ 0x17, 0x00, 0x00, 0x00,\n                /*entry: obj-entry*/0x02, 's',  't',  'r',  'i',  'n',  'g', 0x00, 0x06, 0x00, 0x00, 0x00, 'v', 'a', 'l', 'u', 'e', 0,\n                /*entry: obj-term.*/0x00,\n                /*obj-term*/ 0x00\n            };\n\n            const auto result = json::to_bson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_bson(result) == j);\n            CHECK(json::from_bson(result, true, false) == j);\n        }\n    }\n\n    SECTION(\"Examples from http://bsonspec.org/faq.html\")\n    {\n        SECTION(\"Example 1\")\n        {\n            std::vector<std::uint8_t> input = {0x16, 0x00, 0x00, 0x00, 0x02, 'h', 'e', 'l', 'l', 'o', 0x00, 0x06, 0x00, 0x00, 0x00, 'w', 'o', 'r', 'l', 'd', 0x00, 0x00};\n            json parsed = json::from_bson(input);\n            json expected = {{\"hello\", \"world\"}};\n            CHECK(parsed == expected);\n            auto dumped = json::to_bson(parsed);\n            CHECK(dumped == input);\n            CHECK(json::from_bson(dumped) == expected);\n        }\n\n        SECTION(\"Example 2\")\n        {\n            std::vector<std::uint8_t> input = {0x31, 0x00, 0x00, 0x00, 0x04, 'B', 'S', 'O', 'N', 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 'a', 'w', 'e', 's', 'o', 'm', 'e', 0x00, 0x01, 0x31, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x14, 0x40, 0x10, 0x32, 0x00, 0xc2, 0x07, 0x00, 0x00, 0x00, 0x00};\n            json parsed = json::from_bson(input);\n            json expected = {{\"BSON\", {\"awesome\", 5.05, 1986}}};\n            CHECK(parsed == expected);\n            auto dumped = json::to_bson(parsed);\n            CHECK(dumped == input);\n            CHECK(json::from_bson(dumped) == expected);\n        }\n    }\n}\n\nTEST_CASE(\"BSON input/output_adapters\")\n{\n    json json_representation =\n    {\n        {\"double\", 42.5},\n        {\"entry\", 4.2},\n        {\"number\", 12345},\n        {\"object\", {{ \"string\", \"value\" }}}\n    };\n\n    std::vector<std::uint8_t> bson_representation =\n    {\n        /*size */ 0x4f, 0x00, 0x00, 0x00,\n        /*entry*/ 0x01, 'd',  'o',  'u',  'b',  'l',  'e',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x40,\n        /*entry*/ 0x01, 'e',  'n',  't',  'r',  'y',  0x00, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x40,\n        /*entry*/ 0x10, 'n',  'u',  'm',  'b',  'e',  'r',  0x00, 0x39, 0x30, 0x00, 0x00,\n        /*entry*/ 0x03, 'o',  'b',  'j',  'e',  'c',  't',  0x00,\n        /*entry: obj-size */ 0x17, 0x00, 0x00, 0x00,\n        /*entry: obj-entry*/0x02, 's',  't',  'r',  'i',  'n',  'g', 0x00, 0x06, 0x00, 0x00, 0x00, 'v', 'a', 'l', 'u', 'e', 0,\n        /*entry: obj-term.*/0x00,\n        /*obj-term*/ 0x00\n    };\n\n    json j2;\n    CHECK_NOTHROW(j2 = json::from_bson(bson_representation));\n\n    // compare parsed JSON values\n    CHECK(json_representation == j2);\n\n    SECTION(\"roundtrips\")\n    {\n        SECTION(\"std::ostringstream\")\n        {\n            std::basic_ostringstream<std::uint8_t> ss;\n            json::to_bson(json_representation, ss);\n            json j3 = json::from_bson(ss.str());\n            CHECK(json_representation == j3);\n        }\n\n        SECTION(\"std::string\")\n        {\n            std::string s;\n            json::to_bson(json_representation, s);\n            json j3 = json::from_bson(s);\n            CHECK(json_representation == j3);\n        }\n\n        SECTION(\"std::vector\")\n        {\n            std::vector<std::uint8_t> v;\n            json::to_bson(json_representation, v);\n            json j3 = json::from_bson(v);\n            CHECK(json_representation == j3);\n        }\n    }\n}\n\nnamespace\n{\nclass SaxCountdown\n{\n  public:\n    explicit SaxCountdown(const int count) : events_left(count)\n    {}\n\n    bool null()\n    {\n        return events_left-- > 0;\n    }\n\n    bool boolean(bool /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_integer(json::number_integer_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_unsigned(json::number_unsigned_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool string(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool binary(std::vector<std::uint8_t>& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_object(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool key(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_object()\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_array(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_array()\n    {\n        return events_left-- > 0;\n    }\n\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)\n    {\n        return false;\n    }\n\n  private:\n    int events_left = 0;\n};\n} // namespace\n\nTEST_CASE(\"Incomplete BSON Input\")\n{\n    SECTION(\"Incomplete BSON Input 1\")\n    {\n        std::vector<std::uint8_t> incomplete_bson =\n        {\n            0x0D, 0x00, 0x00, 0x00, // size (little endian)\n            0x08,                   // entry: boolean\n            'e', 'n', 't'           // unexpected EOF\n        };\n\n        json _;\n        CHECK_THROWS_AS(_ = json::from_bson(incomplete_bson), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_bson(incomplete_bson),\n                          \"[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing BSON cstring: unexpected end of input\");\n\n        CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());\n\n        SaxCountdown scp(0);\n        CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));\n    }\n\n    SECTION(\"Incomplete BSON Input 2\")\n    {\n        std::vector<std::uint8_t> incomplete_bson =\n        {\n            0x0D, 0x00, 0x00, 0x00, // size (little endian)\n            0x08,                   // entry: boolean, unexpected EOF\n        };\n\n        json _;\n        CHECK_THROWS_AS(_ = json::from_bson(incomplete_bson), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_bson(incomplete_bson),\n                          \"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing BSON cstring: unexpected end of input\");\n        CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());\n\n        SaxCountdown scp(0);\n        CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));\n    }\n\n    SECTION(\"Incomplete BSON Input 3\")\n    {\n        std::vector<std::uint8_t> incomplete_bson =\n        {\n            0x41, 0x00, 0x00, 0x00, // size (little endian)\n            0x04, /// entry: embedded document\n            'e', 'n', 't', 'r', 'y', '\\x00',\n\n            0x35, 0x00, 0x00, 0x00, // size (little endian)\n            0x10, 0x00, 0x01, 0x00, 0x00, 0x00,\n            0x10, 0x00, 0x02, 0x00, 0x00, 0x00\n            // missing input data...\n        };\n\n        json _;\n        CHECK_THROWS_AS(_ = json::from_bson(incomplete_bson), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_bson(incomplete_bson),\n                          \"[json.exception.parse_error.110] parse error at byte 28: syntax error while parsing BSON element list: unexpected end of input\");\n        CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());\n\n        SaxCountdown scp(1);\n        CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));\n    }\n\n    SECTION(\"Incomplete BSON Input 4\")\n    {\n        std::vector<std::uint8_t> incomplete_bson =\n        {\n            0x0D, 0x00, // size (incomplete), unexpected EOF\n        };\n\n        json _;\n        CHECK_THROWS_AS(_ = json::from_bson(incomplete_bson), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_bson(incomplete_bson),\n                          \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing BSON number: unexpected end of input\");\n        CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());\n\n        SaxCountdown scp(0);\n        CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));\n    }\n\n    SECTION(\"Improve coverage\")\n    {\n        SECTION(\"key\")\n        {\n            json j = {{\"key\", \"value\"}};\n            auto bson_vec = json::to_bson(j);\n            SaxCountdown scp(2);\n            CHECK(!json::sax_parse(bson_vec, &scp, json::input_format_t::bson));\n        }\n\n        SECTION(\"array\")\n        {\n            json j =\n            {\n                { \"entry\", json::array() }\n            };\n            auto bson_vec = json::to_bson(j);\n            SaxCountdown scp(2);\n            CHECK(!json::sax_parse(bson_vec, &scp, json::input_format_t::bson));\n        }\n    }\n}\n\nTEST_CASE(\"Negative size of binary value\")\n{\n    // invalid BSON: the size of the binary value is -1\n    std::vector<std::uint8_t> input =\n    {\n        0x21, 0x00, 0x00, 0x00, // size (little endian)\n        0x05, // entry: binary\n        'e', 'n', 't', 'r', 'y', '\\x00',\n\n        0xFF, 0xFF, 0xFF, 0xFF, // size of binary (little endian)\n        0x05, // MD5 binary subtype\n        0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4,\n\n        0x00 // end marker\n    };\n    json _;\n    CHECK_THROWS_AS(_ = json::from_bson(input), json::parse_error);\n    CHECK_THROWS_WITH(_ = json::from_bson(input), \"[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1\");\n}\n\nTEST_CASE(\"Unsupported BSON input\")\n{\n    std::vector<std::uint8_t> bson =\n    {\n        0x0C, 0x00, 0x00, 0x00, // size (little endian)\n        0xFF,                   // entry type: Min key (not supported yet)\n        'e', 'n', 't', 'r', 'y', '\\x00',\n        0x00 // end marker\n    };\n\n    json _;\n    CHECK_THROWS_AS(_ = json::from_bson(bson), json::parse_error&);\n    CHECK_THROWS_WITH(_ = json::from_bson(bson),\n                      \"[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF\");\n    CHECK(json::from_bson(bson, true, false).is_discarded());\n\n    SaxCountdown scp(0);\n    CHECK(!json::sax_parse(bson, &scp, json::input_format_t::bson));\n}\n\nTEST_CASE(\"BSON numerical data\")\n{\n    SECTION(\"number\")\n    {\n        SECTION(\"signed\")\n        {\n            SECTION(\"std::int64_t: INT64_MIN .. INT32_MIN-1\")\n            {\n                std::vector<int64_t> numbers\n                {\n                    INT64_MIN,\n                    -1000000000000000000LL,\n                    -100000000000000000LL,\n                    -10000000000000000LL,\n                    -1000000000000000LL,\n                    -100000000000000LL,\n                    -10000000000000LL,\n                    -1000000000000LL,\n                    -100000000000LL,\n                    -10000000000LL,\n                    static_cast<std::int64_t>(INT32_MIN) - 1,\n                };\n\n                for (auto i : numbers)\n                {\n\n                    CAPTURE(i)\n\n                    json j =\n                    {\n                        { \"entry\", i }\n                    };\n                    CHECK(j.at(\"entry\").is_number_integer());\n\n                    std::uint64_t iu = *reinterpret_cast<std::uint64_t*>(&i);\n                    std::vector<std::uint8_t> expected_bson =\n                    {\n                        0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)\n                        0x12u, /// entry: int64\n                        'e', 'n', 't', 'r', 'y', '\\x00',\n                        static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),\n                        0x00u // end marker\n                    };\n\n                    const auto bson = json::to_bson(j);\n                    CHECK(bson == expected_bson);\n\n                    auto j_roundtrip = json::from_bson(bson);\n\n                    CHECK(j_roundtrip.at(\"entry\").is_number_integer());\n                    CHECK(j_roundtrip == j);\n                    CHECK(json::from_bson(bson, true, false) == j);\n\n                }\n            }\n\n\n            SECTION(\"signed std::int32_t: INT32_MIN .. INT32_MAX\")\n            {\n                std::vector<int32_t> numbers\n                {\n                    INT32_MIN,\n                    -2147483647L,\n                    -1000000000L,\n                    -100000000L,\n                    -10000000L,\n                    -1000000L,\n                    -100000L,\n                    -10000L,\n                    -1000L,\n                    -100L,\n                    -10L,\n                    -1L,\n                    0L,\n                    1L,\n                    10L,\n                    100L,\n                    1000L,\n                    10000L,\n                    100000L,\n                    1000000L,\n                    10000000L,\n                    100000000L,\n                    1000000000L,\n                    2147483646L,\n                    INT32_MAX\n                };\n\n                for (auto i : numbers)\n                {\n\n                    CAPTURE(i)\n\n                    json j =\n                    {\n                        { \"entry\", i }\n                    };\n                    CHECK(j.at(\"entry\").is_number_integer());\n\n                    std::uint32_t iu = *reinterpret_cast<std::uint32_t*>(&i);\n                    std::vector<std::uint8_t> expected_bson =\n                    {\n                        0x10u, 0x00u, 0x00u, 0x00u, // size (little endian)\n                        0x10u, /// entry: int32\n                        'e', 'n', 't', 'r', 'y', '\\x00',\n                        static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),\n                        0x00u // end marker\n                    };\n\n                    const auto bson = json::to_bson(j);\n                    CHECK(bson == expected_bson);\n\n                    auto j_roundtrip = json::from_bson(bson);\n\n                    CHECK(j_roundtrip.at(\"entry\").is_number_integer());\n                    CHECK(j_roundtrip == j);\n                    CHECK(json::from_bson(bson, true, false) == j);\n\n                }\n            }\n\n            SECTION(\"signed std::int64_t: INT32_MAX+1 .. INT64_MAX\")\n            {\n                std::vector<int64_t> numbers\n                {\n                    INT64_MAX,\n                    1000000000000000000LL,\n                    100000000000000000LL,\n                    10000000000000000LL,\n                    1000000000000000LL,\n                    100000000000000LL,\n                    10000000000000LL,\n                    1000000000000LL,\n                    100000000000LL,\n                    10000000000LL,\n                    static_cast<std::int64_t>(INT32_MAX) + 1,\n                };\n\n                for (auto i : numbers)\n                {\n\n                    CAPTURE(i)\n\n                    json j =\n                    {\n                        { \"entry\", i }\n                    };\n                    CHECK(j.at(\"entry\").is_number_integer());\n\n                    std::uint64_t iu = *reinterpret_cast<std::uint64_t*>(&i);\n                    std::vector<std::uint8_t> expected_bson =\n                    {\n                        0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)\n                        0x12u, /// entry: int64\n                        'e', 'n', 't', 'r', 'y', '\\x00',\n                        static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),\n                        0x00u // end marker\n                    };\n\n                    const auto bson = json::to_bson(j);\n                    CHECK(bson == expected_bson);\n\n                    auto j_roundtrip = json::from_bson(bson);\n\n                    CHECK(j_roundtrip.at(\"entry\").is_number_integer());\n                    CHECK(j_roundtrip == j);\n                    CHECK(json::from_bson(bson, true, false) == j);\n\n                }\n            }\n        }\n\n        SECTION(\"unsigned\")\n        {\n            SECTION(\"unsigned std::uint64_t: 0 .. INT32_MAX\")\n            {\n                std::vector<std::uint64_t> numbers\n                {\n                    0ULL,\n                    1ULL,\n                    10ULL,\n                    100ULL,\n                    1000ULL,\n                    10000ULL,\n                    100000ULL,\n                    1000000ULL,\n                    10000000ULL,\n                    100000000ULL,\n                    1000000000ULL,\n                    2147483646ULL,\n                    static_cast<std::uint64_t>(INT32_MAX)\n                };\n\n                for (auto i : numbers)\n                {\n\n                    CAPTURE(i)\n\n                    json j =\n                    {\n                        { \"entry\", i }\n                    };\n\n                    auto iu = i;\n                    std::vector<std::uint8_t> expected_bson =\n                    {\n                        0x10u, 0x00u, 0x00u, 0x00u, // size (little endian)\n                        0x10u, /// entry: int32\n                        'e', 'n', 't', 'r', 'y', '\\x00',\n                        static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),\n                        0x00u // end marker\n                    };\n\n                    const auto bson = json::to_bson(j);\n                    CHECK(bson == expected_bson);\n\n                    auto j_roundtrip = json::from_bson(bson);\n\n                    CHECK(j.at(\"entry\").is_number_unsigned());\n                    CHECK(j_roundtrip.at(\"entry\").is_number_integer());\n                    CHECK(j_roundtrip == j);\n                    CHECK(json::from_bson(bson, true, false) == j);\n\n                }\n            }\n\n            SECTION(\"unsigned std::uint64_t: INT32_MAX+1 .. INT64_MAX\")\n            {\n                std::vector<std::uint64_t> numbers\n                {\n                    static_cast<std::uint64_t>(INT32_MAX) + 1,\n                    4000000000ULL,\n                    static_cast<std::uint64_t>(UINT32_MAX),\n                    10000000000ULL,\n                    100000000000ULL,\n                    1000000000000ULL,\n                    10000000000000ULL,\n                    100000000000000ULL,\n                    1000000000000000ULL,\n                    10000000000000000ULL,\n                    100000000000000000ULL,\n                    1000000000000000000ULL,\n                    static_cast<std::uint64_t>(INT64_MAX),\n                };\n\n                for (auto i : numbers)\n                {\n\n                    CAPTURE(i)\n\n                    json j =\n                    {\n                        { \"entry\", i }\n                    };\n\n                    auto iu = i;\n                    std::vector<std::uint8_t> expected_bson =\n                    {\n                        0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)\n                        0x12u, /// entry: int64\n                        'e', 'n', 't', 'r', 'y', '\\x00',\n                        static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),\n                        0x00u // end marker\n                    };\n\n                    const auto bson = json::to_bson(j);\n                    CHECK(bson == expected_bson);\n\n                    auto j_roundtrip = json::from_bson(bson);\n\n                    CHECK(j.at(\"entry\").is_number_unsigned());\n                    CHECK(j_roundtrip.at(\"entry\").is_number_integer());\n                    CHECK(j_roundtrip == j);\n                    CHECK(json::from_bson(bson, true, false) == j);\n                }\n            }\n\n            SECTION(\"unsigned std::uint64_t: INT64_MAX+1 .. UINT64_MAX\")\n            {\n                std::vector<std::uint64_t> numbers\n                {\n                    static_cast<std::uint64_t>(INT64_MAX) + 1ULL,\n                    10000000000000000000ULL,\n                    18000000000000000000ULL,\n                    UINT64_MAX - 1ULL,\n                    UINT64_MAX,\n                };\n\n                for (auto i : numbers)\n                {\n\n                    CAPTURE(i)\n\n                    json j =\n                    {\n                        { \"entry\", i }\n                    };\n\n                    auto iu = i;\n                    std::vector<std::uint8_t> expected_bson =\n                    {\n                        0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)\n                        0x12u, /// entry: int64\n                        'e', 'n', 't', 'r', 'y', '\\x00',\n                        static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),\n                        static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),\n                        0x00u // end marker\n                    };\n\n                    CHECK_THROWS_AS(json::to_bson(j), json::out_of_range&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH_STD_STR(json::to_bson(j), \"[json.exception.out_of_range.407] (/entry) integer number \" + std::to_string(i) + \" cannot be represented by BSON as it does not fit int64\");\n#else\n                    CHECK_THROWS_WITH_STD_STR(json::to_bson(j), \"[json.exception.out_of_range.407] integer number \" + std::to_string(i) + \" cannot be represented by BSON as it does not fit int64\");\n#endif\n                }\n            }\n\n        }\n    }\n}\n\nTEST_CASE(\"BSON roundtrips\" * doctest::skip())\n{\n    SECTION(\"reference files\")\n    {\n        for (std::string filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json.org/1.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/2.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/3.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/4.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/5.json\"\n                })\n        {\n            CAPTURE(filename)\n\n            {\n                INFO_WITH_TEMP(filename + \": std::vector<std::uint8_t>\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse BSON file\n                auto packed = utils::read_binary_file(filename + \".bson\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_bson(packed));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": std::ifstream\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse BSON file\n                std::ifstream f_bson(filename + \".bson\", std::ios::binary);\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_bson(f_bson));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": uint8_t* and size\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse BSON file\n                auto packed = utils::read_binary_file(filename + \".bson\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_bson({packed.data(), packed.size()}));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": output to output adapters\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse BSON file\n                auto packed = utils::read_binary_file(filename + \".bson\");\n\n                {\n                    INFO_WITH_TEMP(filename + \": output adapters: std::vector<std::uint8_t>\");\n                    std::vector<std::uint8_t> vec;\n                    json::to_bson(j1, vec);\n\n                    if (vec != packed)\n                    {\n                        // the exact serializations may differ due to the order of\n                        // object keys; in these cases, just compare whether both\n                        // serializations create the same JSON value\n                        CHECK(json::from_bson(vec) == json::from_bson(packed));\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-byte_container_with_subtype.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"byte_container_with_subtype\")\n{\n    using subtype_type = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>::subtype_type;\n\n    SECTION(\"empty container\")\n    {\n        nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>> container;\n\n        CHECK(!container.has_subtype());\n        CHECK(container.subtype() == static_cast<subtype_type>(-1));\n\n        container.clear_subtype();\n        CHECK(!container.has_subtype());\n        CHECK(container.subtype() == static_cast<subtype_type>(-1));\n\n        container.set_subtype(42);\n        CHECK(container.has_subtype());\n        CHECK(container.subtype() == 42);\n    }\n\n    SECTION(\"subtyped container\")\n    {\n        nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>> container({}, 42);\n        CHECK(container.has_subtype());\n        CHECK(container.subtype() == 42);\n\n        container.clear_subtype();\n        CHECK(!container.has_subtype());\n        CHECK(container.subtype() == static_cast<subtype_type>(-1));\n    }\n\n    SECTION(\"comparisons\")\n    {\n        std::vector<std::uint8_t> bytes = {{0xCA, 0xFE, 0xBA, 0xBE}};\n        nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>> container1;\n        nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>> container2({}, 42);\n        nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>> container3(bytes);\n        nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>> container4(bytes, 42);\n\n        CHECK(container1 == container1);\n        CHECK(container1 != container2);\n        CHECK(container1 != container3);\n        CHECK(container1 != container4);\n        CHECK(container2 != container1);\n        CHECK(container2 == container2);\n        CHECK(container2 != container3);\n        CHECK(container2 != container4);\n        CHECK(container3 != container1);\n        CHECK(container3 != container2);\n        CHECK(container3 == container3);\n        CHECK(container3 != container4);\n        CHECK(container4 != container1);\n        CHECK(container4 != container2);\n        CHECK(container4 != container3);\n        CHECK(container4 == container4);\n\n        container3.clear();\n        container4.clear();\n\n        CHECK(container1 == container3);\n        CHECK(container2 == container4);\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-capacity.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"capacity\")\n{\n    SECTION(\"empty()\")\n    {\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            const json j_const(j);\n\n            SECTION(\"result of empty\")\n            {\n                CHECK(j.empty() == false);\n                CHECK(j_const.empty() == false);\n            }\n\n            SECTION(\"definition of empty\")\n            {\n                CHECK(j.empty() == (j.begin() == j.end()));\n                CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"hello world\";\n            const json j_const(j);\n\n            SECTION(\"result of empty\")\n            {\n                CHECK(j.empty() == false);\n                CHECK(j_const.empty() == false);\n            }\n\n            SECTION(\"definition of empty\")\n            {\n                CHECK(j.empty() == (j.begin() == j.end()));\n                CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty array\")\n            {\n                json j = json::array();\n                const json j_const(j);\n\n                SECTION(\"result of empty\")\n                {\n                    CHECK(j.empty() == true);\n                    CHECK(j_const.empty() == true);\n                }\n\n                SECTION(\"definition of empty\")\n                {\n                    CHECK(j.empty() == (j.begin() == j.end()));\n                    CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n                }\n            }\n\n            SECTION(\"filled array\")\n            {\n                json j = {1, 2, 3};\n                const json j_const(j);\n\n                SECTION(\"result of empty\")\n                {\n                    CHECK(j.empty() == false);\n                    CHECK(j_const.empty() == false);\n                }\n\n                SECTION(\"definition of empty\")\n                {\n                    CHECK(j.empty() == (j.begin() == j.end()));\n                    CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n                }\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty object\")\n            {\n                json j = json::object();\n                const json j_const(j);\n\n                SECTION(\"result of empty\")\n                {\n                    CHECK(j.empty() == true);\n                    CHECK(j_const.empty() == true);\n                }\n\n                SECTION(\"definition of empty\")\n                {\n                    CHECK(j.empty() == (j.begin() == j.end()));\n                    CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n                }\n            }\n\n            SECTION(\"filled object\")\n            {\n                json j = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n                const json j_const(j);\n\n                SECTION(\"result of empty\")\n                {\n                    CHECK(j.empty() == false);\n                    CHECK(j_const.empty() == false);\n                }\n\n                SECTION(\"definition of empty\")\n                {\n                    CHECK(j.empty() == (j.begin() == j.end()));\n                    CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n                }\n            }\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j = -23;\n            const json j_const(j);\n\n            SECTION(\"result of empty\")\n            {\n                CHECK(j.empty() == false);\n                CHECK(j_const.empty() == false);\n            }\n\n            SECTION(\"definition of empty\")\n            {\n                CHECK(j.empty() == (j.begin() == j.end()));\n                CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n            }\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            const json j_const(j);\n\n            SECTION(\"result of empty\")\n            {\n                CHECK(j.empty() == false);\n                CHECK(j_const.empty() == false);\n            }\n\n            SECTION(\"definition of empty\")\n            {\n                CHECK(j.empty() == (j.begin() == j.end()));\n                CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n            }\n        }\n\n        SECTION(\"number (float)\")\n        {\n            json j = 23.42;\n            const json j_const(j);\n\n            SECTION(\"result of empty\")\n            {\n                CHECK(j.empty() == false);\n                CHECK(j_const.empty() == false);\n            }\n\n            SECTION(\"definition of empty\")\n            {\n                CHECK(j.empty() == (j.begin() == j.end()));\n                CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n            }\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            const json j_const(j);\n\n            SECTION(\"result of empty\")\n            {\n                CHECK(j.empty() == true);\n                CHECK(j_const.empty() == true);\n            }\n\n            SECTION(\"definition of empty\")\n            {\n                CHECK(j.empty() == (j.begin() == j.end()));\n                CHECK(j_const.empty() == (j_const.begin() == j_const.end()));\n            }\n        }\n    }\n\n    SECTION(\"size()\")\n    {\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            const json j_const(j);\n\n            SECTION(\"result of size\")\n            {\n                CHECK(j.size() == 1);\n                CHECK(j_const.size() == 1);\n            }\n\n            SECTION(\"definition of size\")\n            {\n                CHECK(std::distance(j.begin(), j.end()) == j.size());\n                CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"hello world\";\n            const json j_const(j);\n\n            SECTION(\"result of size\")\n            {\n                CHECK(j.size() == 1);\n                CHECK(j_const.size() == 1);\n            }\n\n            SECTION(\"definition of size\")\n            {\n                CHECK(std::distance(j.begin(), j.end()) == j.size());\n                CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty array\")\n            {\n                json j = json::array();\n                const json j_const(j);\n\n                SECTION(\"result of size\")\n                {\n                    CHECK(j.size() == 0);\n                    CHECK(j_const.size() == 0);\n                }\n\n                SECTION(\"definition of size\")\n                {\n                    CHECK(std::distance(j.begin(), j.end()) == j.size());\n                    CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n                }\n            }\n\n            SECTION(\"filled array\")\n            {\n                json j = {1, 2, 3};\n                const json j_const(j);\n\n                SECTION(\"result of size\")\n                {\n                    CHECK(j.size() == 3);\n                    CHECK(j_const.size() == 3);\n                }\n\n                SECTION(\"definition of size\")\n                {\n                    CHECK(std::distance(j.begin(), j.end()) == j.size());\n                    CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n                }\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty object\")\n            {\n                json j = json::object();\n                const json j_const(j);\n\n                SECTION(\"result of size\")\n                {\n                    CHECK(j.size() == 0);\n                    CHECK(j_const.size() == 0);\n                }\n\n                SECTION(\"definition of size\")\n                {\n                    CHECK(std::distance(j.begin(), j.end()) == j.size());\n                    CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n                }\n            }\n\n            SECTION(\"filled object\")\n            {\n                json j = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n                const json j_const(j);\n\n                SECTION(\"result of size\")\n                {\n                    CHECK(j.size() == 3);\n                    CHECK(j_const.size() == 3);\n                }\n\n                SECTION(\"definition of size\")\n                {\n                    CHECK(std::distance(j.begin(), j.end()) == j.size());\n                    CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n                }\n            }\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j = -23;\n            const json j_const(j);\n\n            SECTION(\"result of size\")\n            {\n                CHECK(j.size() == 1);\n                CHECK(j_const.size() == 1);\n            }\n\n            SECTION(\"definition of size\")\n            {\n                CHECK(std::distance(j.begin(), j.end()) == j.size());\n                CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n            }\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            const json j_const(j);\n\n            SECTION(\"result of size\")\n            {\n                CHECK(j.size() == 1);\n                CHECK(j_const.size() == 1);\n            }\n\n            SECTION(\"definition of size\")\n            {\n                CHECK(std::distance(j.begin(), j.end()) == j.size());\n                CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n            }\n        }\n\n        SECTION(\"number (float)\")\n        {\n            json j = 23.42;\n            const json j_const(j);\n\n            SECTION(\"result of size\")\n            {\n                CHECK(j.size() == 1);\n                CHECK(j_const.size() == 1);\n            }\n\n            SECTION(\"definition of size\")\n            {\n                CHECK(std::distance(j.begin(), j.end()) == j.size());\n                CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n            }\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            const json j_const(j);\n\n            SECTION(\"result of size\")\n            {\n                CHECK(j.size() == 0);\n                CHECK(j_const.size() == 0);\n            }\n\n            SECTION(\"definition of size\")\n            {\n                CHECK(std::distance(j.begin(), j.end()) == j.size());\n                CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());\n                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());\n                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());\n            }\n        }\n    }\n\n    SECTION(\"max_size()\")\n    {\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            const json j_const = true;\n\n            SECTION(\"result of max_size\")\n            {\n                CHECK(j.max_size() == 1);\n                CHECK(j_const.max_size() == 1);\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"hello world\";\n            const json j_const = \"hello world\";\n\n            SECTION(\"result of max_size\")\n            {\n                CHECK(j.max_size() == 1);\n                CHECK(j_const.max_size() == 1);\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty array\")\n            {\n                json j = json::array();\n                const json j_const = json::array();\n\n                SECTION(\"result of max_size\")\n                {\n                    CHECK(j.max_size() >= j.size());\n                    CHECK(j_const.max_size() >= j_const.size());\n                }\n            }\n\n            SECTION(\"filled array\")\n            {\n                json j = {1, 2, 3};\n                const json j_const = {1, 2, 3};\n\n                SECTION(\"result of max_size\")\n                {\n                    CHECK(j.max_size() >= j.size());\n                    CHECK(j_const.max_size() >= j_const.size());\n                }\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty object\")\n            {\n                json j = json::object();\n                const json j_const = json::object();\n\n                SECTION(\"result of max_size\")\n                {\n                    CHECK(j.max_size() >= j.size());\n                    CHECK(j_const.max_size() >= j_const.size());\n                }\n            }\n\n            SECTION(\"filled object\")\n            {\n                json j = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n                const json j_const = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n\n                SECTION(\"result of max_size\")\n                {\n                    CHECK(j.max_size() >= j.size());\n                    CHECK(j_const.max_size() >= j_const.size());\n                }\n            }\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j = -23;\n            const json j_const = -23;\n\n            SECTION(\"result of max_size\")\n            {\n                CHECK(j.max_size() == 1);\n                CHECK(j_const.max_size() == 1);\n            }\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            const json j_const = 23u;\n\n            SECTION(\"result of max_size\")\n            {\n                CHECK(j.max_size() == 1);\n                CHECK(j_const.max_size() == 1);\n            }\n        }\n\n        SECTION(\"number (float)\")\n        {\n            json j = 23.42;\n            const json j_const = 23.42;\n\n            SECTION(\"result of max_size\")\n            {\n                CHECK(j.max_size() == 1);\n                CHECK(j_const.max_size() == 1);\n            }\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            const json j_const = nullptr;\n\n            SECTION(\"result of max_size\")\n            {\n                CHECK(j.max_size() == 0);\n                CHECK(j_const.max_size() == 0);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-cbor.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <iomanip>\n#include <iostream>\n#include <set>\n#include <test_data.hpp>\n#include \"test_utils.hpp\"\n\nnamespace\n{\nclass SaxCountdown\n{\n  public:\n    explicit SaxCountdown(const int count) : events_left(count)\n    {}\n\n    bool null()\n    {\n        return events_left-- > 0;\n    }\n\n    bool boolean(bool /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_integer(json::number_integer_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_unsigned(json::number_unsigned_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool string(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool binary(std::vector<std::uint8_t>& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_object(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool key(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_object()\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_array(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_array()\n    {\n        return events_left-- > 0;\n    }\n\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)\n    {\n        return false;\n    }\n\n  private:\n    int events_left = 0;\n};\n} // namespace\n\nTEST_CASE(\"CBOR\")\n{\n    SECTION(\"individual values\")\n    {\n        SECTION(\"discarded\")\n        {\n            // discarded values are not serialized\n            json j = json::value_t::discarded;\n            const auto result = json::to_cbor(j);\n            CHECK(result.empty());\n        }\n\n        SECTION(\"NaN\")\n        {\n            // NaN value\n            json j = std::numeric_limits<json::number_float_t>::quiet_NaN();\n            std::vector<uint8_t> expected = {0xf9, 0x7e, 0x00};\n            const auto result = json::to_cbor(j);\n            CHECK(result == expected);\n        }\n\n        SECTION(\"Infinity\")\n        {\n            // Infinity value\n            json j = std::numeric_limits<json::number_float_t>::infinity();\n            std::vector<uint8_t> expected = {0xf9, 0x7c, 0x00};\n            const auto result = json::to_cbor(j);\n            CHECK(result == expected);\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            std::vector<uint8_t> expected = {0xf6};\n            const auto result = json::to_cbor(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_cbor(result) == j);\n            CHECK(json::from_cbor(result, true, false) == j);\n        }\n\n        SECTION(\"boolean\")\n        {\n            SECTION(\"true\")\n            {\n                json j = true;\n                std::vector<uint8_t> expected = {0xf5};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"false\")\n            {\n                json j = false;\n                std::vector<uint8_t> expected = {0xf4};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n        }\n\n        SECTION(\"number\")\n        {\n            SECTION(\"signed\")\n            {\n                SECTION(\"-9223372036854775808..-4294967297\")\n                {\n                    std::vector<int64_t> numbers;\n                    numbers.push_back(INT64_MIN);\n                    numbers.push_back(-1000000000000000000);\n                    numbers.push_back(-100000000000000000);\n                    numbers.push_back(-10000000000000000);\n                    numbers.push_back(-1000000000000000);\n                    numbers.push_back(-100000000000000);\n                    numbers.push_back(-10000000000000);\n                    numbers.push_back(-1000000000000);\n                    numbers.push_back(-100000000000);\n                    numbers.push_back(-10000000000);\n                    numbers.push_back(-4294967297);\n                    for (auto i : numbers)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(0x3b));\n                        auto positive = static_cast<uint64_t>(-1 - i);\n                        expected.push_back(static_cast<uint8_t>((positive >> 56) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 48) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 40) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 32) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(positive & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x3b);\n                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +\n                                            (static_cast<uint64_t>(result[2]) << 060) +\n                                            (static_cast<uint64_t>(result[3]) << 050) +\n                                            (static_cast<uint64_t>(result[4]) << 040) +\n                                            (static_cast<uint64_t>(result[5]) << 030) +\n                                            (static_cast<uint64_t>(result[6]) << 020) +\n                                            (static_cast<uint64_t>(result[7]) << 010) +\n                                            static_cast<uint64_t>(result[8]);\n                        CHECK(restored == positive);\n                        CHECK(-1 - static_cast<int64_t>(restored) == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-4294967296..-65537\")\n                {\n                    std::vector<int64_t> numbers;\n                    numbers.push_back(-65537);\n                    numbers.push_back(-100000);\n                    numbers.push_back(-1000000);\n                    numbers.push_back(-10000000);\n                    numbers.push_back(-100000000);\n                    numbers.push_back(-1000000000);\n                    numbers.push_back(-4294967296);\n                    for (auto i : numbers)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(0x3a));\n                        auto positive = static_cast<uint32_t>(static_cast<uint64_t>(-1 - i) & 0x00000000ffffffff);\n                        expected.push_back(static_cast<uint8_t>((positive >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(positive & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x3a);\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(restored == positive);\n                        CHECK(-1LL - restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-65536..-257\")\n                {\n                    for (int32_t i = -65536; i <= -257; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(0x39));\n                        auto positive = static_cast<uint16_t>(-1 - i);\n                        expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(positive & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x39);\n                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));\n                        CHECK(restored == positive);\n                        CHECK(-1 - restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-9263 (int 16)\")\n                {\n                    json j = -9263;\n                    std::vector<uint8_t> expected = {0x39, 0x24, 0x2e};\n\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n\n                    auto restored = static_cast<int16_t>(-1 - ((result[1] << 8) + result[2]));\n                    CHECK(restored == -9263);\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n\n                SECTION(\"-256..-24\")\n                {\n                    for (auto i = -256; i < -24; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0x38);\n                        expected.push_back(static_cast<uint8_t>(-1 - i));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x38);\n                        CHECK(static_cast<int16_t>(-1 - result[1]) == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-24..-1\")\n                {\n                    for (auto i = -24; i <= -1; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(0x20 - 1 - static_cast<uint8_t>(i)));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 1);\n\n                        // check individual bytes\n                        CHECK(static_cast<int8_t>(0x20 - 1 - result[0]) == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"0..23\")\n                {\n                    for (size_t i = 0; i <= 23; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 1);\n\n                        // check individual bytes\n                        CHECK(result[0] == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"24..255\")\n                {\n                    for (size_t i = 24; i <= 255; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(0x18));\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x18);\n                        CHECK(result[1] == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"256..65535\")\n                {\n                    for (size_t i = 256; i <= 65535; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(0x19));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x19);\n                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"65536..4294967295\")\n                {\n                    for (uint32_t i :\n                            {\n                                65536u, 77777u, 1048576u\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0x1a);\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x1a);\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"4294967296..4611686018427387903\")\n                {\n                    for (uint64_t i :\n                            {\n                                4294967296ul, 4611686018427387903ul\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0x1b);\n                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x1b);\n                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +\n                                            (static_cast<uint64_t>(result[2]) << 060) +\n                                            (static_cast<uint64_t>(result[3]) << 050) +\n                                            (static_cast<uint64_t>(result[4]) << 040) +\n                                            (static_cast<uint64_t>(result[5]) << 030) +\n                                            (static_cast<uint64_t>(result[6]) << 020) +\n                                            (static_cast<uint64_t>(result[7]) << 010) +\n                                            static_cast<uint64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-32768..-129 (int 16)\")\n                {\n                    for (int16_t i = -32768; i <= static_cast<std::int16_t>(-129); ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xd1);\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xd1);\n                        auto restored = static_cast<int16_t>((result[1] << 8) + result[2]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                    }\n                }\n            }\n\n            SECTION(\"unsigned\")\n            {\n                SECTION(\"0..23 (Integer)\")\n                {\n                    for (size_t i = 0; i <= 23; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 1);\n\n                        // check individual bytes\n                        CHECK(result[0] == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"24..255 (one-byte uint8_t)\")\n                {\n                    for (size_t i = 24; i <= 255; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0x18);\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x18);\n                        auto restored = static_cast<uint8_t>(result[1]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"256..65535 (two-byte uint16_t)\")\n                {\n                    for (size_t i = 256; i <= 65535; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0x19);\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x19);\n                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"65536..4294967295 (four-byte uint32_t)\")\n                {\n                    for (uint32_t i :\n                            {\n                                65536u, 77777u, 1048576u\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0x1a);\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x1a);\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"4294967296..4611686018427387903 (eight-byte uint64_t)\")\n                {\n                    for (uint64_t i :\n                            {\n                                4294967296ul, 4611686018427387903ul\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0x1b);\n                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_cbor(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0x1b);\n                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +\n                                            (static_cast<uint64_t>(result[2]) << 060) +\n                                            (static_cast<uint64_t>(result[3]) << 050) +\n                                            (static_cast<uint64_t>(result[4]) << 040) +\n                                            (static_cast<uint64_t>(result[5]) << 030) +\n                                            (static_cast<uint64_t>(result[6]) << 020) +\n                                            (static_cast<uint64_t>(result[7]) << 010) +\n                                            static_cast<uint64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_cbor(result) == j);\n                        CHECK(json::from_cbor(result, true, false) == j);\n                    }\n                }\n            }\n\n            SECTION(\"double-precision float\")\n            {\n                SECTION(\"3.1415925\")\n                {\n                    double v = 3.1415925;\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xfb, 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc\n                    };\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"single-precision float\")\n            {\n                SECTION(\"0.5\")\n                {\n                    double v = 0.5;\n                    json j = v;\n                    // its double-precision float binary value is\n                    // {0xfb, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}\n                    // but to save memory, we can store it as single-precision float.\n                    std::vector<uint8_t> expected = {0xfa, 0x3f, 0x00, 0x00, 0x00};\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"0.0\")\n                {\n                    double v = 0.0;\n                    json j = v;\n                    // its double-precision binary value is:\n                    // {0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}\n                    std::vector<uint8_t> expected = {0xfa, 0x00, 0x00, 0x00, 0x00};\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"-0.0\")\n                {\n                    double v = -0.0;\n                    json j = v;\n                    // its double-precision binary value is:\n                    // {0xfb, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}\n                    std::vector<uint8_t> expected = {0xfa, 0x80, 0x00, 0x00, 0x00};\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"100.0\")\n                {\n                    double v = 100.0;\n                    json j = v;\n                    // its double-precision binary value is:\n                    // {0xfb, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}\n                    std::vector<uint8_t> expected = {0xfa, 0x42, 0xc8, 0x00, 0x00};\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"200.0\")\n                {\n                    double v = 200.0;\n                    json j = v;\n                    // its double-precision binary value is:\n                    // {0xfb, 0x40, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}\n                    std::vector<uint8_t> expected = {0xfa, 0x43, 0x48, 0x00, 0x00};\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"3.40282e+38(max float)\")\n                {\n                    float v = (std::numeric_limits<float>::max)();\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xfa, 0x7f, 0x7f, 0xff, 0xff\n                    };\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"-3.40282e+38(lowest float)\")\n                {\n                    auto v = static_cast<double>(std::numeric_limits<float>::lowest());\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xfa, 0xff, 0x7f, 0xff, 0xff\n                    };\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"1 + 3.40282e+38(more than max float)\")\n                {\n                    double v = static_cast<double>((std::numeric_limits<float>::max)()) + 0.1e+34;\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xfb, 0x47, 0xf0, 0x00, 0x03, 0x04, 0xdc, 0x64, 0x49\n                    };\n                    // double\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n                SECTION(\"-1 - 3.40282e+38(less than lowest float)\")\n                {\n                    double v = static_cast<double>(std::numeric_limits<float>::lowest()) - 1.0;\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xfa, 0xff, 0x7f, 0xff, 0xff\n                    };\n                    // the same with lowest float\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result) == v);\n                }\n\n            }\n\n            SECTION(\"half-precision float (edge cases)\")\n            {\n                SECTION(\"errors\")\n                {\n                    SECTION(\"no byte follows\")\n                    {\n                        json _;\n                        CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf9})), json::parse_error&);\n                        CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0xf9})),\n                                          \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input\");\n                        CHECK(json::from_cbor(std::vector<uint8_t>({0xf9}), true, false).is_discarded());\n                    }\n                    SECTION(\"only one byte follows\")\n                    {\n                        json _;\n                        CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), json::parse_error&);\n                        CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})),\n                                          \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input\");\n                        CHECK(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c}), true, false).is_discarded());\n                    }\n                }\n\n                SECTION(\"exp = 0b00000\")\n                {\n                    SECTION(\"0 (0 00000 0000000000)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x00}));\n                        json::number_float_t d{j};\n                        CHECK(d == 0.0);\n                    }\n\n                    SECTION(\"-0 (1 00000 0000000000)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x80, 0x00}));\n                        json::number_float_t d{j};\n                        CHECK(d == -0.0);\n                    }\n\n                    SECTION(\"2**-24 (0 00000 0000000001)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x01}));\n                        json::number_float_t d{j};\n                        CHECK(d == std::pow(2.0, -24.0));\n                    }\n                }\n\n                SECTION(\"exp = 0b11111\")\n                {\n                    SECTION(\"infinity (0 11111 0000000000)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00}));\n                        json::number_float_t d{j};\n                        CHECK(d == std::numeric_limits<json::number_float_t>::infinity());\n                        CHECK(j.dump() == \"null\");\n                    }\n\n                    SECTION(\"-infinity (1 11111 0000000000)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0xfc, 0x00}));\n                        json::number_float_t d{j};\n                        CHECK(d == -std::numeric_limits<json::number_float_t>::infinity());\n                        CHECK(j.dump() == \"null\");\n                    }\n                }\n\n                SECTION(\"other values from https://en.wikipedia.org/wiki/Half-precision_floating-point_format\")\n                {\n                    SECTION(\"1 (0 01111 0000000000)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x3c, 0x00}));\n                        json::number_float_t d{j};\n                        CHECK(d == 1);\n                    }\n\n                    SECTION(\"-2 (1 10000 0000000000)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0xc0, 0x00}));\n                        json::number_float_t d{j};\n                        CHECK(d == -2);\n                    }\n\n                    SECTION(\"65504 (0 11110 1111111111)\")\n                    {\n                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7b, 0xff}));\n                        json::number_float_t d{j};\n                        CHECK(d == 65504);\n                    }\n                }\n\n                SECTION(\"infinity\")\n                {\n                    json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00}));\n                    json::number_float_t d{j};\n                    CHECK(!std::isfinite(d));\n                    CHECK(j.dump() == \"null\");\n                }\n\n                SECTION(\"NaN\")\n                {\n                    json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7e, 0x00}));\n                    json::number_float_t d{j};\n                    CHECK(std::isnan(d));\n                    CHECK(j.dump() == \"null\");\n                }\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            SECTION(\"N = 0..23\")\n            {\n                for (size_t N = 0; N <= 0x17; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back(static_cast<uint8_t>(0x60 + N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back('x');\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 1);\n                    // check that no null byte is appended\n                    if (N > 0)\n                    {\n                        CHECK(result.back() != '\\x00');\n                    }\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 24..255\")\n            {\n                for (size_t N = 24; N <= 255; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back(0x78);\n                    expected.push_back(static_cast<uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back('x');\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 2);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 256..65535\")\n            {\n                for (size_t N :\n                        {\n                            256u, 999u, 1025u, 3333u, 2048u, 65535u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), 0x79);\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 3);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 65536..4294967295\")\n            {\n                for (size_t N :\n                        {\n                            65536u, 77777u, 1048576u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));\n                    expected.insert(expected.begin(), 0x7a);\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 5);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty\")\n            {\n                json j = json::array();\n                std::vector<uint8_t> expected = {0x80};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"[null]\")\n            {\n                json j = {nullptr};\n                std::vector<uint8_t> expected = {0x81, 0xf6};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"[1,2,3,4,5]\")\n            {\n                json j = json::parse(\"[1,2,3,4,5]\");\n                std::vector<uint8_t> expected = {0x85, 0x01, 0x02, 0x03, 0x04, 0x05};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"[[[[]]]]\")\n            {\n                json j = json::parse(\"[[[[]]]]\");\n                std::vector<uint8_t> expected = {0x81, 0x81, 0x81, 0x80};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"array with uint16_t elements\")\n            {\n                json j(257, nullptr);\n                std::vector<uint8_t> expected(j.size() + 3, 0xf6); // all null\n                expected[0] = 0x99; // array 16 bit\n                expected[1] = 0x01; // size (0x0101), byte 0\n                expected[2] = 0x01; // size (0x0101), byte 1\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"array with uint32_t elements\")\n            {\n                json j(65793, nullptr);\n                std::vector<uint8_t> expected(j.size() + 5, 0xf6); // all null\n                expected[0] = 0x9a; // array 32 bit\n                expected[1] = 0x00; // size (0x00010101), byte 0\n                expected[2] = 0x01; // size (0x00010101), byte 1\n                expected[3] = 0x01; // size (0x00010101), byte 2\n                expected[4] = 0x01; // size (0x00010101), byte 3\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty\")\n            {\n                json j = json::object();\n                std::vector<uint8_t> expected = {0xa0};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"{\\\"\\\":null}\")\n            {\n                json j = {{\"\", nullptr}};\n                std::vector<uint8_t> expected = {0xa1, 0x60, 0xf6};\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"{\\\"a\\\": {\\\"b\\\": {\\\"c\\\": {}}}}\")\n            {\n                json j = json::parse(R\"({\"a\": {\"b\": {\"c\": {}}}})\");\n                std::vector<uint8_t> expected =\n                {\n                    0xa1, 0x61, 0x61, 0xa1, 0x61, 0x62, 0xa1, 0x61, 0x63, 0xa0\n                };\n                const auto result = json::to_cbor(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"object with uint8_t elements\")\n            {\n                json j;\n                for (auto i = 0; i < 255; ++i)\n                {\n                    // format i to a fixed width of 5\n                    // each entry will need 7 bytes: 6 for string, 1 for null\n                    std::stringstream ss;\n                    ss << std::setw(5) << std::setfill('0') << i;\n                    j.emplace(ss.str(), nullptr);\n                }\n\n                const auto result = json::to_cbor(j);\n\n                // Checking against an expected vector byte by byte is\n                // difficult, because no assumption on the order of key/value\n                // pairs are made. We therefore only check the prefix (type and\n                // size and the overall size. The rest is then handled in the\n                // roundtrip check.\n                CHECK(result.size() == 1787); // 1 type, 1 size, 255*7 content\n                CHECK(result[0] == 0xb8); // map 8 bit\n                CHECK(result[1] == 0xff); // size byte (0xff)\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"object with uint16_t elements\")\n            {\n                json j;\n                for (auto i = 0; i < 256; ++i)\n                {\n                    // format i to a fixed width of 5\n                    // each entry will need 7 bytes: 6 for string, 1 for null\n                    std::stringstream ss;\n                    ss << std::setw(5) << std::setfill('0') << i;\n                    j.emplace(ss.str(), nullptr);\n                }\n\n                const auto result = json::to_cbor(j);\n\n                // Checking against an expected vector byte by byte is\n                // difficult, because no assumption on the order of key/value\n                // pairs are made. We therefore only check the prefix (type and\n                // size and the overall size. The rest is then handled in the\n                // roundtrip check.\n                CHECK(result.size() == 1795); // 1 type, 2 size, 256*7 content\n                CHECK(result[0] == 0xb9); // map 16 bit\n                CHECK(result[1] == 0x01); // byte 0 of size (0x0100)\n                CHECK(result[2] == 0x00); // byte 1 of size (0x0100)\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n\n            SECTION(\"object with uint32_t elements\")\n            {\n                json j;\n                for (auto i = 0; i < 65536; ++i)\n                {\n                    // format i to a fixed width of 5\n                    // each entry will need 7 bytes: 6 for string, 1 for null\n                    std::stringstream ss;\n                    ss << std::setw(5) << std::setfill('0') << i;\n                    j.emplace(ss.str(), nullptr);\n                }\n\n                const auto result = json::to_cbor(j);\n\n                // Checking against an expected vector byte by byte is\n                // difficult, because no assumption on the order of key/value\n                // pairs are made. We therefore only check the prefix (type and\n                // size and the overall size. The rest is then handled in the\n                // roundtrip check.\n                CHECK(result.size() == 458757); // 1 type, 4 size, 65536*7 content\n                CHECK(result[0] == 0xba); // map 32 bit\n                CHECK(result[1] == 0x00); // byte 0 of size (0x00010000)\n                CHECK(result[2] == 0x01); // byte 1 of size (0x00010000)\n                CHECK(result[3] == 0x00); // byte 2 of size (0x00010000)\n                CHECK(result[4] == 0x00); // byte 3 of size (0x00010000)\n\n                // roundtrip\n                CHECK(json::from_cbor(result) == j);\n                CHECK(json::from_cbor(result, true, false) == j);\n            }\n        }\n\n        SECTION(\"binary\")\n        {\n            SECTION(\"N = 0..23\")\n            {\n                for (size_t N = 0; N <= 0x17; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with byte array containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back(static_cast<uint8_t>(0x40 + N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back(0x78);\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 1);\n                    // check that no null byte is appended\n                    if (N > 0)\n                    {\n                        CHECK(result.back() != '\\x00');\n                    }\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 24..255\")\n            {\n                for (size_t N = 24; N <= 255; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back(0x58);\n                    expected.push_back(static_cast<uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back('x');\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 2);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 256..65535\")\n            {\n                for (size_t N :\n                        {\n                            256u, 999u, 1025u, 3333u, 2048u, 65535u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), 0x59);\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 3);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 65536..4294967295\")\n            {\n                for (size_t N :\n                        {\n                            65536u, 77777u, 1048576u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));\n                    expected.insert(expected.begin(), 0x5a);\n\n                    // compare result + size\n                    const auto result = json::to_cbor(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 5);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_cbor(result) == j);\n                    CHECK(json::from_cbor(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"indefinite size\")\n            {\n                std::vector<std::uint8_t> input = {0x5F, 0x44, 0xaa, 0xbb, 0xcc, 0xdd, 0x43, 0xee, 0xff, 0x99, 0xFF};\n                auto j = json::from_cbor(input);\n                CHECK(j.is_binary());\n                auto k = json::binary({0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99});\n                CAPTURE(j.dump(0, ' ', false, json::error_handler_t::strict))\n                CHECK(j == k);\n            }\n\n            SECTION(\"binary in array\")\n            {\n                // array with three empty byte strings\n                std::vector<std::uint8_t> input = {0x83, 0x40, 0x40, 0x40};\n                json _;\n                CHECK_NOTHROW(_ = json::from_cbor(input));\n            }\n\n            SECTION(\"binary in object\")\n            {\n                // object mapping \"foo\" to empty byte string\n                std::vector<std::uint8_t> input = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0x40};\n                json _;\n                CHECK_NOTHROW(_ = json::from_cbor(input));\n            }\n\n            SECTION(\"SAX callback with binary\")\n            {\n                // object mapping \"foo\" to byte string\n                std::vector<std::uint8_t> input = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0x41, 0x00};\n\n                // callback to set binary_seen to true if a binary value was seen\n                bool binary_seen = false;\n                auto callback = [&binary_seen](int /*depth*/, json::parse_event_t /*event*/, json & parsed)\n                {\n                    if (parsed.is_binary())\n                    {\n                        binary_seen = true;\n                    }\n                    return true;\n                };\n\n                json j;\n                auto cbp = nlohmann::detail::json_sax_dom_callback_parser<json>(j, callback, true);\n                CHECK(json::sax_parse(input, &cbp, json::input_format_t::cbor));\n                CHECK(j.at(\"foo\").is_binary());\n                CHECK(binary_seen);\n            }\n        }\n    }\n\n    SECTION(\"additional deserialization\")\n    {\n        SECTION(\"0x5b (byte array)\")\n        {\n            std::vector<uint8_t> given = {0x5b, 0x00, 0x00, 0x00, 0x00,\n                                          0x00, 0x00, 0x00, 0x01, 0x61\n                                         };\n            json j = json::from_cbor(given);\n            CHECK(j == json::binary(std::vector<uint8_t> {'a'}));\n        }\n\n        SECTION(\"0x7b (string)\")\n        {\n            std::vector<uint8_t> given = {0x7b, 0x00, 0x00, 0x00, 0x00,\n                                          0x00, 0x00, 0x00, 0x01, 0x61\n                                         };\n            json j = json::from_cbor(given);\n            CHECK(j == \"a\");\n        }\n\n        SECTION(\"0x9b (array)\")\n        {\n            std::vector<uint8_t> given = {0x9b, 0x00, 0x00, 0x00, 0x00,\n                                          0x00, 0x00, 0x00, 0x01, 0xf4\n                                         };\n            json j = json::from_cbor(given);\n            CHECK(j == json::parse(\"[false]\"));\n        }\n\n        SECTION(\"0xbb (map)\")\n        {\n            std::vector<uint8_t> given = {0xbb, 0x00, 0x00, 0x00, 0x00,\n                                          0x00, 0x00, 0x00, 0x01, 0x60, 0xf4\n                                         };\n            json j = json::from_cbor(given);\n            CHECK(j == json::parse(\"{\\\"\\\": false}\"));\n        }\n    }\n\n    SECTION(\"errors\")\n    {\n        SECTION(\"empty byte vector\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>()), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>()),\n                              \"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input\");\n            CHECK(json::from_cbor(std::vector<uint8_t>(), true, false).is_discarded());\n        }\n\n        SECTION(\"too short byte vector\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x18})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x19})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x19, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x62})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x62, 0x60})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x7F})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x82, 0x01})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0X61})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0X61})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x5F})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x5F, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x41})), json::parse_error&);\n\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x18})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x19})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x19, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1a})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing CBOR number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x62})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x62, 0x60})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x7F})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x82, 0x01})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})),\n                              \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x5F})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR binary: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x5F, 0x00})),\n                              \"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR binary: expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x00\");\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x41})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR binary: unexpected end of input\");\n\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x18}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x19}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x19, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x62}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x62, 0x60}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x7F}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x7F, 0x60}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x82, 0x01}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x9F, 0x01}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x5F}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x5F, 0x00}), true, false).is_discarded());\n            CHECK(json::from_cbor(std::vector<uint8_t>({0x41}), true, false).is_discarded());\n        }\n\n        SECTION(\"unsupported bytes\")\n        {\n            SECTION(\"concrete examples\")\n            {\n                json _;\n                CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1c})), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0x1c})),\n                                  \"[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C\");\n                CHECK(json::from_cbor(std::vector<uint8_t>({0x1c}), true, false).is_discarded());\n\n                CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf8})), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0xf8})),\n                                  \"[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xF8\");\n                CHECK(json::from_cbor(std::vector<uint8_t>({0xf8}), true, false).is_discarded());\n            }\n\n            SECTION(\"all unsupported bytes\")\n            {\n                for (auto byte :\n                        {\n                            // ?\n                            0x1c, 0x1d, 0x1e, 0x1f,\n                            // ?\n                            0x3c, 0x3d, 0x3e, 0x3f,\n                            // ?\n                            0x5c, 0x5d, 0x5e,\n                            // ?\n                            0x7c, 0x7d, 0x7e,\n                            // ?\n                            0x9c, 0x9d, 0x9e,\n                            // ?\n                            0xbc, 0xbd, 0xbe,\n                            // date/time\n                            0xc0, 0xc1,\n                            // bignum\n                            0xc2, 0xc3,\n                            // fraction\n                            0xc4,\n                            // bigfloat\n                            0xc5,\n                            // tagged item\n                            0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,\n                            // expected conversion\n                            0xd5, 0xd6, 0xd7,\n                            // more tagged items\n                            0xd8, 0xd9, 0xda, 0xdb,\n                            // ?\n                            0xdc, 0xdd, 0xde, 0xdf,\n                            // (simple value)\n                            0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,\n                            // undefined\n                            0xf7,\n                            // simple value\n                            0xf8\n                        })\n                {\n                    json _;\n                    CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error&);\n                    CHECK(json::from_cbor(std::vector<uint8_t>({static_cast<uint8_t>(byte)}), true, false).is_discarded());\n                }\n            }\n        }\n\n        SECTION(\"invalid string in map\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})),\n                              \"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF\");\n            CHECK(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01}), true, false).is_discarded());\n        }\n\n        SECTION(\"strict mode\")\n        {\n            std::vector<uint8_t> vec = {0xf6, 0xf6};\n            SECTION(\"non-strict mode\")\n            {\n                const auto result = json::from_cbor(vec, false);\n                CHECK(result == json());\n                CHECK(!json::from_cbor(vec, false, false).is_discarded());\n            }\n\n            SECTION(\"strict mode\")\n            {\n                json _;\n                CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_cbor(vec),\n                                  \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: expected end of input; last byte: 0xF6\");\n                CHECK(json::from_cbor(vec, true, false).is_discarded());\n            }\n        }\n    }\n\n    SECTION(\"SAX aborts\")\n    {\n        SECTION(\"start_array(len)\")\n        {\n            std::vector<uint8_t> v = {0x83, 0x01, 0x02, 0x03};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));\n        }\n\n        SECTION(\"start_object(len)\")\n        {\n            std::vector<uint8_t> v = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0xF4};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));\n        }\n\n        SECTION(\"key()\")\n        {\n            std::vector<uint8_t> v = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0xF4};\n            SaxCountdown scp(1);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));\n        }\n    }\n}\n\n// use this testcase outside [hide] to run it with Valgrind\nTEST_CASE(\"single CBOR roundtrip\")\n{\n    SECTION(\"sample.json\")\n    {\n        std::string filename = TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\";\n\n        // parse JSON file\n        std::ifstream f_json(filename);\n        json j1 = json::parse(f_json);\n\n        // parse CBOR file\n        auto packed = utils::read_binary_file(filename + \".cbor\");\n        json j2;\n        CHECK_NOTHROW(j2 = json::from_cbor(packed));\n\n        // compare parsed JSON values\n        CHECK(j1 == j2);\n\n        SECTION(\"roundtrips\")\n        {\n            SECTION(\"std::ostringstream\")\n            {\n                std::basic_ostringstream<std::uint8_t> ss;\n                json::to_cbor(j1, ss);\n                json j3 = json::from_cbor(ss.str());\n                CHECK(j1 == j3);\n            }\n\n            SECTION(\"std::string\")\n            {\n                std::string s;\n                json::to_cbor(j1, s);\n                json j3 = json::from_cbor(s);\n                CHECK(j1 == j3);\n            }\n        }\n\n        // check with different start index\n        packed.insert(packed.begin(), 5, 0xff);\n        CHECK(j1 == json::from_cbor(packed.begin() + 5, packed.end()));\n    }\n}\n\n#if !defined(JSON_NOEXCEPTION)\nTEST_CASE(\"CBOR regressions\")\n{\n    SECTION(\"fuzz test results\")\n    {\n        /*\n        The following test cases were found during a two-day session with\n        AFL-Fuzz. As a result, empty byte vectors and excessive lengths are\n        detected.\n        */\n        for (std::string filename :\n                {\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test01\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test02\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test03\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test04\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test05\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test06\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test07\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test08\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test09\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test10\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test11\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test12\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test13\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test14\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test15\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test16\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test17\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test18\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test19\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test20\",\n                    TEST_DATA_DIRECTORY \"/cbor_regression/test21\"\n                })\n        {\n            CAPTURE(filename)\n\n            try\n            {\n                // parse CBOR file\n                auto vec1 = utils::read_binary_file(filename);\n                json j1 = json::from_cbor(vec1);\n\n                try\n                {\n                    // step 2: round trip\n                    std::vector<uint8_t> vec2 = json::to_cbor(j1);\n\n                    // parse serialization\n                    json j2 = json::from_cbor(vec2);\n\n                    // deserializations must match\n                    CHECK(j1 == j2);\n                }\n                catch (const json::parse_error&)\n                {\n                    // parsing a CBOR serialization must not fail\n                    CHECK(false);\n                }\n            }\n            catch (const json::parse_error&)\n            {\n                // parse errors are ok, because input may be random bytes\n            }\n        }\n    }\n}\n#endif\n\nTEST_CASE(\"CBOR roundtrips\" * doctest::skip())\n{\n    SECTION(\"input from flynn\")\n    {\n        // most of these are excluded due to differences in key order (not a real problem)\n        std::set<std::string> exclude_packed;\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/1.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/2.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/3.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/4.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/5.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\"); // kills AppVeyor\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json_tests/pass1.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/regression/working_file.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_long_strings.json\");\n\n        for (std::string filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/1.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/2.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/3.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/4.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/5.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip01.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip02.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip03.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip04.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip05.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip06.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip07.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip08.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip09.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip10.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip11.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip12.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip13.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip14.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip15.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip16.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip17.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip18.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip19.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip20.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip21.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip22.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip23.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip24.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip25.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip26.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip27.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip28.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip29.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip30.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip31.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip32.json\",\n                    TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\", // kills AppVeyor\n                    TEST_DATA_DIRECTORY \"/json_tests/pass1.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass2.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass3.json\",\n                    TEST_DATA_DIRECTORY \"/regression/floats.json\",\n                    TEST_DATA_DIRECTORY \"/regression/signed_ints.json\",\n                    TEST_DATA_DIRECTORY \"/regression/unsigned_ints.json\",\n                    TEST_DATA_DIRECTORY \"/regression/working_file.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_arraysWithSpaces.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_empty-string.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_empty.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_ending_with_newline.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_false.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_heterogeneous.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_null.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_1_and_newline.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_leading_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_several_null.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_trailing_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_0e+1.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_0e1.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_after_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_huge_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_int_with_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_minus_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_one.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e_neg_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e_pos_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_exponent.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_underflow.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_simple_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_simple_real.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_too_big_neg_int.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_too_big_pos_int.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_very_big_negative_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_basic.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key_and_value.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_empty.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_empty_key.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_escaped_null_in_key.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_extreme_numbers.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_long_strings.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_simple.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_string_unicode.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_with_newlines.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pair.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pairs.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_allowed_escapes.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_backslash_and_u_escaped_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_backslash_doublequotes.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_comments.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_double_escape_a.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_double_escape_n.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_escaped_control_character.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_escaped_noncharacter.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_in_array.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_in_array_with_leading_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_last_surrogates_1_and_2.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_newline_uescaped.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_null_escape.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_one-byte-utf-8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_pi.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_simple_ascii.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_three-byte-utf-8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_two-byte-utf-8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_u+2028_line_sep.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_u+2029_par_sep.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_uEscape.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unescaped_char_delete.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicodeEscapedBackslash.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_2.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_escaped_double_quote.json\",\n                    // TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_utf16.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_utf8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_with_del_character.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_false.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_negative_real.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_null.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_string.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_true.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_string_empty.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_true_in_array.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json\"\n                })\n        {\n            CAPTURE(filename)\n\n            {\n                INFO_WITH_TEMP(filename + \": std::vector<uint8_t>\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse CBOR file\n                auto packed = utils::read_binary_file(filename + \".cbor\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_cbor(packed));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": std::ifstream\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse CBOR file\n                std::ifstream f_cbor(filename + \".cbor\", std::ios::binary);\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_cbor(f_cbor));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": uint8_t* and size\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse CBOR file\n                auto packed = utils::read_binary_file(filename + \".cbor\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()}));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": output to output adapters\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse CBOR file\n                auto packed = utils::read_binary_file(filename + \".cbor\");\n\n                if (exclude_packed.count(filename) == 0u)\n                {\n                    {\n                        INFO_WITH_TEMP(filename + \": output adapters: std::vector<uint8_t>\");\n                        std::vector<uint8_t> vec;\n                        json::to_cbor(j1, vec);\n                        CHECK(vec == packed);\n                    }\n                }\n            }\n        }\n    }\n}\n\n#if !defined(JSON_NOEXCEPTION)\nTEST_CASE(\"all CBOR first bytes\")\n{\n    // these bytes will fail immediately with exception parse_error.112\n    std::set<uint8_t> unsupported =\n    {\n        //// types not supported by this library\n\n        // date/time\n        0xc0, 0xc1,\n        // bignum\n        0xc2, 0xc3,\n        // decimal fracion\n        0xc4,\n        // bigfloat\n        0xc5,\n        // tagged item\n        0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,\n        0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd8,\n        0xd9, 0xda, 0xdb,\n        // expected conversion\n        0xd5, 0xd6, 0xd7,\n        // simple value\n        0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,\n        0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xef, 0xf0,\n        0xf1, 0xf2, 0xf3,\n        0xf8,\n        // undefined\n        0xf7,\n\n        //// bytes not specified by CBOR\n\n        0x1c, 0x1d, 0x1e, 0x1f,\n        0x3c, 0x3d, 0x3e, 0x3f,\n        0x5c, 0x5d, 0x5e,\n        0x7c, 0x7d, 0x7e,\n        0x9c, 0x9d, 0x9e,\n        0xbc, 0xbd, 0xbe,\n        0xdc, 0xdd, 0xde, 0xdf,\n        0xee,\n        0xfc, 0xfe, 0xfd,\n\n        /// break cannot be the first byte\n\n        0xff\n    };\n\n    for (auto i = 0; i < 256; ++i)\n    {\n        const auto byte = static_cast<uint8_t>(i);\n\n        try\n        {\n            auto res = json::from_cbor(std::vector<uint8_t>(1, byte));\n        }\n        catch (const json::parse_error& e)\n        {\n            // check that parse_error.112 is only thrown if the\n            // first byte is in the unsupported set\n            INFO_WITH_TEMP(e.what());\n            if (unsupported.find(byte) != unsupported.end())\n            {\n                CHECK(e.id == 112);\n            }\n            else\n            {\n                CHECK(e.id != 112);\n            }\n        }\n    }\n}\n#endif\n\nTEST_CASE(\"examples from RFC 7049 Appendix A\")\n{\n    SECTION(\"numbers\")\n    {\n        CHECK(json::to_cbor(json::parse(\"0\")) == std::vector<uint8_t>({0x00}));\n        CHECK(json::parse(\"0\") == json::from_cbor(std::vector<uint8_t>({0x00})));\n\n        CHECK(json::to_cbor(json::parse(\"1\")) == std::vector<uint8_t>({0x01}));\n        CHECK(json::parse(\"1\") == json::from_cbor(std::vector<uint8_t>({0x01})));\n\n        CHECK(json::to_cbor(json::parse(\"10\")) == std::vector<uint8_t>({0x0a}));\n        CHECK(json::parse(\"10\") == json::from_cbor(std::vector<uint8_t>({0x0a})));\n\n        CHECK(json::to_cbor(json::parse(\"23\")) == std::vector<uint8_t>({0x17}));\n        CHECK(json::parse(\"23\") == json::from_cbor(std::vector<uint8_t>({0x17})));\n\n        CHECK(json::to_cbor(json::parse(\"24\")) == std::vector<uint8_t>({0x18, 0x18}));\n        CHECK(json::parse(\"24\") == json::from_cbor(std::vector<uint8_t>({0x18, 0x18})));\n\n        CHECK(json::to_cbor(json::parse(\"25\")) == std::vector<uint8_t>({0x18, 0x19}));\n        CHECK(json::parse(\"25\") == json::from_cbor(std::vector<uint8_t>({0x18, 0x19})));\n\n        CHECK(json::to_cbor(json::parse(\"100\")) == std::vector<uint8_t>({0x18, 0x64}));\n        CHECK(json::parse(\"100\") == json::from_cbor(std::vector<uint8_t>({0x18, 0x64})));\n\n        CHECK(json::to_cbor(json::parse(\"1000\")) == std::vector<uint8_t>({0x19, 0x03, 0xe8}));\n        CHECK(json::parse(\"1000\") == json::from_cbor(std::vector<uint8_t>({0x19, 0x03, 0xe8})));\n\n        CHECK(json::to_cbor(json::parse(\"1000000\")) == std::vector<uint8_t>({0x1a, 0x00, 0x0f, 0x42, 0x40}));\n        CHECK(json::parse(\"1000000\") == json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x0f, 0x42, 0x40})));\n\n        CHECK(json::to_cbor(json::parse(\"1000000000000\")) == std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00}));\n        CHECK(json::parse(\"1000000000000\") == json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00})));\n\n        CHECK(json::to_cbor(json::parse(\"18446744073709551615\")) == std::vector<uint8_t>({0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}));\n        CHECK(json::parse(\"18446744073709551615\") == json::from_cbor(std::vector<uint8_t>({0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})));\n\n        // positive bignum is not supported\n        //CHECK(json::to_cbor(json::parse(\"18446744073709551616\")) == std::vector<uint8_t>({0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));\n        //CHECK(json::parse(\"18446744073709551616\") == json::from_cbor(std::vector<uint8_t>({0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})));\n\n        //CHECK(json::to_cbor(json::parse(\"-18446744073709551616\")) == std::vector<uint8_t>({0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}));\n        //CHECK(json::parse(\"-18446744073709551616\") == json::from_cbor(std::vector<uint8_t>({0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})));\n\n        // negative bignum is not supported\n        //CHECK(json::to_cbor(json::parse(\"-18446744073709551617\")) == std::vector<uint8_t>({0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));\n        //CHECK(json::parse(\"-18446744073709551617\") == json::from_cbor(std::vector<uint8_t>({0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})));\n\n        CHECK(json::to_cbor(json::parse(\"-1\")) == std::vector<uint8_t>({0x20}));\n        CHECK(json::parse(\"-1\") == json::from_cbor(std::vector<uint8_t>({0x20})));\n\n        CHECK(json::to_cbor(json::parse(\"-10\")) == std::vector<uint8_t>({0x29}));\n        CHECK(json::parse(\"-10\") == json::from_cbor(std::vector<uint8_t>({0x29})));\n\n        CHECK(json::to_cbor(json::parse(\"-100\")) == std::vector<uint8_t>({0x38, 0x63}));\n        CHECK(json::parse(\"-100\") == json::from_cbor(std::vector<uint8_t>({0x38, 0x63})));\n\n        CHECK(json::to_cbor(json::parse(\"-1000\")) == std::vector<uint8_t>({0x39, 0x03, 0xe7}));\n        CHECK(json::parse(\"-1000\") == json::from_cbor(std::vector<uint8_t>({0x39, 0x03, 0xe7})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"0.0\")) == std::vector<uint8_t>({0xf9, 0x00, 0x00}));\n        CHECK(json::parse(\"0.0\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x00})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"-0.0\")) == std::vector<uint8_t>({0xf9, 0x80, 0x00}));\n        CHECK(json::parse(\"-0.0\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x80, 0x00})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"1.0\")) == std::vector<uint8_t>({0xf9, 0x3c, 0x00}));\n        CHECK(json::parse(\"1.0\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3c, 0x00})));\n\n        CHECK(json::to_cbor(json::parse(\"1.1\")) == std::vector<uint8_t>({0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a}));\n        CHECK(json::parse(\"1.1\") == json::from_cbor(std::vector<uint8_t>({0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"1.5\")) == std::vector<uint8_t>({0xf9, 0x3e, 0x00}));\n        CHECK(json::parse(\"1.5\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3e, 0x00})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"65504.0\")) == std::vector<uint8_t>({0xf9, 0x7b, 0xff}));\n        CHECK(json::parse(\"65504.0\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x7b, 0xff})));\n\n        //CHECK(json::to_cbor(json::parse(\"100000.0\")) == std::vector<uint8_t>({0xfa, 0x47, 0xc3, 0x50, 0x00}));\n        CHECK(json::parse(\"100000.0\") == json::from_cbor(std::vector<uint8_t>({0xfa, 0x47, 0xc3, 0x50, 0x00})));\n\n        //CHECK(json::to_cbor(json::parse(\"3.4028234663852886e+38\")) == std::vector<uint8_t>({0xfa, 0x7f, 0x7f, 0xff, 0xff}));\n        CHECK(json::parse(\"3.4028234663852886e+38\") == json::from_cbor(std::vector<uint8_t>({0xfa, 0x7f, 0x7f, 0xff, 0xff})));\n\n        CHECK(json::to_cbor(json::parse(\"1.0e+300\")) == std::vector<uint8_t>({0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c}));\n        CHECK(json::parse(\"1.0e+300\") == json::from_cbor(std::vector<uint8_t>({0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"5.960464477539063e-8\")) == std::vector<uint8_t>({0xf9, 0x00, 0x01}));\n        CHECK(json::parse(\"-4.0\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"0.00006103515625\")) == std::vector<uint8_t>({0xf9, 0x04, 0x00}));\n        CHECK(json::parse(\"-4.0\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));\n\n        // half-precision float\n        //CHECK(json::to_cbor(json::parse(\"-4.0\")) == std::vector<uint8_t>({0xf9, 0xc4, 0x00}));\n        CHECK(json::parse(\"-4.0\") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));\n\n        CHECK(json::to_cbor(json::parse(\"-4.1\")) == std::vector<uint8_t>({0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}));\n        CHECK(json::parse(\"-4.1\") == json::from_cbor(std::vector<uint8_t>({0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})));\n    }\n\n    SECTION(\"simple values\")\n    {\n        CHECK(json::to_cbor(json::parse(\"false\")) == std::vector<uint8_t>({0xf4}));\n        CHECK(json::parse(\"false\") == json::from_cbor(std::vector<uint8_t>({0xf4})));\n\n        CHECK(json::to_cbor(json::parse(\"true\")) == std::vector<uint8_t>({0xf5}));\n        CHECK(json::parse(\"true\") == json::from_cbor(std::vector<uint8_t>({0xf5})));\n\n        CHECK(json::to_cbor(json::parse(\"true\")) == std::vector<uint8_t>({0xf5}));\n        CHECK(json::parse(\"true\") == json::from_cbor(std::vector<uint8_t>({0xf5})));\n    }\n\n    SECTION(\"strings\")\n    {\n        CHECK(json::to_cbor(json::parse(\"\\\"\\\"\")) == std::vector<uint8_t>({0x60}));\n        CHECK(json::parse(\"\\\"\\\"\") == json::from_cbor(std::vector<uint8_t>({0x60})));\n\n        CHECK(json::to_cbor(json::parse(\"\\\"a\\\"\")) == std::vector<uint8_t>({0x61, 0x61}));\n        CHECK(json::parse(\"\\\"a\\\"\") == json::from_cbor(std::vector<uint8_t>({0x61, 0x61})));\n\n        CHECK(json::to_cbor(json::parse(\"\\\"IETF\\\"\")) == std::vector<uint8_t>({0x64, 0x49, 0x45, 0x54, 0x46}));\n        CHECK(json::parse(\"\\\"IETF\\\"\") == json::from_cbor(std::vector<uint8_t>({0x64, 0x49, 0x45, 0x54, 0x46})));\n\n        CHECK(json::to_cbor(json::parse(\"\\\"\\\\u00fc\\\"\")) == std::vector<uint8_t>({0x62, 0xc3, 0xbc}));\n        CHECK(json::parse(\"\\\"\\\\u00fc\\\"\") == json::from_cbor(std::vector<uint8_t>({0x62, 0xc3, 0xbc})));\n\n        CHECK(json::to_cbor(json::parse(\"\\\"\\\\u6c34\\\"\")) == std::vector<uint8_t>({0x63, 0xe6, 0xb0, 0xb4}));\n        CHECK(json::parse(\"\\\"\\\\u6c34\\\"\") == json::from_cbor(std::vector<uint8_t>({0x63, 0xe6, 0xb0, 0xb4})));\n\n        CHECK(json::to_cbor(json::parse(\"\\\"\\\\ud800\\\\udd51\\\"\")) == std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91}));\n        CHECK(json::parse(\"\\\"\\\\ud800\\\\udd51\\\"\") == json::from_cbor(std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91})));\n\n        // indefinite length strings\n        CHECK(json::parse(\"\\\"streaming\\\"\") == json::from_cbor(std::vector<uint8_t>({0x7f, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x67, 0xff})));\n    }\n\n    SECTION(\"byte arrays\")\n    {\n        auto packed = utils::read_binary_file(TEST_DATA_DIRECTORY \"/binary_data/cbor_binary.cbor\");\n        json j;\n        CHECK_NOTHROW(j = json::from_cbor(packed));\n\n        auto expected = utils::read_binary_file(TEST_DATA_DIRECTORY \"/binary_data/cbor_binary.out\");\n        CHECK(j == json::binary(expected));\n\n        // 0xd8\n        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)) == std::vector<uint8_t> {0xd8, 0x42, 0x40});\n        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());\n        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 0x42);\n        // 0xd9\n        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)) == std::vector<uint8_t> {0xd9, 0x03, 0xe8, 0x40});\n        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());\n        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 1000);\n        // 0xda\n        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)) == std::vector<uint8_t> {0xda, 0x00, 0x06, 0x03, 0xe8, 0x40});\n        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());\n        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 394216);\n        // 0xdb\n        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)) == std::vector<uint8_t> {0xdb, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x40});\n        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());\n        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 8589934590);\n    }\n\n    SECTION(\"arrays\")\n    {\n        CHECK(json::to_cbor(json::parse(\"[]\")) == std::vector<uint8_t>({0x80}));\n        CHECK(json::parse(\"[]\") == json::from_cbor(std::vector<uint8_t>({0x80})));\n\n        CHECK(json::to_cbor(json::parse(\"[1, 2, 3]\")) == std::vector<uint8_t>({0x83, 0x01, 0x02, 0x03}));\n        CHECK(json::parse(\"[1, 2, 3]\") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x02, 0x03})));\n\n        CHECK(json::to_cbor(json::parse(\"[1, [2, 3], [4, 5]]\")) == std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05}));\n        CHECK(json::parse(\"[1, [2, 3], [4, 5]]\") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05})));\n\n        CHECK(json::to_cbor(json::parse(\"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]\")) == std::vector<uint8_t>({0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19}));\n        CHECK(json::parse(\"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]\") == json::from_cbor(std::vector<uint8_t>({0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19})));\n\n        // indefinite length arrays\n        CHECK(json::parse(\"[]\") == json::from_cbor(std::vector<uint8_t>({0x9f, 0xff})));\n        CHECK(json::parse(\"[1, [2, 3], [4, 5]] \") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x82, 0x02, 0x03, 0x9f, 0x04, 0x05, 0xff, 0xff})));\n        CHECK(json::parse(\"[1, [2, 3], [4, 5]]\") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05, 0xff})));\n        CHECK(json::parse(\"[1, [2, 3], [4, 5]]\") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x9f, 0x04, 0x05, 0xff})));\n        CHECK(json::parse(\"[1, [2, 3], [4, 5]]\") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x9f, 0x02, 0x03, 0xff, 0x82, 0x04, 0x05})));\n        CHECK(json::parse(\"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]\") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, 0xff})));\n    }\n\n    SECTION(\"objects\")\n    {\n        CHECK(json::to_cbor(json::parse(\"{}\")) == std::vector<uint8_t>({0xa0}));\n        CHECK(json::parse(\"{}\") == json::from_cbor(std::vector<uint8_t>({0xa0})));\n\n        CHECK(json::to_cbor(json::parse(\"{\\\"a\\\": 1, \\\"b\\\": [2, 3]}\")) == std::vector<uint8_t>({0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03}));\n        CHECK(json::parse(\"{\\\"a\\\": 1, \\\"b\\\": [2, 3]}\") == json::from_cbor(std::vector<uint8_t>({0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03})));\n\n        CHECK(json::to_cbor(json::parse(\"[\\\"a\\\", {\\\"b\\\": \\\"c\\\"}]\")) == std::vector<uint8_t>({0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63}));\n        CHECK(json::parse(\"[\\\"a\\\", {\\\"b\\\": \\\"c\\\"}]\") == json::from_cbor(std::vector<uint8_t>({0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63})));\n\n        CHECK(json::to_cbor(json::parse(\"{\\\"a\\\": \\\"A\\\", \\\"b\\\": \\\"B\\\", \\\"c\\\": \\\"C\\\", \\\"d\\\": \\\"D\\\", \\\"e\\\": \\\"E\\\"}\")) == std::vector<uint8_t>({0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45}));\n        CHECK(json::parse(\"{\\\"a\\\": \\\"A\\\", \\\"b\\\": \\\"B\\\", \\\"c\\\": \\\"C\\\", \\\"d\\\": \\\"D\\\", \\\"e\\\": \\\"E\\\"}\") == json::from_cbor(std::vector<uint8_t>({0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45})));\n\n        // indefinite length objects\n        CHECK(json::parse(\"{\\\"a\\\": 1, \\\"b\\\": [2, 3]}\") == json::from_cbor(std::vector<uint8_t>({0xbf, 0x61, 0x61, 0x01, 0x61, 0x62, 0x9f, 0x02, 0x03, 0xff, 0xff})));\n        CHECK(json::parse(\"[\\\"a\\\", {\\\"b\\\": \\\"c\\\"}]\") == json::from_cbor(std::vector<uint8_t>({0x82, 0x61, 0x61, 0xbf, 0x61, 0x62, 0x61, 0x63, 0xff})));\n        CHECK(json::parse(\"{\\\"Fun\\\": true, \\\"Amt\\\": -2}\") == json::from_cbor(std::vector<uint8_t>({0xbf, 0x63, 0x46, 0x75, 0x6e, 0xf5, 0x63, 0x41, 0x6d, 0x74, 0x21, 0xff})));\n    }\n}\n\nTEST_CASE(\"Tagged values\")\n{\n    json j = \"s\";\n    auto v = json::to_cbor(j);\n\n    SECTION(\"0xC6..0xD4\")\n    {\n        for (auto b : std::vector<std::uint8_t>\n    {\n        0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4\n    })\n        {\n            CAPTURE(b);\n\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), b);\n\n            // check that parsing fails in error mode\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n\n            // check that parsing succeeds and gets original value in ignore mode\n            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);\n            CHECK(j_tagged == j);\n\n            auto j_tagged_stored = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::store);\n            CHECK(j_tagged_stored == j);\n        }\n    }\n\n    SECTION(\"0xD8 - 1 byte follows\")\n    {\n        SECTION(\"success\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0xD8); // tag\n\n            // check that parsing fails in error mode\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n\n            // check that parsing succeeds and gets original value in ignore mode\n            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);\n            CHECK(j_tagged == j);\n        }\n\n        SECTION(\"missing byte after tag\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0xD8); // tag\n\n            // check that parsing fails in all modes\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);\n        }\n    }\n\n    SECTION(\"0xD9 - 2 byte follow\")\n    {\n        SECTION(\"success\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0xD9); // tag\n\n            // check that parsing fails in error mode\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n\n            // check that parsing succeeds and gets original value in ignore mode\n            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);\n            CHECK(j_tagged == j);\n        }\n\n        SECTION(\"missing byte after tag\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0xD9); // tag\n\n            // check that parsing fails in all modes\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);\n        }\n    }\n\n    SECTION(\"0xDA - 4 bytes follow\")\n    {\n        SECTION(\"success\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0xDA); // tag\n\n            // check that parsing fails in error mode\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n\n            // check that parsing succeeds and gets original value in ignore mode\n            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);\n            CHECK(j_tagged == j);\n        }\n\n        SECTION(\"missing bytes after tag\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0xDA); // tag\n\n            // check that parsing fails in all modes\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);\n        }\n    }\n\n    SECTION(\"0xDB - 8 bytes follow\")\n    {\n        SECTION(\"success\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0xDB); // tag\n\n            // check that parsing fails in error mode\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n\n            // check that parsing succeeds and gets original value in ignore mode\n            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);\n            CHECK(j_tagged == j);\n        }\n\n        SECTION(\"missing byte after tag\")\n        {\n            // add tag to value\n            auto v_tagged = v;\n            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte\n            v_tagged.insert(v_tagged.begin(), 0xDB); // tag\n\n            // check that parsing fails in all modes\n            json _;\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);\n            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);\n        }\n    }\n\n    SECTION(\"tagged binary\")\n    {\n        // create a binary value of subtype 42\n        json j_binary;\n        j_binary[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n        // convert to CBOR\n        const auto vec = json::to_cbor(j_binary);\n        CHECK(vec == std::vector<std::uint8_t> {0xA1, 0x66, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0xD8, 0x2A, 0x44, 0xCA, 0xFE, 0xBA, 0xBE});\n\n        // parse error when parsing tagged value\n        json _;\n        CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec), \"[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: invalid byte: 0xD8\");\n\n        // binary without subtype when tags are ignored\n        json jb = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore);\n        CHECK(jb.is_object());\n        CHECK(jb[\"binary\"].is_binary());\n        CHECK(!jb[\"binary\"].get_binary().has_subtype());\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-class_const_iterator.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"const_iterator class\")\n{\n    SECTION(\"construction\")\n    {\n        SECTION(\"constructor\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it(&j);\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                json::const_iterator it(&j);\n            }\n\n            SECTION(\"array\")\n            {\n                json j(json::value_t::array);\n                json::const_iterator it(&j);\n            }\n        }\n\n        SECTION(\"copy assignment\")\n        {\n            json j(json::value_t::null);\n            json::const_iterator it(&j);\n            json::const_iterator it2(&j);\n            it2 = it;\n        }\n\n        SECTION(\"copy constructor from non-const iterator\")\n        {\n            SECTION(\"create from uninitialized iterator\")\n            {\n                const json::iterator it {};\n                json::const_iterator cit(it);\n            }\n\n            SECTION(\"create from initialized iterator\")\n            {\n                json j;\n                const json::iterator it = j.begin();\n                json::const_iterator cit(it);\n            }\n        }\n    }\n\n    SECTION(\"initialization\")\n    {\n        SECTION(\"set_begin\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it(&j);\n                it.set_begin();\n                CHECK((it == j.cbegin()));\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                json::const_iterator it(&j);\n                it.set_begin();\n                CHECK((it == j.cbegin()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j(json::value_t::array);\n                json::const_iterator it(&j);\n                it.set_begin();\n                CHECK((it == j.cbegin()));\n            }\n        }\n\n        SECTION(\"set_end\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it(&j);\n                it.set_end();\n                CHECK((it == j.cend()));\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                json::const_iterator it(&j);\n                it.set_end();\n                CHECK((it == j.cend()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j(json::value_t::array);\n                json::const_iterator it(&j);\n                it.set_end();\n                CHECK((it == j.cend()));\n            }\n        }\n    }\n\n    SECTION(\"element access\")\n    {\n        SECTION(\"operator*\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it = j.cbegin();\n                CHECK_THROWS_AS(*it, json::invalid_iterator&);\n                CHECK_THROWS_WITH(*it, \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::const_iterator it = j.cbegin();\n                CHECK(*it == json(17));\n                it = j.cend();\n                CHECK_THROWS_AS(*it, json::invalid_iterator&);\n                CHECK_THROWS_WITH(*it, \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::const_iterator it = j.cbegin();\n                CHECK(*it == json(\"bar\"));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::const_iterator it = j.cbegin();\n                CHECK(*it == json(1));\n            }\n        }\n\n        SECTION(\"operator->\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it = j.cbegin();\n                CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);\n                CHECK_THROWS_WITH(std::string(it->type_name()), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::const_iterator it = j.cbegin();\n                CHECK(std::string(it->type_name()) == \"number\");\n                it = j.cend();\n                CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);\n                CHECK_THROWS_WITH(std::string(it->type_name()), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::const_iterator it = j.cbegin();\n                CHECK(std::string(it->type_name()) == \"string\");\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::const_iterator it = j.cbegin();\n                CHECK(std::string(it->type_name()) == \"number\");\n            }\n        }\n    }\n\n    SECTION(\"increment/decrement\")\n    {\n        SECTION(\"post-increment\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                it++;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                it++;\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                it++;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n                it++;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n            }\n        }\n\n        SECTION(\"pre-increment\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                ++it;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                ++it;\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                ++it;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n                ++it;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::const_iterator it = j.cbegin();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n            }\n        }\n\n        SECTION(\"post-decrement\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                it--;\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                it--;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n                it--;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n            }\n        }\n\n        SECTION(\"pre-decrement\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                --it;\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                --it;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n                --it;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::const_iterator it = j.cend();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-class_iterator.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"iterator class\")\n{\n    SECTION(\"construction\")\n    {\n        SECTION(\"constructor\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it(&j);\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                json::iterator it(&j);\n            }\n\n            SECTION(\"array\")\n            {\n                json j(json::value_t::array);\n                json::iterator it(&j);\n            }\n        }\n\n        SECTION(\"copy assignment\")\n        {\n            json j(json::value_t::null);\n            json::iterator it(&j);\n            json::iterator it2(&j);\n            it2 = it;\n        }\n    }\n\n    SECTION(\"initialization\")\n    {\n        SECTION(\"set_begin\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it(&j);\n                it.set_begin();\n                CHECK((it == j.begin()));\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                json::iterator it(&j);\n                it.set_begin();\n                CHECK((it == j.begin()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j(json::value_t::array);\n                json::iterator it(&j);\n                it.set_begin();\n                CHECK((it == j.begin()));\n            }\n        }\n\n        SECTION(\"set_end\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it(&j);\n                it.set_end();\n                CHECK((it == j.end()));\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                json::iterator it(&j);\n                it.set_end();\n                CHECK((it == j.end()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j(json::value_t::array);\n                json::iterator it(&j);\n                it.set_end();\n                CHECK((it == j.end()));\n            }\n        }\n    }\n\n    SECTION(\"element access\")\n    {\n        SECTION(\"operator*\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it = j.begin();\n                CHECK_THROWS_AS(*it, json::invalid_iterator&);\n                CHECK_THROWS_WITH(*it, \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::iterator it = j.begin();\n                CHECK(*it == json(17));\n                it = j.end();\n                CHECK_THROWS_AS(*it, json::invalid_iterator&);\n                CHECK_THROWS_WITH(*it, \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::iterator it = j.begin();\n                CHECK(*it == json(\"bar\"));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::iterator it = j.begin();\n                CHECK(*it == json(1));\n            }\n        }\n\n        SECTION(\"operator->\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it = j.begin();\n                CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);\n                CHECK_THROWS_WITH(std::string(it->type_name()), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::iterator it = j.begin();\n                CHECK(std::string(it->type_name()) == \"number\");\n                it = j.end();\n                CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);\n                CHECK_THROWS_WITH(std::string(it->type_name()), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::iterator it = j.begin();\n                CHECK(std::string(it->type_name()) == \"string\");\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::iterator it = j.begin();\n                CHECK(std::string(it->type_name()) == \"number\");\n            }\n        }\n    }\n\n    SECTION(\"increment/decrement\")\n    {\n        SECTION(\"post-increment\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it = j.begin();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                it++;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::iterator it = j.begin();\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                it++;\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                it++;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::iterator it = j.begin();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n                it++;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::iterator it = j.begin();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it++;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n            }\n        }\n\n        SECTION(\"pre-increment\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it = j.begin();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                ++it;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::iterator it = j.begin();\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                ++it;\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                ++it;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::iterator it = j.begin();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n                ++it;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::iterator it = j.begin();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                ++it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n            }\n        }\n\n        SECTION(\"post-decrement\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it = j.end();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::iterator it = j.end();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                it--;\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                it--;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::iterator it = j.end();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n                it--;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::iterator it = j.end();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                it--;\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n            }\n        }\n\n        SECTION(\"pre-decrement\")\n        {\n            SECTION(\"null\")\n            {\n                json j(json::value_t::null);\n                json::iterator it = j.end();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n            }\n\n            SECTION(\"number\")\n            {\n                json j(17);\n                json::iterator it = j.end();\n                CHECK((it.m_it.primitive_iterator.m_it == 1));\n                --it;\n                CHECK((it.m_it.primitive_iterator.m_it == 0));\n                --it;\n                CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));\n            }\n\n            SECTION(\"object\")\n            {\n                json j({{\"foo\", \"bar\"}});\n                json::iterator it = j.end();\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));\n                --it;\n                CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));\n            }\n\n            SECTION(\"array\")\n            {\n                json j({1, 2, 3, 4});\n                json::iterator it = j.end();\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n                --it;\n                CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));\n                CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-class_lexer.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nnamespace\n{\n// shortcut to scan a string literal\njson::lexer::token_type scan_string(const char* s, bool ignore_comments = false);\njson::lexer::token_type scan_string(const char* s, const bool ignore_comments)\n{\n    auto ia = nlohmann::detail::input_adapter(s);\n    return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments).scan(); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)\n}\n} // namespace\n\nstd::string get_error_message(const char* s, bool ignore_comments = false);\nstd::string get_error_message(const char* s, const bool ignore_comments)\n{\n    auto ia = nlohmann::detail::input_adapter(s);\n    auto lexer = nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)\n    lexer.scan();\n    return lexer.get_error_message();\n}\n\nTEST_CASE(\"lexer class\")\n{\n    SECTION(\"scan\")\n    {\n        SECTION(\"structural characters\")\n        {\n            CHECK((scan_string(\"[\") == json::lexer::token_type::begin_array));\n            CHECK((scan_string(\"]\") == json::lexer::token_type::end_array));\n            CHECK((scan_string(\"{\") == json::lexer::token_type::begin_object));\n            CHECK((scan_string(\"}\") == json::lexer::token_type::end_object));\n            CHECK((scan_string(\",\") == json::lexer::token_type::value_separator));\n            CHECK((scan_string(\":\") == json::lexer::token_type::name_separator));\n        }\n\n        SECTION(\"literal names\")\n        {\n            CHECK((scan_string(\"null\") == json::lexer::token_type::literal_null));\n            CHECK((scan_string(\"true\") == json::lexer::token_type::literal_true));\n            CHECK((scan_string(\"false\") == json::lexer::token_type::literal_false));\n        }\n\n        SECTION(\"numbers\")\n        {\n            CHECK((scan_string(\"0\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"1\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"2\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"3\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"4\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"5\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"6\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"7\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"8\") == json::lexer::token_type::value_unsigned));\n            CHECK((scan_string(\"9\") == json::lexer::token_type::value_unsigned));\n\n            CHECK((scan_string(\"-0\") == json::lexer::token_type::value_integer));\n            CHECK((scan_string(\"-1\") == json::lexer::token_type::value_integer));\n\n            CHECK((scan_string(\"1.1\") == json::lexer::token_type::value_float));\n            CHECK((scan_string(\"-1.1\") == json::lexer::token_type::value_float));\n            CHECK((scan_string(\"1E10\") == json::lexer::token_type::value_float));\n        }\n\n        SECTION(\"whitespace\")\n        {\n            // result is end_of_input, because not token is following\n            CHECK((scan_string(\" \") == json::lexer::token_type::end_of_input));\n            CHECK((scan_string(\"\\t\") == json::lexer::token_type::end_of_input));\n            CHECK((scan_string(\"\\n\") == json::lexer::token_type::end_of_input));\n            CHECK((scan_string(\"\\r\") == json::lexer::token_type::end_of_input));\n            CHECK((scan_string(\" \\t\\n\\r\\n\\t \") == json::lexer::token_type::end_of_input));\n        }\n    }\n\n    SECTION(\"token_type_name\")\n    {\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::uninitialized)) == \"<uninitialized>\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::literal_true)) == \"true literal\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::literal_false)) == \"false literal\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::literal_null)) == \"null literal\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_string)) == \"string literal\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_unsigned)) == \"number literal\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_integer)) == \"number literal\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_float)) == \"number literal\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::begin_array)) == \"'['\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::begin_object)) == \"'{'\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::end_array)) == \"']'\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::end_object)) == \"'}'\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::name_separator)) == \"':'\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_separator)) == \"','\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::parse_error)) == \"<parse error>\"));\n        CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::end_of_input)) == \"end of input\"));\n    }\n\n    SECTION(\"parse errors on first character\")\n    {\n        for (int c = 1; c < 128; ++c)\n        {\n            // create string from the ASCII code\n            const auto s = std::string(1, static_cast<char>(c));\n            // store scan() result\n            const auto res = scan_string(s.c_str());\n\n            CAPTURE(s)\n\n            switch (c)\n            {\n                // single characters that are valid tokens\n                case ('['):\n                case (']'):\n                case ('{'):\n                case ('}'):\n                case (','):\n                case (':'):\n                case ('0'):\n                case ('1'):\n                case ('2'):\n                case ('3'):\n                case ('4'):\n                case ('5'):\n                case ('6'):\n                case ('7'):\n                case ('8'):\n                case ('9'):\n                {\n                    CHECK((res != json::lexer::token_type::parse_error));\n                    break;\n                }\n\n                // whitespace\n                case (' '):\n                case ('\\t'):\n                case ('\\n'):\n                case ('\\r'):\n                {\n                    CHECK((res == json::lexer::token_type::end_of_input));\n                    break;\n                }\n\n                // anything else is not expected\n                default:\n                {\n                    CHECK((res == json::lexer::token_type::parse_error));\n                    break;\n                }\n            }\n        }\n    }\n\n    SECTION(\"very large string\")\n    {\n        // strings larger than 1024 bytes yield a resize of the lexer's yytext buffer\n        std::string s(\"\\\"\");\n        s += std::string(2048, 'x');\n        s += \"\\\"\";\n        CHECK((scan_string(s.c_str()) == json::lexer::token_type::value_string));\n    }\n\n    SECTION(\"fail on comments\")\n    {\n        CHECK((scan_string(\"/\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/\", false) == \"invalid literal\");\n\n        CHECK((scan_string(\"/!\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/!\", false) == \"invalid literal\");\n        CHECK((scan_string(\"/*\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/*\", false) == \"invalid literal\");\n        CHECK((scan_string(\"/**\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/**\", false) == \"invalid literal\");\n\n        CHECK((scan_string(\"//\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"//\", false) == \"invalid literal\");\n        CHECK((scan_string(\"/**/\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/**/\", false) == \"invalid literal\");\n        CHECK((scan_string(\"/** /\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/** /\", false) == \"invalid literal\");\n\n        CHECK((scan_string(\"/***/\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/***/\", false) == \"invalid literal\");\n        CHECK((scan_string(\"/* true */\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/* true */\", false) == \"invalid literal\");\n        CHECK((scan_string(\"/*/**/\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/*/**/\", false) == \"invalid literal\");\n        CHECK((scan_string(\"/*/* */\", false) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/*/* */\", false) == \"invalid literal\");\n    }\n\n    SECTION(\"ignore comments\")\n    {\n        CHECK((scan_string(\"/\", true) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/\", true) == \"invalid comment; expecting '/' or '*' after '/'\");\n\n        CHECK((scan_string(\"/!\", true) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/!\", true) == \"invalid comment; expecting '/' or '*' after '/'\");\n        CHECK((scan_string(\"/*\", true) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/*\", true) == \"invalid comment; missing closing '*/'\");\n        CHECK((scan_string(\"/**\", true) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/**\", true) == \"invalid comment; missing closing '*/'\");\n\n        CHECK((scan_string(\"//\", true) == json::lexer::token_type::end_of_input));\n        CHECK((scan_string(\"/**/\", true) == json::lexer::token_type::end_of_input));\n        CHECK((scan_string(\"/** /\", true) == json::lexer::token_type::parse_error));\n        CHECK(get_error_message(\"/** /\", true) == \"invalid comment; missing closing '*/'\");\n\n        CHECK((scan_string(\"/***/\", true) == json::lexer::token_type::end_of_input));\n        CHECK((scan_string(\"/* true */\", true) == json::lexer::token_type::end_of_input));\n        CHECK((scan_string(\"/*/**/\", true) == json::lexer::token_type::end_of_input));\n        CHECK((scan_string(\"/*/* */\", true) == json::lexer::token_type::end_of_input));\n\n        CHECK((scan_string(\"//\\n//\\n\", true) == json::lexer::token_type::end_of_input));\n        CHECK((scan_string(\"/**//**//**/\", true) == json::lexer::token_type::end_of_input));\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-class_parser.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <valarray>\n\nnamespace\n{\nclass SaxEventLogger\n{\n  public:\n    bool null()\n    {\n        events.emplace_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val)\n    {\n        events.emplace_back(val ? \"boolean(true)\" : \"boolean(false)\");\n        return true;\n    }\n\n    bool number_integer(json::number_integer_t val)\n    {\n        events.push_back(\"number_integer(\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(json::number_unsigned_t val)\n    {\n        events.push_back(\"number_unsigned(\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(json::number_float_t /*unused*/, const std::string& s)\n    {\n        events.push_back(\"number_float(\" + s + \")\");\n        return true;\n    }\n\n    bool string(std::string& val)\n    {\n        events.push_back(\"string(\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val)\n    {\n        std::string binary_contents = \"binary(\";\n        std::string comma_space;\n        for (auto b : val)\n        {\n            binary_contents.append(comma_space);\n            binary_contents.append(std::to_string(static_cast<int>(b)));\n            comma_space = \", \";\n        }\n        binary_contents.append(\")\");\n        events.push_back(binary_contents);\n        return true;\n    }\n\n    bool start_object(std::size_t elements)\n    {\n        if (elements == static_cast<std::size_t>(-1))\n        {\n            events.emplace_back(\"start_object()\");\n        }\n        else\n        {\n            events.push_back(\"start_object(\" + std::to_string(elements) + \")\");\n        }\n        return true;\n    }\n\n    bool key(std::string& val)\n    {\n        events.push_back(\"key(\" + val + \")\");\n        return true;\n    }\n\n    bool end_object()\n    {\n        events.emplace_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements)\n    {\n        if (elements == static_cast<std::size_t>(-1))\n        {\n            events.emplace_back(\"start_array()\");\n        }\n        else\n        {\n            events.push_back(\"start_array(\" + std::to_string(elements) + \")\");\n        }\n        return true;\n    }\n\n    bool end_array()\n    {\n        events.emplace_back(\"end_array()\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& /*unused*/, const json::exception& /*unused*/)\n    {\n        errored = true;\n        events.push_back(\"parse_error(\" + std::to_string(position) + \")\");\n        return false;\n    }\n\n    std::vector<std::string> events {};\n    bool errored = false;\n};\n\nclass SaxCountdown : public nlohmann::json::json_sax_t\n{\n  public:\n    explicit SaxCountdown(const int count) : events_left(count)\n    {}\n\n    bool null() override\n    {\n        return events_left-- > 0;\n    }\n\n    bool boolean(bool /*val*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_integer(json::number_integer_t /*val*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_unsigned(json::number_unsigned_t /*val*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_float(json::number_float_t /*val*/, const std::string& /*s*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool string(std::string& /*val*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool binary(json::binary_t& /*val*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_object(std::size_t /*elements*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool key(std::string& /*val*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_object() override\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_array(std::size_t /*elements*/) override\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_array() override\n    {\n        return events_left-- > 0;\n    }\n\n    bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& /*ex*/) override\n    {\n        return false;\n    }\n\n  private:\n    int events_left = 0;\n};\n\njson parser_helper(const std::string& s);\nbool accept_helper(const std::string& s);\nvoid comments_helper(const std::string& s);\n\njson parser_helper(const std::string& s)\n{\n    json j;\n    json::parser(nlohmann::detail::input_adapter(s)).parse(true, j);\n\n    // if this line was reached, no exception occurred\n    // -> check if result is the same without exceptions\n    json j_nothrow;\n    CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter(s), nullptr, false).parse(true, j_nothrow));\n    CHECK(j_nothrow == j);\n\n    json j_sax;\n    nlohmann::detail::json_sax_dom_parser<json> sdp(j_sax);\n    json::sax_parse(s, &sdp);\n    CHECK(j_sax == j);\n\n    comments_helper(s);\n\n    return j;\n}\n\nbool accept_helper(const std::string& s)\n{\n    CAPTURE(s)\n\n    // 1. parse s without exceptions\n    json j;\n    CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter(s), nullptr, false).parse(true, j));\n    const bool ok_noexcept = !j.is_discarded();\n\n    // 2. accept s\n    const bool ok_accept = json::parser(nlohmann::detail::input_adapter(s)).accept(true);\n\n    // 3. check if both approaches come to the same result\n    CHECK(ok_noexcept == ok_accept);\n\n    // 4. parse with SAX (compare with relaxed accept result)\n    SaxEventLogger el;\n    CHECK_NOTHROW(json::sax_parse(s, &el, json::input_format_t::json, false));\n    CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept(false) == !el.errored);\n\n    // 5. parse with simple callback\n    json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/)\n    {\n        return true;\n    };\n    json j_cb = json::parse(s, cb, false);\n    const bool ok_noexcept_cb = !j_cb.is_discarded();\n\n    // 6. check if this approach came to the same result\n    CHECK(ok_noexcept == ok_noexcept_cb);\n\n    // 7. check if comments are properly ignored\n    if (ok_accept)\n    {\n        comments_helper(s);\n    }\n\n    // 8. return result\n    return ok_accept;\n}\n\nvoid comments_helper(const std::string& s)\n{\n    json _;\n\n    // parse/accept with default parser\n    CHECK_NOTHROW(_ = json::parse(s));\n    CHECK(json::accept(s));\n\n    // parse/accept while skipping comments\n    CHECK_NOTHROW(_ = json::parse(s, nullptr, false, true));\n    CHECK(json::accept(s, true));\n\n    std::vector<std::string> json_with_comments;\n\n    // start with a comment\n    json_with_comments.push_back(std::string(\"// this is a comment\\n\") + s);\n    json_with_comments.push_back(std::string(\"/* this is a comment */\") + s);\n    // end with a comment\n    json_with_comments.push_back(s + \"// this is a comment\");\n    json_with_comments.push_back(s + \"/* this is a comment */\");\n\n    // check all strings\n    for (const auto& json_with_comment : json_with_comments)\n    {\n        CAPTURE(json_with_comment)\n        CHECK_THROWS_AS(_ = json::parse(json_with_comment), json::parse_error);\n        CHECK(!json::accept(json_with_comment));\n\n        CHECK_NOTHROW(_ = json::parse(json_with_comment, nullptr, true, true));\n        CHECK(json::accept(json_with_comment, true));\n    }\n}\n\n} // namespace\n\nTEST_CASE(\"parser class\")\n{\n    SECTION(\"parse\")\n    {\n        SECTION(\"null\")\n        {\n            CHECK(parser_helper(\"null\") == json(nullptr));\n        }\n\n        SECTION(\"true\")\n        {\n            CHECK(parser_helper(\"true\") == json(true));\n        }\n\n        SECTION(\"false\")\n        {\n            CHECK(parser_helper(\"false\") == json(false));\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty array\")\n            {\n                CHECK(parser_helper(\"[]\") == json(json::value_t::array));\n                CHECK(parser_helper(\"[ ]\") == json(json::value_t::array));\n            }\n\n            SECTION(\"nonempty array\")\n            {\n                CHECK(parser_helper(\"[true, false, null]\") == json({true, false, nullptr}));\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty object\")\n            {\n                CHECK(parser_helper(\"{}\") == json(json::value_t::object));\n                CHECK(parser_helper(\"{ }\") == json(json::value_t::object));\n            }\n\n            SECTION(\"nonempty object\")\n            {\n                CHECK(parser_helper(\"{\\\"\\\": true, \\\"one\\\": 1, \\\"two\\\": null}\") == json({{\"\", true}, {\"one\", 1}, {\"two\", nullptr}}));\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            // empty string\n            CHECK(parser_helper(\"\\\"\\\"\") == json(json::value_t::string));\n\n            SECTION(\"errors\")\n            {\n                // error: tab in string\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\t\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\t\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\\\u0009 or \\\\t; last read: '\\\"<U+0009>'\");\n                // error: newline in string\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\n\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\r\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\n\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\\\u000A or \\\\n; last read: '\\\"<U+000A>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\r\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\\\u000D or \\\\r; last read: '\\\"<U+000D>'\");\n                // error: backspace in string\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\b\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\b\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\\\u0008 or \\\\b; last read: '\\\"<U+0008>'\");\n                // improve code coverage\n                CHECK_THROWS_AS(parser_helper(\"\\uFF01\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"[-4:1,]\"), json::parse_error&);\n                // unescaped control characters\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x00\\\"\"), json::parse_error&); // NOLINT(bugprone-string-literal-with-embedded-nul)\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x01\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x02\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x03\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x04\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x05\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x06\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x07\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x08\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x09\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x0a\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x0b\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x0c\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x0d\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x0e\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x0f\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x10\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x11\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x12\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x13\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x14\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x15\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x16\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x17\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x18\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x19\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x1a\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x1b\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x1c\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x1d\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x1e\\\"\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"\\\"\\x1f\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x00\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\\\"'\"); // NOLINT(bugprone-string-literal-with-embedded-nul)\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x01\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0001 (SOH) must be escaped to \\\\u0001; last read: '\\\"<U+0001>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x02\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0002 (STX) must be escaped to \\\\u0002; last read: '\\\"<U+0002>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x03\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0003 (ETX) must be escaped to \\\\u0003; last read: '\\\"<U+0003>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x04\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0004 (EOT) must be escaped to \\\\u0004; last read: '\\\"<U+0004>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x05\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0005 (ENQ) must be escaped to \\\\u0005; last read: '\\\"<U+0005>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x06\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0006 (ACK) must be escaped to \\\\u0006; last read: '\\\"<U+0006>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x07\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0007 (BEL) must be escaped to \\\\u0007; last read: '\\\"<U+0007>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x08\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\\\u0008 or \\\\b; last read: '\\\"<U+0008>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x09\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\\\u0009 or \\\\t; last read: '\\\"<U+0009>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x0a\\\"\"), \"[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\\\u000A or \\\\n; last read: '\\\"<U+000A>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x0b\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000B (VT) must be escaped to \\\\u000B; last read: '\\\"<U+000B>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x0c\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000C (FF) must be escaped to \\\\u000C or \\\\f; last read: '\\\"<U+000C>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x0d\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\\\u000D or \\\\r; last read: '\\\"<U+000D>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x0e\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000E (SO) must be escaped to \\\\u000E; last read: '\\\"<U+000E>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x0f\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000F (SI) must be escaped to \\\\u000F; last read: '\\\"<U+000F>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x10\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0010 (DLE) must be escaped to \\\\u0010; last read: '\\\"<U+0010>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x11\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0011 (DC1) must be escaped to \\\\u0011; last read: '\\\"<U+0011>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x12\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0012 (DC2) must be escaped to \\\\u0012; last read: '\\\"<U+0012>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x13\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0013 (DC3) must be escaped to \\\\u0013; last read: '\\\"<U+0013>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x14\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0014 (DC4) must be escaped to \\\\u0014; last read: '\\\"<U+0014>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x15\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0015 (NAK) must be escaped to \\\\u0015; last read: '\\\"<U+0015>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x16\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0016 (SYN) must be escaped to \\\\u0016; last read: '\\\"<U+0016>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x17\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0017 (ETB) must be escaped to \\\\u0017; last read: '\\\"<U+0017>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x18\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0018 (CAN) must be escaped to \\\\u0018; last read: '\\\"<U+0018>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x19\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0019 (EM) must be escaped to \\\\u0019; last read: '\\\"<U+0019>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x1a\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001A (SUB) must be escaped to \\\\u001A; last read: '\\\"<U+001A>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x1b\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001B (ESC) must be escaped to \\\\u001B; last read: '\\\"<U+001B>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x1c\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001C (FS) must be escaped to \\\\u001C; last read: '\\\"<U+001C>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x1d\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001D (GS) must be escaped to \\\\u001D; last read: '\\\"<U+001D>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x1e\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001E (RS) must be escaped to \\\\u001E; last read: '\\\"<U+001E>'\");\n                CHECK_THROWS_WITH(parser_helper(\"\\\"\\x1f\\\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001F (US) must be escaped to \\\\u001F; last read: '\\\"<U+001F>'\");\n\n                SECTION(\"additional test for null byte\")\n                {\n                    // The test above for the null byte is wrong, because passing\n                    // a string to the parser only reads int until it encounters\n                    // a null byte. This test inserts the null byte later on and\n                    // uses an iterator range.\n                    std::string s = \"\\\"1\\\"\";\n                    s[1] = '\\0';\n                    json _;\n                    CHECK_THROWS_AS(_ = json::parse(s.begin(), s.end()), json::parse_error&);\n                    CHECK_THROWS_WITH(_ = json::parse(s.begin(), s.end()), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0000 (NUL) must be escaped to \\\\u0000; last read: '\\\"<U+0000>'\");\n                }\n            }\n\n            SECTION(\"escaped\")\n            {\n                // quotation mark \"\\\"\"\n                auto r1 = R\"(\"\\\"\")\"_json;\n                CHECK(parser_helper(\"\\\"\\\\\\\"\\\"\") == r1);\n                // reverse solidus \"\\\\\"\n                auto r2 = R\"(\"\\\\\")\"_json;\n                CHECK(parser_helper(\"\\\"\\\\\\\\\\\"\") == r2);\n                // solidus\n                CHECK(parser_helper(\"\\\"\\\\/\\\"\") == R\"(\"/\")\"_json);\n                // backspace\n                CHECK(parser_helper(\"\\\"\\\\b\\\"\") == json(\"\\b\"));\n                // formfeed\n                CHECK(parser_helper(\"\\\"\\\\f\\\"\") == json(\"\\f\"));\n                // newline\n                CHECK(parser_helper(\"\\\"\\\\n\\\"\") == json(\"\\n\"));\n                // carriage return\n                CHECK(parser_helper(\"\\\"\\\\r\\\"\") == json(\"\\r\"));\n                // horizontal tab\n                CHECK(parser_helper(\"\\\"\\\\t\\\"\") == json(\"\\t\"));\n\n                CHECK(parser_helper(\"\\\"\\\\u0001\\\"\").get<json::string_t>() == \"\\x01\");\n                CHECK(parser_helper(\"\\\"\\\\u000a\\\"\").get<json::string_t>() == \"\\n\");\n                CHECK(parser_helper(\"\\\"\\\\u00b0\\\"\").get<json::string_t>() == \"°\");\n                CHECK(parser_helper(\"\\\"\\\\u0c00\\\"\").get<json::string_t>() == \"ఀ\");\n                CHECK(parser_helper(\"\\\"\\\\ud000\\\"\").get<json::string_t>() == \"퀀\");\n                CHECK(parser_helper(\"\\\"\\\\u000E\\\"\").get<json::string_t>() == \"\\x0E\");\n                CHECK(parser_helper(\"\\\"\\\\u00F0\\\"\").get<json::string_t>() == \"ð\");\n                CHECK(parser_helper(\"\\\"\\\\u0100\\\"\").get<json::string_t>() == \"Ā\");\n                CHECK(parser_helper(\"\\\"\\\\u2000\\\"\").get<json::string_t>() == \" \");\n                CHECK(parser_helper(\"\\\"\\\\uFFFF\\\"\").get<json::string_t>() == \"￿\");\n                CHECK(parser_helper(\"\\\"\\\\u20AC\\\"\").get<json::string_t>() == \"€\");\n                CHECK(parser_helper(\"\\\"€\\\"\").get<json::string_t>() == \"€\");\n                CHECK(parser_helper(\"\\\"🎈\\\"\").get<json::string_t>() == \"🎈\");\n\n                CHECK(parser_helper(\"\\\"\\\\ud80c\\\\udc60\\\"\").get<json::string_t>() == \"\\xf0\\x93\\x81\\xa0\");\n                CHECK(parser_helper(\"\\\"\\\\ud83c\\\\udf1e\\\"\").get<json::string_t>() == \"🌞\");\n            }\n        }\n\n        SECTION(\"number\")\n        {\n            SECTION(\"integers\")\n            {\n                SECTION(\"without exponent\")\n                {\n                    CHECK(parser_helper(\"-128\") == json(-128));\n                    CHECK(parser_helper(\"-0\") == json(-0));\n                    CHECK(parser_helper(\"0\") == json(0));\n                    CHECK(parser_helper(\"128\") == json(128));\n                }\n\n                SECTION(\"with exponent\")\n                {\n                    CHECK(parser_helper(\"0e1\") == json(0e1));\n                    CHECK(parser_helper(\"0E1\") == json(0e1));\n\n                    CHECK(parser_helper(\"10000E-4\") == json(10000e-4));\n                    CHECK(parser_helper(\"10000E-3\") == json(10000e-3));\n                    CHECK(parser_helper(\"10000E-2\") == json(10000e-2));\n                    CHECK(parser_helper(\"10000E-1\") == json(10000e-1));\n                    CHECK(parser_helper(\"10000E0\") == json(10000e0));\n                    CHECK(parser_helper(\"10000E1\") == json(10000e1));\n                    CHECK(parser_helper(\"10000E2\") == json(10000e2));\n                    CHECK(parser_helper(\"10000E3\") == json(10000e3));\n                    CHECK(parser_helper(\"10000E4\") == json(10000e4));\n\n                    CHECK(parser_helper(\"10000e-4\") == json(10000e-4));\n                    CHECK(parser_helper(\"10000e-3\") == json(10000e-3));\n                    CHECK(parser_helper(\"10000e-2\") == json(10000e-2));\n                    CHECK(parser_helper(\"10000e-1\") == json(10000e-1));\n                    CHECK(parser_helper(\"10000e0\") == json(10000e0));\n                    CHECK(parser_helper(\"10000e1\") == json(10000e1));\n                    CHECK(parser_helper(\"10000e2\") == json(10000e2));\n                    CHECK(parser_helper(\"10000e3\") == json(10000e3));\n                    CHECK(parser_helper(\"10000e4\") == json(10000e4));\n\n                    CHECK(parser_helper(\"-0e1\") == json(-0e1));\n                    CHECK(parser_helper(\"-0E1\") == json(-0e1));\n                    CHECK(parser_helper(\"-0E123\") == json(-0e123));\n\n                    // numbers after exponent\n                    CHECK(parser_helper(\"10E0\") == json(10e0));\n                    CHECK(parser_helper(\"10E1\") == json(10e1));\n                    CHECK(parser_helper(\"10E2\") == json(10e2));\n                    CHECK(parser_helper(\"10E3\") == json(10e3));\n                    CHECK(parser_helper(\"10E4\") == json(10e4));\n                    CHECK(parser_helper(\"10E5\") == json(10e5));\n                    CHECK(parser_helper(\"10E6\") == json(10e6));\n                    CHECK(parser_helper(\"10E7\") == json(10e7));\n                    CHECK(parser_helper(\"10E8\") == json(10e8));\n                    CHECK(parser_helper(\"10E9\") == json(10e9));\n                    CHECK(parser_helper(\"10E+0\") == json(10e0));\n                    CHECK(parser_helper(\"10E+1\") == json(10e1));\n                    CHECK(parser_helper(\"10E+2\") == json(10e2));\n                    CHECK(parser_helper(\"10E+3\") == json(10e3));\n                    CHECK(parser_helper(\"10E+4\") == json(10e4));\n                    CHECK(parser_helper(\"10E+5\") == json(10e5));\n                    CHECK(parser_helper(\"10E+6\") == json(10e6));\n                    CHECK(parser_helper(\"10E+7\") == json(10e7));\n                    CHECK(parser_helper(\"10E+8\") == json(10e8));\n                    CHECK(parser_helper(\"10E+9\") == json(10e9));\n                    CHECK(parser_helper(\"10E-1\") == json(10e-1));\n                    CHECK(parser_helper(\"10E-2\") == json(10e-2));\n                    CHECK(parser_helper(\"10E-3\") == json(10e-3));\n                    CHECK(parser_helper(\"10E-4\") == json(10e-4));\n                    CHECK(parser_helper(\"10E-5\") == json(10e-5));\n                    CHECK(parser_helper(\"10E-6\") == json(10e-6));\n                    CHECK(parser_helper(\"10E-7\") == json(10e-7));\n                    CHECK(parser_helper(\"10E-8\") == json(10e-8));\n                    CHECK(parser_helper(\"10E-9\") == json(10e-9));\n                }\n\n                SECTION(\"edge cases\")\n                {\n                    // From RFC8259, Section 6:\n                    // Note that when such software is used, numbers that are\n                    // integers and are in the range [-(2**53)+1, (2**53)-1]\n                    // are interoperable in the sense that implementations will\n                    // agree exactly on their numeric values.\n\n                    // -(2**53)+1\n                    CHECK(parser_helper(\"-9007199254740991\").get<int64_t>() == -9007199254740991);\n                    // (2**53)-1\n                    CHECK(parser_helper(\"9007199254740991\").get<int64_t>() == 9007199254740991);\n                }\n\n                SECTION(\"over the edge cases\")  // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers)\n                {\n                    // While RFC8259, Section 6 specifies a preference for support\n                    // for ranges in range of IEEE 754-2008 binary64 (double precision)\n                    // this does not accommodate 64 bit integers without loss of accuracy.\n                    // As 64 bit integers are now widely used in software, it is desirable\n                    // to expand support to to the full 64 bit (signed and unsigned) range\n                    // i.e. -(2**63) -> (2**64)-1.\n\n                    // -(2**63)    ** Note: compilers see negative literals as negated positive numbers (hence the -1))\n                    CHECK(parser_helper(\"-9223372036854775808\").get<int64_t>() == -9223372036854775807 - 1);\n                    // (2**63)-1\n                    CHECK(parser_helper(\"9223372036854775807\").get<int64_t>() == 9223372036854775807);\n                    // (2**64)-1\n                    CHECK(parser_helper(\"18446744073709551615\").get<uint64_t>() == 18446744073709551615u);\n                }\n            }\n\n            SECTION(\"floating-point\")\n            {\n                SECTION(\"without exponent\")\n                {\n                    CHECK(parser_helper(\"-128.5\") == json(-128.5));\n                    CHECK(parser_helper(\"0.999\") == json(0.999));\n                    CHECK(parser_helper(\"128.5\") == json(128.5));\n                    CHECK(parser_helper(\"-0.0\") == json(-0.0));\n                }\n\n                SECTION(\"with exponent\")\n                {\n                    CHECK(parser_helper(\"-128.5E3\") == json(-128.5E3));\n                    CHECK(parser_helper(\"-128.5E-3\") == json(-128.5E-3));\n                    CHECK(parser_helper(\"-0.0e1\") == json(-0.0e1));\n                    CHECK(parser_helper(\"-0.0E1\") == json(-0.0e1));\n                }\n            }\n\n            SECTION(\"overflow\")\n            {\n                // overflows during parsing yield an exception\n                CHECK_THROWS_AS(parser_helper(\"1.18973e+4932\").empty(), json::out_of_range&);\n                CHECK_THROWS_WITH(parser_helper(\"1.18973e+4932\").empty(),\n                                  \"[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'\");\n            }\n\n            SECTION(\"invalid numbers\")\n            {\n                CHECK_THROWS_AS(parser_helper(\"01\"),      json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"--1\"),     json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"1.\"),      json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"1E\"),      json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"1E-\"),     json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"1.E1\"),    json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-1E\"),     json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0E#\"),    json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0E-#\"),   json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0#\"),     json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0.0:\"),   json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0.0Z\"),   json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0E123:\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0e0-:\"),  json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0e-:\"),   json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"-0f\"),     json::parse_error&);\n\n                // numbers must not begin with \"+\"\n                CHECK_THROWS_AS(parser_helper(\"+1\"), json::parse_error&);\n                CHECK_THROWS_AS(parser_helper(\"+0\"), json::parse_error&);\n\n                CHECK_THROWS_WITH(parser_helper(\"01\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected number literal; expected end of input\");\n                CHECK_THROWS_WITH(parser_helper(\"-01\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - unexpected number literal; expected end of input\");\n                CHECK_THROWS_WITH(parser_helper(\"--1\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'\");\n                CHECK_THROWS_WITH(parser_helper(\"1.\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.'\");\n                CHECK_THROWS_WITH(parser_helper(\"1E\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'\");\n                CHECK_THROWS_WITH(parser_helper(\"1E-\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '1E-'\");\n                CHECK_THROWS_WITH(parser_helper(\"1.E1\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.E'\");\n                CHECK_THROWS_WITH(parser_helper(\"-1E\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'\");\n                CHECK_THROWS_WITH(parser_helper(\"-0E#\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'\");\n                CHECK_THROWS_WITH(parser_helper(\"-0E-#\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0E-#'\");\n                CHECK_THROWS_WITH(parser_helper(\"-0#\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: '-0#'; expected end of input\");\n                CHECK_THROWS_WITH(parser_helper(\"-0.0:\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - unexpected ':'; expected end of input\");\n                CHECK_THROWS_WITH(parser_helper(\"-0.0Z\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: '-0.0Z'; expected end of input\");\n                CHECK_THROWS_WITH(parser_helper(\"-0E123:\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - unexpected ':'; expected end of input\");\n                CHECK_THROWS_WITH(parser_helper(\"-0e0-:\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'; expected end of input\");\n                CHECK_THROWS_WITH(parser_helper(\"-0e-:\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0e-:'\");\n                CHECK_THROWS_WITH(parser_helper(\"-0f\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: '-0f'; expected end of input\");\n            }\n        }\n    }\n\n    SECTION(\"accept\")\n    {\n        SECTION(\"null\")\n        {\n            CHECK(accept_helper(\"null\"));\n        }\n\n        SECTION(\"true\")\n        {\n            CHECK(accept_helper(\"true\"));\n        }\n\n        SECTION(\"false\")\n        {\n            CHECK(accept_helper(\"false\"));\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty array\")\n            {\n                CHECK(accept_helper(\"[]\"));\n                CHECK(accept_helper(\"[ ]\"));\n            }\n\n            SECTION(\"nonempty array\")\n            {\n                CHECK(accept_helper(\"[true, false, null]\"));\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty object\")\n            {\n                CHECK(accept_helper(\"{}\"));\n                CHECK(accept_helper(\"{ }\"));\n            }\n\n            SECTION(\"nonempty object\")\n            {\n                CHECK(accept_helper(\"{\\\"\\\": true, \\\"one\\\": 1, \\\"two\\\": null}\"));\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            // empty string\n            CHECK(accept_helper(\"\\\"\\\"\"));\n\n            SECTION(\"errors\")\n            {\n                // error: tab in string\n                CHECK(accept_helper(\"\\\"\\t\\\"\") == false);\n                // error: newline in string\n                CHECK(accept_helper(\"\\\"\\n\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\r\\\"\") == false);\n                // error: backspace in string\n                CHECK(accept_helper(\"\\\"\\b\\\"\") == false);\n                // improve code coverage\n                CHECK(accept_helper(\"\\uFF01\") == false);\n                CHECK(accept_helper(\"[-4:1,]\") == false);\n                // unescaped control characters\n                CHECK(accept_helper(\"\\\"\\x00\\\"\") == false); // NOLINT(bugprone-string-literal-with-embedded-nul)\n                CHECK(accept_helper(\"\\\"\\x01\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x02\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x03\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x04\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x05\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x06\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x07\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x08\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x09\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x0a\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x0b\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x0c\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x0d\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x0e\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x0f\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x10\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x11\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x12\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x13\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x14\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x15\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x16\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x17\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x18\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x19\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x1a\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x1b\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x1c\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x1d\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x1e\\\"\") == false);\n                CHECK(accept_helper(\"\\\"\\x1f\\\"\") == false);\n            }\n\n            SECTION(\"escaped\")\n            {\n                // quotation mark \"\\\"\"\n                auto r1 = R\"(\"\\\"\")\"_json;\n                CHECK(accept_helper(\"\\\"\\\\\\\"\\\"\"));\n                // reverse solidus \"\\\\\"\n                auto r2 = R\"(\"\\\\\")\"_json;\n                CHECK(accept_helper(\"\\\"\\\\\\\\\\\"\"));\n                // solidus\n                CHECK(accept_helper(\"\\\"\\\\/\\\"\"));\n                // backspace\n                CHECK(accept_helper(\"\\\"\\\\b\\\"\"));\n                // formfeed\n                CHECK(accept_helper(\"\\\"\\\\f\\\"\"));\n                // newline\n                CHECK(accept_helper(\"\\\"\\\\n\\\"\"));\n                // carriage return\n                CHECK(accept_helper(\"\\\"\\\\r\\\"\"));\n                // horizontal tab\n                CHECK(accept_helper(\"\\\"\\\\t\\\"\"));\n\n                CHECK(accept_helper(\"\\\"\\\\u0001\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u000a\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u00b0\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u0c00\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\ud000\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u000E\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u00F0\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u0100\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u2000\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\uFFFF\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\u20AC\\\"\"));\n                CHECK(accept_helper(\"\\\"€\\\"\"));\n                CHECK(accept_helper(\"\\\"🎈\\\"\"));\n\n                CHECK(accept_helper(\"\\\"\\\\ud80c\\\\udc60\\\"\"));\n                CHECK(accept_helper(\"\\\"\\\\ud83c\\\\udf1e\\\"\"));\n            }\n        }\n\n        SECTION(\"number\")\n        {\n            SECTION(\"integers\")\n            {\n                SECTION(\"without exponent\")\n                {\n                    CHECK(accept_helper(\"-128\"));\n                    CHECK(accept_helper(\"-0\"));\n                    CHECK(accept_helper(\"0\"));\n                    CHECK(accept_helper(\"128\"));\n                }\n\n                SECTION(\"with exponent\")\n                {\n                    CHECK(accept_helper(\"0e1\"));\n                    CHECK(accept_helper(\"0E1\"));\n\n                    CHECK(accept_helper(\"10000E-4\"));\n                    CHECK(accept_helper(\"10000E-3\"));\n                    CHECK(accept_helper(\"10000E-2\"));\n                    CHECK(accept_helper(\"10000E-1\"));\n                    CHECK(accept_helper(\"10000E0\"));\n                    CHECK(accept_helper(\"10000E1\"));\n                    CHECK(accept_helper(\"10000E2\"));\n                    CHECK(accept_helper(\"10000E3\"));\n                    CHECK(accept_helper(\"10000E4\"));\n\n                    CHECK(accept_helper(\"10000e-4\"));\n                    CHECK(accept_helper(\"10000e-3\"));\n                    CHECK(accept_helper(\"10000e-2\"));\n                    CHECK(accept_helper(\"10000e-1\"));\n                    CHECK(accept_helper(\"10000e0\"));\n                    CHECK(accept_helper(\"10000e1\"));\n                    CHECK(accept_helper(\"10000e2\"));\n                    CHECK(accept_helper(\"10000e3\"));\n                    CHECK(accept_helper(\"10000e4\"));\n\n                    CHECK(accept_helper(\"-0e1\"));\n                    CHECK(accept_helper(\"-0E1\"));\n                    CHECK(accept_helper(\"-0E123\"));\n                }\n\n                SECTION(\"edge cases\")\n                {\n                    // From RFC8259, Section 6:\n                    // Note that when such software is used, numbers that are\n                    // integers and are in the range [-(2**53)+1, (2**53)-1]\n                    // are interoperable in the sense that implementations will\n                    // agree exactly on their numeric values.\n\n                    // -(2**53)+1\n                    CHECK(accept_helper(\"-9007199254740991\"));\n                    // (2**53)-1\n                    CHECK(accept_helper(\"9007199254740991\"));\n                }\n\n                SECTION(\"over the edge cases\")  // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers)\n                {\n                    // While RFC8259, Section 6 specifies a preference for support\n                    // for ranges in range of IEEE 754-2008 binary64 (double precision)\n                    // this does not accommodate 64 bit integers without loss of accuracy.\n                    // As 64 bit integers are now widely used in software, it is desirable\n                    // to expand support to to the full 64 bit (signed and unsigned) range\n                    // i.e. -(2**63) -> (2**64)-1.\n\n                    // -(2**63)    ** Note: compilers see negative literals as negated positive numbers (hence the -1))\n                    CHECK(accept_helper(\"-9223372036854775808\"));\n                    // (2**63)-1\n                    CHECK(accept_helper(\"9223372036854775807\"));\n                    // (2**64)-1\n                    CHECK(accept_helper(\"18446744073709551615\"));\n                }\n            }\n\n            SECTION(\"floating-point\")\n            {\n                SECTION(\"without exponent\")\n                {\n                    CHECK(accept_helper(\"-128.5\"));\n                    CHECK(accept_helper(\"0.999\"));\n                    CHECK(accept_helper(\"128.5\"));\n                    CHECK(accept_helper(\"-0.0\"));\n                }\n\n                SECTION(\"with exponent\")\n                {\n                    CHECK(accept_helper(\"-128.5E3\"));\n                    CHECK(accept_helper(\"-128.5E-3\"));\n                    CHECK(accept_helper(\"-0.0e1\"));\n                    CHECK(accept_helper(\"-0.0E1\"));\n                }\n            }\n\n            SECTION(\"overflow\")\n            {\n                // overflows during parsing\n                CHECK(!accept_helper(\"1.18973e+4932\"));\n            }\n\n            SECTION(\"invalid numbers\")\n            {\n                CHECK(accept_helper(\"01\") == false);\n                CHECK(accept_helper(\"--1\") == false);\n                CHECK(accept_helper(\"1.\") == false);\n                CHECK(accept_helper(\"1E\") == false);\n                CHECK(accept_helper(\"1E-\") == false);\n                CHECK(accept_helper(\"1.E1\") == false);\n                CHECK(accept_helper(\"-1E\") == false);\n                CHECK(accept_helper(\"-0E#\") == false);\n                CHECK(accept_helper(\"-0E-#\") == false);\n                CHECK(accept_helper(\"-0#\") == false);\n                CHECK(accept_helper(\"-0.0:\") == false);\n                CHECK(accept_helper(\"-0.0Z\") == false);\n                CHECK(accept_helper(\"-0E123:\") == false);\n                CHECK(accept_helper(\"-0e0-:\") == false);\n                CHECK(accept_helper(\"-0e-:\") == false);\n                CHECK(accept_helper(\"-0f\") == false);\n\n                // numbers must not begin with \"+\"\n                CHECK(accept_helper(\"+1\") == false);\n                CHECK(accept_helper(\"+0\") == false);\n            }\n        }\n    }\n\n    SECTION(\"parse errors\")\n    {\n        // unexpected end of number\n        CHECK_THROWS_AS(parser_helper(\"0.\"),  json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"-\"),   json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"--\"),  json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"-0.\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"-.\"),  json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"-:\"),  json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"0.:\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"e.\"),  json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"1e.\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"1e/\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"1e:\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"1E.\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"1E/\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"1E:\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"0.\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.'\");\n        CHECK_THROWS_WITH(parser_helper(\"-\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-'\");\n        CHECK_THROWS_WITH(parser_helper(\"--\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'\");\n        CHECK_THROWS_WITH(parser_helper(\"-0.\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after '.'; last read: '-0.'\");\n        CHECK_THROWS_WITH(parser_helper(\"-.\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-.'\");\n        CHECK_THROWS_WITH(parser_helper(\"-:\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'\");\n        CHECK_THROWS_WITH(parser_helper(\"0.:\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.:'\");\n        CHECK_THROWS_WITH(parser_helper(\"e.\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'e'\");\n        CHECK_THROWS_WITH(parser_helper(\"1e.\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'\");\n        CHECK_THROWS_WITH(parser_helper(\"1e/\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'\");\n        CHECK_THROWS_WITH(parser_helper(\"1e:\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'\");\n        CHECK_THROWS_WITH(parser_helper(\"1E.\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'\");\n        CHECK_THROWS_WITH(parser_helper(\"1E/\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'\");\n        CHECK_THROWS_WITH(parser_helper(\"1E:\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'\");\n\n        // unexpected end of null\n        CHECK_THROWS_AS(parser_helper(\"n\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"nu\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"nul\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"nulk\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"nulm\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"n\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'n'\");\n        CHECK_THROWS_WITH(parser_helper(\"nu\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'nu'\");\n        CHECK_THROWS_WITH(parser_helper(\"nul\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nul'\");\n        CHECK_THROWS_WITH(parser_helper(\"nulk\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulk'\");\n        CHECK_THROWS_WITH(parser_helper(\"nulm\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulm'\");\n\n        // unexpected end of true\n        CHECK_THROWS_AS(parser_helper(\"t\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"tr\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"tru\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"trud\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"truf\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"t\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 't'\");\n        CHECK_THROWS_WITH(parser_helper(\"tr\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'tr'\");\n        CHECK_THROWS_WITH(parser_helper(\"tru\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'tru'\");\n        CHECK_THROWS_WITH(parser_helper(\"trud\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'trud'\");\n        CHECK_THROWS_WITH(parser_helper(\"truf\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'truf'\");\n\n        // unexpected end of false\n        CHECK_THROWS_AS(parser_helper(\"f\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"fa\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"fal\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"fals\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"falsd\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"falsf\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"f\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'f'\");\n        CHECK_THROWS_WITH(parser_helper(\"fa\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'fa'\");\n        CHECK_THROWS_WITH(parser_helper(\"fal\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'fal'\");\n        CHECK_THROWS_WITH(parser_helper(\"fals\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'fals'\");\n        CHECK_THROWS_WITH(parser_helper(\"falsd\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsd'\");\n        CHECK_THROWS_WITH(parser_helper(\"falsf\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsf'\");\n\n        // missing/unexpected end of array\n        CHECK_THROWS_AS(parser_helper(\"[\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"[1\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"[1,\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"[1,]\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"]\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"[\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        CHECK_THROWS_WITH(parser_helper(\"[1\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing array - unexpected end of input; expected ']'\");\n        CHECK_THROWS_WITH(parser_helper(\"[1,\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        CHECK_THROWS_WITH(parser_helper(\"[1,]\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\");\n        CHECK_THROWS_WITH(parser_helper(\"]\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\");\n\n        // missing/unexpected end of object\n        CHECK_THROWS_AS(parser_helper(\"{\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"{\\\"foo\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"{\\\"foo\\\":\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"{\\\"foo\\\":}\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"{\\\"foo\\\":1,}\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"}\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"{\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected end of input; expected string literal\");\n        CHECK_THROWS_WITH(parser_helper(\"{\\\"foo\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing object separator - unexpected end of input; expected ':'\");\n        CHECK_THROWS_WITH(parser_helper(\"{\\\"foo\\\":\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        CHECK_THROWS_WITH(parser_helper(\"{\\\"foo\\\":}\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal\");\n        CHECK_THROWS_WITH(parser_helper(\"{\\\"foo\\\":1,}\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 10: syntax error while parsing object key - unexpected '}'; expected string literal\");\n        CHECK_THROWS_WITH(parser_helper(\"}\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal\");\n\n        // missing/unexpected end of string\n        CHECK_THROWS_AS(parser_helper(\"\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u0\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u01\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u012\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u0\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u01\"), json::parse_error&);\n        CHECK_THROWS_AS(parser_helper(\"\\\"\\\\u012\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\\\"'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: missing closing quote; last read: '\\\"\\\\\\\"'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u\\\"'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u0\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u0\\\"'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u01\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u01\\\"'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u012\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u012\\\"'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u0\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u0'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u01\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u01'\");\n        CHECK_THROWS_WITH(parser_helper(\"\\\"\\\\u012\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\u012'\");\n\n        // invalid escapes\n        for (int c = 1; c < 128; ++c)\n        {\n            auto s = std::string(\"\\\"\\\\\") + std::string(1, static_cast<char>(c)) + \"\\\"\";\n\n            switch (c)\n            {\n                // valid escapes\n                case ('\"'):\n                case ('\\\\'):\n                case ('/'):\n                case ('b'):\n                case ('f'):\n                case ('n'):\n                case ('r'):\n                case ('t'):\n                {\n                    CHECK_NOTHROW(parser_helper(s));\n                    break;\n                }\n\n                // \\u must be followed with four numbers, so we skip it here\n                case ('u'):\n                {\n                    break;\n                }\n\n                // any other combination of backslash and character is invalid\n                default:\n                {\n                    CHECK_THROWS_AS(parser_helper(s), json::parse_error&);\n                    // only check error message if c is not a control character\n                    if (c > 0x1f)\n                    {\n                        CHECK_THROWS_WITH_STD_STR(parser_helper(s),\n                                                  \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid string: forbidden character after backslash; last read: '\\\"\\\\\" + std::string(1, static_cast<char>(c)) + \"'\");\n                    }\n                    break;\n                }\n            }\n        }\n\n        // invalid \\uxxxx escapes\n        {\n            // check whether character is a valid hex character\n            const auto valid = [](int c)\n            {\n                switch (c)\n                {\n                    case ('0'):\n                    case ('1'):\n                    case ('2'):\n                    case ('3'):\n                    case ('4'):\n                    case ('5'):\n                    case ('6'):\n                    case ('7'):\n                    case ('8'):\n                    case ('9'):\n                    case ('a'):\n                    case ('b'):\n                    case ('c'):\n                    case ('d'):\n                    case ('e'):\n                    case ('f'):\n                    case ('A'):\n                    case ('B'):\n                    case ('C'):\n                    case ('D'):\n                    case ('E'):\n                    case ('F'):\n                    {\n                        return true;\n                    }\n\n                    default:\n                    {\n                        return false;\n                    }\n                }\n            };\n\n            for (int c = 1; c < 128; ++c)\n            {\n                std::string s = \"\\\"\\\\u\";\n\n                // create a string with the iterated character at each position\n                auto s1 = s + \"000\" + std::string(1, static_cast<char>(c)) + \"\\\"\";\n                auto s2 = s + \"00\" + std::string(1, static_cast<char>(c)) + \"0\\\"\";\n                auto s3 = s + \"0\" + std::string(1, static_cast<char>(c)) + \"00\\\"\";\n                auto s4 = s + std::string(1, static_cast<char>(c)) + \"000\\\"\";\n\n                if (valid(c))\n                {\n                    CAPTURE(s1)\n                    CHECK_NOTHROW(parser_helper(s1));\n                    CAPTURE(s2)\n                    CHECK_NOTHROW(parser_helper(s2));\n                    CAPTURE(s3)\n                    CHECK_NOTHROW(parser_helper(s3));\n                    CAPTURE(s4)\n                    CHECK_NOTHROW(parser_helper(s4));\n                }\n                else\n                {\n                    CAPTURE(s1)\n                    CHECK_THROWS_AS(parser_helper(s1), json::parse_error&);\n                    // only check error message if c is not a control character\n                    if (c > 0x1f)\n                    {\n                        CHECK_THROWS_WITH_STD_STR(parser_helper(s1),\n                                                  \"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\" + s1.substr(0, 7) + \"'\");\n                    }\n\n                    CAPTURE(s2)\n                    CHECK_THROWS_AS(parser_helper(s2), json::parse_error&);\n                    // only check error message if c is not a control character\n                    if (c > 0x1f)\n                    {\n                        CHECK_THROWS_WITH_STD_STR(parser_helper(s2),\n                                                  \"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\" + s2.substr(0, 6) + \"'\");\n                    }\n\n                    CAPTURE(s3)\n                    CHECK_THROWS_AS(parser_helper(s3), json::parse_error&);\n                    // only check error message if c is not a control character\n                    if (c > 0x1f)\n                    {\n                        CHECK_THROWS_WITH_STD_STR(parser_helper(s3),\n                                                  \"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\" + s3.substr(0, 5) + \"'\");\n                    }\n\n                    CAPTURE(s4)\n                    CHECK_THROWS_AS(parser_helper(s4), json::parse_error&);\n                    // only check error message if c is not a control character\n                    if (c > 0x1f)\n                    {\n                        CHECK_THROWS_WITH_STD_STR(parser_helper(s4),\n                                                  \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\" + s4.substr(0, 4) + \"'\");\n                    }\n                }\n            }\n        }\n\n        json _;\n\n        // missing part of a surrogate pair\n        CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD80C\\\"\"), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD80C\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD80C\\\"'\");\n        // invalid surrogate pair\n        CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD80C\\\\uD80C\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD80C\\\\u0000\\\"\"), json::parse_error&);\n        CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD80C\\\\uFFFF\\\"\"), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD80C\\\\uD80C\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD80C\\\\uD80C'\");\n        CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD80C\\\\u0000\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD80C\\\\u0000'\");\n        CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD80C\\\\uFFFF\\\"\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD80C\\\\uFFFF'\");\n    }\n\n    SECTION(\"parse errors (accept)\")\n    {\n        // unexpected end of number\n        CHECK(accept_helper(\"0.\") == false);\n        CHECK(accept_helper(\"-\") == false);\n        CHECK(accept_helper(\"--\") == false);\n        CHECK(accept_helper(\"-0.\") == false);\n        CHECK(accept_helper(\"-.\") == false);\n        CHECK(accept_helper(\"-:\") == false);\n        CHECK(accept_helper(\"0.:\") == false);\n        CHECK(accept_helper(\"e.\") == false);\n        CHECK(accept_helper(\"1e.\") == false);\n        CHECK(accept_helper(\"1e/\") == false);\n        CHECK(accept_helper(\"1e:\") == false);\n        CHECK(accept_helper(\"1E.\") == false);\n        CHECK(accept_helper(\"1E/\") == false);\n        CHECK(accept_helper(\"1E:\") == false);\n\n        // unexpected end of null\n        CHECK(accept_helper(\"n\") == false);\n        CHECK(accept_helper(\"nu\") == false);\n        CHECK(accept_helper(\"nul\") == false);\n\n        // unexpected end of true\n        CHECK(accept_helper(\"t\") == false);\n        CHECK(accept_helper(\"tr\") == false);\n        CHECK(accept_helper(\"tru\") == false);\n\n        // unexpected end of false\n        CHECK(accept_helper(\"f\") == false);\n        CHECK(accept_helper(\"fa\") == false);\n        CHECK(accept_helper(\"fal\") == false);\n        CHECK(accept_helper(\"fals\") == false);\n\n        // missing/unexpected end of array\n        CHECK(accept_helper(\"[\") == false);\n        CHECK(accept_helper(\"[1\") == false);\n        CHECK(accept_helper(\"[1,\") == false);\n        CHECK(accept_helper(\"[1,]\") == false);\n        CHECK(accept_helper(\"]\") == false);\n\n        // missing/unexpected end of object\n        CHECK(accept_helper(\"{\") == false);\n        CHECK(accept_helper(\"{\\\"foo\\\"\") == false);\n        CHECK(accept_helper(\"{\\\"foo\\\":\") == false);\n        CHECK(accept_helper(\"{\\\"foo\\\":}\") == false);\n        CHECK(accept_helper(\"{\\\"foo\\\":1,}\") == false);\n        CHECK(accept_helper(\"}\") == false);\n\n        // missing/unexpected end of string\n        CHECK(accept_helper(\"\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u0\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u01\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u012\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u0\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u01\") == false);\n        CHECK(accept_helper(\"\\\"\\\\u012\") == false);\n\n        // unget of newline\n        CHECK(parser_helper(\"\\n123\\n\") == 123);\n\n        // invalid escapes\n        for (int c = 1; c < 128; ++c)\n        {\n            auto s = std::string(\"\\\"\\\\\") + std::string(1, static_cast<char>(c)) + \"\\\"\";\n\n            switch (c)\n            {\n                // valid escapes\n                case ('\"'):\n                case ('\\\\'):\n                case ('/'):\n                case ('b'):\n                case ('f'):\n                case ('n'):\n                case ('r'):\n                case ('t'):\n                {\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept());\n                    break;\n                }\n\n                // \\u must be followed with four numbers, so we skip it here\n                case ('u'):\n                {\n                    break;\n                }\n\n                // any other combination of backslash and character is invalid\n                default:\n                {\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept() == false);\n                    break;\n                }\n            }\n        }\n\n        // invalid \\uxxxx escapes\n        {\n            // check whether character is a valid hex character\n            const auto valid = [](int c)\n            {\n                switch (c)\n                {\n                    case ('0'):\n                    case ('1'):\n                    case ('2'):\n                    case ('3'):\n                    case ('4'):\n                    case ('5'):\n                    case ('6'):\n                    case ('7'):\n                    case ('8'):\n                    case ('9'):\n                    case ('a'):\n                    case ('b'):\n                    case ('c'):\n                    case ('d'):\n                    case ('e'):\n                    case ('f'):\n                    case ('A'):\n                    case ('B'):\n                    case ('C'):\n                    case ('D'):\n                    case ('E'):\n                    case ('F'):\n                    {\n                        return true;\n                    }\n\n                    default:\n                    {\n                        return false;\n                    }\n                }\n            };\n\n            for (int c = 1; c < 128; ++c)\n            {\n                std::string s = \"\\\"\\\\u\";\n\n                // create a string with the iterated character at each position\n                const auto s1 = s + \"000\" + std::string(1, static_cast<char>(c)) + \"\\\"\";\n                const auto s2 = s + \"00\" + std::string(1, static_cast<char>(c)) + \"0\\\"\";\n                const auto s3 = s + \"0\" + std::string(1, static_cast<char>(c)) + \"00\\\"\";\n                const auto s4 = s + std::string(1, static_cast<char>(c)) + \"000\\\"\";\n\n                if (valid(c))\n                {\n                    CAPTURE(s1)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept());\n                    CAPTURE(s2)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept());\n                    CAPTURE(s3)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept());\n                    CAPTURE(s4)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept());\n                }\n                else\n                {\n                    CAPTURE(s1)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept() == false);\n\n                    CAPTURE(s2)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept() == false);\n\n                    CAPTURE(s3)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept() == false);\n\n                    CAPTURE(s4)\n                    CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept() == false);\n                }\n            }\n        }\n\n        // missing part of a surrogate pair\n        CHECK(accept_helper(\"\\\"\\\\uD80C\\\"\") == false);\n        // invalid surrogate pair\n        CHECK(accept_helper(\"\\\"\\\\uD80C\\\\uD80C\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\uD80C\\\\u0000\\\"\") == false);\n        CHECK(accept_helper(\"\\\"\\\\uD80C\\\\uFFFF\\\"\") == false);\n    }\n\n    SECTION(\"tests found by mutate++\")\n    {\n        // test case to make sure no comma precedes the first key\n        CHECK_THROWS_AS(parser_helper(\"{,\\\"key\\\": false}\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"{,\\\"key\\\": false}\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected ','; expected string literal\");\n        // test case to make sure an object is properly closed\n        CHECK_THROWS_AS(parser_helper(\"[{\\\"key\\\": false true]\"), json::parse_error&);\n        CHECK_THROWS_WITH(parser_helper(\"[{\\\"key\\\": false true]\"),\n                          \"[json.exception.parse_error.101] parse error at line 1, column 19: syntax error while parsing object - unexpected true literal; expected '}'\");\n\n        // test case to make sure the callback is properly evaluated after reading a key\n        {\n            json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t event, json& /*unused*/)\n            {\n                return event != json::parse_event_t::key;\n            };\n\n            json x = json::parse(\"{\\\"key\\\": false}\", cb);\n            CHECK(x == json::object());\n        }\n    }\n\n    SECTION(\"callback function\")\n    {\n        const auto* s_object = R\"(\n            {\n                \"foo\": 2,\n                \"bar\": {\n                    \"baz\": 1\n                }\n            }\n        )\";\n\n        const auto* s_array = R\"(\n            [1,2,[3,4,5],4,5]\n        )\";\n\n        const auto* structured_array = R\"(\n            [\n                1,\n                {\n                     \"foo\": \"bar\"\n                },\n                {\n                     \"qux\": \"baz\"\n                }\n            ]\n        )\";\n\n        SECTION(\"filter nothing\")\n        {\n            json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)\n            {\n                return true;\n            });\n\n            CHECK (j_object == json({{\"foo\", 2}, {\"bar\", {{\"baz\", 1}}}}));\n\n            json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)\n            {\n                return true;\n            });\n\n            CHECK (j_array == json({1, 2, {3, 4, 5}, 4, 5}));\n        }\n\n        SECTION(\"filter everything\")\n        {\n            json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)\n            {\n                return false;\n            });\n\n            // the top-level object will be discarded, leaving a null\n            CHECK (j_object.is_null());\n\n            json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)\n            {\n                return false;\n            });\n\n            // the top-level array will be discarded, leaving a null\n            CHECK (j_array.is_null());\n        }\n\n        SECTION(\"filter specific element\")\n        {\n            json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j)\n            {\n                // filter all number(2) elements\n                return j != json(2);\n            });\n\n            CHECK (j_object == json({{\"bar\", {{\"baz\", 1}}}}));\n\n            json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j)\n            {\n                return j != json(2);\n            });\n\n            CHECK (j_array == json({1, {3, 4, 5}, 4, 5}));\n        }\n\n        SECTION(\"filter object in array\")\n        {\n            json j_filtered1 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json & parsed)\n            {\n                return !(e == json::parse_event_t::object_end && parsed.contains(\"foo\"));\n            });\n\n            // the specified object will be discarded, and removed.\n            CHECK (j_filtered1.size() == 2);\n            CHECK (j_filtered1 == json({1, {{\"qux\", \"baz\"}}}));\n\n            json j_filtered2 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json& /*parsed*/)\n            {\n                return e != json::parse_event_t::object_end;\n            });\n\n            // removed all objects in array.\n            CHECK (j_filtered2.size() == 1);\n            CHECK (j_filtered2 == json({1}));\n        }\n\n        SECTION(\"filter specific events\")\n        {\n            SECTION(\"first closing event\")\n            {\n                {\n                    json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)\n                    {\n                        static bool first = true;\n                        if (e == json::parse_event_t::object_end && first)\n                        {\n                            first = false;\n                            return false;\n                        }\n\n                        return true;\n                    });\n\n                    // the first completed object will be discarded\n                    CHECK (j_object == json({{\"foo\", 2}}));\n                }\n\n                {\n                    json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)\n                    {\n                        static bool first = true;\n                        if (e == json::parse_event_t::array_end && first)\n                        {\n                            first = false;\n                            return false;\n                        }\n\n                        return true;\n                    });\n\n                    // the first completed array will be discarded\n                    CHECK (j_array == json({1, 2, 4, 5}));\n                }\n            }\n        }\n\n        SECTION(\"special cases\")\n        {\n            // the following test cases cover the situation in which an empty\n            // object and array is discarded only after the closing character\n            // has been read\n\n            json j_empty_object = json::parse(\"{}\", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)\n            {\n                return e != json::parse_event_t::object_end;\n            });\n            CHECK(j_empty_object == json());\n\n            json j_empty_array = json::parse(\"[]\", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/)\n            {\n                return e != json::parse_event_t::array_end;\n            });\n            CHECK(j_empty_array == json());\n        }\n    }\n\n    SECTION(\"constructing from contiguous containers\")\n    {\n        SECTION(\"from std::vector\")\n        {\n            std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};\n            json j;\n            json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);\n            CHECK(j == json(true));\n        }\n\n        SECTION(\"from std::array\")\n        {\n            std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };\n            json j;\n            json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);\n            CHECK(j == json(true));\n        }\n\n        SECTION(\"from array\")\n        {\n            uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n            json j;\n            json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);\n            CHECK(j == json(true));\n        }\n\n        SECTION(\"from char literal\")\n        {\n            CHECK(parser_helper(\"true\") == json(true));\n        }\n\n        SECTION(\"from std::string\")\n        {\n            std::string v = {'t', 'r', 'u', 'e'};\n            json j;\n            json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);\n            CHECK(j == json(true));\n        }\n\n        SECTION(\"from std::initializer_list\")\n        {\n            std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};\n            json j;\n            json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);\n            CHECK(j == json(true));\n        }\n\n        SECTION(\"from std::valarray\")\n        {\n            std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};\n            json j;\n            json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);\n            CHECK(j == json(true));\n        }\n    }\n\n    SECTION(\"improve test coverage\")\n    {\n        SECTION(\"parser with callback\")\n        {\n            json::parser_callback_t cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/)\n            {\n                return true;\n            };\n\n            CHECK(json::parse(\"{\\\"foo\\\": true:\", cb, false).is_discarded());\n\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(\"{\\\"foo\\\": true:\", cb), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(\"{\\\"foo\\\": true:\", cb),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing object - unexpected ':'; expected '}'\");\n\n            CHECK_THROWS_AS(_ = json::parse(\"1.18973e+4932\", cb), json::out_of_range&);\n            CHECK_THROWS_WITH(_ = json::parse(\"1.18973e+4932\", cb),\n                              \"[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'\");\n        }\n\n        SECTION(\"SAX parser\")\n        {\n            SECTION(\"} without value\")\n            {\n                SaxCountdown s(1);\n                CHECK(json::sax_parse(\"{}\", &s) == false);\n            }\n\n            SECTION(\"} with value\")\n            {\n                SaxCountdown s(3);\n                CHECK(json::sax_parse(\"{\\\"k1\\\": true}\", &s) == false);\n            }\n\n            SECTION(\"second key\")\n            {\n                SaxCountdown s(3);\n                CHECK(json::sax_parse(\"{\\\"k1\\\": true, \\\"k2\\\": false}\", &s) == false);\n            }\n\n            SECTION(\"] without value\")\n            {\n                SaxCountdown s(1);\n                CHECK(json::sax_parse(\"[]\", &s) == false);\n            }\n\n            SECTION(\"] with value\")\n            {\n                SaxCountdown s(2);\n                CHECK(json::sax_parse(\"[1]\", &s) == false);\n            }\n\n            SECTION(\"float\")\n            {\n                SaxCountdown s(0);\n                CHECK(json::sax_parse(\"3.14\", &s) == false);\n            }\n\n            SECTION(\"false\")\n            {\n                SaxCountdown s(0);\n                CHECK(json::sax_parse(\"false\", &s) == false);\n            }\n\n            SECTION(\"null\")\n            {\n                SaxCountdown s(0);\n                CHECK(json::sax_parse(\"null\", &s) == false);\n            }\n\n            SECTION(\"true\")\n            {\n                SaxCountdown s(0);\n                CHECK(json::sax_parse(\"true\", &s) == false);\n            }\n\n            SECTION(\"unsigned\")\n            {\n                SaxCountdown s(0);\n                CHECK(json::sax_parse(\"12\", &s) == false);\n            }\n\n            SECTION(\"integer\")\n            {\n                SaxCountdown s(0);\n                CHECK(json::sax_parse(\"-12\", &s) == false);\n            }\n\n            SECTION(\"string\")\n            {\n                SaxCountdown s(0);\n                CHECK(json::sax_parse(\"\\\"foo\\\"\", &s) == false);\n            }\n        }\n    }\n\n    SECTION(\"error messages for comments\")\n    {\n        json _;\n        CHECK_THROWS_WITH_AS(_ = json::parse(\"/a\", nullptr, true, true), \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'\", json::parse_error);\n        CHECK_THROWS_WITH_AS(_ = json::parse(\"/*\", nullptr, true, true), \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'\", json::parse_error);\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-comparison.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nnamespace\n{\n// helper function to check std::less<json::value_t>\n// see https://en.cppreference.com/w/cpp/utility/functional/less\ntemplate <typename A, typename B, typename U = std::less<json::value_t>>\nbool f(A a, B b, U u = U())\n{\n    return u(a, b);\n}\n} // namespace\n\nTEST_CASE(\"lexicographical comparison operators\")\n{\n    SECTION(\"types\")\n    {\n        std::vector<json::value_t> j_types =\n        {\n            json::value_t::null,\n            json::value_t::boolean,\n            json::value_t::number_integer,\n            json::value_t::number_unsigned,\n            json::value_t::number_float,\n            json::value_t::object,\n            json::value_t::array,\n            json::value_t::string,\n            json::value_t::binary\n        };\n\n        SECTION(\"comparison: less\")\n        {\n            std::vector<std::vector<bool>> expected =\n            {\n                {false, true, true, true, true, true, true, true, true},\n                {false, false, true, true, true, true, true, true, true},\n                {false, false, false, false, false, true, true, true, true},\n                {false, false, false, false, false, true, true, true, true},\n                {false, false, false, false, false, true, true, true, true},\n                {false, false, false, false, false, false, true, true, true},\n                {false, false, false, false, false, false, false, true, true},\n                {false, false, false, false, false, false, false, false, true},\n                {false, false, false, false, false, false, false, false, false}\n            };\n\n            for (size_t i = 0; i < j_types.size(); ++i)\n            {\n                for (size_t j = 0; j < j_types.size(); ++j)\n                {\n                    CAPTURE(i)\n                    CAPTURE(j)\n                    // check precomputed values\n                    CHECK(operator<(j_types[i], j_types[j]) == expected[i][j]);\n                    CHECK(f(j_types[i], j_types[j]) == expected[i][j]);\n                }\n            }\n        }\n    }\n\n    SECTION(\"values\")\n    {\n        json j_values =\n        {\n            nullptr, nullptr,\n            -17, 42,\n            8u, 13u,\n            3.14159, 23.42,\n            \"foo\", \"bar\",\n            true, false,\n            {1, 2, 3}, {\"one\", \"two\", \"three\"},\n            {{\"first\", 1}, {\"second\", 2}}, {{\"a\", \"A\"}, {\"b\", {\"B\"}}},\n            json::binary({1, 2, 3}), json::binary({1, 2, 4})\n        };\n\n        SECTION(\"comparison: equal\")\n        {\n            std::vector<std::vector<bool>> expected =\n            {\n                {true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},\n                {true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},\n                {false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},\n                {false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false},\n                {false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false},\n                {false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false},\n                {false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false},\n                {false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false},\n                {false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false},\n                {false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false},\n                {false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false},\n                {false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false},\n                {false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true}\n            };\n\n            for (size_t i = 0; i < j_values.size(); ++i)\n            {\n                for (size_t j = 0; j < j_values.size(); ++j)\n                {\n                    CAPTURE(i)\n                    CAPTURE(j)\n                    CAPTURE(j_values[i])\n                    CAPTURE(j_values[j])\n                    // check precomputed values\n                    CHECK( (j_values[i] == j_values[j]) == expected[i][j] );\n                }\n            }\n\n            // comparison with discarded elements\n            json j_discarded(json::value_t::discarded);\n            for (const auto& v : j_values)\n            {\n                CHECK( (v == j_discarded) == false);\n                CHECK( (j_discarded == v) == false);\n                CHECK( (j_discarded == j_discarded) == false);\n            }\n\n            // compare with null pointer\n            json j_null;\n            CHECK(j_null == nullptr);\n            CHECK(nullptr == j_null);\n        }\n\n        SECTION(\"comparison: not equal\")\n        {\n            for (size_t i = 0; i < j_values.size(); ++i)\n            {\n                for (size_t j = 0; j < j_values.size(); ++j)\n                {\n                    CAPTURE(i)\n                    CAPTURE(j)\n                    // check definition\n                    CHECK( (j_values[i] != j_values[j]) == !(j_values[i] == j_values[j]) );\n                }\n            }\n\n            // compare with null pointer\n            json j_null;\n            CHECK( (j_null != nullptr) == false);\n            CHECK( (nullptr != j_null) == false);\n            CHECK( (j_null != nullptr) == !(j_null == nullptr));\n            CHECK( (nullptr != j_null) == !(nullptr == j_null));\n        }\n\n        SECTION(\"comparison: less\")\n        {\n            std::vector<std::vector<bool>> expected =\n            {\n                {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true},\n                {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true},\n                {false, false, false, true, true, true, true, true, true, true, false, false, true, true, true, true, true, true},\n                {false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, true, true, true},\n                {false, false, false, true, false, true, false, true, true, true, false, false, true, true, true, true, true, true},\n                {false, false, false, true, false, false, false, true, true, true, false, false, true, true, true, true, true, true},\n                {false, false, false, true, true, true, false, true, true, true, false, false, true, true, true, true, true, true},\n                {false, false, false, true, false, false, false, false, true, true, false, false, true, true, true, true, true, true},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true},\n                {false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, true, true},\n                {false, false, true, true, true, true, true, true, true, true, false, false, true, true, true, true, true, true},\n                {false, false, true, true, true, true, true, true, true, true, true, false, true, true, true, true, true, true},\n                {false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, false, true, true},\n                {false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, true, true},\n                {false, false, false, false, false, false, false, false, true, true, false, false, true, true, false, false, true, true},\n                {false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, false, true, true},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true},\n                {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}\n            };\n\n            for (size_t i = 0; i < j_values.size(); ++i)\n            {\n                for (size_t j = 0; j < j_values.size(); ++j)\n                {\n                    CAPTURE(i)\n                    CAPTURE(j)\n                    CAPTURE(j_values[i])\n                    CAPTURE(j_values[j])\n                    // check precomputed values\n                    CHECK( (j_values[i] < j_values[j]) == expected[i][j] );\n                }\n            }\n\n            // comparison with discarded elements\n            json j_discarded(json::value_t::discarded);\n            for (size_t i = 0; i < j_values.size(); ++i)\n            {\n                CAPTURE(i)\n                CHECK( (j_values[i] < j_discarded) == false);\n                CHECK( (j_discarded < j_values[i]) == false);\n                CHECK( (j_discarded < j_discarded) == false);\n            }\n        }\n\n        SECTION(\"comparison: less than or equal equal\")\n        {\n            for (size_t i = 0; i < j_values.size(); ++i)\n            {\n                for (size_t j = 0; j < j_values.size(); ++j)\n                {\n                    CAPTURE(i)\n                    CAPTURE(j)\n                    // check definition\n                    CHECK( (j_values[i] <= j_values[j]) == !(j_values[j] < j_values[i]) );\n                }\n            }\n        }\n\n        SECTION(\"comparison: greater than\")\n        {\n            for (size_t i = 0; i < j_values.size(); ++i)\n            {\n                for (size_t j = 0; j < j_values.size(); ++j)\n                {\n                    CAPTURE(i)\n                    CAPTURE(j)\n                    // check definition\n                    CHECK( (j_values[i] > j_values[j]) == (j_values[j] < j_values[i]) );\n                }\n            }\n        }\n\n        SECTION(\"comparison: greater than or equal\")\n        {\n            for (size_t i = 0; i < j_values.size(); ++i)\n            {\n                for (size_t j = 0; j < j_values.size(); ++j)\n                {\n                    CAPTURE(i)\n                    CAPTURE(j)\n                    // check definition\n                    CHECK( (j_values[i] >= j_values[j]) == !(j_values[i] < j_values[j]) );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-concepts.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"concepts\")\n{\n    SECTION(\"container requirements for json\")\n    {\n        // X: container class: json\n        // T: type of objects: json\n        // a, b: values of type X: json\n\n        // TABLE 96 - Container Requirements\n\n        // X::value_type must return T\n        CHECK((std::is_same<json::value_type, json>::value));\n\n        // X::reference must return lvalue of T\n        CHECK((std::is_same<json::reference, json&>::value));\n\n        // X::const_reference must return const lvalue of T\n        CHECK((std::is_same<json::const_reference, const json&>::value));\n\n        // X::iterator must return iterator whose value_type is T\n        CHECK((std::is_same<json::iterator::value_type, json>::value));\n        // X::iterator must meet the forward iterator requirements\n        CHECK((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::iterator>::iterator_category>::value));\n        // X::iterator must be convertible to X::const_iterator\n        CHECK((std::is_convertible<json::iterator, json::const_iterator>::value));\n\n        // X::const_iterator must return iterator whose value_type is T\n        CHECK((std::is_same<json::const_iterator::value_type, json>::value));\n        // X::const_iterator must meet the forward iterator requirements\n        CHECK((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::const_iterator>::iterator_category>::value));\n\n        // X::difference_type must return a signed integer\n        CHECK((std::is_signed<json::difference_type>::value));\n        // X::difference_type must be identical to X::iterator::difference_type\n        CHECK((std::is_same<json::difference_type, json::iterator::difference_type>::value));\n        // X::difference_type must be identical to X::const_iterator::difference_type\n        CHECK((std::is_same<json::difference_type, json::const_iterator::difference_type>::value));\n\n        // X::size_type must return an unsigned integer\n        CHECK((std::is_unsigned<json::size_type>::value));\n        // X::size_type can represent any non-negative value of X::difference_type\n        CHECK(static_cast<json::size_type>((std::numeric_limits<json::difference_type>::max)()) <=\n              (std::numeric_limits<json::size_type>::max)());\n\n        // the expression \"X u\" has the post-condition \"u.empty()\"\n        {\n            json u;\n            CHECK(u.empty());\n        }\n\n        // the expression \"X()\" has the post-condition \"X().empty()\"\n        CHECK(json().empty());\n    }\n\n    SECTION(\"class json\")\n    {\n        SECTION(\"DefaultConstructible\")\n        {\n            CHECK(std::is_nothrow_default_constructible<json>::value);\n        }\n\n        SECTION(\"MoveConstructible\")\n        {\n            CHECK(std::is_move_constructible<json>::value);\n            CHECK(std::is_nothrow_move_constructible<json>::value);\n        }\n\n        SECTION(\"CopyConstructible\")\n        {\n            CHECK(std::is_copy_constructible<json>::value);\n        }\n\n        SECTION(\"MoveAssignable\")\n        {\n            CHECK(std::is_nothrow_move_assignable<json>::value);\n        }\n\n        SECTION(\"CopyAssignable\")\n        {\n            CHECK(std::is_copy_assignable<json>::value);\n        }\n\n        SECTION(\"Destructible\")\n        {\n            CHECK(std::is_nothrow_destructible<json>::value);\n        }\n\n        SECTION(\"StandardLayoutType\")\n        {\n            CHECK(std::is_standard_layout<json>::value);\n        }\n    }\n\n    SECTION(\"class iterator\")\n    {\n        SECTION(\"CopyConstructible\")\n        {\n            CHECK(std::is_nothrow_copy_constructible<json::iterator>::value);\n            CHECK(std::is_nothrow_copy_constructible<json::const_iterator>::value);\n        }\n\n        SECTION(\"CopyAssignable\")\n        {\n            // STL iterators used by json::iterator don't pass this test in Debug mode\n#if !defined(_MSC_VER) || (_ITERATOR_DEBUG_LEVEL == 0)\n            CHECK(std::is_nothrow_copy_assignable<json::iterator>::value);\n            CHECK(std::is_nothrow_copy_assignable<json::const_iterator>::value);\n#endif\n        }\n\n        SECTION(\"Destructible\")\n        {\n            CHECK(std::is_nothrow_destructible<json::iterator>::value);\n            CHECK(std::is_nothrow_destructible<json::const_iterator>::value);\n        }\n\n        SECTION(\"Swappable\")\n        {\n            {\n                json j {1, 2, 3};\n                json::iterator it1 = j.begin();\n                json::iterator it2 = j.end();\n                swap(it1, it2);\n                CHECK(it1 == j.end());\n                CHECK(it2 == j.begin());\n            }\n            {\n                json j {1, 2, 3};\n                json::const_iterator it1 = j.cbegin();\n                json::const_iterator it2 = j.cend();\n                swap(it1, it2);\n                CHECK(it1 == j.end());\n                CHECK(it2 == j.begin());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-constructor1.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <deque>\n#include <forward_list>\n#include <fstream>\n#include <list>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <valarray>\n\nTEST_CASE(\"constructors\")\n{\n    SECTION(\"create an empty value with a given type\")\n    {\n        SECTION(\"null\")\n        {\n            auto t = json::value_t::null;\n            json j(t);\n            CHECK(j.type() == t);\n        }\n\n        SECTION(\"discarded\")\n        {\n            auto t = json::value_t::discarded;\n            json j(t);\n            CHECK(j.type() == t);\n        }\n\n        SECTION(\"object\")\n        {\n            auto t = json::value_t::object;\n            json j(t);\n            CHECK(j.type() == t);\n        }\n\n        SECTION(\"array\")\n        {\n            auto t = json::value_t::array;\n            json j(t);\n            CHECK(j.type() == t);\n        }\n\n        SECTION(\"boolean\")\n        {\n            auto t = json::value_t::boolean;\n            json j(t);\n            CHECK(j.type() == t);\n            CHECK(j == false);\n        }\n\n        SECTION(\"string\")\n        {\n            auto t = json::value_t::string;\n            json j(t);\n            CHECK(j.type() == t);\n            CHECK(j == \"\");\n        }\n\n        SECTION(\"number_integer\")\n        {\n            auto t = json::value_t::number_integer;\n            json j(t);\n            CHECK(j.type() == t);\n            CHECK(j == 0);\n        }\n\n        SECTION(\"number_unsigned\")\n        {\n            auto t = json::value_t::number_unsigned;\n            json j(t);\n            CHECK(j.type() == t);\n            CHECK(j == 0);\n        }\n\n        SECTION(\"number_float\")\n        {\n            auto t = json::value_t::number_float;\n            json j(t);\n            CHECK(j.type() == t);\n            CHECK(j == 0.0);\n        }\n\n        SECTION(\"binary\")\n        {\n            auto t = json::value_t::binary;\n            json j(t);\n            CHECK(j.type() == t);\n            CHECK(j == json::binary({}));\n        }\n    }\n\n    SECTION(\"create a null object (implicitly)\")\n    {\n        SECTION(\"no parameter\")\n        {\n            json j{};\n            CHECK(j.type() == json::value_t::null);\n        }\n    }\n\n    SECTION(\"create a null object (explicitly)\")\n    {\n        SECTION(\"parameter\")\n        {\n            json j(nullptr);\n            CHECK(j.type() == json::value_t::null);\n        }\n    }\n\n    SECTION(\"create an object (explicit)\")\n    {\n        SECTION(\"empty object\")\n        {\n            json::object_t o;\n            json j(o);\n            CHECK(j.type() == json::value_t::object);\n        }\n\n        SECTION(\"filled object\")\n        {\n            json::object_t o {{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}};\n            json j(o);\n            CHECK(j.type() == json::value_t::object);\n        }\n    }\n\n    SECTION(\"create an object (implicit)\")\n    {\n        // reference object\n        json::object_t o_reference {{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}};\n        json j_reference(o_reference);\n\n        SECTION(\"std::map<json::string_t, json>\")\n        {\n            std::map<json::string_t, json> o {{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}};\n            json j(o);\n            CHECK(j.type() == json::value_t::object);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"std::map<std::string, std::string> #600\")\n        {\n            std::map<std::string, std::string> m;\n            m[\"a\"] = \"b\";\n            m[\"c\"] = \"d\";\n            m[\"e\"] = \"f\";\n\n            json j(m);\n            CHECK((j.get<decltype(m)>() == m));\n        }\n\n        SECTION(\"std::map<const char*, json>\")\n        {\n            std::map<const char*, json> o {{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}};\n            json j(o);\n            CHECK(j.type() == json::value_t::object);\n            CHECK(j == j_reference);\n        }\n\n\n        SECTION(\"std::multimap<json::string_t, json>\")\n        {\n            std::multimap<json::string_t, json> o {{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}};\n            json j(o);\n            CHECK(j.type() == json::value_t::object);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"std::unordered_map<json::string_t, json>\")\n        {\n            std::unordered_map<json::string_t, json> o {{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}};\n            json j(o);\n            CHECK(j.type() == json::value_t::object);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"std::unordered_multimap<json::string_t, json>\")\n        {\n            std::unordered_multimap<json::string_t, json> o {{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}};\n            json j(o);\n            CHECK(j.type() == json::value_t::object);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"associative container literal\")\n        {\n            json j({{\"a\", json(1)}, {\"b\", json(1u)}, {\"c\", json(2.2)}, {\"d\", json(false)}, {\"e\", json(\"string\")}, {\"f\", json()}});\n            CHECK(j.type() == json::value_t::object);\n            CHECK(j == j_reference);\n        }\n    }\n\n    SECTION(\"create an array (explicit)\")\n    {\n        SECTION(\"empty array\")\n        {\n            json::array_t a;\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n        }\n\n        SECTION(\"filled array\")\n        {\n            json::array_t a {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n        }\n    }\n\n    SECTION(\"create an array (implicit)\")\n    {\n        // reference array\n        json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n        json j_reference(a_reference);\n\n        SECTION(\"std::list<json>\")\n        {\n            std::list<json> a {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"std::pair\")\n        {\n            std::pair<float, std::string> p{1.0f, \"string\"};\n            json j(p);\n\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j.get<decltype(p)>() == p);\n            REQUIRE(j.size() == 2);\n            CHECK(j[0] == std::get<0>(p));\n            CHECK(j[1] == std::get<1>(p));\n        }\n\n        SECTION(\"std::pair with discarded values\")\n        {\n            json j{1, 2.0, \"string\"};\n\n            const auto p = j.get<std::pair<int, float>>();\n            CHECK(p.first == j[0]);\n            CHECK(p.second == j[1]);\n        }\n\n        SECTION(\"std::tuple\")\n        {\n            const auto t = std::make_tuple(1.0, std::string{\"string\"}, 42, std::vector<int> {0, 1});\n            json j(t);\n\n            CHECK(j.type() == json::value_t::array);\n            REQUIRE(j.size() == 4);\n            CHECK(j.get<decltype(t)>() == t);\n            CHECK(j[0] == std::get<0>(t));\n            CHECK(j[1] == std::get<1>(t));\n            CHECK(j[2] == std::get<2>(t));\n            CHECK(j[3][0] == 0);\n            CHECK(j[3][1] == 1);\n        }\n\n        SECTION(\"std::tuple with discarded values\")\n        {\n            json j{1, 2.0, \"string\", 42};\n\n            const auto t = j.get<std::tuple<int, float, std::string>>();\n            CHECK(std::get<0>(t) == j[0]);\n            CHECK(std::get<1>(t) == j[1]);\n            CHECK(std::get<2>(t) == j[2]);\n        }\n\n        SECTION(\"std::pair/tuple/array failures\")\n        {\n            json j{1};\n\n            CHECK_THROWS_AS((j.get<std::pair<int, int>>()), json::out_of_range&);\n            CHECK_THROWS_WITH((j.get<std::pair<int, int>>()), \"[json.exception.out_of_range.401] array index 1 is out of range\");\n            CHECK_THROWS_AS((j.get<std::tuple<int, int>>()), json::out_of_range&);\n            CHECK_THROWS_WITH((j.get<std::tuple<int, int>>()), \"[json.exception.out_of_range.401] array index 1 is out of range\");\n            CHECK_THROWS_AS((j.get<std::array<int, 3>>()), json::out_of_range&);\n            CHECK_THROWS_WITH((j.get<std::array<int, 3>>()), \"[json.exception.out_of_range.401] array index 1 is out of range\");\n        }\n\n        SECTION(\"std::forward_list<json>\")\n        {\n            std::forward_list<json> a {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"std::array<json, 6>\")\n        {\n            std::array<json, 6> a {{json(1), json(1u), json(2.2), json(false), json(\"string\"), json()}};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == j_reference);\n\n            const auto a2 = j.get<std::array<json, 6>>();\n            CHECK(a2 == a);\n        }\n\n        SECTION(\"std::valarray<int>\")\n        {\n            std::valarray<int> va = {1, 2, 3, 4, 5};\n            json j(va);\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == json({1, 2, 3, 4, 5}));\n\n            auto jva = j.get<std::valarray<int>>();\n            CHECK(jva.size() == va.size());\n            for (size_t i = 0; i < jva.size(); ++i)\n            {\n                CHECK(va[i] == jva[i]);\n            }\n        }\n\n        SECTION(\"std::valarray<double>\")\n        {\n            std::valarray<double> va = {1.2, 2.3, 3.4, 4.5, 5.6};\n            json j(va);\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == json({1.2, 2.3, 3.4, 4.5, 5.6}));\n\n            auto jva = j.get<std::valarray<double>>();\n            CHECK(jva.size() == va.size());\n            for (size_t i = 0; i < jva.size(); ++i)\n            {\n                CHECK(va[i] == jva[i]);\n            }\n        }\n\n        SECTION(\"std::vector<json>\")\n        {\n            std::vector<json> a {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"std::deque<json>\")\n        {\n            std::deque<json> a {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"std::set<json>\")\n        {\n            std::set<json> a {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n            // we cannot really check for equality here\n        }\n\n        SECTION(\"std::unordered_set<json>\")\n        {\n            std::unordered_set<json> a {json(1), json(1u), json(2.2), json(false), json(\"string\"), json()};\n            json j(a);\n            CHECK(j.type() == json::value_t::array);\n            // we cannot really check for equality here\n        }\n\n        SECTION(\"sequence container literal\")\n        {\n            json j({json(1), json(1u), json(2.2), json(false), json(\"string\"), json()});\n            CHECK(j.type() == json::value_t::array);\n            CHECK(j == j_reference);\n        }\n    }\n\n    SECTION(\"create a string (explicit)\")\n    {\n        SECTION(\"empty string\")\n        {\n            json::string_t s;\n            json j(s);\n            CHECK(j.type() == json::value_t::string);\n        }\n\n        SECTION(\"filled string\")\n        {\n            json::string_t s {\"Hello world\"};\n            json j(s);\n            CHECK(j.type() == json::value_t::string);\n        }\n    }\n\n    SECTION(\"create a string (implicit)\")\n    {\n        // reference string\n        json::string_t s_reference {\"Hello world\"};\n        json j_reference(s_reference);\n\n        SECTION(\"std::string\")\n        {\n            std::string s {\"Hello world\"};\n            json j(s);\n            CHECK(j.type() == json::value_t::string);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"char[]\")\n        {\n            char s[] {\"Hello world\"}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n            json j(s);\n            CHECK(j.type() == json::value_t::string);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"const char*\")\n        {\n            const char* s {\"Hello world\"};\n            json j(s);\n            CHECK(j.type() == json::value_t::string);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"string literal\")\n        {\n            json j(\"Hello world\");\n            CHECK(j.type() == json::value_t::string);\n            CHECK(j == j_reference);\n        }\n    }\n\n    SECTION(\"create a boolean (explicit)\")\n    {\n        SECTION(\"empty boolean\")\n        {\n            json::boolean_t b{};\n            json j(b);\n            CHECK(j.type() == json::value_t::boolean);\n        }\n\n        SECTION(\"filled boolean (true)\")\n        {\n            json j(true);\n            CHECK(j.type() == json::value_t::boolean);\n        }\n\n        SECTION(\"filled boolean (false)\")\n        {\n            json j(false);\n            CHECK(j.type() == json::value_t::boolean);\n        }\n    }\n\n    SECTION(\"create a binary (explicit)\")\n    {\n        SECTION(\"empty binary\")\n        {\n            json::binary_t b{};\n            json j(b);\n            CHECK(j.type() == json::value_t::binary);\n        }\n\n        SECTION(\"filled binary\")\n        {\n            json::binary_t b({1, 2, 3});\n            json j(b);\n            CHECK(j.type() == json::value_t::binary);\n        }\n    }\n\n    SECTION(\"create an integer number (explicit)\")\n    {\n        SECTION(\"uninitialized value\")\n        {\n            json::number_integer_t n{};\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n        }\n\n        SECTION(\"initialized value\")\n        {\n            json::number_integer_t n(42);\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n        }\n    }\n\n    SECTION(\"create an integer number (implicit)\")\n    {\n        // reference objects\n        json::number_integer_t n_reference = 42;\n        json j_reference(n_reference);\n        json::number_unsigned_t n_unsigned_reference = 42;\n        json j_unsigned_reference(n_unsigned_reference);\n\n        SECTION(\"short\")\n        {\n            short n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"unsigned short\")\n        {\n            unsigned short n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"int\")\n        {\n            int n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"unsigned int\")\n        {\n            unsigned int n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"long\")\n        {\n            long n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"unsigned long\")\n        {\n            unsigned long n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"long long\")\n        {\n            long long n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"unsigned long long\")\n        {\n            unsigned long long n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"int8_t\")\n        {\n            int8_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int16_t\")\n        {\n            int16_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int32_t\")\n        {\n            int32_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int64_t\")\n        {\n            int64_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_fast8_t\")\n        {\n            int_fast8_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_fast16_t\")\n        {\n            int_fast16_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_fast32_t\")\n        {\n            int_fast32_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_fast64_t\")\n        {\n            int_fast64_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_least8_t\")\n        {\n            int_least8_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_least16_t\")\n        {\n            int_least16_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_least32_t\")\n        {\n            int_least32_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"int_least64_t\")\n        {\n            int_least64_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"uint8_t\")\n        {\n            uint8_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint16_t\")\n        {\n            uint16_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint32_t\")\n        {\n            uint32_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint64_t\")\n        {\n            uint64_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_fast8_t\")\n        {\n            uint_fast8_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_fast16_t\")\n        {\n            uint_fast16_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_fast32_t\")\n        {\n            uint_fast32_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_fast64_t\")\n        {\n            uint_fast64_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_least8_t\")\n        {\n            uint_least8_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_least16_t\")\n        {\n            uint_least16_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_least32_t\")\n        {\n            uint_least32_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"uint_least64_t\")\n        {\n            uint_least64_t n = 42;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"integer literal without suffix\")\n        {\n            json j(42);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"integer literal with u suffix\")\n        {\n            json j(42u);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"integer literal with l suffix\")\n        {\n            json j(42L);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"integer literal with ul suffix\")\n        {\n            json j(42ul);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n\n        SECTION(\"integer literal with ll suffix\")\n        {\n            json j(42LL);\n            CHECK(j.type() == json::value_t::number_integer);\n            CHECK(j == j_reference);\n        }\n\n        SECTION(\"integer literal with ull suffix\")\n        {\n            json j(42ull);\n            CHECK(j.type() == json::value_t::number_unsigned);\n            CHECK(j == j_unsigned_reference);\n        }\n    }\n\n    SECTION(\"create a floating-point number (explicit)\")\n    {\n        SECTION(\"uninitialized value\")\n        {\n            json::number_float_t n{};\n            json j(n);\n            CHECK(j.type() == json::value_t::number_float);\n        }\n\n        SECTION(\"initialized value\")\n        {\n            json::number_float_t n(42.23);\n            json j(n);\n            CHECK(j.type() == json::value_t::number_float);\n        }\n\n        SECTION(\"NaN\")\n        {\n            // NaN is stored properly, but serialized to null\n            json::number_float_t n(std::numeric_limits<json::number_float_t>::quiet_NaN());\n            json j(n);\n            CHECK(j.type() == json::value_t::number_float);\n\n            // check round trip of NaN\n            json::number_float_t d{j};\n            CHECK((std::isnan(d) && std::isnan(n)) == true);\n\n            // check that NaN is serialized to null\n            CHECK(j.dump() == \"null\");\n        }\n\n        SECTION(\"infinity\")\n        {\n            // infinity is stored properly, but serialized to null\n            json::number_float_t n(std::numeric_limits<json::number_float_t>::infinity());\n            json j(n);\n            CHECK(j.type() == json::value_t::number_float);\n\n            // check round trip of infinity\n            json::number_float_t d{j};\n            CHECK(d == n);\n\n            // check that inf is serialized to null\n            CHECK(j.dump() == \"null\");\n        }\n    }\n\n    SECTION(\"create a floating-point number (implicit)\")\n    {\n        // reference object\n        json::number_float_t n_reference = 42.23;\n        json j_reference(n_reference);\n\n        SECTION(\"float\")\n        {\n            float n = 42.23f;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_float);\n            CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));\n        }\n\n        SECTION(\"double\")\n        {\n            double n = 42.23;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_float);\n            CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));\n        }\n\n        SECTION(\"long double\")\n        {\n            long double n = 42.23L;\n            json j(n);\n            CHECK(j.type() == json::value_t::number_float);\n            CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));\n        }\n\n        SECTION(\"floating-point literal without suffix\")\n        {\n            json j(42.23);\n            CHECK(j.type() == json::value_t::number_float);\n            CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));\n        }\n\n        SECTION(\"integer literal with f suffix\")\n        {\n            json j(42.23f);\n            CHECK(j.type() == json::value_t::number_float);\n            CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));\n        }\n\n        SECTION(\"integer literal with l suffix\")\n        {\n            json j(42.23L);\n            CHECK(j.type() == json::value_t::number_float);\n            CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));\n        }\n    }\n\n    SECTION(\"create a container (array or object) from an initializer list\")\n    {\n        SECTION(\"empty initializer list\")\n        {\n            SECTION(\"explicit\")\n            {\n                json j(json::initializer_list_t {});\n                CHECK(j.type() == json::value_t::object);\n            }\n\n            SECTION(\"implicit\")\n            {\n                json j {};\n                CHECK(j.type() == json::value_t::null);\n            }\n        }\n\n        SECTION(\"one element\")\n        {\n            SECTION(\"array\")\n            {\n                SECTION(\"explicit\")\n                {\n                    json j(json::initializer_list_t {json(json::array_t())});\n                    CHECK(j.type() == json::value_t::array);\n                }\n\n                SECTION(\"implicit\")\n                {\n                    json j {json::array_t()};\n                    CHECK(j.type() == json::value_t::array);\n                }\n            }\n\n            SECTION(\"object\")\n            {\n                SECTION(\"explicit\")\n                {\n                    json j(json::initializer_list_t {json(json::object_t())});\n                    CHECK(j.type() == json::value_t::array);\n                }\n\n                SECTION(\"implicit\")\n                {\n                    json j {json::object_t()};\n                    CHECK(j.type() == json::value_t::array);\n                }\n            }\n\n            SECTION(\"string\")\n            {\n                SECTION(\"explicit\")\n                {\n                    json j(json::initializer_list_t {json(\"Hello world\")});\n                    CHECK(j.type() == json::value_t::array);\n                }\n\n                SECTION(\"implicit\")\n                {\n                    json j {\"Hello world\"};\n                    CHECK(j.type() == json::value_t::array);\n                }\n            }\n\n            SECTION(\"boolean\")\n            {\n                SECTION(\"explicit\")\n                {\n                    json j(json::initializer_list_t {json(true)});\n                    CHECK(j.type() == json::value_t::array);\n                }\n\n                SECTION(\"implicit\")\n                {\n                    json j {true};\n                    CHECK(j.type() == json::value_t::array);\n                }\n            }\n\n            SECTION(\"number (integer)\")\n            {\n                SECTION(\"explicit\")\n                {\n                    json j(json::initializer_list_t {json(1)});\n                    CHECK(j.type() == json::value_t::array);\n                }\n\n                SECTION(\"implicit\")\n                {\n                    json j {1};\n                    CHECK(j.type() == json::value_t::array);\n                }\n            }\n\n            SECTION(\"number (unsigned)\")\n            {\n                SECTION(\"explicit\")\n                {\n                    json j(json::initializer_list_t {json(1u)});\n                    CHECK(j.type() == json::value_t::array);\n                }\n\n                SECTION(\"implicit\")\n                {\n                    json j {1u};\n                    CHECK(j.type() == json::value_t::array);\n                }\n            }\n\n            SECTION(\"number (floating-point)\")\n            {\n                SECTION(\"explicit\")\n                {\n                    json j(json::initializer_list_t {json(42.23)});\n                    CHECK(j.type() == json::value_t::array);\n                }\n\n                SECTION(\"implicit\")\n                {\n                    json j {42.23};\n                    CHECK(j.type() == json::value_t::array);\n                }\n            }\n        }\n\n        SECTION(\"more elements\")\n        {\n            SECTION(\"explicit\")\n            {\n                json j(json::initializer_list_t {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()});\n                CHECK(j.type() == json::value_t::array);\n            }\n\n            SECTION(\"implicit\")\n            {\n                json j {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()};\n                CHECK(j.type() == json::value_t::array);\n            }\n        }\n\n        SECTION(\"implicit type deduction\")\n        {\n            SECTION(\"object\")\n            {\n                json j { {\"one\", 1}, {\"two\", 1u}, {\"three\", 2.2}, {\"four\", false} };\n                CHECK(j.type() == json::value_t::object);\n            }\n\n            SECTION(\"array\")\n            {\n                json j { {\"one\", 1}, {\"two\", 1u}, {\"three\", 2.2}, {\"four\", false}, 13 };\n                CHECK(j.type() == json::value_t::array);\n            }\n        }\n\n        SECTION(\"explicit type deduction\")\n        {\n            SECTION(\"empty object\")\n            {\n                json j = json::object();\n                CHECK(j.type() == json::value_t::object);\n            }\n\n            SECTION(\"object\")\n            {\n                json j = json::object({ {\"one\", 1}, {\"two\", 1u}, {\"three\", 2.2}, {\"four\", false} });\n                CHECK(j.type() == json::value_t::object);\n            }\n\n            SECTION(\"object with error\")\n            {\n                json _;\n                CHECK_THROWS_AS(_ = json::object({ {\"one\", 1}, {\"two\", 1u}, {\"three\", 2.2}, {\"four\", false}, 13 }),\n                json::type_error&);\n                CHECK_THROWS_WITH(_ = json::object({ {\"one\", 1}, {\"two\", 1u}, {\"three\", 2.2}, {\"four\", false}, 13 }),\n                \"[json.exception.type_error.301] cannot create object from initializer list\");\n            }\n\n            SECTION(\"empty array\")\n            {\n                json j = json::array();\n                CHECK(j.type() == json::value_t::array);\n            }\n\n            SECTION(\"array\")\n            {\n                json j = json::array({ {\"one\", 1}, {\"two\", 1u}, {\"three\", 2.2}, {\"four\", false} });\n                CHECK(j.type() == json::value_t::array);\n            }\n        }\n\n        SECTION(\"move from initializer_list\")\n        {\n            SECTION(\"string\")\n            {\n                SECTION(\"constructor with implicit types (array)\")\n                {\n                    // This should break through any short string optimization in std::string\n                    std::string source(1024, '!');\n                    const auto* source_addr = source.data();\n                    json j = {std::move(source)};\n                    const auto* target_addr = j[0].get_ref<std::string const&>().data();\n                    const bool success = (target_addr == source_addr);\n                    CHECK(success);\n                }\n\n                SECTION(\"constructor with implicit types (object)\")\n                {\n                    // This should break through any short string optimization in std::string\n                    std::string source(1024, '!');\n                    const auto* source_addr = source.data();\n                    json j = {{\"key\", std::move(source)}};\n                    const auto* target_addr = j[\"key\"].get_ref<std::string const&>().data();\n                    const bool success = (target_addr == source_addr);\n                    CHECK(success);\n                }\n\n                SECTION(\"constructor with implicit types (object key)\")\n                {\n                    // This should break through any short string optimization in std::string\n                    std::string source(1024, '!');\n                    const auto* source_addr = source.data();\n                    json j = {{std::move(source), 42}};\n                    const auto* target_addr = j.get_ref<json::object_t&>().begin()->first.data();\n                    const bool success = (target_addr == source_addr);\n                    CHECK(success);\n                }\n            }\n\n            SECTION(\"array\")\n            {\n                SECTION(\"constructor with implicit types (array)\")\n                {\n                    json::array_t source = {1, 2, 3};\n                    const auto* source_addr = source.data();\n                    json j {std::move(source)};\n                    const auto* target_addr = j[0].get_ref<json::array_t const&>().data();\n                    const bool success = (target_addr == source_addr);\n                    CHECK(success);\n                }\n\n                SECTION(\"constructor with implicit types (object)\")\n                {\n                    json::array_t source = {1, 2, 3};\n                    const auto* source_addr = source.data();\n                    json j {{\"key\", std::move(source)}};\n                    const auto* target_addr = j[\"key\"].get_ref<json::array_t const&>().data();\n                    const bool success = (target_addr == source_addr);\n                    CHECK(success);\n                }\n\n                SECTION(\"assignment with implicit types (array)\")\n                {\n                    json::array_t source = {1, 2, 3};\n                    const auto* source_addr = source.data();\n                    json j = {std::move(source)};\n                    const auto* target_addr = j[0].get_ref<json::array_t const&>().data();\n                    const bool success = (target_addr == source_addr);\n                    CHECK(success);\n                }\n\n                SECTION(\"assignment with implicit types (object)\")\n                {\n                    json::array_t source = {1, 2, 3};\n                    const auto* source_addr = source.data();\n                    json j = {{\"key\", std::move(source)}};\n                    const auto* target_addr = j[\"key\"].get_ref<json::array_t const&>().data();\n                    const bool success = (target_addr == source_addr);\n                    CHECK(success);\n                }\n            }\n\n            SECTION(\"object\")\n            {\n                SECTION(\"constructor with implicit types (array)\")\n                {\n                    json::object_t source = {{\"hello\", \"world\"}};\n                    const json* source_addr = &source.at(\"hello\");\n                    json j {std::move(source)};\n                    CHECK(&(j[0].get_ref<json::object_t const&>().at(\"hello\")) == source_addr);\n                }\n\n                SECTION(\"constructor with implicit types (object)\")\n                {\n                    json::object_t source = {{\"hello\", \"world\"}};\n                    const json* source_addr = &source.at(\"hello\");\n                    json j {{\"key\", std::move(source)}};\n                    CHECK(&(j[\"key\"].get_ref<json::object_t const&>().at(\"hello\")) == source_addr);\n                }\n\n                SECTION(\"assignment with implicit types (array)\")\n                {\n                    json::object_t source = {{\"hello\", \"world\"}};\n                    const json* source_addr = &source.at(\"hello\");\n                    json j = {std::move(source)};\n                    CHECK(&(j[0].get_ref<json::object_t const&>().at(\"hello\")) == source_addr);\n                }\n\n                SECTION(\"assignment with implicit types (object)\")\n                {\n                    json::object_t source = {{\"hello\", \"world\"}};\n                    const json* source_addr = &source.at(\"hello\");\n                    json j = {{\"key\", std::move(source)}};\n                    CHECK(&(j[\"key\"].get_ref<json::object_t const&>().at(\"hello\")) == source_addr);\n                }\n            }\n\n            SECTION(\"json\")\n            {\n                SECTION(\"constructor with implicit types (array)\")\n                {\n                    json source {1, 2, 3};\n                    const json* source_addr = &source[0];\n                    json j {std::move(source), {}};\n                    CHECK(&j[0][0] == source_addr);\n                }\n\n                SECTION(\"constructor with implicit types (object)\")\n                {\n                    json source {1, 2, 3};\n                    const json* source_addr = &source[0];\n                    json j {{\"key\", std::move(source)}};\n                    CHECK(&j[\"key\"][0] == source_addr);\n                }\n\n                SECTION(\"assignment with implicit types (array)\")\n                {\n                    json source {1, 2, 3};\n                    const json* source_addr = &source[0];\n                    json j = {std::move(source), {}};\n                    CHECK(&j[0][0] == source_addr);\n                }\n\n                SECTION(\"assignment with implicit types (object)\")\n                {\n                    json source {1, 2, 3};\n                    const json* source_addr = &source[0];\n                    json j = {{\"key\", std::move(source)}};\n                    CHECK(&j[\"key\"][0] == source_addr);\n                }\n            }\n\n        }\n    }\n\n    SECTION(\"create an array of n copies of a given value\")\n    {\n        SECTION(\"cnt = 0\")\n        {\n            json v = {1, \"foo\", 34.23, {1, 2, 3}, {{\"A\", 1}, {\"B\", 2u}}};\n            json arr(0, v);\n            CHECK(arr.size() == 0);\n        }\n\n        SECTION(\"cnt = 1\")\n        {\n            json v = {1, \"foo\", 34.23, {1, 2, 3}, {{\"A\", 1}, {\"B\", 2u}}};\n            json arr(1, v);\n            CHECK(arr.size() == 1);\n            for (auto& x : arr)\n            {\n                CHECK(x == v);\n            }\n        }\n\n        SECTION(\"cnt = 3\")\n        {\n            json v = {1, \"foo\", 34.23, {1, 2, 3}, {{\"A\", 1}, {\"B\", 2u}}};\n            json arr(3, v);\n            CHECK(arr.size() == 3);\n            for (auto& x : arr)\n            {\n                CHECK(x == v);\n            }\n        }\n    }\n\n    SECTION(\"create a JSON container from an iterator range\")\n    {\n        SECTION(\"object\")\n        {\n            SECTION(\"json(begin(), end())\")\n            {\n                {\n                    json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                    json j_new(jobject.begin(), jobject.end());\n                    CHECK(j_new == jobject);\n                }\n                {\n                    json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                    json j_new(jobject.cbegin(), jobject.cend());\n                    CHECK(j_new == jobject);\n                }\n            }\n\n            SECTION(\"json(begin(), begin())\")\n            {\n                {\n                    json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                    json j_new(jobject.begin(), jobject.begin());\n                    CHECK(j_new == json::object());\n                }\n                {\n                    json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                    json j_new(jobject.cbegin(), jobject.cbegin());\n                    CHECK(j_new == json::object());\n                }\n            }\n\n            SECTION(\"construct from subrange\")\n            {\n                json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}, {\"d\", false}, {\"e\", true}};\n                json j_new(jobject.find(\"b\"), jobject.find(\"e\"));\n                CHECK(j_new == json({{\"b\", 1}, {\"c\", 17u}, {\"d\", false}}));\n            }\n\n            SECTION(\"incompatible iterators\")\n            {\n                {\n                    json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}, {\"d\", false}, {\"e\", true}};\n                    json jobject2 = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                    CHECK_THROWS_AS(json(jobject.begin(), jobject2.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(json(jobject2.begin(), jobject.end()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(json(jobject.begin(), jobject2.end()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                    CHECK_THROWS_WITH(json(jobject2.begin(), jobject.end()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                }\n                {\n                    json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}, {\"d\", false}, {\"e\", true}};\n                    json jobject2 = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                    CHECK_THROWS_AS(json(jobject.cbegin(), jobject2.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(json(jobject2.cbegin(), jobject.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(json(jobject.cbegin(), jobject2.cend()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                    CHECK_THROWS_WITH(json(jobject2.cbegin(), jobject.cend()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                }\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"json(begin(), end())\")\n            {\n                {\n                    json jarray = {1, 2, 3, 4, 5};\n                    json j_new(jarray.begin(), jarray.end());\n                    CHECK(j_new == jarray);\n                }\n                {\n                    json jarray = {1, 2, 3, 4, 5};\n                    json j_new(jarray.cbegin(), jarray.cend());\n                    CHECK(j_new == jarray);\n                }\n            }\n\n            SECTION(\"json(begin(), begin())\")\n            {\n                {\n                    json jarray = {1, 2, 3, 4, 5};\n                    json j_new(jarray.begin(), jarray.begin());\n                    CHECK(j_new == json::array());\n                }\n                {\n                    json jarray = {1, 2, 3, 4, 5};\n                    json j_new(jarray.cbegin(), jarray.cbegin());\n                    CHECK(j_new == json::array());\n                }\n            }\n\n            SECTION(\"construct from subrange\")\n            {\n                {\n                    json jarray = {1, 2, 3, 4, 5};\n                    json j_new(jarray.begin() + 1, jarray.begin() + 3);\n                    CHECK(j_new == json({2, 3}));\n                }\n                {\n                    json jarray = {1, 2, 3, 4, 5};\n                    json j_new(jarray.cbegin() + 1, jarray.cbegin() + 3);\n                    CHECK(j_new == json({2, 3}));\n                }\n            }\n\n            SECTION(\"incompatible iterators\")\n            {\n                {\n                    json jarray = {1, 2, 3, 4};\n                    json jarray2 = {2, 3, 4, 5};\n                    CHECK_THROWS_AS(json(jarray.begin(), jarray2.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(json(jarray2.begin(), jarray.end()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(json(jarray.begin(), jarray2.end()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                    CHECK_THROWS_WITH(json(jarray2.begin(), jarray.end()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                }\n                {\n                    json jarray = {1, 2, 3, 4};\n                    json jarray2 = {2, 3, 4, 5};\n                    CHECK_THROWS_AS(json(jarray.cbegin(), jarray2.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(json(jarray2.cbegin(), jarray.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(json(jarray.cbegin(), jarray2.cend()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                    CHECK_THROWS_WITH(json(jarray2.cbegin(), jarray.cend()), \"[json.exception.invalid_iterator.201] iterators are not compatible\");\n                }\n            }\n        }\n\n        SECTION(\"other values\")\n        {\n            SECTION(\"construct with two valid iterators\")\n            {\n                SECTION(\"null\")\n                {\n                    {\n                        json j;\n                        CHECK_THROWS_AS(json(j.begin(), j.end()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.begin(), j.end()),\n                                          \"[json.exception.invalid_iterator.206] cannot construct with iterators from null\");\n                    }\n                    {\n                        json j;\n                        CHECK_THROWS_AS(json(j.cbegin(), j.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.cbegin(), j.cend()),\n                                          \"[json.exception.invalid_iterator.206] cannot construct with iterators from null\");\n                    }\n                }\n\n                SECTION(\"string\")\n                {\n                    {\n                        json j = \"foo\";\n                        json j_new(j.begin(), j.end());\n                        CHECK(j == j_new);\n                    }\n                    {\n                        json j = \"bar\";\n                        json j_new(j.cbegin(), j.cend());\n                        CHECK(j == j_new);\n                    }\n                }\n\n                SECTION(\"number (boolean)\")\n                {\n                    {\n                        json j = false;\n                        json j_new(j.begin(), j.end());\n                        CHECK(j == j_new);\n                    }\n                    {\n                        json j = true;\n                        json j_new(j.cbegin(), j.cend());\n                        CHECK(j == j_new);\n                    }\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    {\n                        json j = 17;\n                        json j_new(j.begin(), j.end());\n                        CHECK(j == j_new);\n                    }\n                    {\n                        json j = 17;\n                        json j_new(j.cbegin(), j.cend());\n                        CHECK(j == j_new);\n                    }\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    {\n                        json j = 17u;\n                        json j_new(j.begin(), j.end());\n                        CHECK(j == j_new);\n                    }\n                    {\n                        json j = 17u;\n                        json j_new(j.cbegin(), j.cend());\n                        CHECK(j == j_new);\n                    }\n                }\n\n                SECTION(\"number (floating point)\")\n                {\n                    {\n                        json j = 23.42;\n                        json j_new(j.begin(), j.end());\n                        CHECK(j == j_new);\n                    }\n                    {\n                        json j = 23.42;\n                        json j_new(j.cbegin(), j.cend());\n                        CHECK(j == j_new);\n                    }\n                }\n\n                SECTION(\"binary\")\n                {\n                    {\n                        json j = json::binary({1, 2, 3});\n                        json j_new(j.begin(), j.end());\n                        CHECK((j == j_new));\n                    }\n                    {\n                        json j = json::binary({1, 2, 3});\n                        json j_new(j.cbegin(), j.cend());\n                        CHECK((j == j_new));\n                    }\n                }\n            }\n\n            SECTION(\"construct with two invalid iterators\")\n            {\n                SECTION(\"string\")\n                {\n                    {\n                        json j = \"foo\";\n                        CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                    {\n                        json j = \"bar\";\n                        CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                }\n\n                SECTION(\"number (boolean)\")\n                {\n                    {\n                        json j = false;\n                        CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                    {\n                        json j = true;\n                        CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    {\n                        json j = 17;\n                        CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                    {\n                        json j = 17;\n                        CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    {\n                        json j = 17u;\n                        CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                    {\n                        json j = 17u;\n                        CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                }\n\n                SECTION(\"number (floating point)\")\n                {\n                    {\n                        json j = 23.42;\n                        CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                    {\n                        json j = 23.42;\n                        CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-constructor2.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"other constructors and destructor\")\n{\n    SECTION(\"copy constructor\")\n    {\n        SECTION(\"object\")\n        {\n            json j {{\"foo\", 1}, {\"bar\", false}};\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"array\")\n        {\n            json j {\"foo\", 1, 42.23, false};\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"null\")\n        {\n            json j(nullptr);\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"boolean\")\n        {\n            json j(true);\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"string\")\n        {\n            json j(\"Hello world\");\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j(42);\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j(42u);\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"number (floating-point)\")\n        {\n            json j(42.23);\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n\n        SECTION(\"binary\")\n        {\n            json j = json::binary({1, 2, 3});\n            json k(j); // NOLINT(performance-unnecessary-copy-initialization)\n            CHECK(j == k);\n        }\n    }\n\n    SECTION(\"move constructor\")\n    {\n        json j {{\"foo\", \"bar\"}, {\"baz\", {1, 2, 3, 4}}, {\"a\", 42u}, {\"b\", 42.23}, {\"c\", nullptr}};\n        CHECK(j.type() == json::value_t::object);\n        json k(std::move(j));\n        CHECK(k.type() == json::value_t::object);\n        CHECK(j.type() == json::value_t::null); // NOLINT: access after move is OK here\n    }\n\n    SECTION(\"copy assignment\")\n    {\n        SECTION(\"object\")\n        {\n            json j {{\"foo\", 1}, {\"bar\", false}};\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"array\")\n        {\n            json j {\"foo\", 1, 42.23, false};\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"null\")\n        {\n            json j(nullptr);\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"boolean\")\n        {\n            json j(true);\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"string\")\n        {\n            json j(\"Hello world\");\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j(42);\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j(42u);\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"number (floating-point)\")\n        {\n            json j(42.23);\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n\n        SECTION(\"binary\")\n        {\n            json j = json::binary({1, 2, 3});\n            json k;\n            k = j;\n            CHECK(j == k);\n        }\n    }\n\n    SECTION(\"destructor\")\n    {\n        SECTION(\"object\")\n        {\n            auto* j = new json {{\"foo\", 1}, {\"bar\", false}}; // NOLINT(cppcoreguidelines-owning-memory)\n            delete j; // NOLINT(cppcoreguidelines-owning-memory)\n        }\n\n        SECTION(\"array\")\n        {\n            auto* j = new json {\"foo\", 1, 1u, false, 23.42}; // NOLINT(cppcoreguidelines-owning-memory)\n            delete j; // NOLINT(cppcoreguidelines-owning-memory)\n        }\n\n        SECTION(\"string\")\n        {\n            auto* j = new json(\"Hello world\"); // NOLINT(cppcoreguidelines-owning-memory)\n            delete j; // NOLINT(cppcoreguidelines-owning-memory)\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-convenience.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <sstream>\n\nnamespace\n{\nvoid check_escaped(const char* original, const char* escaped = \"\", bool ensure_ascii = false);\nvoid check_escaped(const char* original, const char* escaped, const bool ensure_ascii)\n{\n    std::stringstream ss;\n    json::serializer s(nlohmann::detail::output_adapter<char>(ss), ' ');\n    s.dump_escaped(original, ensure_ascii);\n    CHECK(ss.str() == escaped);\n}\n} // namespace\n\nTEST_CASE(\"convenience functions\")\n{\n    SECTION(\"type name as string\")\n    {\n        CHECK(std::string(json(json::value_t::null).type_name()) == \"null\");\n        CHECK(std::string(json(json::value_t::object).type_name()) == \"object\");\n        CHECK(std::string(json(json::value_t::array).type_name()) == \"array\");\n        CHECK(std::string(json(json::value_t::number_integer).type_name()) == \"number\");\n        CHECK(std::string(json(json::value_t::number_unsigned).type_name()) == \"number\");\n        CHECK(std::string(json(json::value_t::number_float).type_name()) == \"number\");\n        CHECK(std::string(json(json::value_t::binary).type_name()) == \"binary\");\n        CHECK(std::string(json(json::value_t::boolean).type_name()) == \"boolean\");\n        CHECK(std::string(json(json::value_t::string).type_name()) == \"string\");\n        CHECK(std::string(json(json::value_t::discarded).type_name()) == \"discarded\");\n    }\n\n    SECTION(\"string escape\")\n    {\n        check_escaped(\"\\\"\", \"\\\\\\\"\");\n        check_escaped(\"\\\\\", \"\\\\\\\\\");\n        check_escaped(\"\\b\", \"\\\\b\");\n        check_escaped(\"\\f\", \"\\\\f\");\n        check_escaped(\"\\n\", \"\\\\n\");\n        check_escaped(\"\\r\", \"\\\\r\");\n        check_escaped(\"\\t\", \"\\\\t\");\n\n        check_escaped(\"\\x01\", \"\\\\u0001\");\n        check_escaped(\"\\x02\", \"\\\\u0002\");\n        check_escaped(\"\\x03\", \"\\\\u0003\");\n        check_escaped(\"\\x04\", \"\\\\u0004\");\n        check_escaped(\"\\x05\", \"\\\\u0005\");\n        check_escaped(\"\\x06\", \"\\\\u0006\");\n        check_escaped(\"\\x07\", \"\\\\u0007\");\n        check_escaped(\"\\x08\", \"\\\\b\");\n        check_escaped(\"\\x09\", \"\\\\t\");\n        check_escaped(\"\\x0a\", \"\\\\n\");\n        check_escaped(\"\\x0b\", \"\\\\u000b\");\n        check_escaped(\"\\x0c\", \"\\\\f\");\n        check_escaped(\"\\x0d\", \"\\\\r\");\n        check_escaped(\"\\x0e\", \"\\\\u000e\");\n        check_escaped(\"\\x0f\", \"\\\\u000f\");\n        check_escaped(\"\\x10\", \"\\\\u0010\");\n        check_escaped(\"\\x11\", \"\\\\u0011\");\n        check_escaped(\"\\x12\", \"\\\\u0012\");\n        check_escaped(\"\\x13\", \"\\\\u0013\");\n        check_escaped(\"\\x14\", \"\\\\u0014\");\n        check_escaped(\"\\x15\", \"\\\\u0015\");\n        check_escaped(\"\\x16\", \"\\\\u0016\");\n        check_escaped(\"\\x17\", \"\\\\u0017\");\n        check_escaped(\"\\x18\", \"\\\\u0018\");\n        check_escaped(\"\\x19\", \"\\\\u0019\");\n        check_escaped(\"\\x1a\", \"\\\\u001a\");\n        check_escaped(\"\\x1b\", \"\\\\u001b\");\n        check_escaped(\"\\x1c\", \"\\\\u001c\");\n        check_escaped(\"\\x1d\", \"\\\\u001d\");\n        check_escaped(\"\\x1e\", \"\\\\u001e\");\n        check_escaped(\"\\x1f\", \"\\\\u001f\");\n\n        // invalid UTF-8 characters\n        CHECK_THROWS_AS(check_escaped(\"ä\\xA9ü\"), json::type_error&);\n        CHECK_THROWS_WITH(check_escaped(\"ä\\xA9ü\"),\n                          \"[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\");\n\n        CHECK_THROWS_AS(check_escaped(\"\\xC2\"), json::type_error&);\n        CHECK_THROWS_WITH(check_escaped(\"\\xC2\"),\n                          \"[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2\");\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-conversions.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <deque>\n#include <forward_list>\n#include <list>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <valarray>\n\n#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464\n    #define JSON_HAS_CPP_17\n    #define JSON_HAS_CPP_14\n#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)\n    #define JSON_HAS_CPP_14\n#endif\n\n// NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wexit-time-destructors\")\n\nTEST_CASE(\"value conversion\")\n{\n    SECTION(\"get an object (explicit)\")\n    {\n        json::object_t o_reference = {{\"object\", json::object()},\n            {\"array\", {1, 2, 3, 4}},\n            {\"number\", 42},\n            {\"boolean\", false},\n            {\"null\", nullptr},\n            {\"string\", \"Hello world\"}\n        };\n        json j(o_reference);\n\n        SECTION(\"json::object_t\")\n        {\n            json::object_t o = j.get<json::object_t>();\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::map<json::string_t, json>\")\n        {\n            std::map<json::string_t, json> o =\n                j.get<std::map<json::string_t, json>>();\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::multimap<json::string_t, json>\")\n        {\n            std::multimap<json::string_t, json> o =\n                j.get<std::multimap<json::string_t, json>>();\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::unordered_map<json::string_t, json>\")\n        {\n            std::unordered_map<json::string_t, json> o =\n                j.get<std::unordered_map<json::string_t, json>>();\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::unordered_multimap<json::string_t, json>\")\n        {\n            std::unordered_multimap<json::string_t, json> o =\n                j.get<std::unordered_multimap<json::string_t, json>>();\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"exception in case of a non-object type\")\n        {\n            CHECK_THROWS_AS(json(json::value_t::null).get<json::object_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::array).get<json::object_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::string).get<json::object_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(\n                json(json::value_t::number_unsigned).get<json::object_t>(),\n                json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(),\n                            json::type_error&);\n\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<json::object_t>(),\n                \"[json.exception.type_error.302] type must be object, but is null\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::array).get<json::object_t>(),\n                \"[json.exception.type_error.302] type must be object, but is array\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::string).get<json::object_t>(),\n                \"[json.exception.type_error.302] type must be object, but is string\");\n            CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::object_t>(),\n                              \"[json.exception.type_error.302] type must be object, \"\n                              \"but is boolean\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_integer).get<json::object_t>(),\n                \"[json.exception.type_error.302] type must be object, but is number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_unsigned).get<json::object_t>(),\n                \"[json.exception.type_error.302] type must be object, but is number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_float).get<json::object_t>(),\n                \"[json.exception.type_error.302] type must be object, but is number\");\n        }\n    }\n\n    SECTION(\"get an object (explicit, get_to)\")\n    {\n        json::object_t o_reference = {{\"object\", json::object()},\n            {\"array\", {1, 2, 3, 4}},\n            {\"number\", 42},\n            {\"boolean\", false},\n            {\"null\", nullptr},\n            {\"string\", \"Hello world\"}\n        };\n        json j(o_reference);\n\n        SECTION(\"json::object_t\")\n        {\n            json::object_t o = {{\"previous\", \"value\"}};\n            j.get_to(o);\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::map<json::string_t, json>\")\n        {\n            std::map<json::string_t, json> o{{\"previous\", \"value\"}};\n            j.get_to(o);\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::multimap<json::string_t, json>\")\n        {\n            std::multimap<json::string_t, json> o{{\"previous\", \"value\"}};\n            j.get_to(o);\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::unordered_map<json::string_t, json>\")\n        {\n            std::unordered_map<json::string_t, json> o{{\"previous\", \"value\"}};\n            j.get_to(o);\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::unordered_multimap<json::string_t, json>\")\n        {\n            std::unordered_multimap<json::string_t, json> o{{\"previous\", \"value\"}};\n            j.get_to(o);\n            CHECK(json(o) == j);\n        }\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"get an object (implicit)\")\n    {\n        json::object_t o_reference = {{\"object\", json::object()},\n            {\"array\", {1, 2, 3, 4}},\n            {\"number\", 42},\n            {\"boolean\", false},\n            {\"null\", nullptr},\n            {\"string\", \"Hello world\"}\n        };\n        json j(o_reference);\n\n        SECTION(\"json::object_t\")\n        {\n            json::object_t o = j;\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::map<json::string_t, json>\")\n        {\n            std::map<json::string_t, json> o = j;\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::multimap<json::string_t, json>\")\n        {\n            std::multimap<json::string_t, json> o = j;\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::unordered_map<json::string_t, json>\")\n        {\n            std::unordered_map<json::string_t, json> o = j;\n            CHECK(json(o) == j);\n        }\n\n        SECTION(\"std::unordered_multimap<json::string_t, json>\")\n        {\n            std::unordered_multimap<json::string_t, json> o = j;\n            CHECK(json(o) == j);\n        }\n    }\n#endif\n\n    SECTION(\"get an array (explicit)\")\n    {\n        json::array_t a_reference{json(1),     json(1u),       json(2.2),\n                                  json(false), json(\"string\"), json()};\n        json j(a_reference);\n\n        SECTION(\"json::array_t\")\n        {\n            json::array_t a = j.get<json::array_t>();\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::list<json>\")\n        {\n            std::list<json> a = j.get<std::list<json>>();\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::forward_list<json>\")\n        {\n            std::forward_list<json> a = j.get<std::forward_list<json>>();\n            CHECK(json(a) == j);\n\n            CHECK_THROWS_AS(json(json::value_t::null).get<std::forward_list<json>>(),\n                            json::type_error&);\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<std::forward_list<json>>(),\n                \"[json.exception.type_error.302] type must be array, but is null\");\n        }\n\n        SECTION(\"std::vector<json>\")\n        {\n            std::vector<json> a = j.get<std::vector<json>>();\n            CHECK(json(a) == j);\n\n            CHECK_THROWS_AS(json(json::value_t::null).get<std::vector<json>>(),\n                            json::type_error&);\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<std::vector<json>>(),\n                \"[json.exception.type_error.302] type must be array, but is null\");\n\n#if !defined(JSON_NOEXCEPTION)\n            SECTION(\"reserve is called on containers that supports it\")\n            {\n                // make sure all values are properly copied\n                json j2({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});\n                auto v2 = j2.get<std::vector<int>>();\n                CHECK(v2.size() == 10);\n            }\n#endif\n        }\n\n        SECTION(\"built-in arrays\")\n        {\n            const char str[] = \"a string\"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n            const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n\n            json j2 = nbs;\n            json j3 = str;\n\n            auto v = j2.get<std::vector<int>>();\n            auto s = j3.get<std::string>();\n            CHECK(std::equal(v.begin(), v.end(), std::begin(nbs)));\n            CHECK(s == str);\n        }\n\n        SECTION(\"std::deque<json>\")\n        {\n            std::deque<json> a = j.get<std::deque<json>>();\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"exception in case of a non-array type\")\n        {\n            CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(),\n                            json::type_error&);\n\n            CHECK_THROWS_WITH(\n                json(json::value_t::object).get<std::vector<int>>(),\n                \"[json.exception.type_error.302] type must be array, but is object\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<json::array_t>(),\n                \"[json.exception.type_error.302] type must be array, but is null\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::object).get<json::array_t>(),\n                \"[json.exception.type_error.302] type must be array, but is object\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::string).get<json::array_t>(),\n                \"[json.exception.type_error.302] type must be array, but is string\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::boolean).get<json::array_t>(),\n                \"[json.exception.type_error.302] type must be array, but is boolean\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_integer).get<json::array_t>(),\n                \"[json.exception.type_error.302] type must be array, but is number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_unsigned).get<json::array_t>(),\n                \"[json.exception.type_error.302] type must be array, but is number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_float).get<json::array_t>(),\n                \"[json.exception.type_error.302] type must be array, but is number\");\n        }\n    }\n\n    SECTION(\"get an array (explicit, get_to)\")\n    {\n        json::array_t a_reference{json(1),     json(1u),       json(2.2),\n                                  json(false), json(\"string\"), json()};\n        json j(a_reference);\n\n        SECTION(\"json::array_t\")\n        {\n            json::array_t a{\"previous\", \"value\"};\n            j.get_to(a);\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::valarray<json>\")\n        {\n            std::valarray<json> a{\"previous\", \"value\"};\n            j.get_to(a);\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::list<json>\")\n        {\n            std::list<json> a{\"previous\", \"value\"};\n            j.get_to(a);\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::forward_list<json>\")\n        {\n            std::forward_list<json> a{\"previous\", \"value\"};\n            j.get_to(a);\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::vector<json>\")\n        {\n            std::vector<json> a{\"previous\", \"value\"};\n            j.get_to(a);\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"built-in arrays\")\n        {\n            const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n            int nbs2[] = {0, 0, 0}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n\n            json j2 = nbs;\n            j2.get_to(nbs2);\n            CHECK(std::equal(std::begin(nbs), std::end(nbs), std::begin(nbs2)));\n        }\n\n        SECTION(\"std::deque<json>\")\n        {\n            std::deque<json> a{\"previous\", \"value\"};\n            j.get_to(a);\n            CHECK(json(a) == j);\n        }\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"get an array (implicit)\")\n    {\n        json::array_t a_reference{json(1),     json(1u),       json(2.2),\n                                  json(false), json(\"string\"), json()};\n        json j(a_reference);\n\n        SECTION(\"json::array_t\")\n        {\n            json::array_t a = j;\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::list<json>\")\n        {\n            std::list<json> a = j;\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::forward_list<json>\")\n        {\n            std::forward_list<json> a = j;\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::vector<json>\")\n        {\n            std::vector<json> a = j;\n            CHECK(json(a) == j);\n        }\n\n        SECTION(\"std::deque<json>\")\n        {\n            std::deque<json> a = j;\n            CHECK(json(a) == j);\n        }\n    }\n#endif\n\n    SECTION(\"get a string (explicit)\")\n    {\n        json::string_t s_reference{\"Hello world\"};\n        json j(s_reference);\n\n        SECTION(\"string_t\")\n        {\n            json::string_t s = j.get<json::string_t>();\n            CHECK(json(s) == j);\n        }\n\n        SECTION(\"std::string\")\n        {\n            std::string s = j.get<std::string>();\n            CHECK(json(s) == j);\n        }\n#if defined(JSON_HAS_CPP_17)\n        SECTION(\"std::string_view\")\n        {\n            std::string_view s = j.get<std::string_view>();\n            CHECK(json(s) == j);\n        }\n#endif\n\n        SECTION(\"exception in case of a non-string type\")\n        {\n            CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(\n                json(json::value_t::number_unsigned).get<json::string_t>(),\n                json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(),\n                            json::type_error&);\n\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<json::string_t>(),\n                \"[json.exception.type_error.302] type must be string, but is null\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::object).get<json::string_t>(),\n                \"[json.exception.type_error.302] type must be string, but is object\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::array).get<json::string_t>(),\n                \"[json.exception.type_error.302] type must be string, but is array\");\n            CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(),\n                              \"[json.exception.type_error.302] type must be string, \"\n                              \"but is boolean\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_integer).get<json::string_t>(),\n                \"[json.exception.type_error.302] type must be string, but is number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_unsigned).get<json::string_t>(),\n                \"[json.exception.type_error.302] type must be string, but is number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_float).get<json::string_t>(),\n                \"[json.exception.type_error.302] type must be string, but is number\");\n        }\n\n#if defined(JSON_HAS_CPP_17)\n        SECTION(\"exception in case of a non-string type using string_view\")\n        {\n            CHECK_THROWS_AS(json(json::value_t::null).get<std::string_view>(), json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::object).get<std::string_view>(), json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::array).get<std::string_view>(), json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::boolean).get<std::string_view>(), json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_integer).get<std::string_view>(), json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<std::string_view>(), json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_float).get<std::string_view>(), json::type_error&);\n\n            CHECK_THROWS_WITH(json(json::value_t::null).get<std::string_view>(),\n                              \"[json.exception.type_error.302] type must be string, but is null\");\n            CHECK_THROWS_WITH(json(json::value_t::object).get<std::string_view>(),\n                              \"[json.exception.type_error.302] type must be string, but is object\");\n            CHECK_THROWS_WITH(json(json::value_t::array).get<std::string_view>(),\n                              \"[json.exception.type_error.302] type must be string, but is array\");\n            CHECK_THROWS_WITH(json(json::value_t::boolean).get<std::string_view>(),\n                              \"[json.exception.type_error.302] type must be string, but is boolean\");\n            CHECK_THROWS_WITH(json(json::value_t::number_integer).get<std::string_view>(),\n                              \"[json.exception.type_error.302] type must be string, but is number\");\n            CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<std::string_view>(),\n                              \"[json.exception.type_error.302] type must be string, but is number\");\n            CHECK_THROWS_WITH(json(json::value_t::number_float).get<std::string_view>(),\n                              \"[json.exception.type_error.302] type must be string, but is number\");\n        }\n#endif\n    }\n\n    SECTION(\"get a string (explicit, get_to)\")\n    {\n        json::string_t s_reference{\"Hello world\"};\n        json j(s_reference);\n\n        SECTION(\"string_t\")\n        {\n            json::string_t s = \"previous value\";\n            j.get_to(s);\n            CHECK(json(s) == j);\n        }\n\n        SECTION(\"std::string\")\n        {\n            std::string s = \"previous value\";\n            j.get_to(s);\n            CHECK(json(s) == j);\n        }\n#if defined(JSON_HAS_CPP_17)\n        SECTION(\"std::string_view\")\n        {\n            std::string s = \"previous value\";\n            std::string_view sv = s;\n            j.get_to(sv);\n            CHECK(json(sv) == j);\n        }\n#endif\n    }\n\n    SECTION(\"get null (explicit)\")\n    {\n        std::nullptr_t n = nullptr;\n        json j(n);\n\n        auto n2 = j.get<std::nullptr_t>();\n        CHECK(n2 == n);\n\n        CHECK_THROWS_AS(json(json::value_t::string).get<std::nullptr_t>(), json::type_error&);\n        CHECK_THROWS_AS(json(json::value_t::object).get<std::nullptr_t>(), json::type_error&);\n        CHECK_THROWS_AS(json(json::value_t::array).get<std::nullptr_t>(), json::type_error&);\n        CHECK_THROWS_AS(json(json::value_t::boolean).get<std::nullptr_t>(), json::type_error&);\n        CHECK_THROWS_AS(json(json::value_t::number_integer).get<std::nullptr_t>(), json::type_error&);\n        CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<std::nullptr_t>(), json::type_error&);\n        CHECK_THROWS_AS(json(json::value_t::number_float).get<std::nullptr_t>(), json::type_error&);\n\n        CHECK_THROWS_WITH(json(json::value_t::string).get<std::nullptr_t>(),\n                          \"[json.exception.type_error.302] type must be null, but is string\");\n        CHECK_THROWS_WITH(json(json::value_t::object).get<std::nullptr_t>(),\n                          \"[json.exception.type_error.302] type must be null, but is object\");\n        CHECK_THROWS_WITH(json(json::value_t::array).get<std::nullptr_t>(),\n                          \"[json.exception.type_error.302] type must be null, but is array\");\n        CHECK_THROWS_WITH(json(json::value_t::boolean).get<std::nullptr_t>(),\n                          \"[json.exception.type_error.302] type must be null, but is boolean\");\n        CHECK_THROWS_WITH(json(json::value_t::number_integer).get<std::nullptr_t>(),\n                          \"[json.exception.type_error.302] type must be null, but is number\");\n        CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<std::nullptr_t>(),\n                          \"[json.exception.type_error.302] type must be null, but is number\");\n        CHECK_THROWS_WITH(json(json::value_t::number_float).get<std::nullptr_t>(),\n                          \"[json.exception.type_error.302] type must be null, but is number\");\n\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"get a string (implicit)\")\n    {\n        json::string_t s_reference{\"Hello world\"};\n        json j(s_reference);\n\n        SECTION(\"string_t\")\n        {\n            json::string_t s = j;\n            CHECK(json(s) == j);\n        }\n\n#if defined(JSON_HAS_CPP_17)\n        SECTION(\"std::string_view\")\n        {\n            std::string_view s = j.get<std::string_view>();\n            CHECK(json(s) == j);\n        }\n#endif\n\n        SECTION(\"std::string\")\n        {\n            std::string s = j;\n            CHECK(json(s) == j);\n        }\n    }\n#endif\n\n    SECTION(\"get a boolean (explicit)\")\n    {\n        json::boolean_t b_reference{true};\n        json j(b_reference);\n\n        SECTION(\"boolean_t\")\n        {\n            auto b = j.get<json::boolean_t>();\n            CHECK(json(b) == j);\n        }\n\n        SECTION(\"uint8_t\")\n        {\n            auto n = j.get<uint8_t>();\n            CHECK(n == 1);\n        }\n\n        SECTION(\"bool\")\n        {\n            bool b = j.get<bool>();\n            CHECK(json(b) == j);\n        }\n\n        SECTION(\"exception in case of a non-number type\")\n        {\n            CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::string).get<uint8_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(\n                json(json::value_t::number_integer).get<json::boolean_t>(),\n                json::type_error&);\n            CHECK_THROWS_AS(\n                json(json::value_t::number_unsigned).get<json::boolean_t>(),\n                json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(),\n                            json::type_error&);\n\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<json::boolean_t>(),\n                \"[json.exception.type_error.302] type must be boolean, but is null\");\n            CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(),\n                              \"[json.exception.type_error.302] type must be boolean, \"\n                              \"but is object\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::array).get<json::boolean_t>(),\n                \"[json.exception.type_error.302] type must be boolean, but is array\");\n            CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(),\n                              \"[json.exception.type_error.302] type must be boolean, \"\n                              \"but is string\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_integer).get<json::boolean_t>(),\n                \"[json.exception.type_error.302] type must be boolean, but is \"\n                \"number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_unsigned).get<json::boolean_t>(),\n                \"[json.exception.type_error.302] type must be boolean, but is \"\n                \"number\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::number_float).get<json::boolean_t>(),\n                \"[json.exception.type_error.302] type must be boolean, but is \"\n                \"number\");\n        }\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"get a boolean (implicit)\")\n    {\n        json::boolean_t b_reference{true};\n        json j(b_reference);\n\n        SECTION(\"boolean_t\")\n        {\n            json::boolean_t b = j;\n            CHECK(json(b) == j);\n        }\n\n        SECTION(\"bool\")\n        {\n            bool b = j;\n            CHECK(json(b) == j);\n        }\n    }\n#endif\n\n    SECTION(\"get an integer number (explicit)\")\n    {\n        json::number_integer_t n_reference{42};\n        json j(n_reference);\n        json::number_unsigned_t n_unsigned_reference{42u};\n        json j_unsigned(n_unsigned_reference);\n\n        SECTION(\"number_integer_t\")\n        {\n            auto n = j.get<json::number_integer_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"number_unsigned_t\")\n        {\n            auto n = j_unsigned.get<json::number_unsigned_t>();\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"short\")\n        {\n            auto n = j.get<short>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned short\")\n        {\n            auto n = j.get<unsigned short>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int\")\n        {\n            int n = j.get<int>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned int\")\n        {\n            auto n = j.get<unsigned int>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"long\")\n        {\n            long n = j.get<long>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned long\")\n        {\n            auto n = j.get<unsigned long>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"long long\")\n        {\n            auto n = j.get<long long>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned long long\")\n        {\n            auto n = j.get<unsigned long long>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int8_t\")\n        {\n            auto n = j.get<int8_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int16_t\")\n        {\n            auto n = j.get<int16_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int32_t\")\n        {\n            auto n = j.get<int32_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int64_t\")\n        {\n            auto n = j.get<int64_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int8_fast_t\")\n        {\n            auto n = j.get<int_fast8_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int16_fast_t\")\n        {\n            auto n = j.get<int_fast16_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int32_fast_t\")\n        {\n            auto n = j.get<int_fast32_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int64_fast_t\")\n        {\n            auto n = j.get<int_fast64_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int8_least_t\")\n        {\n            auto n = j.get<int_least8_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int16_least_t\")\n        {\n            auto n = j.get<int_least16_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int32_least_t\")\n        {\n            auto n = j.get<int_least32_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int64_least_t\")\n        {\n            auto n = j.get<int_least64_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint8_t\")\n        {\n            auto n = j.get<uint8_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint16_t\")\n        {\n            auto n = j.get<uint16_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint32_t\")\n        {\n            auto n = j.get<uint32_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint64_t\")\n        {\n            auto n = j.get<uint64_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint8_fast_t\")\n        {\n            auto n = j.get<uint_fast8_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint16_fast_t\")\n        {\n            auto n = j.get<uint_fast16_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint32_fast_t\")\n        {\n            auto n = j.get<uint_fast32_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint64_fast_t\")\n        {\n            auto n = j.get<uint_fast64_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint8_least_t\")\n        {\n            auto n = j.get<uint_least8_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint16_least_t\")\n        {\n            auto n = j.get<uint_least16_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint32_least_t\")\n        {\n            auto n = j.get<uint_least32_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint64_least_t\")\n        {\n            auto n = j.get<uint_least64_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"exception in case of a non-number type\")\n        {\n            CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(\n                json(json::value_t::boolean).get<json::number_integer_t>(),\n                json::type_error&);\n\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<json::number_integer_t>(),\n                \"[json.exception.type_error.302] type must be number, but is null\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::object).get<json::number_integer_t>(),\n                \"[json.exception.type_error.302] type must be number, but is object\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::array).get<json::number_integer_t>(),\n                \"[json.exception.type_error.302] type must be number, but is array\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::string).get<json::number_integer_t>(),\n                \"[json.exception.type_error.302] type must be number, but is string\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::boolean).get<json::number_integer_t>(),\n                \"[json.exception.type_error.302] type must be number, but is \"\n                \"boolean\");\n\n            CHECK_NOTHROW(\n                json(json::value_t::number_float).get<json::number_integer_t>());\n            CHECK_NOTHROW(\n                json(json::value_t::number_float).get<json::number_unsigned_t>());\n        }\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"get an integer number (implicit)\")\n    {\n        json::number_integer_t n_reference{42};\n        json j(n_reference);\n        json::number_unsigned_t n_unsigned_reference{42u};\n        json j_unsigned(n_unsigned_reference);\n\n        SECTION(\"number_integer_t\")\n        {\n            auto n = j.get<json::number_integer_t>();\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"number_unsigned_t\")\n        {\n            auto n = j_unsigned.get<json::number_unsigned_t>();\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"short\")\n        {\n            short n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned short\")\n        {\n            unsigned short n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"int\")\n        {\n            int n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned int\")\n        {\n            unsigned int n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"long\")\n        {\n            long n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned long\")\n        {\n            unsigned long n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"long long\")\n        {\n            long long n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"unsigned long long\")\n        {\n            unsigned long long n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"int8_t\")\n        {\n            int8_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int16_t\")\n        {\n            int16_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int32_t\")\n        {\n            int32_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int64_t\")\n        {\n            int64_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int8_fast_t\")\n        {\n            int_fast8_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int16_fast_t\")\n        {\n            int_fast16_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int32_fast_t\")\n        {\n            int_fast32_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int64_fast_t\")\n        {\n            int_fast64_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int8_least_t\")\n        {\n            int_least8_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int16_least_t\")\n        {\n            int_least16_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int32_least_t\")\n        {\n            int_least32_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"int64_least_t\")\n        {\n            int_least64_t n = j;\n            CHECK(json(n) == j);\n        }\n\n        SECTION(\"uint8_t\")\n        {\n            uint8_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint16_t\")\n        {\n            uint16_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint32_t\")\n        {\n            uint32_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint64_t\")\n        {\n            uint64_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint8_fast_t\")\n        {\n            uint_fast8_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint16_fast_t\")\n        {\n            uint_fast16_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint32_fast_t\")\n        {\n            uint_fast32_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint64_fast_t\")\n        {\n            uint_fast64_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint8_least_t\")\n        {\n            uint_least8_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint16_least_t\")\n        {\n            uint_least16_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint32_least_t\")\n        {\n            uint_least32_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n\n        SECTION(\"uint64_least_t\")\n        {\n            uint_least64_t n = j_unsigned;\n            CHECK(json(n) == j_unsigned);\n        }\n    }\n#endif\n\n    SECTION(\"get a floating-point number (explicit)\")\n    {\n        json::number_float_t n_reference{42.23};\n        json j(n_reference);\n\n        SECTION(\"number_float_t\")\n        {\n            auto n = j.get<json::number_float_t>();\n            CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));\n        }\n\n        SECTION(\"float\")\n        {\n            auto n = j.get<float>();\n            CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));\n        }\n\n        SECTION(\"double\")\n        {\n            auto n = j.get<double>();\n            CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));\n        }\n\n        SECTION(\"exception in case of a non-string type\")\n        {\n            CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(),\n                            json::type_error&);\n            CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(),\n                            json::type_error&);\n\n            CHECK_THROWS_WITH(\n                json(json::value_t::null).get<json::number_float_t>(),\n                \"[json.exception.type_error.302] type must be number, but is null\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::object).get<json::number_float_t>(),\n                \"[json.exception.type_error.302] type must be number, but is object\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::array).get<json::number_float_t>(),\n                \"[json.exception.type_error.302] type must be number, but is array\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::string).get<json::number_float_t>(),\n                \"[json.exception.type_error.302] type must be number, but is string\");\n            CHECK_THROWS_WITH(\n                json(json::value_t::boolean).get<json::number_float_t>(),\n                \"[json.exception.type_error.302] type must be number, but is \"\n                \"boolean\");\n\n            CHECK_NOTHROW(\n                json(json::value_t::number_integer).get<json::number_float_t>());\n            CHECK_NOTHROW(\n                json(json::value_t::number_unsigned).get<json::number_float_t>());\n        }\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"get a floating-point number (implicit)\")\n    {\n        json::number_float_t n_reference{42.23};\n        json j(n_reference);\n\n        SECTION(\"number_float_t\")\n        {\n            json::number_float_t n = j;\n            CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));\n        }\n\n        SECTION(\"float\")\n        {\n            float n = j;\n            CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));\n        }\n\n        SECTION(\"double\")\n        {\n            double n = j;\n            CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));\n        }\n    }\n#endif\n\n    SECTION(\"get a binary value (explicit)\")\n    {\n        json::binary_t n_reference{{1, 2, 3}};\n        json j(n_reference);\n\n        SECTION(\"binary_t\")\n        {\n            json::binary_t b = j.get<json::binary_t>();\n            CHECK(*json(b).m_value.binary == *j.m_value.binary);\n        }\n\n        SECTION(\"get_binary()\")\n        {\n            SECTION(\"non-const\")\n            {\n                auto& b = j.get_binary();\n                CHECK(*json(b).m_value.binary == *j.m_value.binary);\n            }\n\n            SECTION(\"non-const\")\n            {\n                const json j_const = j;\n                const auto& b = j_const.get_binary();\n                CHECK(*json(b).m_value.binary == *j.m_value.binary);\n            }\n        }\n\n        SECTION(\"exception in case of a non-string type\")\n        {\n            json j_null(json::value_t::null);\n            json j_object(json::value_t::object);\n            json j_array(json::value_t::array);\n            json j_string(json::value_t::string);\n            json j_boolean(json::value_t::boolean);\n            const json j_null_const(json::value_t::null);\n            const json j_object_const(json::value_t::object);\n            const json j_array_const(json::value_t::array);\n            const json j_string_const(json::value_t::string);\n            const json j_boolean_const(json::value_t::boolean);\n\n            CHECK_THROWS_WITH_AS(j_null.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is null\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_object.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is object\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_array.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is array\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_string.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is string\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_boolean.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is boolean\",\n                                 json::type_error&);\n\n            CHECK_THROWS_WITH_AS(j_null_const.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is null\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_object_const.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is object\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_array_const.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is array\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_string_const.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is string\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_boolean_const.get<json::binary_t>(),\n                                 \"[json.exception.type_error.302] type must be binary, but is boolean\",\n                                 json::type_error&);\n\n            CHECK_THROWS_WITH_AS(j_null.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is null\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_object.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is object\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_array.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is array\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_string.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is string\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_boolean.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is boolean\",\n                                 json::type_error&);\n\n            CHECK_THROWS_WITH_AS(j_null_const.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is null\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_object_const.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is object\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_array_const.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is array\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_string_const.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is string\",\n                                 json::type_error&);\n            CHECK_THROWS_WITH_AS(j_boolean_const.get_binary(),\n                                 \"[json.exception.type_error.302] type must be binary, but is boolean\",\n                                 json::type_error&);\n        }\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"get a binary value (implicit)\")\n    {\n        json::binary_t n_reference{{1, 2, 3}};\n        json j(n_reference);\n\n        SECTION(\"binary_t\")\n        {\n            json::binary_t b = j;\n            CHECK(*json(b).m_value.binary == *j.m_value.binary);\n        }\n    }\n#endif\n\n    SECTION(\"get an enum\")\n    {\n        enum c_enum { value_1, value_2 };\n        enum class cpp_enum { value_1, value_2 };\n\n        CHECK(json(value_1).get<c_enum>() == value_1);\n        CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);\n    }\n\n    SECTION(\"more involved conversions\")\n    {\n        SECTION(\"object-like STL containers\")\n        {\n            json j1 = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n            json j2 = {{\"one\", 1u}, {\"two\", 2u}, {\"three\", 3u}};\n            json j3 = {{\"one\", 1.1}, {\"two\", 2.2}, {\"three\", 3.3}};\n            json j4 = {{\"one\", true}, {\"two\", false}, {\"three\", true}};\n            json j5 = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}, {\"three\", \"drei\"}};\n\n            SECTION(\"std::map\")\n            {\n                j1.get<std::map<std::string, int>>();\n                j2.get<std::map<std::string, unsigned int>>();\n                j3.get<std::map<std::string, double>>();\n                j4.get<std::map<std::string, bool>>();\n                j5.get<std::map<std::string, std::string>>();\n            }\n\n            SECTION(\"std::unordered_map\")\n            {\n                j1.get<std::unordered_map<std::string, int>>();\n                j2.get<std::unordered_map<std::string, unsigned int>>();\n                j3.get<std::unordered_map<std::string, double>>();\n                j4.get<std::unordered_map<std::string, bool>>();\n                j5.get<std::unordered_map<std::string, std::string>>();\n                // CHECK(m5[\"one\"] == \"eins\");\n            }\n\n            SECTION(\"std::multimap\")\n            {\n                j1.get<std::multimap<std::string, int>>();\n                j2.get<std::multimap<std::string, unsigned int>>();\n                j3.get<std::multimap<std::string, double>>();\n                j4.get<std::multimap<std::string, bool>>();\n                j5.get<std::multimap<std::string, std::string>>();\n                // CHECK(m5[\"one\"] == \"eins\");\n            }\n\n            SECTION(\"std::unordered_multimap\")\n            {\n                j1.get<std::unordered_multimap<std::string, int>>();\n                j2.get<std::unordered_multimap<std::string, unsigned int>>();\n                j3.get<std::unordered_multimap<std::string, double>>();\n                j4.get<std::unordered_multimap<std::string, bool>>();\n                j5.get<std::unordered_multimap<std::string, std::string>>();\n                // CHECK(m5[\"one\"] == \"eins\");\n            }\n\n            SECTION(\"exception in case of a non-object type\")\n            {\n                CHECK_THROWS_AS((json().get<std::map<std::string, int>>()),\n                                json::type_error&);\n                CHECK_THROWS_WITH(\n                    (json().get<std::map<std::string, int>>()),\n                    \"[json.exception.type_error.302] type must be object, but is null\");\n            }\n        }\n\n        SECTION(\"array-like STL containers\")\n        {\n            json j1 = {1, 2, 3, 4};\n            json j2 = {1u, 2u, 3u, 4u};\n            json j3 = {1.2, 2.3, 3.4, 4.5};\n            json j4 = {true, false, true};\n            json j5 = {\"one\", \"two\", \"three\"};\n\n            SECTION(\"std::list\")\n            {\n                j1.get<std::list<int>>();\n                j2.get<std::list<unsigned int>>();\n                j3.get<std::list<double>>();\n                j4.get<std::list<bool>>();\n                j5.get<std::list<std::string>>();\n            }\n\n            SECTION(\"std::forward_list\")\n            {\n                j1.get<std::forward_list<int>>();\n                j2.get<std::forward_list<unsigned int>>();\n                j3.get<std::forward_list<double>>();\n                j4.get<std::forward_list<bool>>();\n                j5.get<std::forward_list<std::string>>();\n            }\n\n            SECTION(\"std::array\")\n            {\n                j1.get<std::array<int, 4>>();\n                j2.get<std::array<unsigned int, 3>>();\n                j3.get<std::array<double, 4>>();\n                j4.get<std::array<bool, 3>>();\n                j5.get<std::array<std::string, 3>>();\n\n                SECTION(\"std::array is larger than JSON\")\n                {\n                    std::array<int, 6> arr6 = {{1, 2, 3, 4, 5, 6}};\n                    CHECK_THROWS_AS(j1.get_to(arr6), json::out_of_range&);\n                    CHECK_THROWS_WITH(j1.get_to(arr6), \"[json.exception.out_of_range.401] \"\n                                      \"array index 4 is out of range\");\n                }\n\n                SECTION(\"std::array is smaller than JSON\")\n                {\n                    std::array<int, 2> arr2 = {{8, 9}};\n                    j1.get_to(arr2);\n                    CHECK(arr2[0] == 1);\n                    CHECK(arr2[1] == 2);\n                }\n            }\n\n            SECTION(\"std::valarray\")\n            {\n                j1.get<std::valarray<int>>();\n                j2.get<std::valarray<unsigned int>>();\n                j3.get<std::valarray<double>>();\n                j4.get<std::valarray<bool>>();\n                j5.get<std::valarray<std::string>>();\n            }\n\n            SECTION(\"std::vector\")\n            {\n                j1.get<std::vector<int>>();\n                j2.get<std::vector<unsigned int>>();\n                j3.get<std::vector<double>>();\n                j4.get<std::vector<bool>>();\n                j5.get<std::vector<std::string>>();\n            }\n\n            SECTION(\"std::deque\")\n            {\n                j1.get<std::deque<int>>();\n                j2.get<std::deque<unsigned int>>();\n                j2.get<std::deque<double>>();\n                j4.get<std::deque<bool>>();\n                j5.get<std::deque<std::string>>();\n            }\n\n            SECTION(\"std::set\")\n            {\n                j1.get<std::set<int>>();\n                j2.get<std::set<unsigned int>>();\n                j3.get<std::set<double>>();\n                j4.get<std::set<bool>>();\n                j5.get<std::set<std::string>>();\n            }\n\n            SECTION(\"std::unordered_set\")\n            {\n                j1.get<std::unordered_set<int>>();\n                j2.get<std::unordered_set<unsigned int>>();\n                j3.get<std::unordered_set<double>>();\n                j4.get<std::unordered_set<bool>>();\n                j5.get<std::unordered_set<std::string>>();\n            }\n\n            SECTION(\"std::map (array of pairs)\")\n            {\n                std::map<int, int> m{{0, 1}, {1, 2}, {2, 3}};\n                json j6 = m;\n\n                auto m2 = j6.get<std::map<int, int>>();\n                CHECK(m == m2);\n\n                json j7 = {0, 1, 2, 3};\n                json j8 = 2;\n                CHECK_THROWS_AS((j7.get<std::map<int, int>>()), json::type_error&);\n                CHECK_THROWS_AS((j8.get<std::map<int, int>>()), json::type_error&);\n                CHECK_THROWS_WITH((j7.get<std::map<int, int>>()),\n                                  \"[json.exception.type_error.302] type must be array, \"\n                                  \"but is number\");\n                CHECK_THROWS_WITH((j8.get<std::map<int, int>>()),\n                                  \"[json.exception.type_error.302] type must be array, \"\n                                  \"but is number\");\n\n                SECTION(\"superfluous entries\")\n                {\n                    json j9 = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};\n                    m2 = j9.get<std::map<int, int>>();\n                    CHECK(m == m2);\n                }\n            }\n\n            SECTION(\"std::unordered_map (array of pairs)\")\n            {\n                std::unordered_map<int, int> m{{0, 1}, {1, 2}, {2, 3}};\n                json j6 = m;\n\n                auto m2 = j6.get<std::unordered_map<int, int>>();\n                CHECK(m == m2);\n\n                json j7 = {0, 1, 2, 3};\n                json j8 = 2;\n                CHECK_THROWS_AS((j7.get<std::unordered_map<int, int>>()), json::type_error&);\n                CHECK_THROWS_AS((j8.get<std::unordered_map<int, int>>()), json::type_error&);\n                CHECK_THROWS_WITH((j7.get<std::unordered_map<int, int>>()),\n                                  \"[json.exception.type_error.302] type must be array, \"\n                                  \"but is number\");\n                CHECK_THROWS_WITH((j8.get<std::unordered_map<int, int>>()),\n                                  \"[json.exception.type_error.302] type must be array, \"\n                                  \"but is number\");\n\n                SECTION(\"superfluous entries\")\n                {\n                    json j9{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};\n                    m2 = j9.get<std::unordered_map<int, int>>();\n                    CHECK(m == m2);\n                }\n            }\n\n            SECTION(\"exception in case of a non-object type\")\n            {\n                CHECK_THROWS_AS((json().get<std::list<int>>()), json::type_error&);\n                CHECK_THROWS_AS((json().get<std::vector<int>>()), json::type_error&);\n                CHECK_THROWS_AS((json().get<std::vector<json>>()), json::type_error&);\n                CHECK_THROWS_AS((json().get<std::list<json>>()), json::type_error&);\n                CHECK_THROWS_AS((json().get<std::valarray<int>>()), json::type_error&);\n\n                // does type really must be an array? or it rather must not be null?\n                // that's what I thought when other test like this one broke\n                CHECK_THROWS_WITH(\n                    (json().get<std::list<int>>()),\n                    \"[json.exception.type_error.302] type must be array, but is null\");\n                CHECK_THROWS_WITH(\n                    (json().get<std::vector<int>>()),\n                    \"[json.exception.type_error.302] type must be array, but is null\");\n                CHECK_THROWS_WITH(\n                    (json().get<std::vector<json>>()),\n                    \"[json.exception.type_error.302] type must be array, but is null\");\n                CHECK_THROWS_WITH(\n                    (json().get<std::list<json>>()),\n                    \"[json.exception.type_error.302] type must be array, but is null\");\n                CHECK_THROWS_WITH(\n                    (json().get<std::valarray<int>>()),\n                    \"[json.exception.type_error.302] type must be array, but is null\");\n                CHECK_THROWS_WITH(\n                    (json().get<std::map<int, int>>()),\n                    \"[json.exception.type_error.302] type must be array, but is null\");\n            }\n        }\n    }\n}\n\nenum class cards {kreuz, pik, herz, karo};\n\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive\nNLOHMANN_JSON_SERIALIZE_ENUM(cards,\n{\n    {cards::kreuz, \"kreuz\"},\n    {cards::pik, \"pik\"},\n    {cards::pik, \"puk\"},  // second entry for cards::puk; will not be used\n    {cards::herz, \"herz\"},\n    {cards::karo, \"karo\"}\n})\n\nenum TaskState\n{\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID = -1,\n};\n\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState,\n{\n    {TS_INVALID, nullptr},\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n\nTEST_CASE(\"JSON to enum mapping\")\n{\n    SECTION(\"enum class\")\n    {\n        // enum -> json\n        CHECK(json(cards::kreuz) == \"kreuz\");\n        CHECK(json(cards::pik) == \"pik\");\n        CHECK(json(cards::herz) == \"herz\");\n        CHECK(json(cards::karo) == \"karo\");\n\n        // json -> enum\n        CHECK(cards::kreuz == json(\"kreuz\"));\n        CHECK(cards::pik == json(\"pik\"));\n        CHECK(cards::herz == json(\"herz\"));\n        CHECK(cards::karo == json(\"karo\"));\n\n        // invalid json -> first enum\n        CHECK(cards::kreuz == json(\"what?\").get<cards>());\n    }\n\n    SECTION(\"traditional enum\")\n    {\n        // enum -> json\n        CHECK(json(TS_STOPPED) == \"stopped\");\n        CHECK(json(TS_RUNNING) == \"running\");\n        CHECK(json(TS_COMPLETED) == \"completed\");\n        CHECK(json(TS_INVALID) == json());\n\n        // json -> enum\n        CHECK(TS_STOPPED == json(\"stopped\"));\n        CHECK(TS_RUNNING == json(\"running\"));\n        CHECK(TS_COMPLETED == json(\"completed\"));\n        CHECK(TS_INVALID == json());\n\n        // invalid json -> first enum\n        CHECK(TS_INVALID == json(\"what?\").get<TaskState>());\n    }\n}\n\n#ifdef JSON_HAS_CPP_17\n    #undef JSON_HAS_CPP_17\n#endif\n\n#ifdef JSON_HAS_CPP_14\n    #undef JSON_HAS_CPP_14\n#endif\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-deserialization.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <iostream>\n#include <sstream>\n#include <valarray>\n\nnamespace\n{\nstruct SaxEventLogger : public nlohmann::json_sax<json>\n{\n    bool null() override\n    {\n        events.emplace_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.emplace_back(val ? \"boolean(true)\" : \"boolean(false)\");\n        return true;\n    }\n\n    bool number_integer(json::number_integer_t val) override\n    {\n        events.push_back(\"number_integer(\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(json::number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(json::number_float_t /*val*/, const std::string& s) override\n    {\n        events.push_back(\"number_float(\" + s + \")\");\n        return true;\n    }\n\n    bool string(std::string& val) override\n    {\n        events.push_back(\"string(\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        std::string binary_contents = \"binary(\";\n        std::string comma_space;\n        for (auto b : val)\n        {\n            binary_contents.append(comma_space);\n            binary_contents.append(std::to_string(static_cast<int>(b)));\n            comma_space = \", \";\n        }\n        binary_contents.append(\")\");\n        events.push_back(binary_contents);\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        if (elements == static_cast<std::size_t>(-1))\n        {\n            events.emplace_back(\"start_object()\");\n        }\n        else\n        {\n            events.push_back(\"start_object(\" + std::to_string(elements) + \")\");\n        }\n        return true;\n    }\n\n    bool key(std::string& val) override\n    {\n        events.push_back(\"key(\" + val + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.emplace_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        if (elements == static_cast<std::size_t>(-1))\n        {\n            events.emplace_back(\"start_array()\");\n        }\n        else\n        {\n            events.push_back(\"start_array(\" + std::to_string(elements) + \")\");\n        }\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.emplace_back(\"end_array()\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& /*last_token*/, const json::exception& /*ex*/) override\n    {\n        events.push_back(\"parse_error(\" + std::to_string(position) + \")\");\n        return false;\n    }\n\n    std::vector<std::string> events {};\n};\n\nstruct SaxEventLoggerExitAfterStartObject : public SaxEventLogger\n{\n    bool start_object(std::size_t elements) override\n    {\n        if (elements == static_cast<std::size_t>(-1))\n        {\n            events.emplace_back(\"start_object()\");\n        }\n        else\n        {\n            events.push_back(\"start_object(\" + std::to_string(elements) + \")\");\n        }\n        return false;\n    }\n};\n\nstruct SaxEventLoggerExitAfterKey : public SaxEventLogger\n{\n    bool key(std::string& val) override\n    {\n        events.push_back(\"key(\" + val + \")\");\n        return false;\n    }\n};\n\nstruct SaxEventLoggerExitAfterStartArray : public SaxEventLogger\n{\n    bool start_array(std::size_t elements) override\n    {\n        if (elements == static_cast<std::size_t>(-1))\n        {\n            events.emplace_back(\"start_array()\");\n        }\n        else\n        {\n            events.push_back(\"start_array(\" + std::to_string(elements) + \")\");\n        }\n        return false;\n    }\n};\n} // namespace\n\nTEST_CASE(\"deserialization\")\n{\n    SECTION(\"successful deserialization\")\n    {\n        SECTION(\"stream\")\n        {\n            std::stringstream ss1;\n            std::stringstream ss2;\n            std::stringstream ss3;\n            ss1 << R\"([\"foo\",1,2,3,false,{\"one\":1}])\";\n            ss2 << R\"([\"foo\",1,2,3,false,{\"one\":1}])\";\n            ss3 << R\"([\"foo\",1,2,3,false,{\"one\":1}])\";\n            json j = json::parse(ss1);\n            CHECK(json::accept(ss2));\n            CHECK(j == json({\"foo\", 1, 2, 3, false, {{\"one\", 1}}}));\n\n            SaxEventLogger l;\n            CHECK(json::sax_parse(ss3, &l));\n            CHECK(l.events.size() == 11);\n            CHECK(l.events == std::vector<std::string>(\n            {\n                \"start_array()\", \"string(foo)\", \"number_unsigned(1)\",\n                \"number_unsigned(2)\", \"number_unsigned(3)\", \"boolean(false)\",\n                \"start_object()\", \"key(one)\", \"number_unsigned(1)\",\n                \"end_object()\", \"end_array()\"\n            }));\n        }\n\n        SECTION(\"string literal\")\n        {\n            const auto* s = R\"([\"foo\",1,2,3,false,{\"one\":1}])\";\n            json j = json::parse(s);\n            CHECK(json::accept(s));\n            CHECK(j == json({\"foo\", 1, 2, 3, false, {{\"one\", 1}}}));\n\n            SaxEventLogger l;\n            CHECK(json::sax_parse(s, &l));\n            CHECK(l.events.size() == 11);\n            CHECK(l.events == std::vector<std::string>(\n            {\n                \"start_array()\", \"string(foo)\", \"number_unsigned(1)\",\n                \"number_unsigned(2)\", \"number_unsigned(3)\", \"boolean(false)\",\n                \"start_object()\", \"key(one)\", \"number_unsigned(1)\",\n                \"end_object()\", \"end_array()\"\n            }));\n        }\n\n        SECTION(\"string_t\")\n        {\n            json::string_t s = R\"([\"foo\",1,2,3,false,{\"one\":1}])\";\n            json j = json::parse(s);\n            CHECK(json::accept(s));\n            CHECK(j == json({\"foo\", 1, 2, 3, false, {{\"one\", 1}}}));\n\n            SaxEventLogger l;\n            CHECK(json::sax_parse(s, &l));\n            CHECK(l.events.size() == 11);\n            CHECK(l.events == std::vector<std::string>(\n            {\n                \"start_array()\", \"string(foo)\", \"number_unsigned(1)\",\n                \"number_unsigned(2)\", \"number_unsigned(3)\", \"boolean(false)\",\n                \"start_object()\", \"key(one)\", \"number_unsigned(1)\",\n                \"end_object()\", \"end_array()\"\n            }));\n        }\n\n        SECTION(\"operator<<\")\n        {\n            std::stringstream ss;\n            ss << R\"([\"foo\",1,2,3,false,{\"one\":1}])\";\n            json j;\n            j << ss;\n            CHECK(j == json({\"foo\", 1, 2, 3, false, {{\"one\", 1}}}));\n        }\n\n        SECTION(\"operator>>\")\n        {\n            std::stringstream ss;\n            ss << R\"([\"foo\",1,2,3,false,{\"one\":1}])\";\n            json j;\n            ss >> j;\n            CHECK(j == json({\"foo\", 1, 2, 3, false, {{\"one\", 1}}}));\n        }\n\n        SECTION(\"user-defined string literal\")\n        {\n            CHECK(\"[\\\"foo\\\",1,2,3,false,{\\\"one\\\":1}]\"_json == json({\"foo\", 1, 2, 3, false, {{\"one\", 1}}}));\n        }\n    }\n\n    SECTION(\"unsuccessful deserialization\")\n    {\n        SECTION(\"stream\")\n        {\n            std::stringstream ss1;\n            std::stringstream ss2;\n            std::stringstream ss3;\n            std::stringstream ss4;\n            std::stringstream ss5;\n            ss1 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            ss2 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            ss3 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            ss4 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            ss5 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(ss1), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(ss2),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'\");\n            CHECK(!json::accept(ss3));\n\n            json j_error;\n            CHECK_NOTHROW(j_error = json::parse(ss4, nullptr, false));\n            CHECK(j_error.is_discarded());\n\n            SaxEventLogger l;\n            CHECK(!json::sax_parse(ss5, &l));\n            CHECK(l.events.size() == 11);\n            CHECK(l.events == std::vector<std::string>(\n            {\n                \"start_array()\", \"string(foo)\", \"number_unsigned(1)\",\n                \"number_unsigned(2)\", \"number_unsigned(3)\", \"boolean(false)\",\n                \"start_object()\", \"key(one)\", \"number_unsigned(1)\",\n                \"end_object()\", \"parse_error(29)\"\n            }));\n        }\n\n        SECTION(\"string\")\n        {\n            json::string_t s = R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(s), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(s),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'\");\n            CHECK(!json::accept(s));\n\n            json j_error;\n            CHECK_NOTHROW(j_error = json::parse(s, nullptr, false));\n            CHECK(j_error.is_discarded());\n\n            SaxEventLogger l;\n            CHECK(!json::sax_parse(s, &l));\n            CHECK(l.events.size() == 11);\n            CHECK(l.events == std::vector<std::string>(\n            {\n                \"start_array()\", \"string(foo)\", \"number_unsigned(1)\",\n                \"number_unsigned(2)\", \"number_unsigned(3)\", \"boolean(false)\",\n                \"start_object()\", \"key(one)\", \"number_unsigned(1)\",\n                \"end_object()\", \"parse_error(29)\"\n            }));\n        }\n\n        SECTION(\"operator<<\")\n        {\n            std::stringstream ss1;\n            std::stringstream ss2;\n            ss1 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            ss2 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            json j;\n            CHECK_THROWS_AS(j << ss1, json::parse_error&);\n            CHECK_THROWS_WITH(j << ss2,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'\");\n        }\n\n        SECTION(\"operator>>\")\n        {\n            std::stringstream ss1;\n            std::stringstream ss2;\n            ss1 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            ss2 << R\"([\"foo\",1,2,3,false,{\"one\":1})\";\n            json j;\n            CHECK_THROWS_AS(ss1 >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss2 >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'\");\n        }\n\n        SECTION(\"user-defined string literal\")\n        {\n            CHECK_THROWS_AS(\"[\\\"foo\\\",1,2,3,false,{\\\"one\\\":1}\"_json, json::parse_error&);\n            CHECK_THROWS_WITH(\"[\\\"foo\\\",1,2,3,false,{\\\"one\\\":1}\"_json,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'\");\n        }\n    }\n\n    SECTION(\"contiguous containers\")\n    {\n        SECTION(\"directly\")\n        {\n            SECTION(\"from std::vector\")\n            {\n                std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};\n                CHECK(json::parse(v) == json(true));\n                CHECK(json::accept(v));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(v, &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from std::array\")\n            {\n                std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };\n                CHECK(json::parse(v) == json(true));\n                CHECK(json::accept(v));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(v, &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from array\")\n            {\n                uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n                CHECK(json::parse(v) == json(true));\n                CHECK(json::accept(v));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(v, &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from chars\")\n            {\n                auto* v = new uint8_t[5]; // NOLINT(cppcoreguidelines-owning-memory)\n                v[0] = 't';\n                v[1] = 'r';\n                v[2] = 'u';\n                v[3] = 'e';\n                v[4] = '\\0';\n                CHECK(json::parse(v) == json(true));\n                CHECK(json::accept(v));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(v, &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n\n                delete[] v; // NOLINT(cppcoreguidelines-owning-memory)\n            }\n\n            SECTION(\"from std::string\")\n            {\n                std::string v = {'t', 'r', 'u', 'e'};\n                CHECK(json::parse(v) == json(true));\n                CHECK(json::accept(v));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(v, &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from std::initializer_list\")\n            {\n                std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};\n                CHECK(json::parse(v) == json(true));\n                CHECK(json::accept(v));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(v, &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"empty container\")\n            {\n                std::vector<uint8_t> v;\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(v), json::parse_error&);\n                CHECK(!json::accept(v));\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(v, &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(1)\"}));\n            }\n        }\n\n        SECTION(\"via iterator range\")\n        {\n            SECTION(\"from std::vector\")\n            {\n                std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};\n                CHECK(json::parse(std::begin(v), std::end(v)) == json(true));\n                CHECK(json::accept(std::begin(v), std::end(v)));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n\n            }\n\n            SECTION(\"from std::array\")\n            {\n                std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };\n                CHECK(json::parse(std::begin(v), std::end(v)) == json(true));\n                CHECK(json::accept(std::begin(v), std::end(v)));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from array\")\n            {\n                uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n                CHECK(json::parse(std::begin(v), std::end(v)) == json(true));\n                CHECK(json::accept(std::begin(v), std::end(v)));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from std::string\")\n            {\n                std::string v = {'t', 'r', 'u', 'e'};\n                CHECK(json::parse(std::begin(v), std::end(v)) == json(true));\n                CHECK(json::accept(std::begin(v), std::end(v)));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from std::initializer_list\")\n            {\n                std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};\n                CHECK(json::parse(std::begin(v), std::end(v)) == json(true));\n                CHECK(json::accept(std::begin(v), std::end(v)));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"from std::valarray\")\n            {\n                std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};\n                CHECK(json::parse(std::begin(v), std::end(v)) == json(true));\n                CHECK(json::accept(std::begin(v), std::end(v)));\n\n                SaxEventLogger l;\n                CHECK(json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n            }\n\n            SECTION(\"with empty range\")\n            {\n                std::vector<uint8_t> v;\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(1)\"}));\n            }\n        }\n\n        // these cases are required for 100% line coverage\n        SECTION(\"error cases\")\n        {\n            SECTION(\"case 1\")\n            {\n                std::array<std::uint8_t, 9> v = {{'\\\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\\\', 'u'}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(10)\"}));\n            }\n\n            SECTION(\"case 2\")\n            {\n                std::array<std::uint8_t, 10> v = {{'\\\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\\\', 'u', '1'}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(11)\"}));\n            }\n\n            SECTION(\"case 3\")\n            {\n                std::array<std::uint8_t, 17> v = {{'\\\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(18)\"}));\n            }\n\n            SECTION(\"case 4\")\n            {\n                std::array<std::uint8_t, 17> v = {{'\\\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\\\'}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(18)\"}));\n            }\n\n            SECTION(\"case 5\")\n            {\n                std::array<std::uint8_t, 3> v = {{'\\\"', 0x7F, 0xC1}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(3)\"}));\n            }\n\n            SECTION(\"case 6\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xDF, 0x7F}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(std::begin(v), std::end(v)),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\\\"\\x7f\\xdf\\x7f'\");\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 7\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xDF, 0xC0}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 8\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xE0, 0x9F}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 9\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xEF, 0xC0}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 10\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xED, 0x7F}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 11\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xF0, 0x8F}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 12\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xF0, 0xC0}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 13\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xF3, 0x7F}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 14\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xF3, 0xC0}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 15\")\n            {\n                std::array<std::uint8_t, 4> v = {{'\\\"', 0x7F, 0xF4, 0x7F}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 1);\n                CHECK(l.events == std::vector<std::string>({\"parse_error(4)\"}));\n            }\n\n            SECTION(\"case 16\")\n            {\n                std::array<std::uint8_t, 6> v = {{'{', '\\\"', '\\\"', ':', '1', '1'}};\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);\n                CHECK(!json::accept(std::begin(v), std::end(v)));\n\n                json j_error;\n                CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));\n                CHECK(j_error.is_discarded());\n\n                SaxEventLogger l;\n                CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));\n                CHECK(l.events.size() == 4);\n                CHECK(l.events == std::vector<std::string>(\n                {\n                    \"start_object()\", \"key()\", \"number_unsigned(11)\",\n                    \"parse_error(7)\"\n                }));\n            }\n        }\n    }\n\n    SECTION(\"ignoring byte-order marks\")\n    {\n        std::string bom = \"\\xEF\\xBB\\xBF\";\n\n        SECTION(\"BOM only\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(bom), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(bom),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n\n            CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom)), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom)),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n\n            SaxEventLogger l;\n            CHECK(!json::sax_parse(bom, &l));\n            CHECK(l.events.size() == 1);\n            CHECK(l.events == std::vector<std::string>(\n            {\n                \"parse_error(4)\"\n            }));\n        }\n\n        SECTION(\"BOM and content\")\n        {\n            CHECK(json::parse(bom + \"1\") == 1);\n            CHECK(json::parse(std::istringstream(bom + \"1\")) == 1);\n\n            SaxEventLogger l1;\n            SaxEventLogger l2;\n            CHECK(json::sax_parse(std::istringstream(bom + \"1\"), &l1));\n            CHECK(json::sax_parse(bom + \"1\", &l2));\n            CHECK(l1.events.size() == 1);\n            CHECK(l1.events == std::vector<std::string>(\n            {\n                \"number_unsigned(1)\"\n            }));\n            CHECK(l2.events.size() == 1);\n            CHECK(l2.events == std::vector<std::string>(\n            {\n                \"number_unsigned(1)\"\n            }));\n        }\n\n        SECTION(\"2 byte of BOM\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 2)), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 2)),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\\xEF\\xBB'\");\n\n            CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 2))), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 2))),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\\xEF\\xBB'\");\n\n            SaxEventLogger l1;\n            SaxEventLogger l2;\n            CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1));\n            CHECK(!json::sax_parse(bom.substr(0, 2), &l2));\n            CHECK(l1.events.size() == 1);\n            CHECK(l1.events == std::vector<std::string>(\n            {\n                \"parse_error(3)\"\n            }));\n            CHECK(l2.events.size() == 1);\n            CHECK(l2.events == std::vector<std::string>(\n            {\n                \"parse_error(3)\"\n            }));\n        }\n\n        SECTION(\"1 byte of BOM\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 1)), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 1)),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\\xEF'\");\n\n            CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 1))), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 1))),\n                              \"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\\xEF'\");\n\n            SaxEventLogger l1;\n            SaxEventLogger l2;\n            CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1));\n            CHECK(!json::sax_parse(bom.substr(0, 1), &l2));\n            CHECK(l1.events.size() == 1);\n            CHECK(l1.events == std::vector<std::string>(\n            {\n                \"parse_error(2)\"\n            }));\n            CHECK(l2.events.size() == 1);\n            CHECK(l2.events == std::vector<std::string>(\n            {\n                \"parse_error(2)\"\n            }));\n        }\n\n        SECTION(\"variations\")\n        {\n            // calculate variations of each byte of the BOM to make sure\n            // that the BOM and only the BOM is skipped\n            for (int i0 = -1; i0 < 2; ++i0)\n            {\n                for (int i1 = -1; i1 < 2; ++i1)\n                {\n                    for (int i2 = -1; i2 < 2; ++i2)\n                    {\n                        // debug output for the variations\n                        CAPTURE(i0)\n                        CAPTURE(i1)\n                        CAPTURE(i2)\n\n                        std::string s;\n                        s.push_back(static_cast<char>(bom[0] + i0));\n                        s.push_back(static_cast<char>(bom[1] + i1));\n                        s.push_back(static_cast<char>(bom[2] + i2));\n\n                        if (i0 == 0 && i1 == 0 && i2 == 0)\n                        {\n                            // without any variation, we skip the BOM\n                            CHECK(json::parse(s + \"null\") == json());\n                            CHECK(json::parse(std::istringstream(s + \"null\")) == json());\n\n                            SaxEventLogger l;\n                            CHECK(json::sax_parse(s + \"null\", &l));\n                            CHECK(l.events.size() == 1);\n                            CHECK(l.events == std::vector<std::string>(\n                            {\n                                \"null()\"\n                            }));\n                        }\n                        else\n                        {\n                            // any variation is an error\n                            json _;\n                            CHECK_THROWS_AS(_ = json::parse(s + \"null\"), json::parse_error&);\n                            CHECK_THROWS_AS(_ = json::parse(std::istringstream(s + \"null\")), json::parse_error&);\n\n                            SaxEventLogger l;\n                            CHECK(!json::sax_parse(s + \"null\", &l));\n                            CHECK(l.events.size() == 1);\n\n                            if (i0 != 0)\n                            {\n                                CHECK(l.events == std::vector<std::string>(\n                                {\n                                    \"parse_error(1)\"\n                                }));\n                            }\n                            else if (i1 != 0)\n                            {\n                                CHECK(l.events == std::vector<std::string>(\n                                {\n                                    \"parse_error(2)\"\n                                }));\n                            }\n                            else\n                            {\n                                CHECK(l.events == std::vector<std::string>(\n                                {\n                                    \"parse_error(3)\"\n                                }));\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        SECTION(\"preserve state after parsing\")\n        {\n            std::istringstream s(bom + \"123 456\");\n            json j;\n            j << s;\n            CHECK(j == 123);\n            j << s;\n            CHECK(j == 456);\n        }\n    }\n\n    SECTION(\"SAX and early abort\")\n    {\n        std::string s = R\"([1, [\"string\", 43.12], null, {\"key1\": true, \"key2\": false}])\";\n\n        SaxEventLogger default_logger;\n        SaxEventLoggerExitAfterStartObject exit_after_start_object;\n        SaxEventLoggerExitAfterKey exit_after_key;\n        SaxEventLoggerExitAfterStartArray exit_after_start_array;\n\n        json::sax_parse(s, &default_logger);\n        CHECK(default_logger.events.size() == 14);\n        CHECK(default_logger.events == std::vector<std::string>(\n        {\n            \"start_array()\", \"number_unsigned(1)\", \"start_array()\",\n            \"string(string)\", \"number_float(43.12)\", \"end_array()\", \"null()\",\n            \"start_object()\", \"key(key1)\", \"boolean(true)\", \"key(key2)\",\n            \"boolean(false)\", \"end_object()\", \"end_array()\"\n        }));\n\n        json::sax_parse(s, &exit_after_start_object);\n        CHECK(exit_after_start_object.events.size() == 8);\n        CHECK(exit_after_start_object.events == std::vector<std::string>(\n        {\n            \"start_array()\", \"number_unsigned(1)\", \"start_array()\",\n            \"string(string)\", \"number_float(43.12)\", \"end_array()\", \"null()\",\n            \"start_object()\"\n        }));\n\n        json::sax_parse(s, &exit_after_key);\n        CHECK(exit_after_key.events.size() == 9);\n        CHECK(exit_after_key.events == std::vector<std::string>(\n        {\n            \"start_array()\", \"number_unsigned(1)\", \"start_array()\",\n            \"string(string)\", \"number_float(43.12)\", \"end_array()\", \"null()\",\n            \"start_object()\", \"key(key1)\"\n        }));\n\n        json::sax_parse(s, &exit_after_start_array);\n        CHECK(exit_after_start_array.events.size() == 1);\n        CHECK(exit_after_start_array.events == std::vector<std::string>(\n        {\n            \"start_array()\"\n        }));\n    }\n}\n\nTEST_CASE_TEMPLATE(\"deserialization of different character types (ASCII)\", T,\n                   char, unsigned char, signed char,\n                   wchar_t,\n                   char16_t, char32_t,\n                   std::uint8_t, std::int8_t,\n                   std::int16_t, std::uint16_t,\n                   std::int32_t, std::uint32_t)\n{\n    std::vector<T> v = {'t', 'r', 'u', 'e'};\n    CHECK(json::parse(v) == json(true));\n    CHECK(json::accept(v));\n\n    SaxEventLogger l;\n    CHECK(json::sax_parse(v, &l));\n    CHECK(l.events.size() == 1);\n    CHECK(l.events == std::vector<std::string>({\"boolean(true)\"}));\n}\n\nTEST_CASE_TEMPLATE(\"deserialization of different character types (UTF-8)\", T,\n                   char, unsigned char, std::uint8_t)\n{\n    // a star emoji\n    std::vector<T> v = {'\"', static_cast<T>(0xe2u), static_cast<T>(0xadu), static_cast<T>(0x90u), static_cast<T>(0xefu), static_cast<T>(0xb8u), static_cast<T>(0x8fu), '\"'};\n    CHECK(json::parse(v).dump(-1, ' ', true) == \"\\\"\\\\u2b50\\\\ufe0f\\\"\");\n    CHECK(json::accept(v));\n\n    SaxEventLogger l;\n    CHECK(json::sax_parse(v, &l));\n    CHECK(l.events.size() == 1);\n}\n\nTEST_CASE_TEMPLATE(\"deserialization of different character types (UTF-16)\", T,\n                   char16_t, std::uint16_t)\n{\n    // a star emoji\n    std::vector<T> v = {static_cast<T>('\"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('\"')};\n    CHECK(json::parse(v).dump(-1, ' ', true) == \"\\\"\\\\u2b50\\\\ufe0f\\\"\");\n    CHECK(json::accept(v));\n\n    SaxEventLogger l;\n    CHECK(json::sax_parse(v, &l));\n    CHECK(l.events.size() == 1);\n}\n\nTEST_CASE_TEMPLATE(\"deserialization of different character types (UTF-32)\", T,\n                   char32_t, std::uint32_t)\n{\n    // a star emoji\n    std::vector<T> v = {static_cast<T>('\"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('\"')};\n    CHECK(json::parse(v).dump(-1, ' ', true) == \"\\\"\\\\u2b50\\\\ufe0f\\\"\");\n    CHECK(json::accept(v));\n\n    SaxEventLogger l;\n    CHECK(json::sax_parse(v, &l));\n    CHECK(l.events.size() == 1);\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-diagnostics.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#ifdef JSON_DIAGNOSTICS\n    #undef JSON_DIAGNOSTICS\n#endif\n\n#define JSON_DIAGNOSTICS 1\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"Better diagnostics\")\n{\n    SECTION(\"empty JSON Pointer\")\n    {\n        json j = 1;\n        std::string s;\n        CHECK_THROWS_WITH_AS(s = j.get<std::string>(), \"[json.exception.type_error.302] type must be string, but is number\", json::type_error);\n    }\n\n    SECTION(\"invalid type\")\n    {\n        json j;\n        j[\"a\"][\"b\"][\"c\"] = 1;\n        std::string s;\n        CHECK_THROWS_WITH_AS(s = j[\"a\"][\"b\"][\"c\"].get<std::string>(), \"[json.exception.type_error.302] (/a/b/c) type must be string, but is number\", json::type_error);\n    }\n\n    SECTION(\"missing key\")\n    {\n        json j;\n        j[\"object\"][\"object\"] = true;\n        CHECK_THROWS_WITH_AS(j[\"object\"].at(\"not_found\"), \"[json.exception.out_of_range.403] (/object) key 'not_found' not found\", json::out_of_range);\n    }\n\n    SECTION(\"array index out of range\")\n    {\n        json j;\n        j[\"array\"][4] = true;\n        CHECK_THROWS_WITH_AS(j[\"array\"].at(5), \"[json.exception.out_of_range.401] (/array) array index 5 is out of range\", json::out_of_range);\n    }\n\n    SECTION(\"array index at wrong type\")\n    {\n        json j;\n        j[\"array\"][4] = true;\n        CHECK_THROWS_WITH_AS(j[\"array\"][4][5], \"[json.exception.type_error.305] (/array/4) cannot use operator[] with a numeric argument with boolean\", json::type_error);\n    }\n\n    SECTION(\"wrong iterator\")\n    {\n        json j;\n        j[\"array\"] = json::array();\n        CHECK_THROWS_WITH_AS(j[\"array\"].erase(j.begin()), \"[json.exception.invalid_iterator.202] (/array) iterator does not fit current value\", json::invalid_iterator);\n    }\n\n    SECTION(\"JSON Pointer escaping\")\n    {\n        json j;\n        j[\"a/b\"][\"m~n\"] = 1;\n        std::string s;\n        CHECK_THROWS_WITH_AS(s = j[\"a/b\"][\"m~n\"].get<std::string>(), \"[json.exception.type_error.302] (/a~1b/m~0n) type must be string, but is number\", json::type_error);\n    }\n\n    SECTION(\"Parse error\")\n    {\n        json _;\n        CHECK_THROWS_WITH_AS(_ = json::parse(\"\"), \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\", json::parse_error);\n    }\n\n    SECTION(\"Wrong type in update()\")\n    {\n        json j = {{\"foo\", \"bar\"}};\n        json k = {{\"bla\", 1}};\n\n        CHECK_THROWS_WITH_AS(j.update(k[\"bla\"].begin(), k[\"bla\"].end()), \"[json.exception.type_error.312] (/bla) cannot use update() with number\", json::type_error);\n        CHECK_THROWS_WITH_AS(j.update(k[\"bla\"]), \"[json.exception.type_error.312] (/bla) cannot use update() with number\", json::type_error);\n    }\n}\n\nTEST_CASE(\"Regression tests for extended diagnostics\")\n{\n    SECTION(\"Regression test for https://github.com/nlohmann/json/pull/2562#pullrequestreview-574858448\")\n    {\n        CHECK_THROWS_WITH_AS(json({\"0\", \"0\"})[1].get<int>(), \"[json.exception.type_error.302] (/1) type must be number, but is string\", json::type_error);\n        CHECK_THROWS_WITH_AS(json({\"0\", \"1\"})[1].get<int>(), \"[json.exception.type_error.302] (/1) type must be number, but is string\", json::type_error);\n    }\n\n    SECTION(\"Regression test for https://github.com/nlohmann/json/pull/2562/files/380a613f2b5d32425021129cd1f371ddcfd54ddf#r563259793\")\n    {\n        json j;\n        j[\"/foo\"] = {1, 2, 3};\n        CHECK_THROWS_WITH_AS(j.unflatten(), \"[json.exception.type_error.315] (/~1foo) values in object must be primitive\", json::type_error);\n    }\n\n    SECTION(\"Regression test for issue #2838 - Assertion failure when inserting into arrays with JSON_DIAGNOSTICS set\")\n    {\n        // void push_back(basic_json&& val)\n        {\n            json j_arr = json::array();\n            j_arr.push_back(json::object());\n            j_arr.push_back(json::object());\n            j_arr.push_back(json::object());\n            j_arr.push_back(json::object());\n            json j_obj = json::object();\n            j_obj[\"key\"] = j_arr;\n        }\n\n        // void push_back(const basic_json& val)\n        {\n            json j_arr = json::array();\n            auto object = json::object();\n            j_arr.push_back(object);\n            j_arr.push_back(object);\n            j_arr.push_back(object);\n            j_arr.push_back(object);\n            json j_obj = json::object();\n            j_obj[\"key\"] = j_arr;\n        }\n\n        // reference emplace_back(Args&& ... args)\n        {\n            json j_arr = json::array();\n            j_arr.emplace_back(json::object());\n            j_arr.emplace_back(json::object());\n            j_arr.emplace_back(json::object());\n            j_arr.emplace_back(json::object());\n            json j_obj = json::object();\n            j_obj[\"key\"] = j_arr;\n        }\n\n        // iterator insert(const_iterator pos, const basic_json& val)\n        {\n            json j_arr = json::array();\n            j_arr.insert(j_arr.begin(), json::object());\n            j_arr.insert(j_arr.begin(), json::object());\n            j_arr.insert(j_arr.begin(), json::object());\n            j_arr.insert(j_arr.begin(), json::object());\n            json j_obj = json::object();\n            j_obj[\"key\"] = j_arr;\n        }\n\n        // iterator insert(const_iterator pos, size_type cnt, const basic_json& val)\n        {\n            json j_arr = json::array();\n            j_arr.insert(j_arr.begin(), 2, json::object());\n            json j_obj = json::object();\n            j_obj[\"key\"] = j_arr;\n        }\n\n        // iterator insert(const_iterator pos, const_iterator first, const_iterator last)\n        {\n            json j_arr = json::array();\n            json j_objects = {json::object(), json::object()};\n            j_arr.insert(j_arr.begin(), j_objects.begin(), j_objects.end());\n            json j_obj = json::object();\n            j_obj[\"key\"] = j_arr;\n        }\n    }\n\n    SECTION(\"Regression test for issue #2962 - JSON_DIAGNOSTICS assertion for ordered_json\")\n    {\n        nlohmann::ordered_json j;\n        nlohmann::ordered_json j2;\n        const std::string value;\n        j[\"first\"] = value;\n        j[\"second\"] = value;\n        j2[\"something\"] = j;\n    }\n\n    SECTION(\"Regression test for issue #3007 - Parent pointers properly set when using update()\")\n    {\n        // void update(const_reference j)\n        {\n            json j = json::object();\n\n            {\n                json j2 = json::object();\n                j2[\"one\"] = 1;\n\n                j.update(j2);\n            }\n\n            // Must call operator[] on const element, otherwise m_parent gets updated.\n            auto const& constJ = j;\n            CHECK_THROWS_WITH_AS(constJ[\"one\"].at(0), \"[json.exception.type_error.304] (/one) cannot use at() with number\", json::type_error);\n        }\n\n        // void update(const_iterator first, const_iterator last)\n        {\n            json j = json::object();\n\n            {\n                json j2 = json::object();\n                j2[\"one\"] = 1;\n\n                j.update(j2.begin(), j2.end());\n            }\n\n            // Must call operator[] on const element, otherwise m_parent gets updated.\n            auto const& constJ = j;\n            CHECK_THROWS_WITH_AS(constJ[\"one\"].at(0), \"[json.exception.type_error.304] (/one) cannot use at() with number\", json::type_error);\n        }\n\n        // Code from #3007 triggering unwanted assertion without fix to update().\n        {\n            json root = json::array();\n            json lower = json::object();\n\n            {\n                json lowest = json::object();\n                lowest[\"one\"] = 1;\n\n                lower.update(lowest);\n            }\n\n            root.push_back(lower);\n        }\n    }\n\n    SECTION(\"Regression test for issue #3032 - Yet another assertion failure when inserting into arrays with JSON_DIAGNOSTICS set\")\n    {\n        // reference operator[](size_type idx)\n        {\n            json j_arr = json::array();\n            j_arr[0] = 0;\n            j_arr[1] = 1;\n            j_arr[2] = 2;\n            j_arr[3] = 3;\n            j_arr[4] = 4;\n            j_arr[5] = 5;\n            j_arr[6] = 6;\n            j_arr[7] = 7;\n            json j_arr_copy = j_arr;\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-disabled_exceptions.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// disable -Wnoexcept as exceptions are switched off for this test suite\nDOCTEST_GCC_SUPPRESS_WARNING_PUSH\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wnoexcept\")\n\n#include <nlohmann/json.hpp>\nusing json = nlohmann::json;\n\n/////////////////////////////////////////////////////////////////////\n// for #2824\n/////////////////////////////////////////////////////////////////////\n\nclass sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>\n{\n  public:\n    explicit sax_no_exception(json& j) : nlohmann::detail::json_sax_dom_parser<json>(j, false) {}\n\n    static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)\n    {\n        error_string = new std::string(ex.what()); // NOLINT(cppcoreguidelines-owning-memory)\n        return false;\n    }\n\n    static std::string* error_string;\n};\n\nstd::string* sax_no_exception::error_string = nullptr;\n\nTEST_CASE(\"Tests with disabled exceptions\")\n{\n    SECTION(\"issue #2824 - encoding of json::exception::what()\")\n    {\n        json j;\n        sax_no_exception sax(j);\n\n        CHECK (!json::sax_parse(\"xyz\", &sax));\n        CHECK(*sax_no_exception::error_string == \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'\");\n        delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)\n    }\n}\n\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-element_access1.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"element access 1\")\n{\n    SECTION(\"array\")\n    {\n        json j = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n        const json j_const = j;\n\n        SECTION(\"access specified element with bounds checking\")\n        {\n            SECTION(\"access within bounds\")\n            {\n                CHECK(j.at(0) == json(1));\n                CHECK(j.at(1) == json(1u));\n                CHECK(j.at(2) == json(true));\n                CHECK(j.at(3) == json(nullptr));\n                CHECK(j.at(4) == json(\"string\"));\n                CHECK(j.at(5) == json(42.23));\n                CHECK(j.at(6) == json::object());\n                CHECK(j.at(7) == json({1, 2, 3}));\n\n                CHECK(j_const.at(0) == json(1));\n                CHECK(j_const.at(1) == json(1u));\n                CHECK(j_const.at(2) == json(true));\n                CHECK(j_const.at(3) == json(nullptr));\n                CHECK(j_const.at(4) == json(\"string\"));\n                CHECK(j_const.at(5) == json(42.23));\n                CHECK(j_const.at(6) == json::object());\n                CHECK(j_const.at(7) == json({1, 2, 3}));\n            }\n\n            SECTION(\"access outside bounds\")\n            {\n                CHECK_THROWS_AS(j.at(8), json::out_of_range&);\n                CHECK_THROWS_AS(j_const.at(8), json::out_of_range&);\n\n                CHECK_THROWS_WITH(j.at(8),\n                                  \"[json.exception.out_of_range.401] array index 8 is out of range\");\n                CHECK_THROWS_WITH(j_const.at(8),\n                                  \"[json.exception.out_of_range.401] array index 8 is out of range\");\n            }\n\n            SECTION(\"access on non-array type\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonarray(json::value_t::null);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray.at(0), json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_nonarray.at(0), \"[json.exception.type_error.304] cannot use at() with null\");\n                    CHECK_THROWS_WITH(j_nonarray_const.at(0), \"[json.exception.type_error.304] cannot use at() with null\");\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonarray(json::value_t::boolean);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray.at(0), json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_nonarray.at(0), \"[json.exception.type_error.304] cannot use at() with boolean\");\n                    CHECK_THROWS_WITH(j_nonarray_const.at(0), \"[json.exception.type_error.304] cannot use at() with boolean\");\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonarray(json::value_t::string);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray.at(0), json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_nonarray.at(0), \"[json.exception.type_error.304] cannot use at() with string\");\n                    CHECK_THROWS_WITH(j_nonarray_const.at(0), \"[json.exception.type_error.304] cannot use at() with string\");\n                }\n\n                SECTION(\"object\")\n                {\n                    json j_nonarray(json::value_t::object);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray.at(0), json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_nonarray.at(0), \"[json.exception.type_error.304] cannot use at() with object\");\n                    CHECK_THROWS_WITH(j_nonarray_const.at(0), \"[json.exception.type_error.304] cannot use at() with object\");\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonarray(json::value_t::number_integer);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray.at(0), json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_nonarray.at(0), \"[json.exception.type_error.304] cannot use at() with number\");\n                    CHECK_THROWS_WITH(j_nonarray_const.at(0), \"[json.exception.type_error.304] cannot use at() with number\");\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonarray(json::value_t::number_unsigned);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray.at(0), json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_nonarray.at(0), \"[json.exception.type_error.304] cannot use at() with number\");\n                    CHECK_THROWS_WITH(j_nonarray_const.at(0), \"[json.exception.type_error.304] cannot use at() with number\");\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonarray(json::value_t::number_float);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray.at(0), json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_nonarray.at(0), \"[json.exception.type_error.304] cannot use at() with number\");\n                    CHECK_THROWS_WITH(j_nonarray_const.at(0), \"[json.exception.type_error.304] cannot use at() with number\");\n                }\n            }\n        }\n\n        SECTION(\"front and back\")\n        {\n            CHECK(j.front() == json(1));\n            CHECK(j_const.front() == json(1));\n            CHECK(j.back() == json({1, 2, 3}));\n            CHECK(j_const.back() == json({1, 2, 3}));\n        }\n\n        SECTION(\"access specified element\")\n        {\n            SECTION(\"access within bounds\")\n            {\n                CHECK(j[0] == json(1));\n                CHECK(j[1] == json(1u));\n                CHECK(j[2] == json(true));\n                CHECK(j[3] == json(nullptr));\n                CHECK(j[4] == json(\"string\"));\n                CHECK(j[5] == json(42.23));\n                CHECK(j[6] == json::object());\n                CHECK(j[7] == json({1, 2, 3}));\n\n                CHECK(j_const[0] == json(1));\n                CHECK(j_const[1] == json(1u));\n                CHECK(j_const[2] == json(true));\n                CHECK(j_const[3] == json(nullptr));\n                CHECK(j_const[4] == json(\"string\"));\n                CHECK(j_const[5] == json(42.23));\n                CHECK(j_const[6] == json::object());\n                CHECK(j_const[7] == json({1, 2, 3}));\n            }\n\n            SECTION(\"access on non-array type\")\n            {\n                SECTION(\"null\")\n                {\n                    SECTION(\"standard tests\")\n                    {\n                        json j_nonarray(json::value_t::null);\n                        const json j_nonarray_const(j_nonarray);\n                        CHECK_NOTHROW(j_nonarray[0]);\n                        CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);\n                        CHECK_THROWS_WITH(j_nonarray_const[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with null\");\n                    }\n\n                    SECTION(\"implicit transformation to properly filled array\")\n                    {\n                        json j_nonarray;\n                        j_nonarray[3] = 42;\n                        CHECK(j_nonarray == json({nullptr, nullptr, nullptr, 42}));\n                    }\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonarray(json::value_t::boolean);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray[0], json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonarray[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean\");\n                    CHECK_THROWS_WITH(j_nonarray_const[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean\");\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonarray(json::value_t::string);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray[0], json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonarray[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with string\");\n                    CHECK_THROWS_WITH(j_nonarray_const[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with string\");\n                }\n\n                SECTION(\"object\")\n                {\n                    json j_nonarray(json::value_t::object);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray[0], json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonarray[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with object\");\n                    CHECK_THROWS_WITH(j_nonarray_const[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with object\");\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonarray(json::value_t::number_integer);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray[0], json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonarray[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number\");\n                    CHECK_THROWS_WITH(j_nonarray_const[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number\");\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonarray(json::value_t::number_unsigned);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray[0], json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonarray[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number\");\n                    CHECK_THROWS_WITH(j_nonarray_const[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number\");\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonarray(json::value_t::number_float);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK_THROWS_AS(j_nonarray[0], json::type_error&);\n                    CHECK_THROWS_AS(j_nonarray_const[0], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonarray[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number\");\n                    CHECK_THROWS_WITH(j_nonarray_const[0], \"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number\");\n                }\n            }\n        }\n\n        SECTION(\"remove specified element\")\n        {\n            SECTION(\"remove element by index\")\n            {\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(0);\n                    CHECK(jarray == json({1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(1);\n                    CHECK(jarray == json({1, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(2);\n                    CHECK(jarray == json({1, 1u, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(3);\n                    CHECK(jarray == json({1, 1u, true, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(4);\n                    CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(5);\n                    CHECK(jarray == json({1, 1u, true, nullptr, \"string\", json::object(), {1, 2, 3}}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(6);\n                    CHECK(jarray == json({1, 1u, true, nullptr, \"string\", 42.23, {1, 2, 3}}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    jarray.erase(7);\n                    CHECK(jarray == json({1, 1u, true, nullptr, \"string\", 42.23, json::object()}));\n                }\n                {\n                    json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                    CHECK_THROWS_AS(jarray.erase(8), json::out_of_range&);\n                    CHECK_THROWS_WITH(jarray.erase(8),\n                                      \"[json.exception.out_of_range.401] array index 8 is out of range\");\n                }\n            }\n\n            SECTION(\"remove element by iterator\")\n            {\n                SECTION(\"erase(begin())\")\n                {\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::iterator it2 = jarray.erase(jarray.begin());\n                        CHECK(jarray == json({1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json(1u));\n                    }\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::const_iterator it2 = jarray.erase(jarray.cbegin());\n                        CHECK(jarray == json({1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json(1u));\n                    }\n                }\n\n                SECTION(\"erase(begin(), end())\")\n                {\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::iterator it2 = jarray.erase(jarray.begin(), jarray.end());\n                        CHECK(jarray == json::array());\n                        CHECK(it2 == jarray.end());\n                    }\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cend());\n                        CHECK(jarray == json::array());\n                        CHECK(it2 == jarray.cend());\n                    }\n                }\n\n                SECTION(\"erase(begin(), begin())\")\n                {\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::iterator it2 = jarray.erase(jarray.begin(), jarray.begin());\n                        CHECK(jarray == json({1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json(1));\n                    }\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cbegin());\n                        CHECK(jarray == json({1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json(1));\n                    }\n                }\n\n                SECTION(\"erase at offset\")\n                {\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::iterator it = jarray.begin() + 4;\n                        json::iterator it2 = jarray.erase(it);\n                        CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json(42.23));\n                    }\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::const_iterator it = jarray.cbegin() + 4;\n                        json::const_iterator it2 = jarray.erase(it);\n                        CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json(42.23));\n                    }\n                }\n\n                SECTION(\"erase subrange\")\n                {\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::iterator it2 = jarray.erase(jarray.begin() + 3, jarray.begin() + 6);\n                        CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json::object());\n                    }\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json::const_iterator it2 = jarray.erase(jarray.cbegin() + 3, jarray.cbegin() + 6);\n                        CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));\n                        CHECK(*it2 == json::object());\n                    }\n                }\n\n                SECTION(\"different arrays\")\n                {\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json jarray2 = {\"foo\", \"bar\"};\n                        CHECK_THROWS_AS(jarray.erase(jarray2.begin()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), json::invalid_iterator&);\n\n                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin()),\n                                          \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n                        CHECK_THROWS_WITH(jarray.erase(jarray.begin(), jarray2.end()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray.end()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray2.end()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                    }\n                    {\n                        json jarray = {1, 1u, true, nullptr, \"string\", 42.23, json::object(), {1, 2, 3}};\n                        json jarray2 = {\"foo\", \"bar\"};\n                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), json::invalid_iterator&);\n\n                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin()),\n                                          \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n                        CHECK_THROWS_WITH(jarray.erase(jarray.cbegin(), jarray2.cend()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray.cend()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray2.cend()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                    }\n                }\n            }\n\n            SECTION(\"remove element by index in non-array type\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonobject(json::value_t::null);\n                    CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(0),\n                                      \"[json.exception.type_error.307] cannot use erase() with null\");\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonobject(json::value_t::boolean);\n                    CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(0),\n                                      \"[json.exception.type_error.307] cannot use erase() with boolean\");\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonobject(json::value_t::string);\n                    CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(0),\n                                      \"[json.exception.type_error.307] cannot use erase() with string\");\n                }\n\n                SECTION(\"object\")\n                {\n                    json j_nonobject(json::value_t::object);\n                    CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(0),\n                                      \"[json.exception.type_error.307] cannot use erase() with object\");\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonobject(json::value_t::number_integer);\n                    CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(0),\n                                      \"[json.exception.type_error.307] cannot use erase() with number\");\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonobject(json::value_t::number_unsigned);\n                    CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(0),\n                                      \"[json.exception.type_error.307] cannot use erase() with number\");\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonobject(json::value_t::number_float);\n                    CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(0),\n                                      \"[json.exception.type_error.307] cannot use erase() with number\");\n                }\n            }\n        }\n    }\n\n    SECTION(\"other values\")\n    {\n        SECTION(\"front and back\")\n        {\n            SECTION(\"null\")\n            {\n                {\n                    json j;\n                    CHECK_THROWS_AS(j.front(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.back(), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.front(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                    CHECK_THROWS_WITH(j.back(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n                {\n                    const json j{};\n                    CHECK_THROWS_AS(j.front(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.back(), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.front(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                    CHECK_THROWS_WITH(j.back(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n            }\n\n            SECTION(\"string\")\n            {\n                {\n                    json j = \"foo\";\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n                {\n                    const json j = \"bar\";\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n            }\n\n            SECTION(\"number (boolean)\")\n            {\n                {\n                    json j = false;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n                {\n                    const json j = true;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n            }\n\n            SECTION(\"number (integer)\")\n            {\n                {\n                    json j = 17;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n                {\n                    const json j = 17;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n            }\n\n            SECTION(\"number (unsigned)\")\n            {\n                {\n                    json j = 17u;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n                {\n                    const json j = 17u;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n            }\n\n            SECTION(\"number (floating point)\")\n            {\n                {\n                    json j = 23.42;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n                {\n                    const json j = 23.42;\n                    CHECK(j.front() == j);\n                    CHECK(j.back() == j);\n                }\n            }\n        }\n\n        SECTION(\"erase with one valid iterator\")\n        {\n            SECTION(\"null\")\n            {\n                {\n                    json j;\n                    CHECK_THROWS_AS(j.erase(j.begin()), json::type_error&);\n                    CHECK_THROWS_WITH(j.erase(j.begin()),\n                                      \"[json.exception.type_error.307] cannot use erase() with null\");\n                }\n                {\n                    json j;\n                    CHECK_THROWS_AS(j.erase(j.cbegin()), json::type_error&);\n                    CHECK_THROWS_WITH(j.erase(j.begin()),\n                                      \"[json.exception.type_error.307] cannot use erase() with null\");\n                }\n            }\n\n            SECTION(\"string\")\n            {\n                {\n                    json j = \"foo\";\n                    json::iterator it = j.erase(j.begin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = \"bar\";\n                    json::const_iterator it = j.erase(j.cbegin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (boolean)\")\n            {\n                {\n                    json j = false;\n                    json::iterator it = j.erase(j.begin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = true;\n                    json::const_iterator it = j.erase(j.cbegin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (integer)\")\n            {\n                {\n                    json j = 17;\n                    json::iterator it = j.erase(j.begin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = 17;\n                    json::const_iterator it = j.erase(j.cbegin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (unsigned)\")\n            {\n                {\n                    json j = 17u;\n                    json::iterator it = j.erase(j.begin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = 17u;\n                    json::const_iterator it = j.erase(j.cbegin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (floating point)\")\n            {\n                {\n                    json j = 23.42;\n                    json::iterator it = j.erase(j.begin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = 23.42;\n                    json::const_iterator it = j.erase(j.cbegin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"binary\")\n            {\n                {\n                    json j = json::binary({1, 2, 3});\n                    json::iterator it = j.erase(j.begin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = json::binary({1, 2, 3});\n                    json::const_iterator it = j.erase(j.cbegin());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n        }\n\n        SECTION(\"erase with one invalid iterator\")\n        {\n            SECTION(\"string\")\n            {\n                {\n                    json j = \"foo\";\n                    CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n                {\n                    json j = \"bar\";\n                    CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n            }\n\n            SECTION(\"number (boolean)\")\n            {\n                {\n                    json j = false;\n                    CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n                {\n                    json j = true;\n                    CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n            }\n\n            SECTION(\"number (integer)\")\n            {\n                {\n                    json j = 17;\n                    CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n                {\n                    json j = 17;\n                    CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n            }\n\n            SECTION(\"number (unsigned)\")\n            {\n                {\n                    json j = 17u;\n                    CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n                {\n                    json j = 17u;\n                    CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n            }\n\n            SECTION(\"number (floating point)\")\n            {\n                {\n                    json j = 23.42;\n                    CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n                {\n                    json j = 23.42;\n                    CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend()),\n                                      \"[json.exception.invalid_iterator.205] iterator out of range\");\n                }\n            }\n        }\n\n        SECTION(\"erase with two valid iterators\")\n        {\n            SECTION(\"null\")\n            {\n                {\n                    json j;\n                    CHECK_THROWS_AS(j.erase(j.begin(), j.end()), json::type_error&);\n                    CHECK_THROWS_WITH(j.erase(j.begin(), j.end()),\n                                      \"[json.exception.type_error.307] cannot use erase() with null\");\n                }\n                {\n                    json j;\n                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), json::type_error&);\n                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cend()),\n                                      \"[json.exception.type_error.307] cannot use erase() with null\");\n                }\n            }\n\n            SECTION(\"string\")\n            {\n                {\n                    json j = \"foo\";\n                    json::iterator it = j.erase(j.begin(), j.end());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = \"bar\";\n                    json::const_iterator it = j.erase(j.cbegin(), j.cend());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (boolean)\")\n            {\n                {\n                    json j = false;\n                    json::iterator it = j.erase(j.begin(), j.end());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = true;\n                    json::const_iterator it = j.erase(j.cbegin(), j.cend());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (integer)\")\n            {\n                {\n                    json j = 17;\n                    json::iterator it = j.erase(j.begin(), j.end());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = 17;\n                    json::const_iterator it = j.erase(j.cbegin(), j.cend());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (unsigned)\")\n            {\n                {\n                    json j = 17u;\n                    json::iterator it = j.erase(j.begin(), j.end());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = 17u;\n                    json::const_iterator it = j.erase(j.cbegin(), j.cend());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"number (floating point)\")\n            {\n                {\n                    json j = 23.42;\n                    json::iterator it = j.erase(j.begin(), j.end());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = 23.42;\n                    json::const_iterator it = j.erase(j.cbegin(), j.cend());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n\n            SECTION(\"binary\")\n            {\n                {\n                    json j = json::binary({1, 2, 3});\n                    json::iterator it = j.erase(j.begin(), j.end());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n                {\n                    json j = json::binary({1, 2, 3});\n                    json::const_iterator it = j.erase(j.cbegin(), j.cend());\n                    CHECK(j.type() == json::value_t::null);\n                    CHECK(it == j.end());\n                }\n            }\n        }\n\n        SECTION(\"erase with two invalid iterators\")\n        {\n            SECTION(\"string\")\n            {\n                {\n                    json j = \"foo\";\n                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n                {\n                    json j = \"bar\";\n                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n            }\n\n            SECTION(\"number (boolean)\")\n            {\n                {\n                    json j = false;\n                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n                {\n                    json j = true;\n                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n            }\n\n            SECTION(\"number (integer)\")\n            {\n                {\n                    json j = 17;\n                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n                {\n                    json j = 17;\n                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n            }\n\n            SECTION(\"number (unsigned)\")\n            {\n                {\n                    json j = 17u;\n                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n                {\n                    json j = 17u;\n                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n            }\n\n            SECTION(\"number (floating point)\")\n            {\n                {\n                    json j = 23.42;\n                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n                {\n                    json j = 23.42;\n                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator&);\n                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), \"[json.exception.invalid_iterator.204] iterators out of range\");\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-element_access2.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"element access 2\")\n{\n    SECTION(\"object\")\n    {\n        json j = {{\"integer\", 1}, {\"unsigned\", 1u}, {\"floating\", 42.23}, {\"null\", nullptr}, {\"string\", \"hello world\"}, {\"boolean\", true}, {\"object\", json::object()}, {\"array\", {1, 2, 3}}};\n        const json j_const = j;\n\n        SECTION(\"access specified element with bounds checking\")\n        {\n            SECTION(\"access within bounds\")\n            {\n                CHECK(j.at(\"integer\") == json(1));\n                CHECK(j.at(\"unsigned\") == json(1u));\n                CHECK(j.at(\"boolean\") == json(true));\n                CHECK(j.at(\"null\") == json(nullptr));\n                CHECK(j.at(\"string\") == json(\"hello world\"));\n                CHECK(j.at(\"floating\") == json(42.23));\n                CHECK(j.at(\"object\") == json::object());\n                CHECK(j.at(\"array\") == json({1, 2, 3}));\n\n                CHECK(j_const.at(\"integer\") == json(1));\n                CHECK(j_const.at(\"unsigned\") == json(1u));\n                CHECK(j_const.at(\"boolean\") == json(true));\n                CHECK(j_const.at(\"null\") == json(nullptr));\n                CHECK(j_const.at(\"string\") == json(\"hello world\"));\n                CHECK(j_const.at(\"floating\") == json(42.23));\n                CHECK(j_const.at(\"object\") == json::object());\n                CHECK(j_const.at(\"array\") == json({1, 2, 3}));\n            }\n\n            SECTION(\"access outside bounds\")\n            {\n                CHECK_THROWS_AS(j.at(\"foo\"), json::out_of_range&);\n                CHECK_THROWS_AS(j_const.at(\"foo\"), json::out_of_range&);\n                CHECK_THROWS_WITH(j.at(\"foo\"),\n                                  \"[json.exception.out_of_range.403] key 'foo' not found\");\n                CHECK_THROWS_WITH(j_const.at(\"foo\"),\n                                  \"[json.exception.out_of_range.403] key 'foo' not found\");\n            }\n\n            SECTION(\"access on non-object type\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonobject(json::value_t::null);\n                    const json j_nonobject_const(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject_const.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with null\");\n                    CHECK_THROWS_WITH(j_nonobject_const.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with null\");\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonobject(json::value_t::boolean);\n                    const json j_nonobject_const(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject_const.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with boolean\");\n                    CHECK_THROWS_WITH(j_nonobject_const.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with boolean\");\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonobject(json::value_t::string);\n                    const json j_nonobject_const(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject_const.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with string\");\n                    CHECK_THROWS_WITH(j_nonobject_const.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with string\");\n                }\n\n                SECTION(\"array\")\n                {\n                    json j_nonobject(json::value_t::array);\n                    const json j_nonobject_const(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject_const.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with array\");\n                    CHECK_THROWS_WITH(j_nonobject_const.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with array\");\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonobject(json::value_t::number_integer);\n                    const json j_nonobject_const(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject_const.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with number\");\n                    CHECK_THROWS_WITH(j_nonobject_const.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with number\");\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonobject(json::value_t::number_unsigned);\n                    const json j_nonobject_const(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject_const.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with number\");\n                    CHECK_THROWS_WITH(j_nonobject_const.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with number\");\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonobject(json::value_t::number_float);\n                    const json j_nonobject_const(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject_const.at(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with number\");\n                    CHECK_THROWS_WITH(j_nonobject_const.at(\"foo\"), \"[json.exception.type_error.304] cannot use at() with number\");\n                }\n            }\n        }\n\n        SECTION(\"access specified element with default value\")\n        {\n            SECTION(\"given a key\")\n            {\n                SECTION(\"access existing value\")\n                {\n                    CHECK(j.value(\"integer\", 2) == 1);\n                    CHECK(j.value(\"integer\", 1.0) == Approx(1));\n                    CHECK(j.value(\"unsigned\", 2) == 1u);\n                    CHECK(j.value(\"unsigned\", 1.0) == Approx(1u));\n                    CHECK(j.value(\"null\", json(1)) == json());\n                    CHECK(j.value(\"boolean\", false) == true);\n                    CHECK(j.value(\"string\", \"bar\") == \"hello world\");\n                    CHECK(j.value(\"string\", std::string(\"bar\")) == \"hello world\");\n                    CHECK(j.value(\"floating\", 12.34) == Approx(42.23));\n                    CHECK(j.value(\"floating\", 12) == 42);\n                    CHECK(j.value(\"object\", json({{\"foo\", \"bar\"}})) == json::object());\n                    CHECK(j.value(\"array\", json({10, 100})) == json({1, 2, 3}));\n\n                    CHECK(j_const.value(\"integer\", 2) == 1);\n                    CHECK(j_const.value(\"integer\", 1.0) == Approx(1));\n                    CHECK(j_const.value(\"unsigned\", 2) == 1u);\n                    CHECK(j_const.value(\"unsigned\", 1.0) == Approx(1u));\n                    CHECK(j_const.value(\"boolean\", false) == true);\n                    CHECK(j_const.value(\"string\", \"bar\") == \"hello world\");\n                    CHECK(j_const.value(\"string\", std::string(\"bar\")) == \"hello world\");\n                    CHECK(j_const.value(\"floating\", 12.34) == Approx(42.23));\n                    CHECK(j_const.value(\"floating\", 12) == 42);\n                    CHECK(j_const.value(\"object\", json({{\"foo\", \"bar\"}})) == json::object());\n                    CHECK(j_const.value(\"array\", json({10, 100})) == json({1, 2, 3}));\n                }\n\n                SECTION(\"access non-existing value\")\n                {\n                    CHECK(j.value(\"_\", 2) == 2);\n                    CHECK(j.value(\"_\", 2u) == 2u);\n                    CHECK(j.value(\"_\", false) == false);\n                    CHECK(j.value(\"_\", \"bar\") == \"bar\");\n                    CHECK(j.value(\"_\", 12.34) == Approx(12.34));\n                    CHECK(j.value(\"_\", json({{\"foo\", \"bar\"}})) == json({{\"foo\", \"bar\"}}));\n                    CHECK(j.value(\"_\", json({10, 100})) == json({10, 100}));\n\n                    CHECK(j_const.value(\"_\", 2) == 2);\n                    CHECK(j_const.value(\"_\", 2u) == 2u);\n                    CHECK(j_const.value(\"_\", false) == false);\n                    CHECK(j_const.value(\"_\", \"bar\") == \"bar\");\n                    CHECK(j_const.value(\"_\", 12.34) == Approx(12.34));\n                    CHECK(j_const.value(\"_\", json({{\"foo\", \"bar\"}})) == json({{\"foo\", \"bar\"}}));\n                    CHECK(j_const.value(\"_\", json({10, 100})) == json({10, 100}));\n                }\n\n                SECTION(\"access on non-object type\")\n                {\n                    SECTION(\"null\")\n                    {\n                        json j_nonobject(json::value_t::null);\n                        const json j_nonobject_const(json::value_t::null);\n                        CHECK_THROWS_AS(j_nonobject.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with null\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with null\");\n                    }\n\n                    SECTION(\"boolean\")\n                    {\n                        json j_nonobject(json::value_t::boolean);\n                        const json j_nonobject_const(json::value_t::boolean);\n                        CHECK_THROWS_AS(j_nonobject.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with boolean\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with boolean\");\n                    }\n\n                    SECTION(\"string\")\n                    {\n                        json j_nonobject(json::value_t::string);\n                        const json j_nonobject_const(json::value_t::string);\n                        CHECK_THROWS_AS(j_nonobject.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with string\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with string\");\n                    }\n\n                    SECTION(\"array\")\n                    {\n                        json j_nonobject(json::value_t::array);\n                        const json j_nonobject_const(json::value_t::array);\n                        CHECK_THROWS_AS(j_nonobject.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with array\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with array\");\n                    }\n\n                    SECTION(\"number (integer)\")\n                    {\n                        json j_nonobject(json::value_t::number_integer);\n                        const json j_nonobject_const(json::value_t::number_integer);\n                        CHECK_THROWS_AS(j_nonobject.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                    }\n\n                    SECTION(\"number (unsigned)\")\n                    {\n                        json j_nonobject(json::value_t::number_unsigned);\n                        const json j_nonobject_const(json::value_t::number_unsigned);\n                        CHECK_THROWS_AS(j_nonobject.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                    }\n\n                    SECTION(\"number (floating-point)\")\n                    {\n                        json j_nonobject(json::value_t::number_float);\n                        const json j_nonobject_const(json::value_t::number_float);\n                        CHECK_THROWS_AS(j_nonobject.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"foo\", 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"foo\", 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                    }\n                }\n            }\n\n            SECTION(\"given a JSON pointer\")\n            {\n                SECTION(\"access existing value\")\n                {\n                    CHECK(j.value(\"/integer\"_json_pointer, 2) == 1);\n                    CHECK(j.value(\"/integer\"_json_pointer, 1.0) == Approx(1));\n                    CHECK(j.value(\"/unsigned\"_json_pointer, 2) == 1u);\n                    CHECK(j.value(\"/unsigned\"_json_pointer, 1.0) == Approx(1u));\n                    CHECK(j.value(\"/null\"_json_pointer, json(1)) == json());\n                    CHECK(j.value(\"/boolean\"_json_pointer, false) == true);\n                    CHECK(j.value(\"/string\"_json_pointer, \"bar\") == \"hello world\");\n                    CHECK(j.value(\"/string\"_json_pointer, std::string(\"bar\")) == \"hello world\");\n                    CHECK(j.value(\"/floating\"_json_pointer, 12.34) == Approx(42.23));\n                    CHECK(j.value(\"/floating\"_json_pointer, 12) == 42);\n                    CHECK(j.value(\"/object\"_json_pointer, json({{\"foo\", \"bar\"}})) == json::object());\n                    CHECK(j.value(\"/array\"_json_pointer, json({10, 100})) == json({1, 2, 3}));\n\n                    CHECK(j_const.value(\"/integer\"_json_pointer, 2) == 1);\n                    CHECK(j_const.value(\"/integer\"_json_pointer, 1.0) == Approx(1));\n                    CHECK(j_const.value(\"/unsigned\"_json_pointer, 2) == 1u);\n                    CHECK(j_const.value(\"/unsigned\"_json_pointer, 1.0) == Approx(1u));\n                    CHECK(j_const.value(\"/boolean\"_json_pointer, false) == true);\n                    CHECK(j_const.value(\"/string\"_json_pointer, \"bar\") == \"hello world\");\n                    CHECK(j_const.value(\"/string\"_json_pointer, std::string(\"bar\")) == \"hello world\");\n                    CHECK(j_const.value(\"/floating\"_json_pointer, 12.34) == Approx(42.23));\n                    CHECK(j_const.value(\"/floating\"_json_pointer, 12) == 42);\n                    CHECK(j_const.value(\"/object\"_json_pointer, json({{\"foo\", \"bar\"}})) == json::object());\n                    CHECK(j_const.value(\"/array\"_json_pointer, json({10, 100})) == json({1, 2, 3}));\n                }\n\n                SECTION(\"access on non-object type\")\n                {\n                    SECTION(\"null\")\n                    {\n                        json j_nonobject(json::value_t::null);\n                        const json j_nonobject_const(json::value_t::null);\n                        CHECK_THROWS_AS(j_nonobject.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with null\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with null\");\n                    }\n\n                    SECTION(\"boolean\")\n                    {\n                        json j_nonobject(json::value_t::boolean);\n                        const json j_nonobject_const(json::value_t::boolean);\n                        CHECK_THROWS_AS(j_nonobject.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with boolean\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with boolean\");\n                    }\n\n                    SECTION(\"string\")\n                    {\n                        json j_nonobject(json::value_t::string);\n                        const json j_nonobject_const(json::value_t::string);\n                        CHECK_THROWS_AS(j_nonobject.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with string\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with string\");\n                    }\n\n                    SECTION(\"array\")\n                    {\n                        json j_nonobject(json::value_t::array);\n                        const json j_nonobject_const(json::value_t::array);\n                        CHECK_THROWS_AS(j_nonobject.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with array\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with array\");\n                    }\n\n                    SECTION(\"number (integer)\")\n                    {\n                        json j_nonobject(json::value_t::number_integer);\n                        const json j_nonobject_const(json::value_t::number_integer);\n                        CHECK_THROWS_AS(j_nonobject.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                    }\n\n                    SECTION(\"number (unsigned)\")\n                    {\n                        json j_nonobject(json::value_t::number_unsigned);\n                        const json j_nonobject_const(json::value_t::number_unsigned);\n                        CHECK_THROWS_AS(j_nonobject.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                    }\n\n                    SECTION(\"number (floating-point)\")\n                    {\n                        json j_nonobject(json::value_t::number_float);\n                        const json j_nonobject_const(json::value_t::number_float);\n                        CHECK_THROWS_AS(j_nonobject.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_AS(j_nonobject_const.value(\"/foo\"_json_pointer, 1), json::type_error&);\n                        CHECK_THROWS_WITH(j_nonobject.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                        CHECK_THROWS_WITH(j_nonobject_const.value(\"/foo\"_json_pointer, 1),\n                                          \"[json.exception.type_error.306] cannot use value() with number\");\n                    }\n                }\n            }\n        }\n\n        SECTION(\"front and back\")\n        {\n            // \"array\" is the smallest key\n            CHECK(j.front() == json({1, 2, 3}));\n            CHECK(j_const.front() == json({1, 2, 3}));\n            // \"unsigned\" is the largest key\n            CHECK(j.back() == json(1u));\n            CHECK(j_const.back() == json(1u));\n        }\n\n        SECTION(\"access specified element\")\n        {\n            SECTION(\"access within bounds\")\n            {\n                CHECK(j[\"integer\"] == json(1));\n                CHECK(j[json::object_t::key_type(\"integer\")] == j[\"integer\"]);\n\n                CHECK(j[\"unsigned\"] == json(1u));\n                CHECK(j[json::object_t::key_type(\"unsigned\")] == j[\"unsigned\"]);\n\n                CHECK(j[\"boolean\"] == json(true));\n                CHECK(j[json::object_t::key_type(\"boolean\")] == j[\"boolean\"]);\n\n                CHECK(j[\"null\"] == json(nullptr));\n                CHECK(j[json::object_t::key_type(\"null\")] == j[\"null\"]);\n\n                CHECK(j[\"string\"] == json(\"hello world\"));\n                CHECK(j[json::object_t::key_type(\"string\")] == j[\"string\"]);\n\n                CHECK(j[\"floating\"] == json(42.23));\n                CHECK(j[json::object_t::key_type(\"floating\")] == j[\"floating\"]);\n\n                CHECK(j[\"object\"] == json::object());\n                CHECK(j[json::object_t::key_type(\"object\")] == j[\"object\"]);\n\n                CHECK(j[\"array\"] == json({1, 2, 3}));\n                CHECK(j[json::object_t::key_type(\"array\")] == j[\"array\"]);\n\n                CHECK(j_const[\"integer\"] == json(1));\n                CHECK(j_const[json::object_t::key_type(\"integer\")] == j[\"integer\"]);\n\n                CHECK(j_const[\"boolean\"] == json(true));\n                CHECK(j_const[json::object_t::key_type(\"boolean\")] == j[\"boolean\"]);\n\n                CHECK(j_const[\"null\"] == json(nullptr));\n                CHECK(j_const[json::object_t::key_type(\"null\")] == j[\"null\"]);\n\n                CHECK(j_const[\"string\"] == json(\"hello world\"));\n                CHECK(j_const[json::object_t::key_type(\"string\")] == j[\"string\"]);\n\n                CHECK(j_const[\"floating\"] == json(42.23));\n                CHECK(j_const[json::object_t::key_type(\"floating\")] == j[\"floating\"]);\n\n                CHECK(j_const[\"object\"] == json::object());\n                CHECK(j_const[json::object_t::key_type(\"object\")] == j[\"object\"]);\n\n                CHECK(j_const[\"array\"] == json({1, 2, 3}));\n                CHECK(j_const[json::object_t::key_type(\"array\")] == j[\"array\"]);\n            }\n\n            SECTION(\"access on non-object type\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonobject(json::value_t::null);\n                    json j_nonobject2(json::value_t::null);\n                    const json j_const_nonobject(j_nonobject);\n                    CHECK_NOTHROW(j_nonobject[\"foo\"]);\n                    CHECK_NOTHROW(j_nonobject2[json::object_t::key_type(\"foo\")]);\n                    CHECK_THROWS_AS(j_const_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_WITH(j_const_nonobject[\"foo\"], \"[json.exception.type_error.305] cannot use operator[] with a string argument with null\");\n                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with null\");\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonobject(json::value_t::boolean);\n                    const json j_const_nonobject(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean\");\n                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean\");\n                    CHECK_THROWS_WITH(j_const_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean\");\n                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean\");\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonobject(json::value_t::string);\n                    const json j_const_nonobject(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with string\");\n                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with string\");\n                    CHECK_THROWS_WITH(j_const_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with string\");\n                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with string\");\n                }\n\n                SECTION(\"array\")\n                {\n                    json j_nonobject(json::value_t::array);\n                    const json j_const_nonobject(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with array\");\n                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type(\"foo\")], \"[json.exception.type_error.305] cannot use operator[] with a string argument with array\");\n                    CHECK_THROWS_WITH(j_const_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with array\");\n                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with array\");\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonobject(json::value_t::number_integer);\n                    const json j_const_nonobject(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_const_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonobject(json::value_t::number_unsigned);\n                    const json j_const_nonobject(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_const_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonobject(json::value_t::number_float);\n                    const json j_const_nonobject(j_nonobject);\n                    CHECK_THROWS_AS(j_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[\"foo\"], json::type_error&);\n                    CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type(\"foo\")], json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_const_nonobject[\"foo\"],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type(\"foo\")],\n                                      \"[json.exception.type_error.305] cannot use operator[] with a string argument with number\");\n                }\n            }\n        }\n\n        SECTION(\"remove specified element\")\n        {\n            SECTION(\"remove element by key\")\n            {\n                CHECK(j.find(\"integer\") != j.end());\n                CHECK(j.erase(\"integer\") == 1);\n                CHECK(j.find(\"integer\") == j.end());\n                CHECK(j.erase(\"integer\") == 0);\n\n                CHECK(j.find(\"unsigned\") != j.end());\n                CHECK(j.erase(\"unsigned\") == 1);\n                CHECK(j.find(\"unsigned\") == j.end());\n                CHECK(j.erase(\"unsigned\") == 0);\n\n                CHECK(j.find(\"boolean\") != j.end());\n                CHECK(j.erase(\"boolean\") == 1);\n                CHECK(j.find(\"boolean\") == j.end());\n                CHECK(j.erase(\"boolean\") == 0);\n\n                CHECK(j.find(\"null\") != j.end());\n                CHECK(j.erase(\"null\") == 1);\n                CHECK(j.find(\"null\") == j.end());\n                CHECK(j.erase(\"null\") == 0);\n\n                CHECK(j.find(\"string\") != j.end());\n                CHECK(j.erase(\"string\") == 1);\n                CHECK(j.find(\"string\") == j.end());\n                CHECK(j.erase(\"string\") == 0);\n\n                CHECK(j.find(\"floating\") != j.end());\n                CHECK(j.erase(\"floating\") == 1);\n                CHECK(j.find(\"floating\") == j.end());\n                CHECK(j.erase(\"floating\") == 0);\n\n                CHECK(j.find(\"object\") != j.end());\n                CHECK(j.erase(\"object\") == 1);\n                CHECK(j.find(\"object\") == j.end());\n                CHECK(j.erase(\"object\") == 0);\n\n                CHECK(j.find(\"array\") != j.end());\n                CHECK(j.erase(\"array\") == 1);\n                CHECK(j.find(\"array\") == j.end());\n                CHECK(j.erase(\"array\") == 0);\n            }\n\n            SECTION(\"remove element by iterator\")\n            {\n                SECTION(\"erase(begin())\")\n                {\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::iterator it2 = jobject.erase(jobject.begin());\n                        CHECK(jobject == json({{\"b\", 1}, {\"c\", 17u}}));\n                        CHECK(*it2 == json(1));\n                    }\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::const_iterator it2 = jobject.erase(jobject.cbegin());\n                        CHECK(jobject == json({{\"b\", 1}, {\"c\", 17u}}));\n                        CHECK(*it2 == json(1));\n                    }\n                }\n\n                SECTION(\"erase(begin(), end())\")\n                {\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::iterator it2 = jobject.erase(jobject.begin(), jobject.end());\n                        CHECK(jobject == json::object());\n                        CHECK(it2 == jobject.end());\n                    }\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend());\n                        CHECK(jobject == json::object());\n                        CHECK(it2 == jobject.cend());\n                    }\n                }\n\n                SECTION(\"erase(begin(), begin())\")\n                {\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::iterator it2 = jobject.erase(jobject.begin(), jobject.begin());\n                        CHECK(jobject == json({{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}}));\n                        CHECK(*it2 == json(\"a\"));\n                    }\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cbegin());\n                        CHECK(jobject == json({{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}}));\n                        CHECK(*it2 == json(\"a\"));\n                    }\n                }\n\n                SECTION(\"erase at offset\")\n                {\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::iterator it = jobject.find(\"b\");\n                        json::iterator it2 = jobject.erase(it);\n                        CHECK(jobject == json({{\"a\", \"a\"}, {\"c\", 17u}}));\n                        CHECK(*it2 == json(17));\n                    }\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        json::const_iterator it = jobject.find(\"b\");\n                        json::const_iterator it2 = jobject.erase(it);\n                        CHECK(jobject == json({{\"a\", \"a\"}, {\"c\", 17u}}));\n                        CHECK(*it2 == json(17));\n                    }\n                }\n\n                SECTION(\"erase subrange\")\n                {\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}, {\"d\", false}, {\"e\", true}};\n                        json::iterator it2 = jobject.erase(jobject.find(\"b\"), jobject.find(\"e\"));\n                        CHECK(jobject == json({{\"a\", \"a\"}, {\"e\", true}}));\n                        CHECK(*it2 == json(true));\n                    }\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}, {\"d\", false}, {\"e\", true}};\n                        json::const_iterator it2 = jobject.erase(jobject.find(\"b\"), jobject.find(\"e\"));\n                        CHECK(jobject == json({{\"a\", \"a\"}, {\"e\", true}}));\n                        CHECK(*it2 == json(true));\n                    }\n                }\n\n                SECTION(\"different objects\")\n                {\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}, {\"d\", false}, {\"e\", true}};\n                        json jobject2 = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        CHECK_THROWS_AS(jobject.erase(jobject2.begin()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(jobject.erase(jobject2.begin()),\n                                          \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n                        CHECK_THROWS_WITH(jobject.erase(jobject.begin(), jobject2.end()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject.end()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject2.end()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                    }\n                    {\n                        json jobject = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}, {\"d\", false}, {\"e\", true}};\n                        json jobject2 = {{\"a\", \"a\"}, {\"b\", 1}, {\"c\", 17u}};\n                        CHECK_THROWS_AS(jobject.erase(jobject2.cbegin()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), json::invalid_iterator&);\n                        CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin()),\n                                          \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n                        CHECK_THROWS_WITH(jobject.erase(jobject.cbegin(), jobject2.cend()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject.cend()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                        CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject2.cend()),\n                                          \"[json.exception.invalid_iterator.203] iterators do not fit current value\");\n                    }\n                }\n            }\n\n            SECTION(\"remove element by key in non-object type\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonobject(json::value_t::null);\n                    CHECK_THROWS_AS(j_nonobject.erase(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(\"foo\"),\n                                      \"[json.exception.type_error.307] cannot use erase() with null\");\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonobject(json::value_t::boolean);\n                    CHECK_THROWS_AS(j_nonobject.erase(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(\"foo\"),\n                                      \"[json.exception.type_error.307] cannot use erase() with boolean\");\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonobject(json::value_t::string);\n                    CHECK_THROWS_AS(j_nonobject.erase(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(\"foo\"),\n                                      \"[json.exception.type_error.307] cannot use erase() with string\");\n                }\n\n                SECTION(\"array\")\n                {\n                    json j_nonobject(json::value_t::array);\n                    CHECK_THROWS_AS(j_nonobject.erase(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(\"foo\"),\n                                      \"[json.exception.type_error.307] cannot use erase() with array\");\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonobject(json::value_t::number_integer);\n                    CHECK_THROWS_AS(j_nonobject.erase(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(\"foo\"),\n                                      \"[json.exception.type_error.307] cannot use erase() with number\");\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonobject(json::value_t::number_float);\n                    CHECK_THROWS_AS(j_nonobject.erase(\"foo\"), json::type_error&);\n                    CHECK_THROWS_WITH(j_nonobject.erase(\"foo\"),\n                                      \"[json.exception.type_error.307] cannot use erase() with number\");\n                }\n            }\n        }\n\n        SECTION(\"find an element in an object\")\n        {\n            SECTION(\"existing element\")\n            {\n                for (const auto* key :\n                        {\"integer\", \"unsigned\", \"floating\", \"null\", \"string\", \"boolean\", \"object\", \"array\"\n                        })\n                {\n                    CHECK(j.find(key) != j.end());\n                    CHECK(*j.find(key) == j.at(key));\n                    CHECK(j_const.find(key) != j_const.end());\n                    CHECK(*j_const.find(key) == j_const.at(key));\n                }\n            }\n\n            SECTION(\"nonexisting element\")\n            {\n                CHECK(j.find(\"foo\") == j.end());\n                CHECK(j_const.find(\"foo\") == j_const.end());\n            }\n\n            SECTION(\"all types\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonarray(json::value_t::null);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonarray(json::value_t::string);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n\n                SECTION(\"object\")\n                {\n                    json j_nonarray(json::value_t::object);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n\n                SECTION(\"array\")\n                {\n                    json j_nonarray(json::value_t::array);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonarray(json::value_t::boolean);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonarray(json::value_t::number_integer);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonarray(json::value_t::number_unsigned);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonarray(json::value_t::number_float);\n                    const json j_nonarray_const(j_nonarray);\n                    CHECK(j_nonarray.find(\"foo\") == j_nonarray.end());\n                    CHECK(j_nonarray_const.find(\"foo\") == j_nonarray_const.end());\n                }\n            }\n        }\n\n        SECTION(\"count keys in an object\")\n        {\n            SECTION(\"existing element\")\n            {\n                for (const auto* key :\n                        {\"integer\", \"unsigned\", \"floating\", \"null\", \"string\", \"boolean\", \"object\", \"array\"\n                        })\n                {\n                    CHECK(j.count(key) == 1);\n                    CHECK(j_const.count(key) == 1);\n                }\n            }\n\n            SECTION(\"nonexisting element\")\n            {\n                CHECK(j.count(\"foo\") == 0);\n                CHECK(j_const.count(\"foo\") == 0);\n            }\n\n            SECTION(\"all types\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonobject(json::value_t::null);\n                    const json j_nonobject_const(json::value_t::null);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonobject(json::value_t::string);\n                    const json j_nonobject_const(json::value_t::string);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n\n                SECTION(\"object\")\n                {\n                    json j_nonobject(json::value_t::object);\n                    const json j_nonobject_const(json::value_t::object);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n\n                SECTION(\"array\")\n                {\n                    json j_nonobject(json::value_t::array);\n                    const json j_nonobject_const(json::value_t::array);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonobject(json::value_t::boolean);\n                    const json j_nonobject_const(json::value_t::boolean);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonobject(json::value_t::number_integer);\n                    const json j_nonobject_const(json::value_t::number_integer);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonobject(json::value_t::number_unsigned);\n                    const json j_nonobject_const(json::value_t::number_unsigned);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonobject(json::value_t::number_float);\n                    const json j_nonobject_const(json::value_t::number_float);\n                    CHECK(j_nonobject.count(\"foo\") == 0);\n                    CHECK(j_nonobject_const.count(\"foo\") == 0);\n                }\n            }\n        }\n\n        SECTION(\"check existence of key in an object\")\n        {\n            SECTION(\"existing element\")\n            {\n                for (const auto* key :\n                        {\"integer\", \"unsigned\", \"floating\", \"null\", \"string\", \"boolean\", \"object\", \"array\"\n                        })\n                {\n                    CHECK(j.contains(key) == true);\n                    CHECK(j_const.contains(key) == true);\n                }\n            }\n\n            SECTION(\"nonexisting element\")\n            {\n                CHECK(j.contains(\"foo\") == false);\n                CHECK(j_const.contains(\"foo\") == false);\n            }\n\n            SECTION(\"all types\")\n            {\n                SECTION(\"null\")\n                {\n                    json j_nonobject(json::value_t::null);\n                    const json j_nonobject_const(json::value_t::null);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n\n                SECTION(\"string\")\n                {\n                    json j_nonobject(json::value_t::string);\n                    const json j_nonobject_const(json::value_t::string);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n\n                SECTION(\"object\")\n                {\n                    json j_nonobject(json::value_t::object);\n                    const json j_nonobject_const(json::value_t::object);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n\n                SECTION(\"array\")\n                {\n                    json j_nonobject(json::value_t::array);\n                    const json j_nonobject_const(json::value_t::array);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n\n                SECTION(\"boolean\")\n                {\n                    json j_nonobject(json::value_t::boolean);\n                    const json j_nonobject_const(json::value_t::boolean);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n\n                SECTION(\"number (integer)\")\n                {\n                    json j_nonobject(json::value_t::number_integer);\n                    const json j_nonobject_const(json::value_t::number_integer);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n\n                SECTION(\"number (unsigned)\")\n                {\n                    json j_nonobject(json::value_t::number_unsigned);\n                    const json j_nonobject_const(json::value_t::number_unsigned);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n\n                SECTION(\"number (floating-point)\")\n                {\n                    json j_nonobject(json::value_t::number_float);\n                    const json j_nonobject_const(json::value_t::number_float);\n                    CHECK(j_nonobject.contains(\"foo\") == false);\n                    CHECK(j_nonobject_const.contains(\"foo\") == false);\n                }\n            }\n        }\n    }\n}\n\n#if !defined(JSON_NOEXCEPTION)\nTEST_CASE(\"element access 2 (throwing tests)\")\n{\n    SECTION(\"object\")\n    {\n        json j = {{\"integer\", 1}, {\"unsigned\", 1u}, {\"floating\", 42.23}, {\"null\", nullptr}, {\"string\", \"hello world\"}, {\"boolean\", true}, {\"object\", json::object()}, {\"array\", {1, 2, 3}}};\n        const json j_const = {{\"integer\", 1}, {\"unsigned\", 1u}, {\"floating\", 42.23}, {\"null\", nullptr}, {\"string\", \"hello world\"}, {\"boolean\", true}, {\"object\", json::object()}, {\"array\", {1, 2, 3}}};\n\n        SECTION(\"access specified element with default value\")\n        {\n            SECTION(\"given a JSON pointer\")\n            {\n                SECTION(\"access non-existing value\")\n                {\n                    CHECK(j.value(\"/not/existing\"_json_pointer, 2) == 2);\n                    CHECK(j.value(\"/not/existing\"_json_pointer, 2u) == 2u);\n                    CHECK(j.value(\"/not/existing\"_json_pointer, false) == false);\n                    CHECK(j.value(\"/not/existing\"_json_pointer, \"bar\") == \"bar\");\n                    CHECK(j.value(\"/not/existing\"_json_pointer, 12.34) == Approx(12.34));\n                    CHECK(j.value(\"/not/existing\"_json_pointer, json({{\"foo\", \"bar\"}})) == json({{\"foo\", \"bar\"}}));\n                    CHECK(j.value(\"/not/existing\"_json_pointer, json({10, 100})) == json({10, 100}));\n\n                    CHECK(j_const.value(\"/not/existing\"_json_pointer, 2) == 2);\n                    CHECK(j_const.value(\"/not/existing\"_json_pointer, 2u) == 2u);\n                    CHECK(j_const.value(\"/not/existing\"_json_pointer, false) == false);\n                    CHECK(j_const.value(\"/not/existing\"_json_pointer, \"bar\") == \"bar\");\n                    CHECK(j_const.value(\"/not/existing\"_json_pointer, 12.34) == Approx(12.34));\n                    CHECK(j_const.value(\"/not/existing\"_json_pointer, json({{\"foo\", \"bar\"}})) == json({{\"foo\", \"bar\"}}));\n                    CHECK(j_const.value(\"/not/existing\"_json_pointer, json({10, 100})) == json({10, 100}));\n                }\n            }\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-hash.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing json = nlohmann::json;\nusing ordered_json = nlohmann::ordered_json;\n\n#include <set>\n\nTEST_CASE(\"hash<nlohmann::json>\")\n{\n    // Collect hashes for different JSON values and make sure that they are distinct\n    // We cannot compare against fixed values, because the implementation of\n    // std::hash may differ between compilers.\n\n    std::set<std::size_t> hashes;\n\n    // null\n    hashes.insert(std::hash<json> {}(json(nullptr)));\n\n    // boolean\n    hashes.insert(std::hash<json> {}(json(true)));\n    hashes.insert(std::hash<json> {}(json(false)));\n\n    // string\n    hashes.insert(std::hash<json> {}(json(\"\")));\n    hashes.insert(std::hash<json> {}(json(\"foo\")));\n\n    // number\n    hashes.insert(std::hash<json> {}(json(0)));\n    hashes.insert(std::hash<json> {}(json(static_cast<unsigned>(0))));\n\n    hashes.insert(std::hash<json> {}(json(-1)));\n    hashes.insert(std::hash<json> {}(json(0.0)));\n    hashes.insert(std::hash<json> {}(json(42.23)));\n\n    // array\n    hashes.insert(std::hash<json> {}(json::array()));\n    hashes.insert(std::hash<json> {}(json::array({1, 2, 3})));\n\n    // object\n    hashes.insert(std::hash<json> {}(json::object()));\n    hashes.insert(std::hash<json> {}(json::object({{\"foo\", \"bar\"}})));\n\n    // binary\n    hashes.insert(std::hash<json> {}(json::binary({})));\n    hashes.insert(std::hash<json> {}(json::binary({}, 0)));\n    hashes.insert(std::hash<json> {}(json::binary({}, 42)));\n    hashes.insert(std::hash<json> {}(json::binary({1, 2, 3})));\n    hashes.insert(std::hash<json> {}(json::binary({1, 2, 3}, 0)));\n    hashes.insert(std::hash<json> {}(json::binary({1, 2, 3}, 42)));\n\n    // discarded\n    hashes.insert(std::hash<json> {}(json(json::value_t::discarded)));\n\n    CHECK(hashes.size() == 21);\n}\n\nTEST_CASE(\"hash<nlohmann::ordered_json>\")\n{\n    // Collect hashes for different JSON values and make sure that they are distinct\n    // We cannot compare against fixed values, because the implementation of\n    // std::hash may differ between compilers.\n\n    std::set<std::size_t> hashes;\n\n    // null\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(nullptr)));\n\n    // boolean\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(true)));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(false)));\n\n    // string\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(\"\")));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(\"foo\")));\n\n    // number\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(0)));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(static_cast<unsigned>(0))));\n\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(-1)));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(0.0)));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(42.23)));\n\n    // array\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::array()));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::array({1, 2, 3})));\n\n    // object\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::object()));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::object({{\"foo\", \"bar\"}})));\n\n    // binary\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({})));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({}, 0)));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({}, 42)));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3})));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3}, 0)));\n    hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3}, 42)));\n\n    // discarded\n    hashes.insert(std::hash<ordered_json> {}(ordered_json(ordered_json::value_t::discarded)));\n\n    CHECK(hashes.size() == 21);\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-inspection.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <test_data.hpp>\n\nTEST_CASE(\"object inspection\")\n{\n    SECTION(\"convenience type checker\")\n    {\n        SECTION(\"object\")\n        {\n            json j {{\"foo\", 1}, {\"bar\", false}};\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(!j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(!j.is_primitive());\n            CHECK(j.is_structured());\n        }\n\n        SECTION(\"array\")\n        {\n            json j {\"foo\", 1, 1u, 42.23, false};\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(!j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(!j.is_primitive());\n            CHECK(j.is_structured());\n        }\n\n        SECTION(\"null\")\n        {\n            json j(nullptr);\n            CHECK(j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(!j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n\n        SECTION(\"boolean\")\n        {\n            json j(true);\n            CHECK(!j.is_null());\n            CHECK(j.is_boolean());\n            CHECK(!j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n\n        SECTION(\"string\")\n        {\n            json j(\"Hello world\");\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(!j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j(42);\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(j.is_number());\n            CHECK(j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j(42u);\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(j.is_number());\n            CHECK(j.is_number_integer());\n            CHECK(j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n\n        SECTION(\"number (floating-point)\")\n        {\n            json j(42.23);\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n\n        SECTION(\"binary\")\n        {\n            json j(json::value_t::binary);\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(!j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(!j.is_discarded());\n            CHECK(j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n\n        SECTION(\"discarded\")\n        {\n            json j(json::value_t::discarded);\n            CHECK(!j.is_null());\n            CHECK(!j.is_boolean());\n            CHECK(!j.is_number());\n            CHECK(!j.is_number_integer());\n            CHECK(!j.is_number_unsigned());\n            CHECK(!j.is_number_float());\n            CHECK(!j.is_binary());\n            CHECK(!j.is_object());\n            CHECK(!j.is_array());\n            CHECK(!j.is_string());\n            CHECK(j.is_discarded());\n            CHECK(!j.is_primitive());\n            CHECK(!j.is_structured());\n        }\n    }\n\n    SECTION(\"serialization\")\n    {\n        json j {{\"object\", json::object()}, {\"array\", {1, 2, 3, 4}}, {\"number\", 42}, {\"boolean\", false}, {\"null\", nullptr}, {\"string\", \"Hello world\"} };\n\n        SECTION(\"no indent / indent=-1\")\n        {\n            CHECK(j.dump() ==\n                  \"{\\\"array\\\":[1,2,3,4],\\\"boolean\\\":false,\\\"null\\\":null,\\\"number\\\":42,\\\"object\\\":{},\\\"string\\\":\\\"Hello world\\\"}\");\n\n            CHECK(j.dump() == j.dump(-1));\n        }\n\n        SECTION(\"indent=0\")\n        {\n            CHECK(j.dump(0) ==\n                  \"{\\n\\\"array\\\": [\\n1,\\n2,\\n3,\\n4\\n],\\n\\\"boolean\\\": false,\\n\\\"null\\\": null,\\n\\\"number\\\": 42,\\n\\\"object\\\": {},\\n\\\"string\\\": \\\"Hello world\\\"\\n}\");\n        }\n\n        SECTION(\"indent=1, space='\\t'\")\n        {\n            CHECK(j.dump(1, '\\t') ==\n                  \"{\\n\\t\\\"array\\\": [\\n\\t\\t1,\\n\\t\\t2,\\n\\t\\t3,\\n\\t\\t4\\n\\t],\\n\\t\\\"boolean\\\": false,\\n\\t\\\"null\\\": null,\\n\\t\\\"number\\\": 42,\\n\\t\\\"object\\\": {},\\n\\t\\\"string\\\": \\\"Hello world\\\"\\n}\");\n        }\n\n        SECTION(\"indent=4\")\n        {\n            CHECK(j.dump(4) ==\n                  \"{\\n    \\\"array\\\": [\\n        1,\\n        2,\\n        3,\\n        4\\n    ],\\n    \\\"boolean\\\": false,\\n    \\\"null\\\": null,\\n    \\\"number\\\": 42,\\n    \\\"object\\\": {},\\n    \\\"string\\\": \\\"Hello world\\\"\\n}\");\n        }\n\n        SECTION(\"indent=x\")\n        {\n            CHECK(j.dump().size() == 94);\n            CHECK(j.dump(1).size() == 127);\n            CHECK(j.dump(2).size() == 142);\n            CHECK(j.dump(512).size() == 7792);\n\n            // important test, because it yields a resize of the indent_string\n            // inside the dump() function\n            CHECK(j.dump(1024).size() == 15472);\n\n            const auto binary = json::binary({1, 2, 3}, 128);\n            CHECK(binary.dump(1024).size() == 2086);\n        }\n\n        SECTION(\"dump and floating-point numbers\")\n        {\n            auto s = json(42.23).dump();\n            CHECK(s.find(\"42.23\") != std::string::npos);\n        }\n\n        SECTION(\"dump and small floating-point numbers\")\n        {\n            auto s = json(1.23456e-78).dump();\n            CHECK(s.find(\"1.23456e-78\") != std::string::npos);\n        }\n\n        SECTION(\"dump and non-ASCII characters\")\n        {\n            CHECK(json(\"ä\").dump() == \"\\\"ä\\\"\");\n            CHECK(json(\"Ö\").dump() == \"\\\"Ö\\\"\");\n            CHECK(json(\"❤️\").dump() == \"\\\"❤️\\\"\");\n        }\n\n        SECTION(\"dump with ensure_ascii and non-ASCII characters\")\n        {\n            CHECK(json(\"ä\").dump(-1, ' ', true) == \"\\\"\\\\u00e4\\\"\");\n            CHECK(json(\"Ö\").dump(-1, ' ', true) == \"\\\"\\\\u00d6\\\"\");\n            CHECK(json(\"❤️\").dump(-1, ' ', true) == \"\\\"\\\\u2764\\\\ufe0f\\\"\");\n        }\n\n        SECTION(\"full Unicode escaping to ASCII\")\n        {\n            SECTION(\"parsing yields the same JSON value\")\n            {\n                std::ifstream f_escaped(TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode_ascii.json\");\n                std::ifstream f_unescaped(TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode.json\");\n\n                json j1 = json::parse(f_escaped);\n                json j2 = json::parse(f_unescaped);\n                CHECK(j1 == j2);\n            }\n\n            SECTION(\"dumping yields the same JSON text\")\n            {\n                std::ifstream f_escaped(TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode_ascii.json\");\n                std::ifstream f_unescaped(TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode.json\");\n\n                json value = json::parse(f_unescaped);\n                std::string text = value.dump(4, ' ', true);\n\n                std::string expected((std::istreambuf_iterator<char>(f_escaped)),\n                                     std::istreambuf_iterator<char>());\n                CHECK(text == expected);\n            }\n        }\n\n        SECTION(\"serialization of discarded element\")\n        {\n            json j_discarded(json::value_t::discarded);\n            CHECK(j_discarded.dump() == \"<discarded>\");\n        }\n\n        SECTION(\"check that precision is reset after serialization\")\n        {\n            // create stringstream and set precision\n            std::stringstream ss;\n            ss.precision(3);\n            ss << 3.141592653589793 << std::fixed;\n            CHECK(ss.str() == \"3.14\");\n\n            // reset stringstream\n            ss.str(std::string());\n\n            // use stringstream for JSON serialization\n            json j_number = 3.14159265358979;\n            ss << j_number;\n\n            // check that precision has been overridden during serialization\n            CHECK(ss.str() == \"3.14159265358979\");\n\n            // check that precision has been restored\n            CHECK(ss.precision() == 3);\n        }\n    }\n\n    SECTION(\"round trips\")\n    {\n        for (const auto& s :\n                {\"3.141592653589793\", \"1000000000000000010E5\"\n                })\n        {\n            json j1 = json::parse(s);\n            std::string s1 = j1.dump();\n            json j2 = json::parse(s1);\n            std::string s2 = j2.dump();\n            CHECK(s1 == s2);\n        }\n    }\n\n    SECTION(\"return the type of the object (explicit)\")\n    {\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            CHECK(j.type() == json::value_t::null);\n        }\n\n        SECTION(\"object\")\n        {\n            json j = {{\"foo\", \"bar\"}};\n            CHECK(j.type() == json::value_t::object);\n        }\n\n        SECTION(\"array\")\n        {\n            json j = {1, 2, 3, 4};\n            CHECK(j.type() == json::value_t::array);\n        }\n\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            CHECK(j.type() == json::value_t::boolean);\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"Hello world\";\n            CHECK(j.type() == json::value_t::string);\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j = 23;\n            CHECK(j.type() == json::value_t::number_integer);\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            CHECK(j.type() == json::value_t::number_unsigned);\n        }\n\n        SECTION(\"number (floating-point)\")\n        {\n            json j = 42.23;\n            CHECK(j.type() == json::value_t::number_float);\n        }\n    }\n\n    SECTION(\"return the type of the object (implicit)\")\n    {\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"object\")\n        {\n            json j = {{\"foo\", \"bar\"}};\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"array\")\n        {\n            json j = {1, 2, 3, 4};\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"Hello world\";\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j = 23;\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"number (floating-point)\")\n        {\n            json j = 42.23;\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n\n        SECTION(\"binary\")\n        {\n            json j = json::binary({});\n            json::value_t t = j;\n            CHECK(t == j.type());\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-items.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464\n    #define JSON_HAS_CPP_17\n    #define JSON_HAS_CPP_14\n#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)\n    #define JSON_HAS_CPP_14\n#endif\n\n// This test suite uses range for loops where values are copied. This is inefficient in usual code, but required to achieve 100% coverage.\nDOCTEST_GCC_SUPPRESS_WARNING_PUSH\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wrange-loop-construct\")\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wrange-loop-construct\")\n\nTEST_CASE(\"iterator_wrapper\")\n{\n    SECTION(\"object\")\n    {\n        SECTION(\"value\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n\n                        // change the value\n                        i.value() = json(11);\n                        CHECK(i.value() == json(11));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n\n                        // change the value\n                        i.value() = json(22);\n                        CHECK(i.value() == json(22));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n\n            // check if values where changed\n            CHECK(j == json({ {\"A\", 11}, {\"B\", 22} }));\n        }\n\n        SECTION(\"const value\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n    }\n\n    SECTION(\"const object\")\n    {\n        SECTION(\"value\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const value\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n    }\n\n    SECTION(\"array\")\n    {\n        SECTION(\"value\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n\n                        // change the value\n                        i.value() = \"AA\";\n                        CHECK(i.value() == \"AA\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n\n                        // change the value\n                        i.value() = \"BB\";\n                        CHECK(i.value() == \"BB\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n\n            // check if values where changed\n            CHECK(j == json({ \"AA\", \"BB\" }));\n        }\n\n        SECTION(\"const value\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n    }\n\n    SECTION(\"const array\")\n    {\n        SECTION(\"value\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const value\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto& i : json::iterator_wrapper(j))\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n    }\n\n    SECTION(\"primitive\")\n    {\n        SECTION(\"value\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"reference\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (auto& i : json::iterator_wrapper(j))\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n\n                // change value\n                i.value() = json(2);\n            }\n\n            CHECK(counter == 2);\n\n            // check if value has changed\n            CHECK(j == json(2));\n        }\n\n        SECTION(\"const value\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (const auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"const reference\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (const auto& i : json::iterator_wrapper(j))\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n    }\n\n    SECTION(\"const primitive\")\n    {\n        SECTION(\"value\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"reference\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (auto& i : json::iterator_wrapper(j))\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"const value\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (const auto i : json::iterator_wrapper(j)) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"const reference\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (const auto& i : json::iterator_wrapper(j))\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n    }\n}\n\nTEST_CASE(\"items()\")\n{\n    SECTION(\"object\")\n    {\n        SECTION(\"value\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n\n                        // change the value\n                        i.value() = json(11);\n                        CHECK(i.value() == json(11));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n\n                        // change the value\n                        i.value() = json(22);\n                        CHECK(i.value() == json(22));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n\n            // check if values where changed\n            CHECK(j == json({ {\"A\", 11}, {\"B\", 22} }));\n        }\n\n        SECTION(\"const value\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n#ifdef JSON_HAS_CPP_17\n        SECTION(\"structured bindings\")\n        {\n            json j = { {\"A\", 1}, {\"B\", 2} };\n\n            std::map<std::string, int> m;\n\n            for (auto const&[key, value] : j.items())\n            {\n                m.emplace(key, value);\n            }\n\n            CHECK(j.get<decltype(m)>() == m);\n        }\n#endif\n    }\n\n    SECTION(\"const object\")\n    {\n        SECTION(\"value\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const value\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            const json j = { {\"A\", 1}, {\"B\", 2} };\n            int counter = 1;\n\n            for (const auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"A\");\n                        CHECK(i.value() == json(1));\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"B\");\n                        CHECK(i.value() == json(2));\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n    }\n\n    SECTION(\"array\")\n    {\n        SECTION(\"value\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n\n                        // change the value\n                        i.value() = \"AA\";\n                        CHECK(i.value() == \"AA\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n\n                        // change the value\n                        i.value() = \"BB\";\n                        CHECK(i.value() == \"BB\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n\n            // check if values where changed\n            CHECK(j == json({ \"AA\", \"BB\" }));\n        }\n\n        SECTION(\"const value\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n    }\n\n    SECTION(\"const array\")\n    {\n        SECTION(\"value\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"reference\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const value\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n\n        SECTION(\"const reference\")\n        {\n            const json j = { \"A\", \"B\" };\n            int counter = 1;\n\n            for (const auto& i : j.items())\n            {\n                switch (counter++)\n                {\n                    case 1:\n                    {\n                        CHECK(i.key() == \"0\");\n                        CHECK(i.value() == \"A\");\n                        break;\n                    }\n\n                    case 2:\n                    {\n                        CHECK(i.key() == \"1\");\n                        CHECK(i.value() == \"B\");\n                        break;\n                    }\n\n                    default:\n                    {\n                        break;\n                    }\n                }\n            }\n\n            CHECK(counter == 3);\n        }\n    }\n\n    SECTION(\"primitive\")\n    {\n        SECTION(\"value\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"reference\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (auto& i : j.items())\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n\n                // change value\n                i.value() = json(2);\n            }\n\n            CHECK(counter == 2);\n\n            // check if value has changed\n            CHECK(j == json(2));\n        }\n\n        SECTION(\"const value\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (const auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"const reference\")\n        {\n            json j = 1;\n            int counter = 1;\n\n            for (const auto& i : j.items())\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n    }\n\n    SECTION(\"const primitive\")\n    {\n        SECTION(\"value\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"reference\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (auto& i : j.items())\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"const value\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (const auto i : j.items()) // NOLINT(performance-for-range-copy)\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n\n        SECTION(\"const reference\")\n        {\n            const json j = 1;\n            int counter = 1;\n\n            for (const auto& i : j.items())\n            {\n                ++counter;\n                CHECK(i.key() == \"\");\n                CHECK(i.value() == json(1));\n            }\n\n            CHECK(counter == 2);\n        }\n    }\n}\n\n#ifdef JSON_HAS_CPP_17\n    #undef JSON_HAS_CPP_17\n#endif\n\n#ifdef JSON_HAS_CPP_14\n    #undef JSON_HAS_CPP_14\n#endif\n\nDOCTEST_GCC_SUPPRESS_WARNING_POP\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-iterators1.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"iterators 1\")\n{\n    SECTION(\"basic behavior\")\n    {\n        SECTION(\"uninitialized\")\n        {\n            json::iterator it;\n            CHECK(it.m_object == nullptr);\n\n            json::const_iterator cit;\n            CHECK(cit.m_object == nullptr);\n        }\n\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it = j.begin();\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                it--;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                --it;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it = j_const.begin();\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                it--;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                --it;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it = j.cbegin();\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                it--;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                --it;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it = j_const.cbegin();\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                it--;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                --it;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it = j.rbegin();\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                it--;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                --it;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j.crbegin();\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                it--;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                --it;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j_const.crbegin();\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                it--;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                --it;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"additional tests\")\n            {\n                SECTION(\"!(begin != begin)\")\n                {\n                    CHECK(!(j.begin() != j.begin()));\n                }\n\n                SECTION(\"!(end != end)\")\n                {\n                    CHECK(!(j.end() != j.end()));\n                }\n\n                SECTION(\"begin < end\")\n                {\n                    CHECK(j.begin() < j.end());\n                }\n\n                SECTION(\"begin <= end\")\n                {\n                    CHECK(j.begin() <= j.end());\n                }\n\n                SECTION(\"end > begin\")\n                {\n                    CHECK(j.end() > j.begin());\n                }\n\n                SECTION(\"end >= begin\")\n                {\n                    CHECK(j.end() >= j.begin());\n                }\n\n                SECTION(\"end == end\")\n                {\n                    CHECK(j.end() == j.end());\n                }\n\n                SECTION(\"end <= end\")\n                {\n                    CHECK(j.end() <= j.end());\n                }\n\n                SECTION(\"begin == begin\")\n                {\n                    CHECK(j.begin() == j.begin());\n                }\n\n                SECTION(\"begin <= begin\")\n                {\n                    CHECK(j.begin() <= j.begin());\n                }\n\n                SECTION(\"begin >= begin\")\n                {\n                    CHECK(j.begin() >= j.begin());\n                }\n\n                SECTION(\"!(begin == end)\")\n                {\n                    CHECK(!(j.begin() == j.end()));\n                }\n\n                SECTION(\"begin != end\")\n                {\n                    CHECK(j.begin() != j.end());\n                }\n\n                SECTION(\"begin+1 == end\")\n                {\n                    CHECK(j.begin() + 1 == j.end());\n                }\n\n                SECTION(\"begin == end-1\")\n                {\n                    CHECK(j.begin() == j.end() - 1);\n                }\n\n                SECTION(\"begin != end+1\")\n                {\n                    CHECK(j.begin() != j.end() + 1);\n                }\n\n                SECTION(\"end != end+1\")\n                {\n                    CHECK(j.end() != j.end() + 1);\n                }\n\n                SECTION(\"begin+1 != begin+2\")\n                {\n                    CHECK(j.begin() + 1 != j.begin() + 2);\n                }\n\n                SECTION(\"begin+1 < begin+2\")\n                {\n                    CHECK(j.begin() + 1 < j.begin() + 2);\n                }\n\n                SECTION(\"begin+1 <= begin+2\")\n                {\n                    CHECK(j.begin() + 1 <= j.begin() + 2);\n                }\n\n                SECTION(\"end+1 != end+2\")\n                {\n                    CHECK(j.end() + 1 != j.end() + 2);\n                }\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK_THROWS_AS(it.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(it.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(it.value() == json(true));\n                CHECK_THROWS_AS(cit.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(cit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(cit.value() == json(true));\n\n                auto rit = j.rend();\n                auto crit = j.crend();\n                CHECK_THROWS_AS(rit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(rit.value(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.value(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(rit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(rit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                CHECK_THROWS_WITH(crit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(crit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"hello world\";\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it = j.begin();\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                it--;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                --it;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it = j_const.begin();\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                it--;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                --it;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it = j.cbegin();\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                it--;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                --it;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it = j_const.cbegin();\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                it--;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                --it;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it = j.rbegin();\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                it--;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                --it;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j.crbegin();\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                it--;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                --it;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j_const.crbegin();\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                it--;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                --it;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK_THROWS_AS(it.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(it.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(it.value() == json(\"hello world\"));\n                CHECK_THROWS_AS(cit.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(cit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(cit.value() == json(\"hello world\"));\n\n                auto rit = j.rend();\n                auto crit = j.crend();\n                CHECK_THROWS_AS(rit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(rit.value(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.value(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(rit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(rit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                CHECK_THROWS_WITH(crit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(crit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            json j = {1, 2, 3};\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it_begin = j.begin();\n                json::iterator it_end = j.end();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[0]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[1]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[2]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it_begin = j_const.begin();\n                json::const_iterator it_end = j_const.end();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j_const[0]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j_const[1]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j_const[2]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it_begin = j.cbegin();\n                json::const_iterator it_end = j.cend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[0]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[1]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[2]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it_begin = j_const.cbegin();\n                json::const_iterator it_end = j_const.cend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[0]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[1]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[2]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it_begin = j.rbegin();\n                json::reverse_iterator it_end = j.rend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[2]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[1]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[0]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it_begin = j.crbegin();\n                json::const_reverse_iterator it_end = j.crend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[2]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[1]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[0]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it_begin = j_const.crbegin();\n                json::const_reverse_iterator it_end = j_const.crend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[2]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[1]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[0]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK_THROWS_AS(it.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(it.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(it.value() == json(1));\n                CHECK_THROWS_AS(cit.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(cit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(cit.value() == json(1));\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            json j = {{\"A\", 1}, {\"B\", 2}, {\"C\", 3}};\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it_begin = j.begin();\n                json::iterator it_end = j.end();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[\"A\"]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"B\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"C\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it_begin = j_const.begin();\n                json::const_iterator it_end = j_const.end();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j_const[\"A\"]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j_const[\"B\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j_const[\"C\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it_begin = j.cbegin();\n                json::const_iterator it_end = j.cend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[\"A\"]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"B\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"C\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it_begin = j_const.cbegin();\n                json::const_iterator it_end = j_const.cend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j_const[\"A\"]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j_const[\"B\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j_const[\"C\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it_begin = j.rbegin();\n                json::reverse_iterator it_end = j.rend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[\"C\"]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"B\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"A\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it_begin = j.crbegin();\n                json::const_reverse_iterator it_end = j.crend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[\"C\"]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"B\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"A\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it_begin = j_const.crbegin();\n                json::const_reverse_iterator it_end = j_const.crend();\n\n                auto it = it_begin;\n                CHECK(it != it_end);\n                CHECK(*it == j[\"C\"]);\n\n                it++;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"B\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it != it_end);\n                CHECK(*it == j[\"A\"]);\n\n                ++it;\n                CHECK(it != it_begin);\n                CHECK(it == it_end);\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK(it.key() == \"A\");\n                CHECK(it.value() == json(1));\n                CHECK(cit.key() == \"A\");\n                CHECK(cit.value() == json(1));\n            }\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j = 23;\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it = j.begin();\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                it--;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                --it;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it = j_const.begin();\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                it--;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                --it;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it = j.cbegin();\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                it--;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                --it;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it = j_const.cbegin();\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                it--;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                --it;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it = j.rbegin();\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                it--;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                --it;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j.crbegin();\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                it--;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                --it;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j_const.crbegin();\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                it--;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                --it;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK_THROWS_AS(it.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(it.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(it.value() == json(23));\n                CHECK_THROWS_AS(cit.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(cit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(cit.value() == json(23));\n\n                auto rit = j.rend();\n                auto crit = j.crend();\n                CHECK_THROWS_AS(rit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(rit.value(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.value(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(rit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(rit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                CHECK_THROWS_WITH(crit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(crit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it = j.begin();\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                it--;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                --it;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it = j_const.begin();\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                it--;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                --it;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it = j.cbegin();\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                it--;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                --it;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it = j_const.cbegin();\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                it--;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                --it;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it = j.rbegin();\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                it--;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                --it;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j.crbegin();\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                it--;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                --it;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j_const.crbegin();\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                it--;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                --it;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK_THROWS_AS(it.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(it.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(it.value() == json(23));\n                CHECK_THROWS_AS(cit.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(cit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(cit.value() == json(23));\n\n                auto rit = j.rend();\n                auto crit = j.crend();\n                CHECK_THROWS_AS(rit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(rit.value(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.value(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(rit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(rit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                CHECK_THROWS_WITH(crit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(crit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n        }\n\n        SECTION(\"number (float)\")\n        {\n            json j = 23.42;\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it = j.begin();\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                it--;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.begin());\n                CHECK(it == j.end());\n\n                --it;\n                CHECK(it == j.begin());\n                CHECK(it != j.end());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it = j_const.begin();\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                it--;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.begin());\n                CHECK(it == j_const.end());\n\n                --it;\n                CHECK(it == j_const.begin());\n                CHECK(it != j_const.end());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it = j.cbegin();\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                it--;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.cbegin());\n                CHECK(it == j.cend());\n\n                --it;\n                CHECK(it == j.cbegin());\n                CHECK(it != j.cend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it = j_const.cbegin();\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                it--;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.cbegin());\n                CHECK(it == j_const.cend());\n\n                --it;\n                CHECK(it == j_const.cbegin());\n                CHECK(it != j_const.cend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it = j.rbegin();\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                it--;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.rbegin());\n                CHECK(it == j.rend());\n\n                --it;\n                CHECK(it == j.rbegin());\n                CHECK(it != j.rend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j.crbegin();\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                it++;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                it--;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n\n                ++it;\n                CHECK(it != j.crbegin());\n                CHECK(it == j.crend());\n\n                --it;\n                CHECK(it == j.crbegin());\n                CHECK(it != j.crend());\n                CHECK(*it == j);\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j_const.crbegin();\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                it++;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                it--;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n\n                ++it;\n                CHECK(it != j_const.crbegin());\n                CHECK(it == j_const.crend());\n\n                --it;\n                CHECK(it == j_const.crbegin());\n                CHECK(it != j_const.crend());\n                CHECK(*it == j_const);\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK_THROWS_AS(it.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(it.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(it.value() == json(23.42));\n                CHECK_THROWS_AS(cit.key(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(cit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK(cit.value() == json(23.42));\n\n                auto rit = j.rend();\n                auto crit = j.crend();\n                CHECK_THROWS_AS(rit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(rit.value(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.value(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(rit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(rit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                CHECK_THROWS_WITH(crit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(crit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            json j_const(j);\n\n            SECTION(\"json + begin/end\")\n            {\n                json::iterator it = j.begin();\n                CHECK(it == j.end());\n            }\n\n            SECTION(\"const json + begin/end\")\n            {\n                json::const_iterator it_begin = j_const.begin();\n                json::const_iterator it_end = j_const.end();\n                CHECK(it_begin == it_end);\n            }\n\n            SECTION(\"json + cbegin/cend\")\n            {\n                json::const_iterator it_begin = j.cbegin();\n                json::const_iterator it_end = j.cend();\n                CHECK(it_begin == it_end);\n            }\n\n            SECTION(\"const json + cbegin/cend\")\n            {\n                json::const_iterator it_begin = j_const.cbegin();\n                json::const_iterator it_end = j_const.cend();\n                CHECK(it_begin == it_end);\n            }\n\n            SECTION(\"json + rbegin/rend\")\n            {\n                json::reverse_iterator it = j.rbegin();\n                CHECK(it == j.rend());\n            }\n\n            SECTION(\"json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j.crbegin();\n                CHECK(it == j.crend());\n            }\n\n            SECTION(\"const json + crbegin/crend\")\n            {\n                json::const_reverse_iterator it = j_const.crbegin();\n                CHECK(it == j_const.crend());\n            }\n\n            SECTION(\"key/value\")\n            {\n                auto it = j.begin();\n                auto cit = j_const.cbegin();\n                CHECK_THROWS_AS(it.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(it.value(), json::invalid_iterator&);\n                CHECK_THROWS_AS(cit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(cit.value(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(it.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(it.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                CHECK_THROWS_WITH(cit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(cit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n\n                auto rit = j.rend();\n                auto crit = j.crend();\n                CHECK_THROWS_AS(rit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(rit.value(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.key(), json::invalid_iterator&);\n                CHECK_THROWS_AS(crit.value(), json::invalid_iterator&);\n                CHECK_THROWS_WITH(rit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(rit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n                CHECK_THROWS_WITH(crit.key(), \"[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\");\n                CHECK_THROWS_WITH(crit.value(), \"[json.exception.invalid_iterator.214] cannot get value\");\n            }\n        }\n    }\n\n    SECTION(\"conversion from iterator to const iterator\")\n    {\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n        SECTION(\"string\")\n        {\n            json j = \"hello world\";\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n        SECTION(\"array\")\n        {\n            json j = {1, 2, 3};\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n        SECTION(\"object\")\n        {\n            json j = {{\"A\", 1}, {\"B\", 2}, {\"C\", 3}};\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n        SECTION(\"number (integer)\")\n        {\n            json j = 23;\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n        SECTION(\"number (float)\")\n        {\n            json j = 23.42;\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            json::const_iterator it = j.begin();\n            CHECK(it == j.cbegin());\n            it = j.begin();\n            CHECK(it == j.cbegin());\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-iterators2.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"iterators 2\")\n{\n    SECTION(\"iterator comparisons\")\n    {\n        json j_values = {nullptr, true, 42, 42u, 23.23, {{\"one\", 1}, {\"two\", 2}}, {1, 2, 3, 4, 5}, \"Hello, world\"};\n\n        for (json& j : j_values)\n        {\n            auto it1 = j.begin();\n            auto it2 = j.begin();\n            auto it3 = j.begin();\n            ++it2;\n            ++it3;\n            ++it3;\n            auto it1_c = j.cbegin();\n            auto it2_c = j.cbegin();\n            auto it3_c = j.cbegin();\n            ++it2_c;\n            ++it3_c;\n            ++it3_c;\n\n            // comparison: equal\n            {\n                CHECK(it1 == it1);\n                CHECK(!(it1 == it2));\n                CHECK(!(it1 == it3));\n                CHECK(!(it2 == it3));\n                CHECK(it1_c == it1_c);\n                CHECK(!(it1_c == it2_c));\n                CHECK(!(it1_c == it3_c));\n                CHECK(!(it2_c == it3_c));\n            }\n\n            // comparison: not equal\n            {\n                // check definition\n                CHECK( (it1 != it1) == !(it1 == it1) );\n                CHECK( (it1 != it2) == !(it1 == it2) );\n                CHECK( (it1 != it3) == !(it1 == it3) );\n                CHECK( (it2 != it3) == !(it2 == it3) );\n                CHECK( (it1_c != it1_c) == !(it1_c == it1_c) );\n                CHECK( (it1_c != it2_c) == !(it1_c == it2_c) );\n                CHECK( (it1_c != it3_c) == !(it1_c == it3_c) );\n                CHECK( (it2_c != it3_c) == !(it2_c == it3_c) );\n            }\n\n            // comparison: smaller\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 < it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 < it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 < it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 < it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c < it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 < it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 < it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c < it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 < it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 < it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c < it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    CHECK(!(it1 < it1));\n                    CHECK(it1 < it2);\n                    CHECK(it1 < it3);\n                    CHECK(it2 < it3);\n                    CHECK(!(it1_c < it1_c));\n                    CHECK(it1_c < it2_c);\n                    CHECK(it1_c < it3_c);\n                    CHECK(it2_c < it3_c);\n                }\n            }\n\n            // comparison: less than or equal\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 <= it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 <= it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 <= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 <= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c <= it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 <= it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 <= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c <= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 <= it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 <= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c <= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    // check definition\n                    CHECK( (it1 <= it1) == !(it1 < it1) );\n                    CHECK( (it1 <= it2) == !(it2 < it1) );\n                    CHECK( (it1 <= it3) == !(it3 < it1) );\n                    CHECK( (it2 <= it3) == !(it3 < it2) );\n                    CHECK( (it1_c <= it1_c) == !(it1_c < it1_c) );\n                    CHECK( (it1_c <= it2_c) == !(it2_c < it1_c) );\n                    CHECK( (it1_c <= it3_c) == !(it3_c < it1_c) );\n                    CHECK( (it2_c <= it3_c) == !(it3_c < it2_c) );\n                }\n            }\n\n            // comparison: greater than\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 > it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 > it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 > it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 > it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c > it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 > it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 > it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c > it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 > it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 > it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c > it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    // check definition\n                    CHECK( (it1 > it1) == (it1 < it1) );\n                    CHECK( (it1 > it2) == (it2 < it1) );\n                    CHECK( (it1 > it3) == (it3 < it1) );\n                    CHECK( (it2 > it3) == (it3 < it2) );\n                    CHECK( (it1_c > it1_c) == (it1_c < it1_c) );\n                    CHECK( (it1_c > it2_c) == (it2_c < it1_c) );\n                    CHECK( (it1_c > it3_c) == (it3_c < it1_c) );\n                    CHECK( (it2_c > it3_c) == (it3_c < it2_c) );\n                }\n            }\n\n            // comparison: greater than or equal\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 >= it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 >= it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 >= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 >= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c >= it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 >= it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 >= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c >= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 >= it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 >= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c >= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    // check definition\n                    CHECK( (it1 >= it1) == !(it1 < it1) );\n                    CHECK( (it1 >= it2) == !(it1 < it2) );\n                    CHECK( (it1 >= it3) == !(it1 < it3) );\n                    CHECK( (it2 >= it3) == !(it2 < it3) );\n                    CHECK( (it1_c >= it1_c) == !(it1_c < it1_c) );\n                    CHECK( (it1_c >= it2_c) == !(it1_c < it2_c) );\n                    CHECK( (it1_c >= it3_c) == !(it1_c < it3_c) );\n                    CHECK( (it2_c >= it3_c) == !(it2_c < it3_c) );\n                }\n            }\n        }\n\n        // check exceptions if different objects are compared\n        for (auto j : j_values)\n        {\n            for (auto k : j_values)\n            {\n                if (j != k)\n                {\n                    CHECK_THROWS_AS(j.begin() == k.begin(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.cbegin() == k.cbegin(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.begin() < k.begin(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.cbegin() < k.cbegin(), json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    // the output differs in each loop, so we cannot fix a string for the expected exception\n#else\n                    CHECK_THROWS_WITH(j.begin() == k.begin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n                    CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n                    CHECK_THROWS_WITH(j.begin() < k.begin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n                    CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n#endif\n                }\n            }\n        }\n    }\n\n    SECTION(\"iterator arithmetic\")\n    {\n        json j_object = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n        json j_array = {1, 2, 3, 4, 5, 6};\n        json j_null = nullptr;\n        json j_value = 42;\n\n        SECTION(\"addition and subtraction\")\n        {\n            SECTION(\"object\")\n            {\n                {\n                    auto it = j_object.begin();\n                    CHECK_THROWS_AS(it += 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it += 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.cbegin();\n                    CHECK_THROWS_AS(it += 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it += 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.begin();\n                    CHECK_THROWS_AS(it + 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it + 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.cbegin();\n                    CHECK_THROWS_AS(it + 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it + 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.begin();\n                    CHECK_THROWS_AS(1 + it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(1 + it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.cbegin();\n                    CHECK_THROWS_AS(1 + it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(1 + it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.begin();\n                    CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it -= 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.cbegin();\n                    CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it -= 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.begin();\n                    CHECK_THROWS_AS(it - 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.cbegin();\n                    CHECK_THROWS_AS(it - 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.begin();\n                    CHECK_THROWS_AS(it - it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.cbegin();\n                    CHECK_THROWS_AS(it - it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n            }\n\n            SECTION(\"array\")\n            {\n                {\n                    auto it = j_array.begin();\n                    it += 3;\n                    CHECK((j_array.begin() + 3) == it);\n                    CHECK((3 + j_array.begin()) == it);\n                    CHECK((it - 3) == j_array.begin());\n                    CHECK((it - j_array.begin()) == 3);\n                    CHECK(*it == json(4));\n                    it -= 2;\n                    CHECK(*it == json(2));\n                }\n                {\n                    auto it = j_array.cbegin();\n                    it += 3;\n                    CHECK((j_array.cbegin() + 3) == it);\n                    CHECK((3 + j_array.cbegin()) == it);\n                    CHECK((it - 3) == j_array.cbegin());\n                    CHECK((it - j_array.cbegin()) == 3);\n                    CHECK(*it == json(4));\n                    it -= 2;\n                    CHECK(*it == json(2));\n                }\n            }\n\n            SECTION(\"null\")\n            {\n                {\n                    auto it = j_null.begin();\n                    it += 3;\n                    CHECK((j_null.begin() + 3) == it);\n                    CHECK((3 + j_null.begin()) == it);\n                    CHECK((it - 3) == j_null.begin());\n                    CHECK((it - j_null.begin()) == 3);\n                    CHECK(it != j_null.end());\n                    it -= 3;\n                    CHECK(it == j_null.end());\n                }\n                {\n                    auto it = j_null.cbegin();\n                    it += 3;\n                    CHECK((j_null.cbegin() + 3) == it);\n                    CHECK((3 + j_null.cbegin()) == it);\n                    CHECK((it - 3) == j_null.cbegin());\n                    CHECK((it - j_null.cbegin()) == 3);\n                    CHECK(it != j_null.cend());\n                    it -= 3;\n                    CHECK(it == j_null.cend());\n                }\n            }\n\n            SECTION(\"value\")\n            {\n                {\n                    auto it = j_value.begin();\n                    it += 3;\n                    CHECK((j_value.begin() + 3) == it);\n                    CHECK((3 + j_value.begin()) == it);\n                    CHECK((it - 3) == j_value.begin());\n                    CHECK((it - j_value.begin()) == 3);\n                    CHECK(it != j_value.end());\n                    it -= 3;\n                    CHECK(*it == json(42));\n                }\n                {\n                    auto it = j_value.cbegin();\n                    it += 3;\n                    CHECK((j_value.cbegin() + 3) == it);\n                    CHECK((3 + j_value.cbegin()) == it);\n                    CHECK((it - 3) == j_value.cbegin());\n                    CHECK((it - j_value.cbegin()) == 3);\n                    CHECK(it != j_value.cend());\n                    it -= 3;\n                    CHECK(*it == json(42));\n                }\n            }\n        }\n\n        SECTION(\"subscript operator\")\n        {\n            SECTION(\"object\")\n            {\n                {\n                    auto it = j_object.begin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators\");\n                }\n                {\n                    auto it = j_object.cbegin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators\");\n                }\n            }\n\n            SECTION(\"array\")\n            {\n                {\n                    auto it = j_array.begin();\n                    CHECK(it[0] == json(1));\n                    CHECK(it[1] == json(2));\n                    CHECK(it[2] == json(3));\n                    CHECK(it[3] == json(4));\n                    CHECK(it[4] == json(5));\n                    CHECK(it[5] == json(6));\n                }\n                {\n                    auto it = j_array.cbegin();\n                    CHECK(it[0] == json(1));\n                    CHECK(it[1] == json(2));\n                    CHECK(it[2] == json(3));\n                    CHECK(it[3] == json(4));\n                    CHECK(it[4] == json(5));\n                    CHECK(it[5] == json(6));\n                }\n            }\n\n            SECTION(\"null\")\n            {\n                {\n                    auto it = j_null.begin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.214] cannot get value\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n                {\n                    auto it = j_null.cbegin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.214] cannot get value\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n            }\n\n            SECTION(\"value\")\n            {\n                {\n                    auto it = j_value.begin();\n                    CHECK(it[0] == json(42));\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n                {\n                    auto it = j_value.cbegin();\n                    CHECK(it[0] == json(42));\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n            }\n        }\n    }\n\n    SECTION(\"reverse iterator comparisons\")\n    {\n        json j_values = {nullptr, true, 42, 42u, 23.23, {{\"one\", 1}, {\"two\", 2}}, {1, 2, 3, 4, 5}, \"Hello, world\"};\n\n        for (json& j : j_values)\n        {\n            auto it1 = j.rbegin();\n            auto it2 = j.rbegin();\n            auto it3 = j.rbegin();\n            ++it2;\n            ++it3;\n            ++it3;\n            auto it1_c = j.crbegin();\n            auto it2_c = j.crbegin();\n            auto it3_c = j.crbegin();\n            ++it2_c;\n            ++it3_c;\n            ++it3_c;\n\n            // comparison: equal\n            {\n                CHECK(it1 == it1);\n                CHECK(!(it1 == it2));\n                CHECK(!(it1 == it3));\n                CHECK(!(it2 == it3));\n                CHECK(it1_c == it1_c);\n                CHECK(!(it1_c == it2_c));\n                CHECK(!(it1_c == it3_c));\n                CHECK(!(it2_c == it3_c));\n            }\n\n            // comparison: not equal\n            {\n                // check definition\n                CHECK( (it1 != it1) == !(it1 == it1) );\n                CHECK( (it1 != it2) == !(it1 == it2) );\n                CHECK( (it1 != it3) == !(it1 == it3) );\n                CHECK( (it2 != it3) == !(it2 == it3) );\n                CHECK( (it1_c != it1_c) == !(it1_c == it1_c) );\n                CHECK( (it1_c != it2_c) == !(it1_c == it2_c) );\n                CHECK( (it1_c != it3_c) == !(it1_c == it3_c) );\n                CHECK( (it2_c != it3_c) == !(it2_c == it3_c) );\n            }\n\n            // comparison: smaller\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 < it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 < it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 < it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 < it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c < it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 < it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 < it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c < it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 < it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 < it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 < it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c < it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c < it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    CHECK(!(it1 < it1));\n                    CHECK(it1 < it2);\n                    CHECK(it1 < it3);\n                    CHECK(it2 < it3);\n                    CHECK(!(it1_c < it1_c));\n                    CHECK(it1_c < it2_c);\n                    CHECK(it1_c < it3_c);\n                    CHECK(it2_c < it3_c);\n                }\n            }\n\n            // comparison: less than or equal\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 <= it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 <= it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 <= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 <= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c <= it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 <= it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 <= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c <= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 <= it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 <= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 <= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c <= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c <= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    // check definition\n                    CHECK( (it1 <= it1) == !(it1 < it1) );\n                    CHECK( (it1 <= it2) == !(it2 < it1) );\n                    CHECK( (it1 <= it3) == !(it3 < it1) );\n                    CHECK( (it2 <= it3) == !(it3 < it2) );\n                    CHECK( (it1_c <= it1_c) == !(it1_c < it1_c) );\n                    CHECK( (it1_c <= it2_c) == !(it2_c < it1_c) );\n                    CHECK( (it1_c <= it3_c) == !(it3_c < it1_c) );\n                    CHECK( (it2_c <= it3_c) == !(it3_c < it2_c) );\n                }\n            }\n\n            // comparison: greater than\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 > it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 > it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 > it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 > it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c > it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 > it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 > it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c > it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 > it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 > it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 > it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c > it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c > it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    // check definition\n                    CHECK( (it1 > it1) == (it1 < it1) );\n                    CHECK( (it1 > it2) == (it2 < it1) );\n                    CHECK( (it1 > it3) == (it3 < it1) );\n                    CHECK( (it2 > it3) == (it3 < it2) );\n                    CHECK( (it1_c > it1_c) == (it1_c < it1_c) );\n                    CHECK( (it1_c > it2_c) == (it2_c < it1_c) );\n                    CHECK( (it1_c > it3_c) == (it3_c < it1_c) );\n                    CHECK( (it2_c > it3_c) == (it3_c < it2_c) );\n                }\n            }\n\n            // comparison: greater than or equal\n            {\n                if (j.type() == json::value_t::object)\n                {\n                    CHECK_THROWS_AS(it1 >= it1, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 >= it2, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2 >= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1 >= it3, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c >= it1_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator&);\n                    CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    CHECK_THROWS_WITH(it1 >= it1, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it2, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 >= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it3, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it1_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it2_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c >= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it3_c, \"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators\");\n#else\n                    CHECK_THROWS_WITH(it1 >= it1, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it2, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2 >= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1 >= it3, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it1_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it2_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it2_c >= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n                    CHECK_THROWS_WITH(it1_c >= it3_c, \"[json.exception.invalid_iterator.213] cannot compare order of object iterators\");\n#endif\n                }\n                else\n                {\n                    // check definition\n                    CHECK( (it1 >= it1) == !(it1 < it1) );\n                    CHECK( (it1 >= it2) == !(it1 < it2) );\n                    CHECK( (it1 >= it3) == !(it1 < it3) );\n                    CHECK( (it2 >= it3) == !(it2 < it3) );\n                    CHECK( (it1_c >= it1_c) == !(it1_c < it1_c) );\n                    CHECK( (it1_c >= it2_c) == !(it1_c < it2_c) );\n                    CHECK( (it1_c >= it3_c) == !(it1_c < it3_c) );\n                    CHECK( (it2_c >= it3_c) == !(it2_c < it3_c) );\n                }\n            }\n        }\n\n        // check exceptions if different objects are compared\n        for (auto j : j_values)\n        {\n            for (auto k : j_values)\n            {\n                if (j != k)\n                {\n                    CHECK_THROWS_AS(j.rbegin() == k.rbegin(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.crbegin() == k.crbegin(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.rbegin() < k.rbegin(), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j.crbegin() < k.crbegin(), json::invalid_iterator&);\n#if JSON_DIAGNOSTICS\n                    // the output differs in each loop, so we cannot fix a string for the expected exception\n#else\n                    CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n                    CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n                    CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n                    CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), \"[json.exception.invalid_iterator.212] cannot compare iterators of different containers\");\n#endif\n                }\n            }\n        }\n    }\n\n    SECTION(\"reverse iterator arithmetic\")\n    {\n        json j_object = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n        json j_array = {1, 2, 3, 4, 5, 6};\n        json j_null = nullptr;\n        json j_value = 42;\n\n        SECTION(\"addition and subtraction\")\n        {\n            SECTION(\"object\")\n            {\n                {\n                    auto it = j_object.rbegin();\n                    CHECK_THROWS_AS(it += 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it += 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.crbegin();\n                    CHECK_THROWS_AS(it += 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it += 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.rbegin();\n                    CHECK_THROWS_AS(it + 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it + 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.crbegin();\n                    CHECK_THROWS_AS(it + 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it + 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.rbegin();\n                    CHECK_THROWS_AS(1 + it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(1 + it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.crbegin();\n                    CHECK_THROWS_AS(1 + it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(1 + it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.rbegin();\n                    CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it -= 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.crbegin();\n                    CHECK_THROWS_AS(it -= 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it -= 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.rbegin();\n                    CHECK_THROWS_AS(it - 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.crbegin();\n                    CHECK_THROWS_AS(it - 1, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - 1, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.rbegin();\n                    CHECK_THROWS_AS(it - it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.crbegin();\n                    CHECK_THROWS_AS(it - it, json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it - it, \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n            }\n\n            SECTION(\"array\")\n            {\n                {\n                    auto it = j_array.rbegin();\n                    it += 3;\n                    CHECK((j_array.rbegin() + 3) == it);\n                    CHECK(json::reverse_iterator(3 + j_array.rbegin()) == it);\n                    CHECK((it - 3) == j_array.rbegin());\n                    CHECK((it - j_array.rbegin()) == 3);\n                    CHECK(*it == json(3));\n                    it -= 2;\n                    CHECK(*it == json(5));\n                }\n                {\n                    auto it = j_array.crbegin();\n                    it += 3;\n                    CHECK((j_array.crbegin() + 3) == it);\n                    CHECK(json::const_reverse_iterator(3 + j_array.crbegin()) == it);\n                    CHECK((it - 3) == j_array.crbegin());\n                    CHECK((it - j_array.crbegin()) == 3);\n                    CHECK(*it == json(3));\n                    it -= 2;\n                    CHECK(*it == json(5));\n                }\n            }\n\n            SECTION(\"null\")\n            {\n                {\n                    auto it = j_null.rbegin();\n                    it += 3;\n                    CHECK((j_null.rbegin() + 3) == it);\n                    CHECK(json::reverse_iterator(3 + j_null.rbegin()) == it);\n                    CHECK((it - 3) == j_null.rbegin());\n                    CHECK((it - j_null.rbegin()) == 3);\n                    CHECK(it != j_null.rend());\n                    it -= 3;\n                    CHECK(it == j_null.rend());\n                }\n                {\n                    auto it = j_null.crbegin();\n                    it += 3;\n                    CHECK((j_null.crbegin() + 3) == it);\n                    CHECK(json::const_reverse_iterator(3 + j_null.crbegin()) == it);\n                    CHECK((it - 3) == j_null.crbegin());\n                    CHECK((it - j_null.crbegin()) == 3);\n                    CHECK(it != j_null.crend());\n                    it -= 3;\n                    CHECK(it == j_null.crend());\n                }\n            }\n\n            SECTION(\"value\")\n            {\n                {\n                    auto it = j_value.rbegin();\n                    it += 3;\n                    CHECK((j_value.rbegin() + 3) == it);\n                    CHECK(json::reverse_iterator(3 + j_value.rbegin()) == it);\n                    CHECK((it - 3) == j_value.rbegin());\n                    CHECK((it - j_value.rbegin()) == 3);\n                    CHECK(it != j_value.rend());\n                    it -= 3;\n                    CHECK(*it == json(42));\n                }\n                {\n                    auto it = j_value.crbegin();\n                    it += 3;\n                    CHECK((j_value.crbegin() + 3) == it);\n                    CHECK(json::const_reverse_iterator(3 + j_value.crbegin()) == it);\n                    CHECK((it - 3) == j_value.crbegin());\n                    CHECK((it - j_value.crbegin()) == 3);\n                    CHECK(it != j_value.crend());\n                    it -= 3;\n                    CHECK(*it == json(42));\n                }\n            }\n        }\n\n        SECTION(\"subscript operator\")\n        {\n            SECTION(\"object\")\n            {\n                {\n                    auto it = j_object.rbegin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n                {\n                    auto it = j_object.crbegin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.209] cannot use offsets with object iterators\");\n                }\n            }\n\n            SECTION(\"array\")\n            {\n                {\n                    auto it = j_array.rbegin();\n                    CHECK(it[0] == json(6));\n                    CHECK(it[1] == json(5));\n                    CHECK(it[2] == json(4));\n                    CHECK(it[3] == json(3));\n                    CHECK(it[4] == json(2));\n                    CHECK(it[5] == json(1));\n                }\n                {\n                    auto it = j_array.crbegin();\n                    CHECK(it[0] == json(6));\n                    CHECK(it[1] == json(5));\n                    CHECK(it[2] == json(4));\n                    CHECK(it[3] == json(3));\n                    CHECK(it[4] == json(2));\n                    CHECK(it[5] == json(1));\n                }\n            }\n\n            SECTION(\"null\")\n            {\n                {\n                    auto it = j_null.rbegin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.214] cannot get value\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n                {\n                    auto it = j_null.crbegin();\n                    CHECK_THROWS_AS(it[0], json::invalid_iterator&);\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[0], \"[json.exception.invalid_iterator.214] cannot get value\");\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n            }\n\n            SECTION(\"value\")\n            {\n                {\n                    auto it = j_value.rbegin();\n                    CHECK(it[0] == json(42));\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n                {\n                    auto it = j_value.crbegin();\n                    CHECK(it[0] == json(42));\n                    CHECK_THROWS_AS(it[1], json::invalid_iterator&);\n                    CHECK_THROWS_WITH(it[1], \"[json.exception.invalid_iterator.214] cannot get value\");\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-json_patch.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <test_data.hpp>\n\nTEST_CASE(\"JSON patch\")\n{\n    SECTION(\"examples from RFC 6902\")\n    {\n        SECTION(\"4. Operations\")\n        {\n            // the ordering of members in JSON objects is not significant:\n            json op1 = R\"({ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": \"foo\" })\"_json;\n            json op2 = R\"({ \"path\": \"/a/b/c\", \"op\": \"add\", \"value\": \"foo\" })\"_json;\n            json op3 = R\"({ \"value\": \"foo\", \"path\": \"/a/b/c\", \"op\": \"add\" })\"_json;\n\n            // check if the operation objects are equivalent\n            CHECK(op1 == op2);\n            CHECK(op1 == op3);\n        }\n\n        SECTION(\"4.1 add\")\n        {\n            json patch = R\"([{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }])\"_json;\n\n            // However, the object itself or an array containing it does need\n            // to exist, and it remains an error for that not to be the case.\n            // For example, an \"add\" with a target location of \"/a/b\" starting\n            // with this document\n            json doc1 = R\"({ \"a\": { \"foo\": 1 } })\"_json;\n\n            // is not an error, because \"a\" exists, and \"b\" will be added to\n            // its value.\n            CHECK_NOTHROW(doc1.patch(patch));\n            auto doc1_ans = R\"(\n                {\n                    \"a\": {\n                        \"foo\": 1,\n                        \"b\": {\n                            \"c\": [ \"foo\", \"bar\" ]\n                        }\n                    }\n                }\n            )\"_json;\n            CHECK(doc1.patch(patch) == doc1_ans);\n\n            // It is an error in this document:\n            json doc2 = R\"({ \"q\": { \"bar\": 2 } })\"_json;\n\n            // because \"a\" does not exist.\n            CHECK_THROWS_AS(doc2.patch(patch), json::out_of_range&);\n            CHECK_THROWS_WITH(doc2.patch(patch),\n                              \"[json.exception.out_of_range.403] key 'a' not found\");\n        }\n\n        SECTION(\"4.2 remove\")\n        {\n            // If removing an element from an array, any elements above the\n            // specified index are shifted one position to the left.\n            json doc = {1, 2, 3, 4};\n            json patch = {{{\"op\", \"remove\"}, {\"path\", \"/1\"}}};\n            CHECK(doc.patch(patch) == json({1, 3, 4}));\n        }\n\n        SECTION(\"A.1. Adding an Object Member\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": \"bar\"}\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"add\", \"path\": \"/baz\", \"value\": \"qux\" }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                    {\n                        \"baz\": \"qux\",\n                        \"foo\": \"bar\"\n                    }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.2. Adding an Array Element\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": [ \"bar\", \"baz\" ] }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"add\", \"path\": \"/foo/1\", \"value\": \"qux\" }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                    { \"foo\": [ \"bar\", \"qux\", \"baz\" ] }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.3. Removing an Object Member\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    {\n                        \"baz\": \"qux\",\n                        \"foo\": \"bar\"\n                    }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"remove\", \"path\": \"/baz\" }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                    { \"foo\": \"bar\" }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.4. Removing an Array Element\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": [ \"bar\", \"qux\", \"baz\" ] }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"remove\", \"path\": \"/foo/1\" }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                    { \"foo\": [ \"bar\", \"baz\" ] }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.5. Replacing a Value\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    {\n                        \"baz\": \"qux\",\n                        \"foo\": \"bar\"\n                    }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" }\n                    ]\n                )\"_json;\n\n            json expected = R\"(\n                    {\n                        \"baz\": \"boo\",\n                        \"foo\": \"bar\"\n                    }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.6. Moving a Value\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    {\n                        \"foo\": {\n                           \"bar\": \"baz\",\n                            \"waldo\": \"fred\"\n                        },\n                        \"qux\": {\n                            \"corge\": \"grault\"\n                        }\n                    }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"move\", \"from\": \"/foo/waldo\", \"path\": \"/qux/thud\" }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                    {\n                        \"foo\": {\n                           \"bar\": \"baz\"\n                        },\n                        \"qux\": {\n                            \"corge\": \"grault\",\n                            \"thud\": \"fred\"\n                        }\n                    }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.7. Moving a Value\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": [ \"all\", \"grass\", \"cows\", \"eat\" ] }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"move\", \"from\": \"/foo/1\", \"path\": \"/foo/3\" }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                    { \"foo\": [ \"all\", \"cows\", \"eat\", \"grass\" ] }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.8. Testing a Value: Success\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    {\n                         \"baz\": \"qux\",\n                         \"foo\": [ \"a\", 2, \"c\" ]\n                    }\n                )\"_json;\n\n            // A JSON Patch document that will result in successful evaluation:\n            json patch = R\"(\n                    [\n                        { \"op\": \"test\", \"path\": \"/baz\", \"value\": \"qux\" },\n                        { \"op\": \"test\", \"path\": \"/foo/1\", \"value\": 2 }\n                    ]\n                )\"_json;\n\n            // check if evaluation does not throw\n            CHECK_NOTHROW(doc.patch(patch));\n            // check if patched document is unchanged\n            CHECK(doc.patch(patch) == doc);\n        }\n\n        SECTION(\"A.9. Testing a Value: Error\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"baz\": \"qux\" }\n                )\"_json;\n\n            // A JSON Patch document that will result in an error condition:\n            json patch = R\"(\n                    [\n                        { \"op\": \"test\", \"path\": \"/baz\", \"value\": \"bar\" }\n                    ]\n                )\"_json;\n\n            // check that evaluation throws\n            CHECK_THROWS_AS(doc.patch(patch), json::other_error&);\n#if JSON_DIAGNOSTICS\n            CHECK_THROWS_WITH_STD_STR(doc.patch(patch), \"[json.exception.other_error.501] (/0) unsuccessful: \" + patch[0].dump());\n#else\n            CHECK_THROWS_WITH_STD_STR(doc.patch(patch), \"[json.exception.other_error.501] unsuccessful: \" + patch[0].dump());\n#endif\n        }\n\n        SECTION(\"A.10. Adding a Nested Member Object\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": \"bar\" }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"add\", \"path\": \"/child\", \"value\": { \"grandchild\": { } } }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                {\n                    \"foo\": \"bar\",\n                    \"child\": {\n                        \"grandchild\": {\n                        }\n                    }\n                }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.11. Ignoring Unrecognized Elements\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": \"bar\" }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"add\", \"path\": \"/baz\", \"value\": \"qux\", \"xyz\": 123 }\n                    ]\n                )\"_json;\n\n            json expected = R\"(\n                    {\n                        \"foo\": \"bar\",\n                        \"baz\": \"qux\"\n                    } \n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.12. Adding to a Nonexistent Target\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": \"bar\" }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"add\", \"path\": \"/baz/bat\", \"value\": \"qux\" }\n                    ]\n                )\"_json;\n\n            // This JSON Patch document, applied to the target JSON document\n            // above, would result in an error (therefore, it would not be\n            // applied), because the \"add\" operation's target location that\n            // references neither the root of the document, nor a member of\n            // an existing object, nor a member of an existing array.\n\n            CHECK_THROWS_AS(doc.patch(patch), json::out_of_range&);\n            CHECK_THROWS_WITH(doc.patch(patch),\n                              \"[json.exception.out_of_range.403] key 'baz' not found\");\n        }\n\n        // A.13. Invalid JSON Patch Document\n        // not applicable\n\n        SECTION(\"A.14. Escape Ordering\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    {\n                        \"/\": 9,\n                        \"~1\": 10\n                    }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        {\"op\": \"test\", \"path\": \"/~01\", \"value\": 10}\n                    ]\n                )\"_json;\n\n            json expected = R\"(\n                    {\n                        \"/\": 9,\n                        \"~1\": 10\n                    } \n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"A.15. Comparing Strings and Numbers\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    {\n                        \"/\": 9,\n                        \"~1\": 10\n                    } \n                )\"_json;\n\n            // A JSON Patch document that will result in an error condition:\n            json patch = R\"(\n                    [\n                        {\"op\": \"test\", \"path\": \"/~01\", \"value\": \"10\"}\n                    ]\n                )\"_json;\n\n            // check that evaluation throws\n            CHECK_THROWS_AS(doc.patch(patch), json::other_error&);\n#if JSON_DIAGNOSTICS\n            CHECK_THROWS_WITH_STD_STR(doc.patch(patch), \"[json.exception.other_error.501] (/0) unsuccessful: \" + patch[0].dump());\n#else\n            CHECK_THROWS_WITH_STD_STR(doc.patch(patch), \"[json.exception.other_error.501] unsuccessful: \" + patch[0].dump());\n#endif\n        }\n\n        SECTION(\"A.16. Adding an Array Value\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                    { \"foo\": [\"bar\"] }\n                )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                    [\n                        { \"op\": \"add\", \"path\": \"/foo/-\", \"value\": [\"abc\", \"def\"] }\n                    ]\n                )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                    { \"foo\": [\"bar\", [\"abc\", \"def\"]] }\n                )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n    }\n\n    SECTION(\"own examples\")\n    {\n        SECTION(\"add\")\n        {\n            SECTION(\"add to the root element\")\n            {\n                // If the path is the root of the target document - the\n                // specified value becomes the entire content of the target\n                // document.\n\n                // An example target JSON document:\n                json doc = 17;\n\n                // A JSON Patch document:\n                json patch = R\"(\n                        [\n                            { \"op\": \"add\", \"path\": \"\", \"value\": [1,2,3] }\n                        ]\n                    )\"_json;\n\n                // The resulting JSON document:\n                json expected = {1, 2, 3};\n\n                // check if patched value is as expected\n                CHECK(doc.patch(patch) == expected);\n\n                // check roundtrip\n                CHECK(doc.patch(json::diff(doc, expected)) == expected);\n            }\n\n            SECTION(\"add to end of the array\")\n            {\n                // The specified index MUST NOT be greater than the number of\n                // elements in the array. The example below uses and index of\n                // exactly the number of elements in the array which is legal.\n\n                // An example target JSON document:\n                json doc = {0, 1, 2};\n\n                // A JSON Patch document:\n                json patch = R\"(\n                    [\n                        { \"op\": \"add\", \"path\": \"/3\", \"value\": 3 }\n                    ]\n                )\"_json;\n\n                // The resulting JSON document:\n                json expected = {0, 1, 2, 3};\n\n                // check if patched value is as expected\n                CHECK(doc.patch(patch) == expected);\n\n                // check roundtrip\n                CHECK(doc.patch(json::diff(doc, expected)) == expected);\n            }\n        }\n\n        SECTION(\"copy\")\n        {\n            // An example target JSON document:\n            json doc = R\"(\n                {\n                    \"foo\": {\n                        \"bar\": \"baz\",\n                        \"waldo\": \"fred\"\n                    },\n                    \"qux\": {\n                       \"corge\": \"grault\"\n                    }\n                }\n            )\"_json;\n\n            // A JSON Patch document:\n            json patch = R\"(\n                [\n                    { \"op\": \"copy\", \"from\": \"/foo/waldo\", \"path\": \"/qux/thud\" }\n                ]\n            )\"_json;\n\n            // The resulting JSON document:\n            json expected = R\"(\n                {\n                    \"foo\": {\n                        \"bar\": \"baz\",\n                        \"waldo\": \"fred\"\n                    },\n                    \"qux\": {\n                       \"corge\": \"grault\",\n                       \"thud\": \"fred\"\n                    }\n                }\n            )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == expected);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, expected)) == expected);\n        }\n\n        SECTION(\"replace\")\n        {\n            json j = \"string\";\n            json patch = {{{\"op\", \"replace\"}, {\"path\", \"\"}, {\"value\", 1}}};\n            CHECK(j.patch(patch) == json(1));\n        }\n\n        SECTION(\"documentation GIF\")\n        {\n            {\n                // a JSON patch\n                json p1 = R\"(\n                     [{\"op\": \"add\", \"path\": \"/GB\", \"value\": \"London\"}]\n                    )\"_json;\n\n                // a JSON value\n                json source = R\"(\n                      {\"D\": \"Berlin\", \"F\": \"Paris\"}\n                    )\"_json;\n\n                // apply the patch\n                json target = source.patch(p1);\n                // target = { \"D\": \"Berlin\", \"F\": \"Paris\", \"GB\": \"London\" }\n                CHECK(target == R\"({ \"D\": \"Berlin\", \"F\": \"Paris\", \"GB\": \"London\" })\"_json);\n\n                // create a diff from two JSONs\n                json p2 = json::diff(target, source); // NOLINT(readability-suspicious-call-argument)\n                // p2 = [{\"op\": \"delete\", \"path\": \"/GB\"}]\n                CHECK(p2 == R\"([{\"op\":\"remove\",\"path\":\"/GB\"}])\"_json);\n            }\n            {\n                // a JSON value\n                json j = {\"good\", \"bad\", \"ugly\"};\n\n                // a JSON pointer\n                auto ptr = json::json_pointer(\"/2\");\n\n                // use to access elements\n                j[ptr] = {{\"it\", \"cattivo\"}};\n                CHECK(j == R\"([\"good\",\"bad\",{\"it\":\"cattivo\"}])\"_json);\n\n                // use user-defined string literal\n                j[\"/2/en\"_json_pointer] = \"ugly\";\n                CHECK(j == R\"([\"good\",\"bad\",{\"en\":\"ugly\",\"it\":\"cattivo\"}])\"_json);\n\n                json flat = j.flatten();\n                CHECK(flat == R\"({\"/0\":\"good\",\"/1\":\"bad\",\"/2/en\":\"ugly\",\"/2/it\":\"cattivo\"})\"_json);\n            }\n        }\n    }\n\n    SECTION(\"errors\")\n    {\n        SECTION(\"unknown operation\")\n        {\n            SECTION(\"not an array\")\n            {\n                json j;\n                json patch = {{\"op\", \"add\"}, {\"path\", \"\"}, {\"value\", 1}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.parse_error.104] parse error: JSON patch must be an array of objects\");\n            }\n\n            SECTION(\"not an array of objects\")\n            {\n                json j;\n                json patch = {\"op\", \"add\", \"path\", \"\", \"value\", 1};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.104] parse error: (/0) JSON patch must be an array of objects\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.104] parse error: JSON patch must be an array of objects\");\n#endif\n            }\n\n            SECTION(\"missing 'op'\")\n            {\n                json j;\n                json patch = {{{\"foo\", \"bar\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation must have member 'op'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation must have member 'op'\");\n#endif\n            }\n\n            SECTION(\"non-string 'op'\")\n            {\n                json j;\n                json patch = {{{\"op\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation must have string member 'op'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation must have string member 'op'\");\n#endif\n            }\n\n            SECTION(\"invalid operation\")\n            {\n                json j;\n                json patch = {{{\"op\", \"foo\"}, {\"path\", \"\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation value 'foo' is invalid\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation value 'foo' is invalid\");\n#endif\n            }\n        }\n\n        SECTION(\"add\")\n        {\n            SECTION(\"missing 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"add\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'add' must have member 'path'\");\n#endif\n            }\n\n            SECTION(\"non-string 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"add\"}, {\"path\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'add' must have string member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'add' must have string member 'path'\");\n#endif\n            }\n\n            SECTION(\"missing 'value'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"add\"}, {\"path\", \"\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'value'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'\");\n#endif\n            }\n\n            SECTION(\"invalid array index\")\n            {\n                json j = {1, 2};\n                json patch = {{{\"op\", \"add\"}, {\"path\", \"/4\"}, {\"value\", 4}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.401] array index 4 is out of range\");\n            }\n        }\n\n        SECTION(\"remove\")\n        {\n            SECTION(\"missing 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"remove\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'remove' must have member 'path'\");\n#endif\n            }\n\n            SECTION(\"non-string 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"remove\"}, {\"path\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have string member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'remove' must have string member 'path'\");\n#endif\n            }\n\n            SECTION(\"nonexisting target location (array)\")\n            {\n                json j = {1, 2, 3};\n                json patch = {{{\"op\", \"remove\"}, {\"path\", \"/17\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.401] array index 17 is out of range\");\n            }\n\n            SECTION(\"nonexisting target location (object)\")\n            {\n                json j = {{\"foo\", 1}, {\"bar\", 2}};\n                json patch = {{{\"op\", \"remove\"}, {\"path\", \"/baz\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.403] key 'baz' not found\");\n            }\n\n            SECTION(\"root element as target location\")\n            {\n                json j = \"string\";\n                json patch = {{{\"op\", \"remove\"}, {\"path\", \"\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.405] JSON pointer has no parent\");\n            }\n        }\n\n        SECTION(\"replace\")\n        {\n            SECTION(\"missing 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"replace\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'path'\");\n#endif\n            }\n\n            SECTION(\"non-string 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"replace\"}, {\"path\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have string member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'replace' must have string member 'path'\");\n#endif\n            }\n\n            SECTION(\"missing 'value'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"replace\"}, {\"path\", \"\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'value'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'value'\");\n#endif\n            }\n\n            SECTION(\"nonexisting target location (array)\")\n            {\n                json j = {1, 2, 3};\n                json patch = {{{\"op\", \"replace\"}, {\"path\", \"/17\"}, {\"value\", 19}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.401] array index 17 is out of range\");\n            }\n\n            SECTION(\"nonexisting target location (object)\")\n            {\n                json j = {{\"foo\", 1}, {\"bar\", 2}};\n                json patch = {{{\"op\", \"replace\"}, {\"path\", \"/baz\"}, {\"value\", 3}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.403] key 'baz' not found\");\n            }\n        }\n\n        SECTION(\"move\")\n        {\n            SECTION(\"missing 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"move\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'move' must have member 'path'\");\n#endif\n            }\n\n            SECTION(\"non-string 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"move\"}, {\"path\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'path'\");\n#endif\n            }\n\n            SECTION(\"missing 'from'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"move\"}, {\"path\", \"\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'from'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'move' must have member 'from'\");\n#endif\n            }\n\n            SECTION(\"non-string 'from'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"move\"}, {\"path\", \"\"}, {\"from\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'from'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'from'\");\n#endif\n            }\n\n            SECTION(\"nonexisting from location (array)\")\n            {\n                json j = {1, 2, 3};\n                json patch = {{{\"op\", \"move\"}, {\"path\", \"/0\"}, {\"from\", \"/5\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.401] array index 5 is out of range\");\n            }\n\n            SECTION(\"nonexisting from location (object)\")\n            {\n                json j = {{\"foo\", 1}, {\"bar\", 2}};\n                json patch = {{{\"op\", \"move\"}, {\"path\", \"/baz\"}, {\"from\", \"/baz\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.403] key 'baz' not found\");\n            }\n        }\n\n        SECTION(\"copy\")\n        {\n            SECTION(\"missing 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"copy\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'path'\");\n#endif\n            }\n\n            SECTION(\"non-string 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"copy\"}, {\"path\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'path'\");\n#endif\n            }\n\n            SECTION(\"missing 'from'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"copy\"}, {\"path\", \"\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'from'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'from'\");\n#endif\n            }\n\n            SECTION(\"non-string 'from'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"copy\"}, {\"path\", \"\"}, {\"from\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'from'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'\");\n#endif\n            }\n\n            SECTION(\"nonexisting from location (array)\")\n            {\n                json j = {1, 2, 3};\n                json patch = {{{\"op\", \"copy\"}, {\"path\", \"/0\"}, {\"from\", \"/5\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.401] array index 5 is out of range\");\n            }\n\n            SECTION(\"nonexisting from location (object)\")\n            {\n                json j = {{\"foo\", 1}, {\"bar\", 2}};\n                json patch = {{{\"op\", \"copy\"}, {\"path\", \"/fob\"}, {\"from\", \"/baz\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::out_of_range&);\n                CHECK_THROWS_WITH(j.patch(patch),\n                                  \"[json.exception.out_of_range.403] key 'baz' not found\");\n            }\n        }\n\n        SECTION(\"test\")\n        {\n            SECTION(\"missing 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"test\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'test' must have member 'path'\");\n#endif\n            }\n\n            SECTION(\"non-string 'path'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"test\"}, {\"path\", 1}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'test' must have string member 'path'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'test' must have string member 'path'\");\n#endif\n            }\n\n            SECTION(\"missing 'value'\")\n            {\n                json j;\n                json patch = {{{\"op\", \"test\"}, {\"path\", \"\"}}};\n                CHECK_THROWS_AS(j.patch(patch), json::parse_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'value'\");\n#else\n                CHECK_THROWS_WITH(j.patch(patch), \"[json.exception.parse_error.105] parse error: operation 'test' must have member 'value'\");\n#endif\n            }\n        }\n    }\n\n    SECTION(\"Examples from jsonpatch.com\")\n    {\n        SECTION(\"Simple Example\")\n        {\n            // The original document\n            json doc = R\"(\n                {\n                  \"baz\": \"qux\",\n                  \"foo\": \"bar\"\n                }\n            )\"_json;\n\n            // The patch\n            json patch = R\"(\n                [\n                  { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n                  { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n                  { \"op\": \"remove\", \"path\": \"/foo\"}\n                ]\n            )\"_json;\n\n            // The result\n            json result = R\"(\n                {\n                   \"baz\": \"boo\",\n                   \"hello\": [\"world\"]\n                }\n            )\"_json;\n\n            // check if patched value is as expected\n            CHECK(doc.patch(patch) == result);\n\n            // check roundtrip\n            CHECK(doc.patch(json::diff(doc, result)) == result);\n        }\n\n        SECTION(\"Operations\")\n        {\n            // The original document\n            json doc = R\"(\n                {\n                  \"biscuits\": [\n                    {\"name\":\"Digestive\"},\n                    {\"name\": \"Choco Liebniz\"}\n                  ]\n                }\n            )\"_json;\n\n            SECTION(\"add\")\n            {\n                // The patch\n                json patch = R\"(\n                    [\n                        {\"op\": \"add\", \"path\": \"/biscuits/1\", \"value\": {\"name\": \"Ginger Nut\"}}\n                    ]\n                )\"_json;\n\n                // The result\n                json result = R\"(\n                    {\n                      \"biscuits\": [\n                        {\"name\": \"Digestive\"},\n                        {\"name\": \"Ginger Nut\"},\n                        {\"name\": \"Choco Liebniz\"}\n                      ]\n                    }\n                )\"_json;\n\n                // check if patched value is as expected\n                CHECK(doc.patch(patch) == result);\n\n                // check roundtrip\n                CHECK(doc.patch(json::diff(doc, result)) == result);\n            }\n\n            SECTION(\"remove\")\n            {\n                // The patch\n                json patch = R\"(\n                    [\n                        {\"op\": \"remove\", \"path\": \"/biscuits\"}\n                    ]\n                )\"_json;\n\n                // The result\n                json result = R\"(\n                    {}\n                )\"_json;\n\n                // check if patched value is as expected\n                CHECK(doc.patch(patch) == result);\n\n                // check roundtrip\n                CHECK(doc.patch(json::diff(doc, result)) == result);\n            }\n\n            SECTION(\"replace\")\n            {\n                // The patch\n                json patch = R\"(\n                    [\n                        {\"op\": \"replace\", \"path\": \"/biscuits/0/name\", \"value\": \"Chocolate Digestive\"}\n                    ]\n                )\"_json;\n\n                // The result\n                json result = R\"(\n                    {\n                      \"biscuits\": [\n                        {\"name\": \"Chocolate Digestive\"},\n                        {\"name\": \"Choco Liebniz\"}\n                      ]\n                    }\n                )\"_json;\n\n                // check if patched value is as expected\n                CHECK(doc.patch(patch) == result);\n\n                // check roundtrip\n                CHECK(doc.patch(json::diff(doc, result)) == result);\n            }\n\n            SECTION(\"copy\")\n            {\n                // The patch\n                json patch = R\"(\n                    [\n                        {\"op\": \"copy\", \"from\": \"/biscuits/0\", \"path\": \"/best_biscuit\"}\n                    ]\n                )\"_json;\n\n                // The result\n                json result = R\"(\n                    {\n                      \"biscuits\": [\n                        {\"name\": \"Digestive\"},\n                        {\"name\": \"Choco Liebniz\"}\n                      ],\n                      \"best_biscuit\": {\n                        \"name\": \"Digestive\"\n                      }\n                    }\n                )\"_json;\n\n                // check if patched value is as expected\n                CHECK(doc.patch(patch) == result);\n\n                // check roundtrip\n                CHECK(doc.patch(json::diff(doc, result)) == result);\n            }\n\n            SECTION(\"move\")\n            {\n                // The patch\n                json patch = R\"(\n                    [\n                        {\"op\": \"move\", \"from\": \"/biscuits\", \"path\": \"/cookies\"}\n                    ]\n                )\"_json;\n\n                // The result\n                json result = R\"(\n                    {\n                      \"cookies\": [\n                        {\"name\": \"Digestive\"},\n                        {\"name\": \"Choco Liebniz\"}\n                      ]\n                    }\n                )\"_json;\n\n                // check if patched value is as expected\n                CHECK(doc.patch(patch) == result);\n\n                // check roundtrip\n                CHECK(doc.patch(json::diff(doc, result)) == result);\n            }\n\n            SECTION(\"test\")\n            {\n                // The patch\n                json patch = R\"(\n                    [\n                        {\"op\": \"test\", \"path\": \"/best_biscuit/name\", \"value\": \"Choco Liebniz\"}\n                    ]\n                )\"_json;\n\n                // the test will fail\n                CHECK_THROWS_AS(doc.patch(patch), json::other_error&);\n#if JSON_DIAGNOSTICS\n                CHECK_THROWS_WITH_STD_STR(doc.patch(patch), \"[json.exception.other_error.501] (/0) unsuccessful: \" + patch[0].dump());\n#else\n                CHECK_THROWS_WITH_STD_STR(doc.patch(patch), \"[json.exception.other_error.501] unsuccessful: \" + patch[0].dump());\n#endif\n            }\n        }\n    }\n\n    SECTION(\"Examples from bruth.github.io/jsonpatch-js\")\n    {\n        SECTION(\"add\")\n        {\n            CHECK(R\"( {} )\"_json.patch(\n                      R\"( [{\"op\": \"add\", \"path\": \"/foo\", \"value\": \"bar\"}] )\"_json\n                  ) == R\"( {\"foo\": \"bar\"} )\"_json);\n\n            CHECK(R\"( {\"foo\": [1, 3]} )\"_json.patch(\n                      R\"( [{\"op\": \"add\", \"path\": \"/foo\", \"value\": \"bar\"}] )\"_json\n                  ) == R\"( {\"foo\": \"bar\"} )\"_json);\n\n            CHECK(R\"( {\"foo\": [{}]} )\"_json.patch(\n                      R\"( [{\"op\": \"add\", \"path\": \"/foo/0/bar\", \"value\": \"baz\"}] )\"_json\n                  ) == R\"( {\"foo\": [{\"bar\": \"baz\"}]} )\"_json);\n        }\n\n        SECTION(\"remove\")\n        {\n            CHECK(R\"( {\"foo\": \"bar\"} )\"_json.patch(\n                      R\"( [{\"op\": \"remove\", \"path\": \"/foo\"}] )\"_json\n                  ) == R\"( {} )\"_json);\n\n            CHECK(R\"( {\"foo\": [1, 2, 3]} )\"_json.patch(\n                      R\"( [{\"op\": \"remove\", \"path\": \"/foo/1\"}] )\"_json\n                  ) == R\"( {\"foo\": [1, 3]} )\"_json);\n\n            CHECK(R\"( {\"foo\": [{\"bar\": \"baz\"}]} )\"_json.patch(\n                      R\"( [{\"op\": \"remove\", \"path\": \"/foo/0/bar\"}] )\"_json\n                  ) == R\"( {\"foo\": [{}]} )\"_json);\n        }\n\n        SECTION(\"replace\")\n        {\n            CHECK(R\"( {\"foo\": \"bar\"} )\"_json.patch(\n                      R\"( [{\"op\": \"replace\", \"path\": \"/foo\", \"value\": 1}] )\"_json\n                  ) == R\"( {\"foo\": 1} )\"_json);\n\n            CHECK(R\"( {\"foo\": [1, 2, 3]} )\"_json.patch(\n                      R\"( [{\"op\": \"replace\", \"path\": \"/foo/1\", \"value\": 4}] )\"_json\n                  ) == R\"( {\"foo\": [1, 4, 3]} )\"_json);\n\n            CHECK(R\"( {\"foo\": [{\"bar\": \"baz\"}]} )\"_json.patch(\n                      R\"( [{\"op\": \"replace\", \"path\": \"/foo/0/bar\", \"value\": 1}] )\"_json\n                  ) == R\"( {\"foo\": [{\"bar\": 1}]} )\"_json);\n        }\n\n        SECTION(\"move\")\n        {\n            CHECK(R\"( {\"foo\": [1, 2, 3]} )\"_json.patch(\n                      R\"( [{\"op\": \"move\", \"from\": \"/foo\", \"path\": \"/bar\"}] )\"_json\n                  ) == R\"( {\"bar\": [1, 2, 3]} )\"_json);\n        }\n\n        SECTION(\"copy\")\n        {\n            CHECK(R\"( {\"foo\": [1, 2, 3]} )\"_json.patch(\n                      R\"( [{\"op\": \"copy\", \"from\": \"/foo/1\", \"path\": \"/bar\"}] )\"_json\n                  ) == R\"( {\"foo\": [1, 2, 3], \"bar\": 2} )\"_json);\n        }\n\n        SECTION(\"copy\")\n        {\n            CHECK_NOTHROW(R\"( {\"foo\": \"bar\"} )\"_json.patch(\n                              R\"( [{\"op\": \"test\", \"path\": \"/foo\", \"value\": \"bar\"}] )\"_json));\n        }\n    }\n\n    SECTION(\"Tests from github.com/json-patch/json-patch-tests\")\n    {\n        for (const auto* filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json-patch-tests/spec_tests.json\",\n                    TEST_DATA_DIRECTORY \"/json-patch-tests/tests.json\"\n                })\n        {\n            CAPTURE(filename)\n            std::ifstream f(filename);\n            json suite = json::parse(f);\n\n            for (const auto& test : suite)\n            {\n                INFO_WITH_TEMP(test.value(\"comment\", \"\"));\n\n                // skip tests marked as disabled\n                if (test.value(\"disabled\", false))\n                {\n                    continue;\n                }\n\n                const auto& doc = test[\"doc\"];\n                const auto& patch = test[\"patch\"];\n\n                if (test.count(\"error\") == 0)\n                {\n                    // if an expected value is given, use it; use doc otherwise\n                    const auto& expected = test.value(\"expected\", doc);\n                    CHECK(doc.patch(patch) == expected);\n                }\n                else\n                {\n                    CHECK_THROWS(doc.patch(patch));\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-json_pointer.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"JSON pointers\")\n{\n    SECTION(\"errors\")\n    {\n        CHECK_THROWS_AS(json::json_pointer(\"foo\"), json::parse_error&);\n        CHECK_THROWS_WITH(json::json_pointer(\"foo\"),\n                          \"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'\");\n\n        CHECK_THROWS_AS(json::json_pointer(\"/~~\"), json::parse_error&);\n        CHECK_THROWS_WITH(json::json_pointer(\"/~~\"),\n                          \"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\");\n\n        CHECK_THROWS_AS(json::json_pointer(\"/~\"), json::parse_error&);\n        CHECK_THROWS_WITH(json::json_pointer(\"/~\"),\n                          \"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\");\n\n        json::json_pointer p;\n        CHECK_THROWS_AS(p.top(), json::out_of_range&);\n        CHECK_THROWS_WITH(p.top(),\n                          \"[json.exception.out_of_range.405] JSON pointer has no parent\");\n        CHECK_THROWS_AS(p.pop_back(), json::out_of_range&);\n        CHECK_THROWS_WITH(p.pop_back(),\n                          \"[json.exception.out_of_range.405] JSON pointer has no parent\");\n\n        SECTION(\"array index error\")\n        {\n            json v = {1, 2, 3, 4};\n            json::json_pointer ptr(\"/10e\");\n            CHECK_THROWS_AS(v[ptr], json::out_of_range&);\n            CHECK_THROWS_WITH(v[ptr],\n                              \"[json.exception.out_of_range.404] unresolved reference token '10e'\");\n        }\n    }\n\n    SECTION(\"examples from RFC 6901\")\n    {\n        SECTION(\"nonconst access\")\n        {\n            json j = R\"(\n            {\n                \"foo\": [\"bar\", \"baz\"],\n                \"\": 0,\n                \"a/b\": 1,\n                \"c%d\": 2,\n                \"e^f\": 3,\n                \"g|h\": 4,\n                \"i\\\\j\": 5,\n                \"k\\\"l\": 6,\n                \" \": 7,\n                \"m~n\": 8\n            }\n            )\"_json;\n\n            // the whole document\n            CHECK(j[json::json_pointer()] == j);\n            CHECK(j[json::json_pointer(\"\")] == j);\n            CHECK(j.contains(json::json_pointer()));\n            CHECK(j.contains(json::json_pointer(\"\")));\n\n            // array access\n            CHECK(j[json::json_pointer(\"/foo\")] == j[\"foo\"]);\n            CHECK(j.contains(json::json_pointer(\"/foo\")));\n            CHECK(j[json::json_pointer(\"/foo/0\")] == j[\"foo\"][0]);\n            CHECK(j[json::json_pointer(\"/foo/1\")] == j[\"foo\"][1]);\n            CHECK(j[\"/foo/1\"_json_pointer] == j[\"foo\"][1]);\n            CHECK(j.contains(json::json_pointer(\"/foo/0\")));\n            CHECK(j.contains(json::json_pointer(\"/foo/1\")));\n            CHECK(!j.contains(json::json_pointer(\"/foo/3\")));\n            CHECK(!j.contains(json::json_pointer(\"/foo/+\")));\n            CHECK(!j.contains(json::json_pointer(\"/foo/1+2\")));\n            CHECK(!j.contains(json::json_pointer(\"/foo/-\")));\n\n            // checked array access\n            CHECK(j.at(json::json_pointer(\"/foo/0\")) == j[\"foo\"][0]);\n            CHECK(j.at(json::json_pointer(\"/foo/1\")) == j[\"foo\"][1]);\n\n            // empty string access\n            CHECK(j[json::json_pointer(\"/\")] == j[\"\"]);\n            CHECK(j.contains(json::json_pointer(\"\")));\n            CHECK(j.contains(json::json_pointer(\"/\")));\n\n            // other cases\n            CHECK(j[json::json_pointer(\"/ \")] == j[\" \"]);\n            CHECK(j[json::json_pointer(\"/c%d\")] == j[\"c%d\"]);\n            CHECK(j[json::json_pointer(\"/e^f\")] == j[\"e^f\"]);\n            CHECK(j[json::json_pointer(\"/g|h\")] == j[\"g|h\"]);\n            CHECK(j[json::json_pointer(\"/i\\\\j\")] == j[\"i\\\\j\"]);\n            CHECK(j[json::json_pointer(\"/k\\\"l\")] == j[\"k\\\"l\"]);\n\n            // contains\n            CHECK(j.contains(json::json_pointer(\"/ \")));\n            CHECK(j.contains(json::json_pointer(\"/c%d\")));\n            CHECK(j.contains(json::json_pointer(\"/e^f\")));\n            CHECK(j.contains(json::json_pointer(\"/g|h\")));\n            CHECK(j.contains(json::json_pointer(\"/i\\\\j\")));\n            CHECK(j.contains(json::json_pointer(\"/k\\\"l\")));\n\n            // checked access\n            CHECK(j.at(json::json_pointer(\"/ \")) == j[\" \"]);\n            CHECK(j.at(json::json_pointer(\"/c%d\")) == j[\"c%d\"]);\n            CHECK(j.at(json::json_pointer(\"/e^f\")) == j[\"e^f\"]);\n            CHECK(j.at(json::json_pointer(\"/g|h\")) == j[\"g|h\"]);\n            CHECK(j.at(json::json_pointer(\"/i\\\\j\")) == j[\"i\\\\j\"]);\n            CHECK(j.at(json::json_pointer(\"/k\\\"l\")) == j[\"k\\\"l\"]);\n\n            // escaped access\n            CHECK(j[json::json_pointer(\"/a~1b\")] == j[\"a/b\"]);\n            CHECK(j[json::json_pointer(\"/m~0n\")] == j[\"m~n\"]);\n            CHECK(j.contains(json::json_pointer(\"/a~1b\")));\n            CHECK(j.contains(json::json_pointer(\"/m~0n\")));\n\n            // unescaped access\n            // access to nonexisting values yield object creation\n            CHECK(!j.contains(json::json_pointer(\"/a/b\")));\n            CHECK_NOTHROW(j[json::json_pointer(\"/a/b\")] = 42);\n            CHECK(j.contains(json::json_pointer(\"/a/b\")));\n            CHECK(j[\"a\"][\"b\"] == json(42));\n\n            CHECK(!j.contains(json::json_pointer(\"/a/c/1\")));\n            CHECK_NOTHROW(j[json::json_pointer(\"/a/c/1\")] = 42);\n            CHECK(j[\"a\"][\"c\"] == json({nullptr, 42}));\n            CHECK(j.contains(json::json_pointer(\"/a/c/1\")));\n\n            CHECK(!j.contains(json::json_pointer(\"/a/d/-\")));\n            CHECK_NOTHROW(j[json::json_pointer(\"/a/d/-\")] = 42);\n            CHECK(!j.contains(json::json_pointer(\"/a/d/-\")));\n            CHECK(j[\"a\"][\"d\"] == json::array({42}));\n            // \"/a/b\" works for JSON {\"a\": {\"b\": 42}}\n            CHECK(json({{\"a\", {{\"b\", 42}}}})[json::json_pointer(\"/a/b\")] == json(42));\n\n            // unresolved access\n            json j_primitive = 1;\n            CHECK_THROWS_AS(j_primitive[\"/foo\"_json_pointer], json::out_of_range&);\n            CHECK_THROWS_WITH(j_primitive[\"/foo\"_json_pointer],\n                              \"[json.exception.out_of_range.404] unresolved reference token 'foo'\");\n            CHECK_THROWS_AS(j_primitive.at(\"/foo\"_json_pointer), json::out_of_range&);\n            CHECK_THROWS_WITH(j_primitive.at(\"/foo\"_json_pointer),\n                              \"[json.exception.out_of_range.404] unresolved reference token 'foo'\");\n            CHECK(!j_primitive.contains(json::json_pointer(\"/foo\")));\n        }\n\n        SECTION(\"const access\")\n        {\n            const json j = R\"(\n            {\n                \"foo\": [\"bar\", \"baz\"],\n                \"\": 0,\n                \"a/b\": 1,\n                \"c%d\": 2,\n                \"e^f\": 3,\n                \"g|h\": 4,\n                \"i\\\\j\": 5,\n                \"k\\\"l\": 6,\n                \" \": 7,\n                \"m~n\": 8\n            }\n            )\"_json;\n\n            // the whole document\n            CHECK(j[json::json_pointer()] == j);\n            CHECK(j[json::json_pointer(\"\")] == j);\n\n            // array access\n            CHECK(j[json::json_pointer(\"/foo\")] == j[\"foo\"]);\n            CHECK(j[json::json_pointer(\"/foo/0\")] == j[\"foo\"][0]);\n            CHECK(j[json::json_pointer(\"/foo/1\")] == j[\"foo\"][1]);\n            CHECK(j[\"/foo/1\"_json_pointer] == j[\"foo\"][1]);\n\n            // checked array access\n            CHECK(j.at(json::json_pointer(\"/foo/0\")) == j[\"foo\"][0]);\n            CHECK(j.at(json::json_pointer(\"/foo/1\")) == j[\"foo\"][1]);\n\n            // empty string access\n            CHECK(j[json::json_pointer(\"/\")] == j[\"\"]);\n\n            // other cases\n            CHECK(j[json::json_pointer(\"/ \")] == j[\" \"]);\n            CHECK(j[json::json_pointer(\"/c%d\")] == j[\"c%d\"]);\n            CHECK(j[json::json_pointer(\"/e^f\")] == j[\"e^f\"]);\n            CHECK(j[json::json_pointer(\"/g|h\")] == j[\"g|h\"]);\n            CHECK(j[json::json_pointer(\"/i\\\\j\")] == j[\"i\\\\j\"]);\n            CHECK(j[json::json_pointer(\"/k\\\"l\")] == j[\"k\\\"l\"]);\n\n            // checked access\n            CHECK(j.at(json::json_pointer(\"/ \")) == j[\" \"]);\n            CHECK(j.at(json::json_pointer(\"/c%d\")) == j[\"c%d\"]);\n            CHECK(j.at(json::json_pointer(\"/e^f\")) == j[\"e^f\"]);\n            CHECK(j.at(json::json_pointer(\"/g|h\")) == j[\"g|h\"]);\n            CHECK(j.at(json::json_pointer(\"/i\\\\j\")) == j[\"i\\\\j\"]);\n            CHECK(j.at(json::json_pointer(\"/k\\\"l\")) == j[\"k\\\"l\"]);\n\n            // escaped access\n            CHECK(j[json::json_pointer(\"/a~1b\")] == j[\"a/b\"]);\n            CHECK(j[json::json_pointer(\"/m~0n\")] == j[\"m~n\"]);\n\n            // unescaped access\n            CHECK_THROWS_AS(j.at(json::json_pointer(\"/a/b\")), json::out_of_range&);\n            CHECK_THROWS_WITH(j.at(json::json_pointer(\"/a/b\")),\n                              \"[json.exception.out_of_range.403] key 'a' not found\");\n\n            // unresolved access\n            const json j_primitive = 1;\n            CHECK_THROWS_AS(j_primitive[\"/foo\"_json_pointer], json::out_of_range&);\n            CHECK_THROWS_WITH(j_primitive[\"/foo\"_json_pointer],\n                              \"[json.exception.out_of_range.404] unresolved reference token 'foo'\");\n            CHECK_THROWS_AS(j_primitive.at(\"/foo\"_json_pointer), json::out_of_range&);\n            CHECK_THROWS_WITH(j_primitive.at(\"/foo\"_json_pointer),\n                              \"[json.exception.out_of_range.404] unresolved reference token 'foo'\");\n        }\n\n        SECTION(\"user-defined string literal\")\n        {\n            json j = R\"(\n            {\n                \"foo\": [\"bar\", \"baz\"],\n                \"\": 0,\n                \"a/b\": 1,\n                \"c%d\": 2,\n                \"e^f\": 3,\n                \"g|h\": 4,\n                \"i\\\\j\": 5,\n                \"k\\\"l\": 6,\n                \" \": 7,\n                \"m~n\": 8\n            }\n            )\"_json;\n\n            // the whole document\n            CHECK(j[\"\"_json_pointer] == j);\n            CHECK(j.contains(\"\"_json_pointer));\n\n            // array access\n            CHECK(j[\"/foo\"_json_pointer] == j[\"foo\"]);\n            CHECK(j[\"/foo/0\"_json_pointer] == j[\"foo\"][0]);\n            CHECK(j[\"/foo/1\"_json_pointer] == j[\"foo\"][1]);\n            CHECK(j.contains(\"/foo\"_json_pointer));\n            CHECK(j.contains(\"/foo/0\"_json_pointer));\n            CHECK(j.contains(\"/foo/1\"_json_pointer));\n            CHECK(!j.contains(\"/foo/-\"_json_pointer));\n        }\n    }\n\n    SECTION(\"array access\")\n    {\n        SECTION(\"nonconst access\")\n        {\n            json j = {1, 2, 3};\n            const json j_const = j;\n\n            // check reading access\n            CHECK(j[\"/0\"_json_pointer] == j[0]);\n            CHECK(j[\"/1\"_json_pointer] == j[1]);\n            CHECK(j[\"/2\"_json_pointer] == j[2]);\n\n            // assign to existing index\n            j[\"/1\"_json_pointer] = 13;\n            CHECK(j[1] == json(13));\n\n            // assign to nonexisting index\n            j[\"/3\"_json_pointer] = 33;\n            CHECK(j[3] == json(33));\n\n            // assign to nonexisting index (with gap)\n            j[\"/5\"_json_pointer] = 55;\n            CHECK(j == json({1, 13, 3, 33, nullptr, 55}));\n\n            // error with leading 0\n            CHECK_THROWS_AS(j[\"/01\"_json_pointer], json::parse_error&);\n            CHECK_THROWS_WITH(j[\"/01\"_json_pointer],\n                              \"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\");\n            CHECK_THROWS_AS(j_const[\"/01\"_json_pointer], json::parse_error&);\n            CHECK_THROWS_WITH(j_const[\"/01\"_json_pointer],\n                              \"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\");\n            CHECK_THROWS_AS(j.at(\"/01\"_json_pointer), json::parse_error&);\n            CHECK_THROWS_WITH(j.at(\"/01\"_json_pointer),\n                              \"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\");\n            CHECK_THROWS_AS(j_const.at(\"/01\"_json_pointer), json::parse_error&);\n            CHECK_THROWS_WITH(j_const.at(\"/01\"_json_pointer),\n                              \"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\");\n\n            CHECK(!j.contains(\"/01\"_json_pointer));\n            CHECK(!j.contains(\"/01\"_json_pointer));\n            CHECK(!j_const.contains(\"/01\"_json_pointer));\n            CHECK(!j_const.contains(\"/01\"_json_pointer));\n\n            // error with incorrect numbers\n            CHECK_THROWS_AS(j[\"/one\"_json_pointer] = 1, json::parse_error&);\n            CHECK_THROWS_WITH(j[\"/one\"_json_pointer] = 1,\n                              \"[json.exception.parse_error.109] parse error: array index 'one' is not a number\");\n            CHECK_THROWS_AS(j_const[\"/one\"_json_pointer] == 1, json::parse_error&);\n            CHECK_THROWS_WITH(j_const[\"/one\"_json_pointer] == 1,\n                              \"[json.exception.parse_error.109] parse error: array index 'one' is not a number\");\n\n            CHECK_THROWS_AS(j.at(\"/one\"_json_pointer) = 1, json::parse_error&);\n            CHECK_THROWS_WITH(j.at(\"/one\"_json_pointer) = 1,\n                              \"[json.exception.parse_error.109] parse error: array index 'one' is not a number\");\n            CHECK_THROWS_AS(j_const.at(\"/one\"_json_pointer) == 1, json::parse_error&);\n            CHECK_THROWS_WITH(j_const.at(\"/one\"_json_pointer) == 1,\n                              \"[json.exception.parse_error.109] parse error: array index 'one' is not a number\");\n\n            CHECK_THROWS_AS(j[\"/+1\"_json_pointer] = 1, json::parse_error&);\n            CHECK_THROWS_WITH(j[\"/+1\"_json_pointer] = 1,\n                              \"[json.exception.parse_error.109] parse error: array index '+1' is not a number\");\n            CHECK_THROWS_AS(j_const[\"/+1\"_json_pointer] == 1, json::parse_error&);\n            CHECK_THROWS_WITH(j_const[\"/+1\"_json_pointer] == 1,\n                              \"[json.exception.parse_error.109] parse error: array index '+1' is not a number\");\n\n            CHECK_THROWS_AS(j[\"/1+1\"_json_pointer] = 1, json::out_of_range&);\n            CHECK_THROWS_WITH(j[\"/1+1\"_json_pointer] = 1,\n                              \"[json.exception.out_of_range.404] unresolved reference token '1+1'\");\n            CHECK_THROWS_AS(j_const[\"/1+1\"_json_pointer] == 1, json::out_of_range&);\n            CHECK_THROWS_WITH(j_const[\"/1+1\"_json_pointer] == 1,\n                              \"[json.exception.out_of_range.404] unresolved reference token '1+1'\");\n\n            {\n                auto too_large_index = std::to_string((std::numeric_limits<unsigned long long>::max)()) + \"1\";\n                json::json_pointer jp(std::string(\"/\") + too_large_index);\n                std::string throw_msg = std::string(\"[json.exception.out_of_range.404] unresolved reference token '\") + too_large_index + \"'\";\n\n                CHECK_THROWS_AS(j[jp] = 1, json::out_of_range&);\n                CHECK_THROWS_WITH(j[jp] = 1, throw_msg.c_str());\n                CHECK_THROWS_AS(j_const[jp] == 1, json::out_of_range&);\n                CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());\n            }\n\n            // on some machines, the check below is not constant\n            DOCTEST_MSVC_SUPPRESS_WARNING_PUSH\n            DOCTEST_MSVC_SUPPRESS_WARNING(4127)\n\n            if (sizeof(typename json::size_type) < sizeof(unsigned long long))\n            {\n                auto size_type_max_uul = static_cast<unsigned long long>((std::numeric_limits<json::size_type>::max)());\n                auto too_large_index = std::to_string(size_type_max_uul);\n                json::json_pointer jp(std::string(\"/\") + too_large_index);\n                std::string throw_msg = std::string(\"[json.exception.out_of_range.410] array index \") + too_large_index + \" exceeds size_type\";\n\n                CHECK_THROWS_AS(j[jp] = 1, json::out_of_range&);\n                CHECK_THROWS_WITH(j[jp] = 1, throw_msg.c_str());\n                CHECK_THROWS_AS(j_const[jp] == 1, json::out_of_range&);\n                CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());\n            }\n\n            DOCTEST_MSVC_SUPPRESS_WARNING_POP\n\n            CHECK_THROWS_AS(j.at(\"/one\"_json_pointer) = 1, json::parse_error&);\n            CHECK_THROWS_WITH(j.at(\"/one\"_json_pointer) = 1,\n                              \"[json.exception.parse_error.109] parse error: array index 'one' is not a number\");\n            CHECK_THROWS_AS(j_const.at(\"/one\"_json_pointer) == 1, json::parse_error&);\n            CHECK_THROWS_WITH(j_const.at(\"/one\"_json_pointer) == 1,\n                              \"[json.exception.parse_error.109] parse error: array index 'one' is not a number\");\n\n            CHECK(!j.contains(\"/one\"_json_pointer));\n            CHECK(!j.contains(\"/one\"_json_pointer));\n            CHECK(!j_const.contains(\"/one\"_json_pointer));\n            CHECK(!j_const.contains(\"/one\"_json_pointer));\n\n            CHECK_THROWS_AS(json({{\"/list/0\", 1}, {\"/list/1\", 2}, {\"/list/three\", 3}}).unflatten(), json::parse_error&);\n            CHECK_THROWS_WITH(json({{\"/list/0\", 1}, {\"/list/1\", 2}, {\"/list/three\", 3}}).unflatten(),\n            \"[json.exception.parse_error.109] parse error: array index 'three' is not a number\");\n\n            // assign to \"-\"\n            j[\"/-\"_json_pointer] = 99;\n            CHECK(j == json({1, 13, 3, 33, nullptr, 55, 99}));\n\n            // error when using \"-\" in const object\n            CHECK_THROWS_AS(j_const[\"/-\"_json_pointer], json::out_of_range&);\n            CHECK_THROWS_WITH(j_const[\"/-\"_json_pointer],\n                              \"[json.exception.out_of_range.402] array index '-' (3) is out of range\");\n            CHECK(!j_const.contains(\"/-\"_json_pointer));\n\n            // error when using \"-\" with at\n            CHECK_THROWS_AS(j.at(\"/-\"_json_pointer), json::out_of_range&);\n            CHECK_THROWS_WITH(j.at(\"/-\"_json_pointer),\n                              \"[json.exception.out_of_range.402] array index '-' (7) is out of range\");\n            CHECK_THROWS_AS(j_const.at(\"/-\"_json_pointer), json::out_of_range&);\n            CHECK_THROWS_WITH(j_const.at(\"/-\"_json_pointer),\n                              \"[json.exception.out_of_range.402] array index '-' (3) is out of range\");\n            CHECK(!j_const.contains(\"/-\"_json_pointer));\n        }\n\n        SECTION(\"const access\")\n        {\n            const json j = {1, 2, 3};\n\n            // check reading access\n            CHECK(j[\"/0\"_json_pointer] == j[0]);\n            CHECK(j[\"/1\"_json_pointer] == j[1]);\n            CHECK(j[\"/2\"_json_pointer] == j[2]);\n\n            // assign to nonexisting index\n            CHECK_THROWS_AS(j.at(\"/3\"_json_pointer), json::out_of_range&);\n            CHECK_THROWS_WITH(j.at(\"/3\"_json_pointer),\n                              \"[json.exception.out_of_range.401] array index 3 is out of range\");\n            CHECK(!j.contains(\"/3\"_json_pointer));\n\n            // assign to nonexisting index (with gap)\n            CHECK_THROWS_AS(j.at(\"/5\"_json_pointer), json::out_of_range&);\n            CHECK_THROWS_WITH(j.at(\"/5\"_json_pointer),\n                              \"[json.exception.out_of_range.401] array index 5 is out of range\");\n            CHECK(!j.contains(\"/5\"_json_pointer));\n\n            // assign to \"-\"\n            CHECK_THROWS_AS(j[\"/-\"_json_pointer], json::out_of_range&);\n            CHECK_THROWS_WITH(j[\"/-\"_json_pointer],\n                              \"[json.exception.out_of_range.402] array index '-' (3) is out of range\");\n            CHECK_THROWS_AS(j.at(\"/-\"_json_pointer), json::out_of_range&);\n            CHECK_THROWS_WITH(j.at(\"/-\"_json_pointer),\n                              \"[json.exception.out_of_range.402] array index '-' (3) is out of range\");\n            CHECK(!j.contains(\"/-\"_json_pointer));\n        }\n    }\n\n    SECTION(\"flatten\")\n    {\n        json j =\n        {\n            {\"pi\", 3.141},\n            {\"happy\", true},\n            {\"name\", \"Niels\"},\n            {\"nothing\", nullptr},\n            {\n                \"answer\", {\n                    {\"everything\", 42}\n                }\n            },\n            {\"list\", {1, 0, 2}},\n            {\n                \"object\", {\n                    {\"currency\", \"USD\"},\n                    {\"value\", 42.99},\n                    {\"\", \"empty string\"},\n                    {\"/\", \"slash\"},\n                    {\"~\", \"tilde\"},\n                    {\"~1\", \"tilde1\"}\n                }\n            }\n        };\n\n        json j_flatten =\n        {\n            {\"/pi\", 3.141},\n            {\"/happy\", true},\n            {\"/name\", \"Niels\"},\n            {\"/nothing\", nullptr},\n            {\"/answer/everything\", 42},\n            {\"/list/0\", 1},\n            {\"/list/1\", 0},\n            {\"/list/2\", 2},\n            {\"/object/currency\", \"USD\"},\n            {\"/object/value\", 42.99},\n            {\"/object/\", \"empty string\"},\n            {\"/object/~1\", \"slash\"},\n            {\"/object/~0\", \"tilde\"},\n            {\"/object/~01\", \"tilde1\"}\n        };\n\n        // check if flattened result is as expected\n        CHECK(j.flatten() == j_flatten);\n\n        // check if unflattened result is as expected\n        CHECK(j_flatten.unflatten() == j);\n\n        // error for nonobjects\n        CHECK_THROWS_AS(json(1).unflatten(), json::type_error&);\n        CHECK_THROWS_WITH(json(1).unflatten(),\n                          \"[json.exception.type_error.314] only objects can be unflattened\");\n\n        // error for nonprimitve values\n        CHECK_THROWS_AS(json({{\"/1\", {1, 2, 3}}}).unflatten(), json::type_error&);\n#if JSON_DIAGNOSTICS\n        CHECK_THROWS_WITH(json({{\"/1\", {1, 2, 3}}}).unflatten(), \"[json.exception.type_error.315] (/~11) values in object must be primitive\");\n#else\n        CHECK_THROWS_WITH(json({{\"/1\", {1, 2, 3}}}).unflatten(), \"[json.exception.type_error.315] values in object must be primitive\");\n#endif\n\n        // error for conflicting values\n        json j_error = {{\"\", 42}, {\"/foo\", 17}};\n        CHECK_THROWS_AS(j_error.unflatten(), json::type_error&);\n        CHECK_THROWS_WITH(j_error.unflatten(),\n                          \"[json.exception.type_error.313] invalid value to unflatten\");\n\n        // explicit roundtrip check\n        CHECK(j.flatten().unflatten() == j);\n\n        // roundtrip for primitive values\n        json j_null;\n        CHECK(j_null.flatten().unflatten() == j_null);\n        json j_number = 42;\n        CHECK(j_number.flatten().unflatten() == j_number);\n        json j_boolean = false;\n        CHECK(j_boolean.flatten().unflatten() == j_boolean);\n        json j_string = \"foo\";\n        CHECK(j_string.flatten().unflatten() == j_string);\n\n        // roundtrip for empty structured values (will be unflattened to null)\n        json j_array(json::value_t::array);\n        CHECK(j_array.flatten().unflatten() == json());\n        json j_object(json::value_t::object);\n        CHECK(j_object.flatten().unflatten() == json());\n    }\n\n    SECTION(\"string representation\")\n    {\n        for (const auto* ptr :\n                {\"\", \"/foo\", \"/foo/0\", \"/\", \"/a~1b\", \"/c%d\", \"/e^f\", \"/g|h\", \"/i\\\\j\", \"/k\\\"l\", \"/ \", \"/m~0n\"\n                })\n        {\n            CHECK(json::json_pointer(ptr).to_string() == ptr);\n            CHECK(std::string(json::json_pointer(ptr)) == ptr);\n        }\n    }\n\n    SECTION(\"conversion\")\n    {\n        SECTION(\"array\")\n        {\n            json j;\n            // all numbers -> array\n            j[\"/12\"_json_pointer] = 0;\n            CHECK(j.is_array());\n        }\n\n        SECTION(\"object\")\n        {\n            json j;\n            // contains a number, but is not a number -> object\n            j[\"/a12\"_json_pointer] = 0;\n            CHECK(j.is_object());\n        }\n    }\n\n    SECTION(\"empty, push, pop and parent\")\n    {\n        const json j =\n        {\n            {\"\", \"Hello\"},\n            {\"pi\", 3.141},\n            {\"happy\", true},\n            {\"name\", \"Niels\"},\n            {\"nothing\", nullptr},\n            {\n                \"answer\", {\n                    {\"everything\", 42}\n                }\n            },\n            {\"list\", {1, 0, 2}},\n            {\n                \"object\", {\n                    {\"currency\", \"USD\"},\n                    {\"value\", 42.99},\n                    {\"\", \"empty string\"},\n                    {\"/\", \"slash\"},\n                    {\"~\", \"tilde\"},\n                    {\"~1\", \"tilde1\"}\n                }\n            }\n        };\n\n        // empty json_pointer returns the root JSON-object\n        auto ptr = \"\"_json_pointer;\n        CHECK(ptr.empty());\n        CHECK(j[ptr] == j);\n\n        // simple field access\n        ptr.push_back(\"pi\");\n        CHECK(!ptr.empty());\n        CHECK(j[ptr] == j[\"pi\"]);\n\n        ptr.pop_back();\n        CHECK(ptr.empty());\n        CHECK(j[ptr] == j);\n\n        // object and children access\n        const std::string answer(\"answer\");\n        ptr.push_back(answer);\n        ptr.push_back(\"everything\");\n        CHECK(!ptr.empty());\n        CHECK(j[ptr] == j[\"answer\"][\"everything\"]);\n\n        // check access via const pointer\n        const auto cptr = ptr;\n        CHECK(cptr.back() == \"everything\");\n\n        ptr.pop_back();\n        ptr.pop_back();\n        CHECK(ptr.empty());\n        CHECK(j[ptr] == j);\n\n        // push key which has to be encoded\n        ptr.push_back(\"object\");\n        ptr.push_back(\"/\");\n        CHECK(j[ptr] == j[\"object\"][\"/\"]);\n        CHECK(ptr.to_string() == \"/object/~1\");\n\n        CHECK(j[ptr.parent_pointer()] == j[\"object\"]);\n        ptr = ptr.parent_pointer().parent_pointer();\n        CHECK(ptr.empty());\n        CHECK(j[ptr] == j);\n        // parent-pointer of the empty json_pointer is empty\n        ptr = ptr.parent_pointer();\n        CHECK(ptr.empty());\n        CHECK(j[ptr] == j);\n\n        CHECK_THROWS_WITH(ptr.pop_back(),\n                          \"[json.exception.out_of_range.405] JSON pointer has no parent\");\n    }\n\n    SECTION(\"operators\")\n    {\n        const json j =\n        {\n            {\"\", \"Hello\"},\n            {\"pi\", 3.141},\n            {\"happy\", true},\n            {\"name\", \"Niels\"},\n            {\"nothing\", nullptr},\n            {\n                \"answer\", {\n                    {\"everything\", 42}\n                }\n            },\n            {\"list\", {1, 0, 2}},\n            {\n                \"object\", {\n                    {\"currency\", \"USD\"},\n                    {\"value\", 42.99},\n                    {\"\", \"empty string\"},\n                    {\"/\", \"slash\"},\n                    {\"~\", \"tilde\"},\n                    {\"~1\", \"tilde1\"}\n                }\n            }\n        };\n\n        // empty json_pointer returns the root JSON-object\n        auto ptr = \"\"_json_pointer;\n        CHECK(j[ptr] == j);\n\n        // simple field access\n        ptr = ptr / \"pi\";\n        CHECK(j[ptr] == j[\"pi\"]);\n\n        ptr.pop_back();\n        CHECK(j[ptr] == j);\n\n        // object and children access\n        const std::string answer(\"answer\");\n        ptr /= answer;\n        ptr = ptr / \"everything\";\n        CHECK(j[ptr] == j[\"answer\"][\"everything\"]);\n\n        ptr.pop_back();\n        ptr.pop_back();\n        CHECK(j[ptr] == j);\n\n        CHECK(ptr / \"\"_json_pointer == ptr);\n        CHECK(j[\"/answer\"_json_pointer / \"/everything\"_json_pointer] == j[\"answer\"][\"everything\"]);\n\n        // list children access\n        CHECK(j[\"/list\"_json_pointer / 1] == j[\"list\"][1]);\n\n        // push key which has to be encoded\n        ptr /= \"object\";\n        ptr = ptr / \"/\";\n        CHECK(j[ptr] == j[\"object\"][\"/\"]);\n        CHECK(ptr.to_string() == \"/object/~1\");\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-large_json.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <algorithm>\n\nTEST_CASE(\"tests on very large JSONs\")\n{\n    SECTION(\"issue #1419 - Segmentation fault (stack overflow) due to unbounded recursion\")\n    {\n        const auto depth = 5000000;\n\n        std::string s(static_cast<std::size_t>(2 * depth), '[');\n        std::fill(s.begin() + depth, s.end(), ']');\n\n        json _;\n        CHECK_NOTHROW(_ = nlohmann::json::parse(s));\n    }\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-merge_patch.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"JSON Merge Patch\")\n{\n    SECTION(\"examples from RFC 7396\")\n    {\n        SECTION(\"Section 1\")\n        {\n            json document = R\"({\n                \"a\": \"b\",\n                \"c\": {\n                    \"d\": \"e\",\n                    \"f\": \"g\"\n                }\n            })\"_json;\n\n            json patch = R\"({\n                \"a\": \"z\",\n                \"c\": {\n                    \"f\": null\n                }\n            })\"_json;\n\n            json expected = R\"({\n                \"a\": \"z\",\n                \"c\": {\n                    \"d\": \"e\"\n                }\n            })\"_json;\n\n            document.merge_patch(patch);\n            CHECK(document == expected);\n        }\n\n        SECTION(\"Section 3\")\n        {\n            json document = R\"({\n                \"title\": \"Goodbye!\",\n                \"author\": {\n                    \"givenName\": \"John\",\n                    \"familyName\": \"Doe\"\n                },\n                \"tags\": [\n                    \"example\",\n                    \"sample\"\n                ],\n                \"content\": \"This will be unchanged\"\n            })\"_json;\n\n            json patch = R\"({\n                \"title\": \"Hello!\",\n                \"phoneNumber\": \"+01-123-456-7890\",\n                \"author\": {\n                    \"familyName\": null\n                },\n                \"tags\": [\n                    \"example\"\n                ]\n            })\"_json;\n\n            json expected = R\"({\n                \"title\": \"Hello!\",\n                \"author\": {\n                    \"givenName\": \"John\"\n                },\n                \"tags\": [\n                    \"example\"\n                ],\n                \"content\": \"This will be unchanged\",\n                \"phoneNumber\": \"+01-123-456-7890\"\n            })\"_json;\n\n            document.merge_patch(patch);\n            CHECK(document == expected);\n        }\n\n        SECTION(\"Appendix A\")\n        {\n            SECTION(\"Example 1\")\n            {\n                json original = R\"({\"a\":\"b\"})\"_json;\n                json patch = R\"({\"a\":\"c\"})\"_json;\n                json result = R\"({\"a\":\"c\"})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 2\")\n            {\n                json original = R\"({\"a\":\"b\"})\"_json;\n                json patch = R\"({\"b\":\"c\"})\"_json;\n                json result = R\"({\"a\":\"b\", \"b\":\"c\"})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 3\")\n            {\n                json original = R\"({\"a\":\"b\"})\"_json;\n                json patch = R\"({\"a\":null})\"_json;\n                json result = R\"({})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 4\")\n            {\n                json original = R\"({\"a\":\"b\",\"b\":\"c\"})\"_json;\n                json patch = R\"({\"a\":null})\"_json;\n                json result = R\"({\"b\":\"c\"})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 5\")\n            {\n                json original = R\"({\"a\":[\"b\"]})\"_json;\n                json patch = R\"({\"a\":\"c\"})\"_json;\n                json result = R\"({\"a\":\"c\"})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 6\")\n            {\n                json original = R\"({\"a\":\"c\"})\"_json;\n                json patch = R\"({\"a\":[\"b\"]})\"_json;\n                json result = R\"({\"a\":[\"b\"]})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 7\")\n            {\n                json original = R\"({\"a\":{\"b\": \"c\"}})\"_json;\n                json patch = R\"({\"a\":{\"b\":\"d\",\"c\":null}})\"_json;\n                json result = R\"({\"a\": {\"b\": \"d\"}})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 8\")\n            {\n                json original = R\"({\"a\":[{\"b\":\"c\"}]})\"_json;\n                json patch = R\"({\"a\":[1]})\"_json;\n                json result = R\"({\"a\":[1]})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 9\")\n            {\n                json original = R\"([\"a\",\"b\"])\"_json;\n                json patch = R\"([\"c\",\"d\"])\"_json;\n                json result = R\"([\"c\",\"d\"])\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 10\")\n            {\n                json original = R\"({\"a\":\"b\"})\"_json;\n                json patch = R\"([\"c\"])\"_json;\n                json result = R\"([\"c\"])\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 11\")\n            {\n                json original = R\"({\"a\":\"foo\"})\"_json;\n                json patch = R\"(null)\"_json;\n                json result = R\"(null)\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 12\")\n            {\n                json original = R\"({\"a\":\"foo\"})\"_json;\n                json patch = R\"(\"bar\")\"_json;\n                json result = R\"(\"bar\")\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 13\")\n            {\n                json original = R\"({\"e\":null})\"_json;\n                json patch = R\"({\"a\":1})\"_json;\n                json result = R\"({\"e\":null,\"a\":1})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 14\")\n            {\n                json original = R\"([1,2])\"_json;\n                json patch = R\"({\"a\":\"b\",\"c\":null})\"_json;\n                json result = R\"({\"a\":\"b\"})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n\n            SECTION(\"Example 15\")\n            {\n                json original = R\"({})\"_json;\n                json patch = R\"({\"a\":{\"bb\":{\"ccc\":null}}})\"_json;\n                json result = R\"({\"a\":{\"bb\":{}}})\"_json;\n\n                original.merge_patch(patch);\n                CHECK(original == result);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-meta.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"version information\")\n{\n    SECTION(\"meta()\")\n    {\n        json j = json::meta();\n\n        CHECK(j[\"name\"] == \"JSON for Modern C++\");\n        CHECK(j[\"copyright\"] == \"(C) 2013-2022 Niels Lohmann\");\n        CHECK(j[\"url\"] == \"https://github.com/nlohmann/json\");\n        CHECK(j[\"version\"] == json(\n        {\n            {\"string\", \"3.10.5\"},\n            {\"major\", 3},\n            {\"minor\", 10},\n            {\"patch\", 5}\n        }));\n\n        CHECK(j.find(\"platform\") != j.end());\n        CHECK(j.at(\"compiler\").find(\"family\") != j.at(\"compiler\").end());\n        CHECK(j.at(\"compiler\").find(\"version\") != j.at(\"compiler\").end());\n        CHECK(j.at(\"compiler\").find(\"c++\") != j.at(\"compiler\").end());\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-modifiers.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"modifiers\")\n{\n    SECTION(\"clear()\")\n    {\n        SECTION(\"boolean\")\n        {\n            json j = true;\n            json k = j;\n\n            j.clear();\n            CHECK(j == json(json::value_t::boolean));\n            CHECK(j == json(k.type()));\n        }\n\n        SECTION(\"string\")\n        {\n            json j = \"hello world\";\n            json k = j;\n\n            j.clear();\n            CHECK(j == json(json::value_t::string));\n            CHECK(j == json(k.type()));\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty array\")\n            {\n                json j = json::array();\n                json k = j;\n\n                j.clear();\n                CHECK(j.empty());\n                CHECK(j == json(json::value_t::array));\n                CHECK(j == json(k.type()));\n            }\n\n            SECTION(\"filled array\")\n            {\n                json j = {1, 2, 3};\n                json k = j;\n\n                j.clear();\n                CHECK(j.empty());\n                CHECK(j == json(json::value_t::array));\n                CHECK(j == json(k.type()));\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty object\")\n            {\n                json j = json::object();\n                json k = j;\n\n                j.clear();\n                CHECK(j.empty());\n                CHECK(j == json(json::value_t::object));\n                CHECK(j == json(k.type()));\n            }\n\n            SECTION(\"filled object\")\n            {\n                json j = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n                json k = j;\n\n                j.clear();\n                CHECK(j.empty());\n                CHECK(j == json(json::value_t::object));\n                CHECK(j == json(k.type()));\n            }\n        }\n\n        SECTION(\"binary\")\n        {\n            SECTION(\"empty binary\")\n            {\n                json j = json::binary({});\n                json k = j;\n\n                j.clear();\n                CHECK(!j.empty());\n                CHECK(j == json(json::value_t::binary));\n                CHECK(j == json(k.type()));\n            }\n\n            SECTION(\"filled binary\")\n            {\n                json j = json::binary({1, 2, 3, 4, 5});\n                json k = j;\n\n                j.clear();\n                CHECK(!j.empty());\n                CHECK(j == json(json::value_t::binary));\n                CHECK(j == json(k.type()));\n            }\n        }\n\n        SECTION(\"number (integer)\")\n        {\n            json j = 23;\n            json k = j;\n\n            j.clear();\n            CHECK(j == json(json::value_t::number_integer));\n            CHECK(j == json(k.type()));\n        }\n\n        SECTION(\"number (unsigned)\")\n        {\n            json j = 23u;\n            json k = j;\n\n            j.clear();\n            CHECK(j == json(json::value_t::number_integer));\n            CHECK(j == json(k.type()));\n        }\n\n        SECTION(\"number (float)\")\n        {\n            json j = 23.42;\n            json k = j;\n\n            j.clear();\n            CHECK(j == json(json::value_t::number_float));\n            CHECK(j == json(k.type()));\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            json k = j;\n\n            j.clear();\n            CHECK(j == json(json::value_t::null));\n            CHECK(j == json(k.type()));\n        }\n    }\n\n    SECTION(\"push_back()\")\n    {\n        SECTION(\"to array\")\n        {\n            SECTION(\"json&&\")\n            {\n                SECTION(\"null\")\n                {\n                    json j;\n                    j.push_back(1);\n                    j.push_back(2);\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 2}));\n                }\n\n                SECTION(\"array\")\n                {\n                    json j = {1, 2, 3};\n                    j.push_back(\"Hello\");\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 2, 3, \"Hello\"}));\n                }\n\n                SECTION(\"other type\")\n                {\n                    json j = 1;\n                    CHECK_THROWS_AS(j.push_back(\"Hello\"), json::type_error&);\n                    CHECK_THROWS_WITH(j.push_back(\"Hello\"), \"[json.exception.type_error.308] cannot use push_back() with number\");\n                }\n            }\n\n            SECTION(\"const json&\")\n            {\n                SECTION(\"null\")\n                {\n                    json j;\n                    json k(1);\n                    j.push_back(k);\n                    j.push_back(k);\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 1}));\n                }\n\n                SECTION(\"array\")\n                {\n                    json j = {1, 2, 3};\n                    json k(\"Hello\");\n                    j.push_back(k);\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 2, 3, \"Hello\"}));\n                }\n\n                SECTION(\"other type\")\n                {\n                    json j = 1;\n                    json k(\"Hello\");\n                    CHECK_THROWS_AS(j.push_back(k), json::type_error&);\n                    CHECK_THROWS_WITH(j.push_back(k), \"[json.exception.type_error.308] cannot use push_back() with number\");\n                }\n            }\n        }\n\n        SECTION(\"to object\")\n        {\n            SECTION(\"null\")\n            {\n                json j;\n                j.push_back(json::object_t::value_type({\"one\", 1}));\n                j.push_back(json::object_t::value_type({\"two\", 2}));\n                CHECK(j.type() == json::value_t::object);\n                CHECK(j.size() == 2);\n                CHECK(j[\"one\"] == json(1));\n                CHECK(j[\"two\"] == json(2));\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                j.push_back(json::object_t::value_type({\"one\", 1}));\n                j.push_back(json::object_t::value_type({\"two\", 2}));\n                CHECK(j.size() == 2);\n                CHECK(j[\"one\"] == json(1));\n                CHECK(j[\"two\"] == json(2));\n            }\n\n            SECTION(\"other type\")\n            {\n                json j = 1;\n                json k(\"Hello\");\n                CHECK_THROWS_AS(j.push_back(json::object_t::value_type({\"one\", 1})), json::type_error&);\n                CHECK_THROWS_WITH(j.push_back(json::object_t::value_type({\"one\", 1})),\n                                  \"[json.exception.type_error.308] cannot use push_back() with number\");\n            }\n        }\n\n        SECTION(\"with initializer_list\")\n        {\n            SECTION(\"null\")\n            {\n                json j;\n                j.push_back({\"foo\", \"bar\"});\n                CHECK(j == json::array({{\"foo\", \"bar\"}}));\n\n                json k;\n                k.push_back({1, 2, 3});\n                CHECK(k == json::array({{1, 2, 3}}));\n            }\n\n            SECTION(\"array\")\n            {\n                json j = {1, 2, 3};\n                j.push_back({\"foo\", \"bar\"});\n                CHECK(j == json({1, 2, 3, {\"foo\", \"bar\"}}));\n\n                json k = {1, 2, 3};\n                k.push_back({1, 2, 3});\n                CHECK(k == json({1, 2, 3, {1, 2, 3}}));\n            }\n\n            SECTION(\"object\")\n            {\n                json j = {{\"key1\", 1}};\n                j.push_back({\"key2\", \"bar\"});\n                CHECK(j == json({{\"key1\", 1}, {\"key2\", \"bar\"}}));\n\n                // invalid values (no string/val pair)\n                CHECK_THROWS_AS(j.push_back({1}), json::type_error&);\n                CHECK_THROWS_WITH(j.push_back({1}), \"[json.exception.type_error.308] cannot use push_back() with object\");\n                CHECK_THROWS_AS(j.push_back({1, 2}), json::type_error&);\n                CHECK_THROWS_WITH(j.push_back({1, 2}), \"[json.exception.type_error.308] cannot use push_back() with object\");\n                CHECK_THROWS_AS(j.push_back({1, 2, 3, 4}), json::type_error&);\n                CHECK_THROWS_WITH(j.push_back({1, 2, 3, 4}), \"[json.exception.type_error.308] cannot use push_back() with object\");\n            }\n        }\n    }\n\n    SECTION(\"emplace_back()\")\n    {\n        SECTION(\"to array\")\n        {\n            SECTION(\"null\")\n            {\n                json j;\n                auto& x1 = j.emplace_back(1);\n                CHECK(x1 == 1);\n                auto& x2 = j.emplace_back(2);\n                CHECK(x2 == 2);\n                CHECK(j.type() == json::value_t::array);\n                CHECK(j == json({1, 2}));\n            }\n\n            SECTION(\"array\")\n            {\n                json j = {1, 2, 3};\n                auto& x = j.emplace_back(\"Hello\");\n                CHECK(x == \"Hello\");\n                CHECK(j.type() == json::value_t::array);\n                CHECK(j == json({1, 2, 3, \"Hello\"}));\n            }\n\n            SECTION(\"multiple values\")\n            {\n                json j;\n                auto& x = j.emplace_back(3, \"foo\");\n                CHECK(x == json({\"foo\", \"foo\", \"foo\"}));\n                CHECK(j.type() == json::value_t::array);\n                CHECK(j == json({{\"foo\", \"foo\", \"foo\"}}));\n            }\n        }\n\n        SECTION(\"other type\")\n        {\n            json j = 1;\n            CHECK_THROWS_AS(j.emplace_back(\"Hello\"), json::type_error&);\n            CHECK_THROWS_WITH(j.emplace_back(\"Hello\"),\n                              \"[json.exception.type_error.311] cannot use emplace_back() with number\");\n        }\n    }\n\n    SECTION(\"emplace()\")\n    {\n        SECTION(\"to object\")\n        {\n            SECTION(\"null\")\n            {\n                // start with a null value\n                json j;\n\n                // add a new key\n                auto res1 = j.emplace(\"foo\", \"bar\");\n                CHECK(res1.second == true);\n                CHECK(*res1.first == \"bar\");\n\n                // the null value is changed to an object\n                CHECK(j.type() == json::value_t::object);\n\n                // add a new key\n                auto res2 = j.emplace(\"baz\", \"bam\");\n                CHECK(res2.second == true);\n                CHECK(*res2.first == \"bam\");\n\n                // we try to insert at given key - no change\n                auto res3 = j.emplace(\"baz\", \"bad\");\n                CHECK(res3.second == false);\n                CHECK(*res3.first == \"bam\");\n\n                // the final object\n                CHECK(j == json({{\"baz\", \"bam\"}, {\"foo\", \"bar\"}}));\n            }\n\n            SECTION(\"object\")\n            {\n                // start with an object\n                json j = {{\"foo\", \"bar\"}};\n\n                // add a new key\n                auto res1 = j.emplace(\"baz\", \"bam\");\n                CHECK(res1.second == true);\n                CHECK(*res1.first == \"bam\");\n\n                // add an existing key\n                auto res2 = j.emplace(\"foo\", \"bad\");\n                CHECK(res2.second == false);\n                CHECK(*res2.first == \"bar\");\n\n                // check final object\n                CHECK(j == json({{\"baz\", \"bam\"}, {\"foo\", \"bar\"}}));\n            }\n        }\n\n        SECTION(\"other type\")\n        {\n            json j = 1;\n            CHECK_THROWS_AS(j.emplace(\"foo\", \"bar\"), json::type_error&);\n            CHECK_THROWS_WITH(j.emplace(\"foo\", \"bar\"),\n                              \"[json.exception.type_error.311] cannot use emplace() with number\");\n        }\n    }\n\n    SECTION(\"operator+=\")\n    {\n        SECTION(\"to array\")\n        {\n            SECTION(\"json&&\")\n            {\n                SECTION(\"null\")\n                {\n                    json j;\n                    j += 1;\n                    j += 2;\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 2}));\n                }\n\n                SECTION(\"array\")\n                {\n                    json j = {1, 2, 3};\n                    j += \"Hello\";\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 2, 3, \"Hello\"}));\n                }\n\n                SECTION(\"other type\")\n                {\n                    json j = 1;\n                    CHECK_THROWS_AS(j += \"Hello\", json::type_error&);\n                    CHECK_THROWS_WITH(j += \"Hello\", \"[json.exception.type_error.308] cannot use push_back() with number\");\n                }\n            }\n\n            SECTION(\"const json&\")\n            {\n                SECTION(\"null\")\n                {\n                    json j;\n                    json k(1);\n                    j += k;\n                    j += k;\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 1}));\n                }\n\n                SECTION(\"array\")\n                {\n                    json j = {1, 2, 3};\n                    json k(\"Hello\");\n                    j += k;\n                    CHECK(j.type() == json::value_t::array);\n                    CHECK(j == json({1, 2, 3, \"Hello\"}));\n                }\n\n                SECTION(\"other type\")\n                {\n                    json j = 1;\n                    json k(\"Hello\");\n                    CHECK_THROWS_AS(j += k, json::type_error&);\n                    CHECK_THROWS_WITH(j += k, \"[json.exception.type_error.308] cannot use push_back() with number\");\n                }\n            }\n        }\n\n        SECTION(\"to object\")\n        {\n            SECTION(\"null\")\n            {\n                json j;\n                j += json::object_t::value_type({\"one\", 1});\n                j += json::object_t::value_type({\"two\", 2});\n                CHECK(j.type() == json::value_t::object);\n                CHECK(j.size() == 2);\n                CHECK(j[\"one\"] == json(1));\n                CHECK(j[\"two\"] == json(2));\n            }\n\n            SECTION(\"object\")\n            {\n                json j(json::value_t::object);\n                j += json::object_t::value_type({\"one\", 1});\n                j += json::object_t::value_type({\"two\", 2});\n                CHECK(j.size() == 2);\n                CHECK(j[\"one\"] == json(1));\n                CHECK(j[\"two\"] == json(2));\n            }\n\n            SECTION(\"other type\")\n            {\n                json j = 1;\n                json k(\"Hello\");\n                CHECK_THROWS_AS(j += json::object_t::value_type({\"one\", 1}), json::type_error&);\n                CHECK_THROWS_WITH(j += json::object_t::value_type({\"one\", 1}),\n                                  \"[json.exception.type_error.308] cannot use push_back() with number\");\n            }\n        }\n\n        SECTION(\"with initializer_list\")\n        {\n            SECTION(\"null\")\n            {\n                json j;\n                j += {\"foo\", \"bar\"};\n                CHECK(j == json::array({{\"foo\", \"bar\"}}));\n\n                json k;\n                k += {1, 2, 3};\n                CHECK(k == json::array({{1, 2, 3}}));\n            }\n\n            SECTION(\"array\")\n            {\n                json j = {1, 2, 3};\n                j += {\"foo\", \"bar\"};\n                CHECK(j == json({1, 2, 3, {\"foo\", \"bar\"}}));\n\n                json k = {1, 2, 3};\n                k += {1, 2, 3};\n                CHECK(k == json({1, 2, 3, {1, 2, 3}}));\n            }\n\n            SECTION(\"object\")\n            {\n                json j = {{\"key1\", 1}};\n                j += {\"key2\", \"bar\"};\n                CHECK(j == json({{\"key1\", 1}, {\"key2\", \"bar\"}}));\n\n                json k = {{\"key1\", 1}};\n                CHECK_THROWS_AS((k += {1, 2, 3, 4}), json::type_error&);\n                CHECK_THROWS_WITH((k += {1, 2, 3, 4}), \"[json.exception.type_error.308] cannot use push_back() with object\");\n            }\n        }\n    }\n\n    SECTION(\"insert()\")\n    {\n        json j_array = {1, 2, 3, 4};\n        json j_value = 5;\n\n        SECTION(\"value at position\")\n        {\n            SECTION(\"insert before begin()\")\n            {\n                auto it = j_array.insert(j_array.begin(), j_value);\n                CHECK(j_array.size() == 5);\n                CHECK(*it == j_value);\n                CHECK(j_array.begin() == it);\n                CHECK(j_array == json({5, 1, 2, 3, 4}));\n            }\n\n            SECTION(\"insert in the middle\")\n            {\n                auto it = j_array.insert(j_array.begin() + 2, j_value);\n                CHECK(j_array.size() == 5);\n                CHECK(*it == j_value);\n                CHECK((it - j_array.begin()) == 2);\n                CHECK(j_array == json({1, 2, 5, 3, 4}));\n            }\n\n            SECTION(\"insert before end()\")\n            {\n                auto it = j_array.insert(j_array.end(), j_value);\n                CHECK(j_array.size() == 5);\n                CHECK(*it == j_value);\n                CHECK((j_array.end() - it) == 1);\n                CHECK(j_array == json({1, 2, 3, 4, 5}));\n            }\n        }\n\n        SECTION(\"rvalue at position\")\n        {\n            SECTION(\"insert before begin()\")\n            {\n                auto it = j_array.insert(j_array.begin(), 5);\n                CHECK(j_array.size() == 5);\n                CHECK(*it == j_value);\n                CHECK(j_array.begin() == it);\n                CHECK(j_array == json({5, 1, 2, 3, 4}));\n            }\n\n            SECTION(\"insert in the middle\")\n            {\n                auto it = j_array.insert(j_array.begin() + 2, 5);\n                CHECK(j_array.size() == 5);\n                CHECK(*it == j_value);\n                CHECK((it - j_array.begin()) == 2);\n                CHECK(j_array == json({1, 2, 5, 3, 4}));\n            }\n\n            SECTION(\"insert before end()\")\n            {\n                auto it = j_array.insert(j_array.end(), 5);\n                CHECK(j_array.size() == 5);\n                CHECK(*it == j_value);\n                CHECK((j_array.end() - it) == 1);\n                CHECK(j_array == json({1, 2, 3, 4, 5}));\n            }\n        }\n\n        SECTION(\"copies at position\")\n        {\n            SECTION(\"insert before begin()\")\n            {\n                auto it = j_array.insert(j_array.begin(), 3, 5);\n                CHECK(j_array.size() == 7);\n                CHECK(*it == j_value);\n                CHECK(j_array.begin() == it);\n                CHECK(j_array == json({5, 5, 5, 1, 2, 3, 4}));\n            }\n\n            SECTION(\"insert in the middle\")\n            {\n                auto it = j_array.insert(j_array.begin() + 2, 3, 5);\n                CHECK(j_array.size() == 7);\n                CHECK(*it == j_value);\n                CHECK((it - j_array.begin()) == 2);\n                CHECK(j_array == json({1, 2, 5, 5, 5, 3, 4}));\n            }\n\n            SECTION(\"insert before end()\")\n            {\n                auto it = j_array.insert(j_array.end(), 3, 5);\n                CHECK(j_array.size() == 7);\n                CHECK(*it == j_value);\n                CHECK((j_array.end() - it) == 3);\n                CHECK(j_array == json({1, 2, 3, 4, 5, 5, 5}));\n            }\n\n            SECTION(\"insert nothing (count = 0)\")\n            {\n                auto it = j_array.insert(j_array.end(), 0, 5);\n                CHECK(j_array.size() == 4);\n                // the returned iterator points to the first inserted element;\n                // there were 4 elements, so it should point to the 5th\n                CHECK(it == j_array.begin() + 4);\n                CHECK(j_array == json({1, 2, 3, 4}));\n            }\n        }\n\n        SECTION(\"range for array\")\n        {\n            json j_other_array = {\"first\", \"second\"};\n\n            SECTION(\"proper usage\")\n            {\n                auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.end());\n                CHECK(j_array.size() == 6);\n                CHECK(*it == *j_other_array.begin());\n                CHECK((j_array.end() - it) == 2);\n                CHECK(j_array == json({1, 2, 3, 4, \"first\", \"second\"}));\n            }\n\n            SECTION(\"empty range\")\n            {\n                auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.begin());\n                CHECK(j_array.size() == 4);\n                CHECK(it == j_array.end());\n                CHECK(j_array == json({1, 2, 3, 4}));\n            }\n\n            SECTION(\"invalid iterators\")\n            {\n                json j_other_array2 = {\"first\", \"second\"};\n\n                CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),\n                                json::invalid_iterator&);\n                CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),\n                                json::invalid_iterator&);\n\n                CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),\n                                  \"[json.exception.invalid_iterator.211] passed iterators may not belong to container\");\n                CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),\n                                  \"[json.exception.invalid_iterator.210] iterators do not fit\");\n            }\n        }\n\n        SECTION(\"range for object\")\n        {\n            json j_object1 = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n            json j_object2 = {{\"eleven\", \"elf\"}, {\"seventeen\", \"siebzehn\"}};\n\n            SECTION(\"proper usage\")\n            {\n                j_object1.insert(j_object2.begin(), j_object2.end());\n                CHECK(j_object1.size() == 4);\n            }\n\n            SECTION(\"empty range\")\n            {\n                j_object1.insert(j_object2.begin(), j_object2.begin());\n                CHECK(j_object1.size() == 2);\n            }\n\n            SECTION(\"invalid iterators\")\n            {\n                json j_other_array2 = {\"first\", \"second\"};\n\n                CHECK_THROWS_AS(j_array.insert(j_object2.begin(), j_object2.end()), json::type_error&);\n                CHECK_THROWS_AS(j_object1.insert(j_object1.begin(), j_object2.end()), json::invalid_iterator&);\n                CHECK_THROWS_AS(j_object1.insert(j_array.begin(), j_array.end()), json::invalid_iterator&);\n\n                CHECK_THROWS_WITH(j_array.insert(j_object2.begin(), j_object2.end()),\n                                  \"[json.exception.type_error.309] cannot use insert() with array\");\n                CHECK_THROWS_WITH(j_object1.insert(j_object1.begin(), j_object2.end()),\n                                  \"[json.exception.invalid_iterator.210] iterators do not fit\");\n                CHECK_THROWS_WITH(j_object1.insert(j_array.begin(), j_array.end()),\n                                  \"[json.exception.invalid_iterator.202] iterators first and last must point to objects\");\n            }\n        }\n\n        SECTION(\"initializer list at position\")\n        {\n            SECTION(\"insert before begin()\")\n            {\n                auto it = j_array.insert(j_array.begin(), {7, 8, 9});\n                CHECK(j_array.size() == 7);\n                CHECK(*it == json(7));\n                CHECK(j_array.begin() == it);\n                CHECK(j_array == json({7, 8, 9, 1, 2, 3, 4}));\n            }\n\n            SECTION(\"insert in the middle\")\n            {\n                auto it = j_array.insert(j_array.begin() + 2, {7, 8, 9});\n                CHECK(j_array.size() == 7);\n                CHECK(*it == json(7));\n                CHECK((it - j_array.begin()) == 2);\n                CHECK(j_array == json({1, 2, 7, 8, 9, 3, 4}));\n            }\n\n            SECTION(\"insert before end()\")\n            {\n                auto it = j_array.insert(j_array.end(), {7, 8, 9});\n                CHECK(j_array.size() == 7);\n                CHECK(*it == json(7));\n                CHECK((j_array.end() - it) == 3);\n                CHECK(j_array == json({1, 2, 3, 4, 7, 8, 9}));\n            }\n        }\n\n        SECTION(\"invalid iterator\")\n        {\n            // pass iterator to a different array\n            json j_another_array = {1, 2};\n            json j_yet_another_array = {\"first\", \"second\"};\n            CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10), json::invalid_iterator&);\n            CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_value), json::invalid_iterator&);\n            CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10, 11), json::invalid_iterator&);\n            CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()), json::invalid_iterator&);\n            CHECK_THROWS_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), json::invalid_iterator&);\n\n            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10),\n                              \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_value),\n                              \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10, 11),\n                              \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()),\n                              \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), {1, 2, 3, 4}),\n                              \"[json.exception.invalid_iterator.202] iterator does not fit current value\");\n        }\n\n        SECTION(\"non-array type\")\n        {\n            // call insert on a non-array type\n            json j_nonarray = 3;\n            json j_yet_another_array = {\"first\", \"second\"};\n            CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10), json::type_error&);\n            CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_value), json::type_error&);\n            CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), json::type_error&);\n            CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),\n                                              j_yet_another_array.end()), json::type_error&);\n            CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), json::type_error&);\n\n            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10), \"[json.exception.type_error.309] cannot use insert() with number\");\n            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_value), \"[json.exception.type_error.309] cannot use insert() with number\");\n            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10, 11), \"[json.exception.type_error.309] cannot use insert() with number\");\n            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),\n                                                j_yet_another_array.end()), \"[json.exception.type_error.309] cannot use insert() with number\");\n            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}),\n                              \"[json.exception.type_error.309] cannot use insert() with number\");\n        }\n    }\n\n    SECTION(\"update()\")\n    {\n        SECTION(\"non-recursive (default)\")\n        {\n            json j_object1 = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n            json j_object2 = {{\"three\", \"drei\"}, {\"two\", \"zwo\"}};\n            json j_array = {1, 2, 3, 4};\n\n            SECTION(\"const reference\")\n            {\n                SECTION(\"proper usage\")\n                {\n                    j_object1.update(j_object2);\n                    CHECK(j_object1 == json({{\"one\", \"eins\"}, {\"two\", \"zwo\"}, {\"three\", \"drei\"}}));\n\n                    json j_null;\n                    j_null.update(j_object2);\n                    CHECK(j_null == j_object2);\n                }\n\n                SECTION(\"wrong types\")\n                {\n                    CHECK_THROWS_AS(j_array.update(j_object1), json::type_error&);\n                    CHECK_THROWS_WITH(j_array.update(j_object1), \"[json.exception.type_error.312] cannot use update() with array\");\n\n                    CHECK_THROWS_AS(j_object1.update(j_array), json::type_error&);\n                    CHECK_THROWS_WITH(j_object1.update(j_array), \"[json.exception.type_error.312] cannot use update() with array\");\n                }\n            }\n\n            SECTION(\"iterator range\")\n            {\n                SECTION(\"proper usage\")\n                {\n                    j_object1.update(j_object2.begin(), j_object2.end());\n                    CHECK(j_object1 == json({{\"one\", \"eins\"}, {\"two\", \"zwo\"}, {\"three\", \"drei\"}}));\n\n                    json j_null;\n                    j_null.update(j_object2.begin(), j_object2.end());\n                    CHECK(j_null == j_object2);\n                }\n\n                SECTION(\"empty range\")\n                {\n                    j_object1.update(j_object2.begin(), j_object2.begin());\n                    CHECK(j_object1 == json({{\"one\", \"eins\"}, {\"two\", \"zwei\"}}));\n                }\n\n                SECTION(\"invalid iterators\")\n                {\n                    json j_other_array2 = {\"first\", \"second\"};\n\n                    CHECK_THROWS_AS(j_array.update(j_object2.begin(), j_object2.end()), json::type_error&);\n                    CHECK_THROWS_AS(j_object1.update(j_object1.begin(), j_object2.end()), json::invalid_iterator&);\n                    CHECK_THROWS_AS(j_object1.update(j_array.begin(), j_array.end()), json::type_error&);\n\n                    CHECK_THROWS_WITH(j_array.update(j_object2.begin(), j_object2.end()),\n                                      \"[json.exception.type_error.312] cannot use update() with array\");\n                    CHECK_THROWS_WITH(j_object1.update(j_object1.begin(), j_object2.end()),\n                                      \"[json.exception.invalid_iterator.210] iterators do not fit\");\n                    CHECK_THROWS_WITH(j_object1.update(j_array.begin(), j_array.end()),\n                                      \"[json.exception.type_error.312] cannot use update() with array\");\n                }\n            }\n        }\n\n        SECTION(\"recursive\")\n        {\n            SECTION(\"const reference\")\n            {\n                SECTION(\"extend object\")\n                {\n                    json j1 = {{\"string\", \"s\"}, {\"numbers\", {{\"one\", 1}}}};\n                    json j2 = {{\"string\", \"t\"}, {\"numbers\", {{\"two\", 2}}}};\n                    j1.update(j2, true);\n                    CHECK(j1 == json({{\"string\", \"t\"}, {\"numbers\", {{\"one\", 1}, {\"two\", 2}}}}));\n                }\n\n                SECTION(\"replace object\")\n                {\n                    json j1 = {{\"string\", \"s\"}, {\"numbers\", {{\"one\", 1}}}};\n                    json j2 = {{\"string\", \"t\"}, {\"numbers\", 1}};\n                    j1.update(j2, true);\n                    CHECK(j1 == json({{\"string\", \"t\"}, {\"numbers\", 1}}));\n                }\n            }\n        }\n    }\n\n    SECTION(\"swap()\")\n    {\n        SECTION(\"json\")\n        {\n            SECTION(\"member swap\")\n            {\n                json j(\"hello world\");\n                json k(42.23);\n\n                j.swap(k);\n\n                CHECK(j == json(42.23));\n                CHECK(k == json(\"hello world\"));\n            }\n\n            SECTION(\"nonmember swap\")\n            {\n                json j(\"hello world\");\n                json k(42.23);\n\n                using std::swap;\n                swap(j, k);\n\n                CHECK(j == json(42.23));\n                CHECK(k == json(\"hello world\"));\n            }\n        }\n\n        SECTION(\"array_t\")\n        {\n            SECTION(\"array_t type\")\n            {\n                json j = {1, 2, 3, 4};\n                json::array_t a = {\"foo\", \"bar\", \"baz\"};\n\n                j.swap(a);\n\n                CHECK(j == json({\"foo\", \"bar\", \"baz\"}));\n\n                j.swap(a);\n\n                CHECK(j == json({1, 2, 3, 4}));\n            }\n\n            SECTION(\"non-array_t type\")\n            {\n                json j = 17;\n                json::array_t a = {\"foo\", \"bar\", \"baz\"};\n\n                CHECK_THROWS_AS(j.swap(a), json::type_error&);\n                CHECK_THROWS_WITH(j.swap(a), \"[json.exception.type_error.310] cannot use swap() with number\");\n            }\n        }\n\n        SECTION(\"object_t\")\n        {\n            SECTION(\"object_t type\")\n            {\n                json j = {{\"one\", 1}, {\"two\", 2}};\n                json::object_t o = {{\"cow\", \"Kuh\"}, {\"chicken\", \"Huhn\"}};\n\n                j.swap(o);\n\n                CHECK(j == json({{\"cow\", \"Kuh\"}, {\"chicken\", \"Huhn\"}}));\n\n                j.swap(o);\n\n                CHECK(j == json({{\"one\", 1}, {\"two\", 2}}));\n            }\n\n            SECTION(\"non-object_t type\")\n            {\n                json j = 17;\n                json::object_t o = {{\"cow\", \"Kuh\"}, {\"chicken\", \"Huhn\"}};\n\n                CHECK_THROWS_AS(j.swap(o), json::type_error&);\n                CHECK_THROWS_WITH(j.swap(o), \"[json.exception.type_error.310] cannot use swap() with number\");\n            }\n        }\n\n        SECTION(\"string_t\")\n        {\n            SECTION(\"string_t type\")\n            {\n                json j = \"Hello world\";\n                json::string_t s = \"Hallo Welt\";\n\n                j.swap(s);\n\n                CHECK(j == json(\"Hallo Welt\"));\n\n                j.swap(s);\n\n                CHECK(j == json(\"Hello world\"));\n            }\n\n            SECTION(\"non-string_t type\")\n            {\n                json j = 17;\n                json::string_t s = \"Hallo Welt\";\n\n                CHECK_THROWS_AS(j.swap(s), json::type_error&);\n                CHECK_THROWS_WITH(j.swap(s), \"[json.exception.type_error.310] cannot use swap() with number\");\n            }\n        }\n\n        SECTION(\"binary_t\")\n        {\n            SECTION(\"binary_t type\")\n            {\n                json j = json::binary({1, 2, 3, 4});\n                json::binary_t s = {{5, 6, 7, 8}};\n\n                j.swap(s);\n\n                CHECK(j == json::binary({5, 6, 7, 8}));\n\n                j.swap(s);\n\n                CHECK(j == json::binary({1, 2, 3, 4}));\n            }\n\n            SECTION(\"binary_t::container_type type\")\n            {\n                json j = json::binary({1, 2, 3, 4});\n                std::vector<std::uint8_t> s = {{5, 6, 7, 8}};\n\n                j.swap(s);\n\n                CHECK(j == json::binary({5, 6, 7, 8}));\n\n                j.swap(s);\n\n                CHECK(j == json::binary({1, 2, 3, 4}));\n            }\n\n            SECTION(\"non-binary_t type\")\n            {\n                json j = 17;\n                json::binary_t s1 = {{1, 2, 3, 4}};\n                std::vector<std::uint8_t> s2 = {{5, 6, 7, 8}};\n\n                CHECK_THROWS_WITH_AS(j.swap(s1), \"[json.exception.type_error.310] cannot use swap() with number\", json::type_error);\n                CHECK_THROWS_WITH_AS(j.swap(s2), \"[json.exception.type_error.310] cannot use swap() with number\", json::type_error);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-msgpack.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <iomanip>\n#include <set>\n#include <test_data.hpp>\n#include \"test_utils.hpp\"\n\nnamespace\n{\nclass SaxCountdown\n{\n  public:\n    explicit SaxCountdown(const int count) : events_left(count)\n    {}\n\n    bool null()\n    {\n        return events_left-- > 0;\n    }\n\n    bool boolean(bool /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_integer(json::number_integer_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_unsigned(json::number_unsigned_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool string(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool binary(std::vector<std::uint8_t>& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_object(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool key(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_object()\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_array(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_array()\n    {\n        return events_left-- > 0;\n    }\n\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)\n    {\n        return false;\n    }\n\n  private:\n    int events_left = 0;\n};\n} // namespace\n\nTEST_CASE(\"MessagePack\")\n{\n    SECTION(\"individual values\")\n    {\n        SECTION(\"discarded\")\n        {\n            // discarded values are not serialized\n            json j = json::value_t::discarded;\n            const auto result = json::to_msgpack(j);\n            CHECK(result.empty());\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            std::vector<uint8_t> expected = {0xc0};\n            const auto result = json::to_msgpack(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_msgpack(result) == j);\n            CHECK(json::from_msgpack(result, true, false) == j);\n        }\n\n        SECTION(\"boolean\")\n        {\n            SECTION(\"true\")\n            {\n                json j = true;\n                std::vector<uint8_t> expected = {0xc3};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"false\")\n            {\n                json j = false;\n                std::vector<uint8_t> expected = {0xc2};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n        }\n\n        SECTION(\"number\")\n        {\n            SECTION(\"signed\")\n            {\n                SECTION(\"-32..-1 (negative fixnum)\")\n                {\n                    for (auto i = -32; i <= -1; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 1);\n\n                        // check individual bytes\n                        CHECK(static_cast<int8_t>(result[0]) == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"0..127 (positive fixnum)\")\n                {\n                    for (size_t i = 0; i <= 127; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 1);\n\n                        // check individual bytes\n                        CHECK(result[0] == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"128..255 (int 8)\")\n                {\n                    for (size_t i = 128; i <= 255; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xcc);\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xcc);\n                        auto restored = static_cast<uint8_t>(result[1]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"256..65535 (int 16)\")\n                {\n                    for (size_t i = 256; i <= 65535; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xcd);\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xcd);\n                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"65536..4294967295 (int 32)\")\n                {\n                    for (uint32_t i :\n                            {\n                                65536u, 77777u, 1048576u, 4294967295u\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xce);\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xce);\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"4294967296..9223372036854775807 (int 64)\")\n                {\n                    for (uint64_t i :\n                            {\n                                4294967296LU, 9223372036854775807LU\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xcf);\n                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xcf);\n                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +\n                                            (static_cast<uint64_t>(result[2]) << 060) +\n                                            (static_cast<uint64_t>(result[3]) << 050) +\n                                            (static_cast<uint64_t>(result[4]) << 040) +\n                                            (static_cast<uint64_t>(result[5]) << 030) +\n                                            (static_cast<uint64_t>(result[6]) << 020) +\n                                            (static_cast<uint64_t>(result[7]) << 010) +\n                                            static_cast<uint64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-128..-33 (int 8)\")\n                {\n                    for (auto i = -128; i <= -33; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xd0);\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xd0);\n                        CHECK(static_cast<int8_t>(result[1]) == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-9263 (int 16)\")\n                {\n                    json j = -9263;\n                    std::vector<uint8_t> expected = {0xd1, 0xdb, 0xd1};\n\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n\n                    auto restored = static_cast<int16_t>((result[1] << 8) + result[2]);\n                    CHECK(restored == -9263);\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n\n                SECTION(\"-32768..-129 (int 16)\")\n                {\n                    for (int16_t i = -32768; i <= static_cast<std::int16_t>(-129); ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xd1);\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xd1);\n                        auto restored = static_cast<int16_t>((result[1] << 8) + result[2]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-32769..-2147483648\")\n                {\n                    std::vector<int32_t> numbers;\n                    numbers.push_back(-32769);\n                    numbers.push_back(-65536);\n                    numbers.push_back(-77777);\n                    numbers.push_back(-1048576);\n                    numbers.push_back(-2147483648LL);\n                    for (auto i : numbers)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xd2);\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xd2);\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(static_cast<std::int32_t>(restored) == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-9223372036854775808..-2147483649 (int 64)\")\n                {\n                    std::vector<int64_t> numbers;\n                    numbers.push_back(INT64_MIN);\n                    numbers.push_back(-2147483649LL);\n                    for (auto i : numbers)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xd3);\n                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xd3);\n                        int64_t restored = (static_cast<int64_t>(result[1]) << 070) +\n                                           (static_cast<int64_t>(result[2]) << 060) +\n                                           (static_cast<int64_t>(result[3]) << 050) +\n                                           (static_cast<int64_t>(result[4]) << 040) +\n                                           (static_cast<int64_t>(result[5]) << 030) +\n                                           (static_cast<int64_t>(result[6]) << 020) +\n                                           (static_cast<int64_t>(result[7]) << 010) +\n                                           static_cast<int64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n            }\n\n            SECTION(\"unsigned\")\n            {\n                SECTION(\"0..127 (positive fixnum)\")\n                {\n                    for (size_t i = 0; i <= 127; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 1);\n\n                        // check individual bytes\n                        CHECK(result[0] == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"128..255 (uint 8)\")\n                {\n                    for (size_t i = 128; i <= 255; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xcc);\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xcc);\n                        auto restored = static_cast<uint8_t>(result[1]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"256..65535 (uint 16)\")\n                {\n                    for (size_t i = 256; i <= 65535; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xcd);\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xcd);\n                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"65536..4294967295 (uint 32)\")\n                {\n                    for (uint32_t i :\n                            {\n                                65536u, 77777u, 1048576u, 4294967295u\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xce);\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xce);\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"4294967296..18446744073709551615 (uint 64)\")\n                {\n                    for (uint64_t i :\n                            {\n                                4294967296LU, 18446744073709551615LU\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(0xcf);\n                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_msgpack(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 0xcf);\n                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +\n                                            (static_cast<uint64_t>(result[2]) << 060) +\n                                            (static_cast<uint64_t>(result[3]) << 050) +\n                                            (static_cast<uint64_t>(result[4]) << 040) +\n                                            (static_cast<uint64_t>(result[5]) << 030) +\n                                            (static_cast<uint64_t>(result[6]) << 020) +\n                                            (static_cast<uint64_t>(result[7]) << 010) +\n                                            static_cast<uint64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_msgpack(result) == j);\n                        CHECK(json::from_msgpack(result, true, false) == j);\n                    }\n                }\n            }\n\n            SECTION(\"float\")\n            {\n                SECTION(\"3.1415925\")\n                {\n                    double v = 3.1415925;\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xcb, 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc\n                    };\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result) == v);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n\n                SECTION(\"1.0\")\n                {\n                    double v = 1.0;\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xca, 0x3f, 0x80, 0x00, 0x00\n                    };\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result) == v);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n\n                SECTION(\"128.128\")\n                {\n                    double v = 128.1280059814453125;\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        0xca, 0x43, 0x00, 0x20, 0xc5\n                    };\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result) == v);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            SECTION(\"N = 0..31\")\n            {\n                // explicitly enumerate the first byte for all 32 strings\n                const std::vector<uint8_t> first_bytes =\n                {\n                    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,\n                    0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1,\n                    0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,\n                    0xbb, 0xbc, 0xbd, 0xbe, 0xbf\n                };\n\n                for (size_t N = 0; N < first_bytes.size(); ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back(first_bytes[N]);\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back('x');\n                    }\n\n                    // check first byte\n                    CHECK((first_bytes[N] & 0x1f) == N);\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 1);\n                    // check that no null byte is appended\n                    if (N > 0)\n                    {\n                        CHECK(result.back() != '\\x00');\n                    }\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 32..255\")\n            {\n                for (size_t N = 32; N <= 255; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back(0xd9);\n                    expected.push_back(static_cast<uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back('x');\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 2);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 256..65535\")\n            {\n                for (size_t N :\n                        {\n                            256u, 999u, 1025u, 3333u, 2048u, 65535u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), 0xda);\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 3);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 65536..4294967295\")\n            {\n                for (size_t N :\n                        {\n                            65536u, 77777u, 1048576u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));\n                    expected.insert(expected.begin(), 0xdb);\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 5);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty\")\n            {\n                json j = json::array();\n                std::vector<uint8_t> expected = {0x90};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"[null]\")\n            {\n                json j = {nullptr};\n                std::vector<uint8_t> expected = {0x91, 0xc0};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"[1,2,3,4,5]\")\n            {\n                json j = json::parse(\"[1,2,3,4,5]\");\n                std::vector<uint8_t> expected = {0x95, 0x01, 0x02, 0x03, 0x04, 0x05};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"[[[[]]]]\")\n            {\n                json j = json::parse(\"[[[[]]]]\");\n                std::vector<uint8_t> expected = {0x91, 0x91, 0x91, 0x90};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"array 16\")\n            {\n                json j(16, nullptr);\n                std::vector<uint8_t> expected(j.size() + 3, 0xc0); // all null\n                expected[0] = 0xdc; // array 16\n                expected[1] = 0x00; // size (0x0010), byte 0\n                expected[2] = 0x10; // size (0x0010), byte 1\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"array 32\")\n            {\n                json j(65536, nullptr);\n                std::vector<uint8_t> expected(j.size() + 5, 0xc0); // all null\n                expected[0] = 0xdd; // array 32\n                expected[1] = 0x00; // size (0x00100000), byte 0\n                expected[2] = 0x01; // size (0x00100000), byte 1\n                expected[3] = 0x00; // size (0x00100000), byte 2\n                expected[4] = 0x00; // size (0x00100000), byte 3\n                const auto result = json::to_msgpack(j);\n                //CHECK(result == expected);\n\n                CHECK(result.size() == expected.size());\n                for (size_t i = 0; i < expected.size(); ++i)\n                {\n                    CAPTURE(i)\n                    CHECK(result[i] == expected[i]);\n                }\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty\")\n            {\n                json j = json::object();\n                std::vector<uint8_t> expected = {0x80};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"{\\\"\\\":null}\")\n            {\n                json j = {{\"\", nullptr}};\n                std::vector<uint8_t> expected = {0x81, 0xa0, 0xc0};\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"{\\\"a\\\": {\\\"b\\\": {\\\"c\\\": {}}}}\")\n            {\n                json j = json::parse(R\"({\"a\": {\"b\": {\"c\": {}}}})\");\n                std::vector<uint8_t> expected =\n                {\n                    0x81, 0xa1, 0x61, 0x81, 0xa1, 0x62, 0x81, 0xa1, 0x63, 0x80\n                };\n                const auto result = json::to_msgpack(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"map 16\")\n            {\n                json j = R\"({\"00\": null, \"01\": null, \"02\": null, \"03\": null,\n                             \"04\": null, \"05\": null, \"06\": null, \"07\": null,\n                             \"08\": null, \"09\": null, \"10\": null, \"11\": null,\n                             \"12\": null, \"13\": null, \"14\": null, \"15\": null})\"_json;\n\n                const auto result = json::to_msgpack(j);\n\n                // Checking against an expected vector byte by byte is\n                // difficult, because no assumption on the order of key/value\n                // pairs are made. We therefore only check the prefix (type and\n                // size and the overall size. The rest is then handled in the\n                // roundtrip check.\n                CHECK(result.size() == 67); // 1 type, 2 size, 16*4 content\n                CHECK(result[0] == 0xde); // map 16\n                CHECK(result[1] == 0x00); // byte 0 of size (0x0010)\n                CHECK(result[2] == 0x10); // byte 1 of size (0x0010)\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n\n            SECTION(\"map 32\")\n            {\n                json j;\n                for (auto i = 0; i < 65536; ++i)\n                {\n                    // format i to a fixed width of 5\n                    // each entry will need 7 bytes: 6 for fixstr, 1 for null\n                    std::stringstream ss;\n                    ss << std::setw(5) << std::setfill('0') << i;\n                    j.emplace(ss.str(), nullptr);\n                }\n\n                const auto result = json::to_msgpack(j);\n\n                // Checking against an expected vector byte by byte is\n                // difficult, because no assumption on the order of key/value\n                // pairs are made. We therefore only check the prefix (type and\n                // size and the overall size. The rest is then handled in the\n                // roundtrip check.\n                CHECK(result.size() == 458757); // 1 type, 4 size, 65536*7 content\n                CHECK(result[0] == 0xdf); // map 32\n                CHECK(result[1] == 0x00); // byte 0 of size (0x00010000)\n                CHECK(result[2] == 0x01); // byte 1 of size (0x00010000)\n                CHECK(result[3] == 0x00); // byte 2 of size (0x00010000)\n                CHECK(result[4] == 0x00); // byte 3 of size (0x00010000)\n\n                // roundtrip\n                CHECK(json::from_msgpack(result) == j);\n                CHECK(json::from_msgpack(result, true, false) == j);\n            }\n        }\n\n        SECTION(\"extension\")\n        {\n            SECTION(\"N = 0..255\")\n            {\n                for (size_t N = 0; N <= 0xFF; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with byte array containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n                    std::uint8_t subtype = 42;\n                    j.get_binary().set_subtype(subtype);\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    switch (N)\n                    {\n                        case 1:\n                            expected.push_back(static_cast<std::uint8_t>(0xD4));\n                            break;\n                        case 2:\n                            expected.push_back(static_cast<std::uint8_t>(0xD5));\n                            break;\n                        case 4:\n                            expected.push_back(static_cast<std::uint8_t>(0xD6));\n                            break;\n                        case 8:\n                            expected.push_back(static_cast<std::uint8_t>(0xD7));\n                            break;\n                        case 16:\n                            expected.push_back(static_cast<std::uint8_t>(0xD8));\n                            break;\n                        default:\n                            expected.push_back(static_cast<std::uint8_t>(0xC7));\n                            expected.push_back(static_cast<std::uint8_t>(N));\n                            break;\n                    }\n                    expected.push_back(subtype);\n\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back(0x78);\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    switch (N)\n                    {\n                        case 1:\n                        case 2:\n                        case 4:\n                        case 8:\n                        case 16:\n                            CHECK(result.size() == N + 2);\n                            break;\n                        default:\n                            CHECK(result.size() == N + 3);\n                            break;\n                    }\n\n                    // check that no null byte is appended\n                    if (N > 0)\n                    {\n                        CHECK(result.back() != '\\x00');\n                    }\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 256..65535\")\n            {\n                for (std::size_t N :\n                        {\n                            256u, 999u, 1025u, 3333u, 2048u, 65535u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n                    std::uint8_t subtype = 42;\n                    j.get_binary().set_subtype(subtype);\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), subtype);\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), 0xC8);\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 4);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 65536..4294967295\")\n            {\n                for (std::size_t N :\n                        {\n                            65536u, 77777u, 1048576u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n                    std::uint8_t subtype = 42;\n                    j.get_binary().set_subtype(subtype);\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), subtype);\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));\n                    expected.insert(expected.begin(), 0xC9);\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 6);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n        }\n\n        SECTION(\"binary\")\n        {\n            SECTION(\"N = 0..255\")\n            {\n                for (std::size_t N = 0; N <= 0xFF; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with byte array containing of N * 'x'\n                    const auto s = std::vector<uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector\n                    std::vector<std::uint8_t> expected;\n                    expected.push_back(static_cast<std::uint8_t>(0xC4));\n                    expected.push_back(static_cast<std::uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back(0x78);\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 2);\n                    // check that no null byte is appended\n                    if (N > 0)\n                    {\n                        CHECK(result.back() != '\\x00');\n                    }\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 256..65535\")\n            {\n                for (std::size_t N :\n                        {\n                            256u, 999u, 1025u, 3333u, 2048u, 65535u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::vector<std::uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<std::uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<std::uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<std::uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), 0xC5);\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 3);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 65536..4294967295\")\n            {\n                for (std::size_t N :\n                        {\n                            65536u, 77777u, 1048576u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::vector<std::uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<std::uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<std::uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), static_cast<std::uint8_t>((N >> 16) & 0xff));\n                    expected.insert(expected.begin(), static_cast<std::uint8_t>((N >> 24) & 0xff));\n                    expected.insert(expected.begin(), 0xC6);\n\n                    // compare result + size\n                    const auto result = json::to_msgpack(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 5);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_msgpack(result) == j);\n                    CHECK(json::from_msgpack(result, true, false) == j);\n                }\n            }\n        }\n    }\n\n    SECTION(\"from float32\")\n    {\n        auto given = std::vector<uint8_t>({0xca, 0x41, 0xc8, 0x00, 0x01});\n        json j = json::from_msgpack(given);\n        CHECK(j.get<double>() == Approx(25.0000019073486));\n    }\n\n    SECTION(\"errors\")\n    {\n        SECTION(\"empty byte vector\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>()), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>()),\n                              \"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input\");\n            CHECK(json::from_msgpack(std::vector<uint8_t>(), true, false).is_discarded());\n        }\n\n        SECTION(\"too short byte vector\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x87})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcc})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcd})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x92, 0x01})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})), json::parse_error&);\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xc4, 0x02})), json::parse_error&);\n\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0x87})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcc})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcd})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xce})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf})),\n                              \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),\n                              \"[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing MessagePack number: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack string: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0x92, 0x01})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack value: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})),\n                              \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack value: unexpected end of input\");\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xc4, 0x02})),\n                              \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack binary: unexpected end of input\");\n\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0x87}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcc}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcd}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xce}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0x92, 0x01}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0x81, 0xA1, 0x61}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xc4, 0x02}), true, false).is_discarded());\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0xc4}), true, false).is_discarded());\n        }\n\n        SECTION(\"unsupported bytes\")\n        {\n            SECTION(\"concrete examples\")\n            {\n                json _;\n                CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xc1})), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0xc1})),\n                                  \"[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1\");\n            }\n\n            SECTION(\"all unsupported bytes\")\n            {\n                for (auto byte :\n                        {\n                            // never used\n                            0xc1\n                        })\n                {\n                    json _;\n                    CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error&);\n                    CHECK(json::from_msgpack(std::vector<uint8_t>({static_cast<uint8_t>(byte)}), true, false).is_discarded());\n                }\n            }\n        }\n\n        SECTION(\"invalid string in map\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})),\n                              \"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF\");\n            CHECK(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01}), true, false).is_discarded());\n        }\n\n        SECTION(\"strict mode\")\n        {\n            std::vector<uint8_t> vec = {0xc0, 0xc0};\n            SECTION(\"non-strict mode\")\n            {\n                const auto result = json::from_msgpack(vec, false);\n                CHECK(result == json());\n            }\n\n            SECTION(\"strict mode\")\n            {\n                json _;\n                CHECK_THROWS_AS(_ = json::from_msgpack(vec), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_msgpack(vec),\n                                  \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack value: expected end of input; last byte: 0xC0\");\n                CHECK(json::from_msgpack(vec, true, false).is_discarded());\n            }\n        }\n    }\n\n    SECTION(\"SAX aborts\")\n    {\n        SECTION(\"start_array(len)\")\n        {\n            std::vector<uint8_t> v = {0x93, 0x01, 0x02, 0x03};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::msgpack));\n        }\n\n        SECTION(\"start_object(len)\")\n        {\n            std::vector<uint8_t> v = {0x81, 0xa3, 0x66, 0x6F, 0x6F, 0xc2};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::msgpack));\n        }\n\n        SECTION(\"key()\")\n        {\n            std::vector<uint8_t> v = {0x81, 0xa3, 0x66, 0x6F, 0x6F, 0xc2};\n            SaxCountdown scp(1);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::msgpack));\n        }\n    }\n}\n\n// use this testcase outside [hide] to run it with Valgrind\nTEST_CASE(\"single MessagePack roundtrip\")\n{\n    SECTION(\"sample.json\")\n    {\n        std::string filename = TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\";\n\n        // parse JSON file\n        std::ifstream f_json(filename);\n        json j1 = json::parse(f_json);\n\n        // parse MessagePack file\n        auto packed = utils::read_binary_file(filename + \".msgpack\");\n        json j2;\n        CHECK_NOTHROW(j2 = json::from_msgpack(packed));\n\n        // compare parsed JSON values\n        CHECK(j1 == j2);\n\n        SECTION(\"roundtrips\")\n        {\n            SECTION(\"std::ostringstream\")\n            {\n                std::basic_ostringstream<std::uint8_t> ss;\n                json::to_msgpack(j1, ss);\n                json j3 = json::from_msgpack(ss.str());\n                CHECK(j1 == j3);\n            }\n\n            SECTION(\"std::string\")\n            {\n                std::string s;\n                json::to_msgpack(j1, s);\n                json j3 = json::from_msgpack(s);\n                CHECK(j1 == j3);\n            }\n        }\n\n        // check with different start index\n        packed.insert(packed.begin(), 5, 0xff);\n        CHECK(j1 == json::from_msgpack(packed.begin() + 5, packed.end()));\n    }\n}\n\nTEST_CASE(\"MessagePack roundtrips\" * doctest::skip())\n{\n    SECTION(\"input from msgpack-python\")\n    {\n        // most of these are excluded due to differences in key order (not a real problem)\n        std::set<std::string> exclude_packed;\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/1.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/2.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/3.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/4.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json.org/5.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\"); // kills AppVeyor\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/json_tests/pass1.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/regression/working_file.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_basic.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_long_strings.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_simple.json\");\n        exclude_packed.insert(TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_string_unicode.json\");\n\n        for (std::string filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/1.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/2.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/3.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/4.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/5.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip01.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip02.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip03.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip04.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip05.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip06.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip07.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip08.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip09.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip10.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip11.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip12.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip13.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip14.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip15.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip16.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip17.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip18.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip19.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip20.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip21.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip22.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip23.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip24.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip25.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip26.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip27.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip28.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip29.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip30.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip31.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip32.json\",\n                    TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\", // kills AppVeyor\n                    TEST_DATA_DIRECTORY \"/json_tests/pass1.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass2.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass3.json\",\n                    TEST_DATA_DIRECTORY \"/regression/floats.json\",\n                    TEST_DATA_DIRECTORY \"/regression/signed_ints.json\",\n                    TEST_DATA_DIRECTORY \"/regression/unsigned_ints.json\",\n                    TEST_DATA_DIRECTORY \"/regression/working_file.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_arraysWithSpaces.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_empty-string.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_empty.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_ending_with_newline.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_false.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_heterogeneous.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_null.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_1_and_newline.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_leading_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_several_null.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_trailing_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_0e+1.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_0e1.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_after_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_huge_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_int_with_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_minus_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_one.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e_neg_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e_pos_exp.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_exponent.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_underflow.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_simple_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_simple_real.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_too_big_neg_int.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_too_big_pos_int.json\",\n                    //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_very_big_negative_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_basic.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key_and_value.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_empty.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_empty_key.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_escaped_null_in_key.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_extreme_numbers.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_long_strings.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_simple.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_string_unicode.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_with_newlines.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pair.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pairs.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_allowed_escapes.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_backslash_and_u_escaped_zero.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_backslash_doublequotes.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_comments.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_double_escape_a.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_double_escape_n.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_escaped_control_character.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_escaped_noncharacter.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_in_array.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_in_array_with_leading_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_last_surrogates_1_and_2.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_newline_uescaped.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_null_escape.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_one-byte-utf-8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_pi.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_simple_ascii.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_space.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_three-byte-utf-8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_two-byte-utf-8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_u+2028_line_sep.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_u+2029_par_sep.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_uEscape.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unescaped_char_delete.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicodeEscapedBackslash.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_2.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_escaped_double_quote.json\",\n                    // TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_utf16.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_utf8.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_with_del_character.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_false.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_int.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_negative_real.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_null.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_string.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_true.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_string_empty.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_true_in_array.json\",\n                    TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json\"\n                })\n        {\n            CAPTURE(filename)\n\n            {\n                INFO_WITH_TEMP(filename + \": std::vector<uint8_t>\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse MessagePack file\n                auto packed = utils::read_binary_file(filename + \".msgpack\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_msgpack(packed));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": std::ifstream\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse MessagePack file\n                std::ifstream f_msgpack(filename + \".msgpack\", std::ios::binary);\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_msgpack(f_msgpack));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": uint8_t* and size\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse MessagePack file\n                auto packed = utils::read_binary_file(filename + \".msgpack\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_msgpack({packed.data(), packed.size()}));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": output to output adapters\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse MessagePack file\n                auto packed = utils::read_binary_file(filename + \".msgpack\");\n\n                if (exclude_packed.count(filename) == 0u)\n                {\n                    {\n                        INFO_WITH_TEMP(filename + \": output adapters: std::vector<uint8_t>\");\n                        std::vector<uint8_t> vec;\n                        json::to_msgpack(j1, vec);\n                        CHECK(vec == packed);\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-noexcept.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// disable -Wnoexcept due to struct pod_bis\nDOCTEST_GCC_SUPPRESS_WARNING_PUSH\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wnoexcept\")\n\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace\n{\nenum test\n{\n};\n\nstruct pod {};\nstruct pod_bis {};\n\nvoid to_json(json& /*unused*/, pod /*unused*/) noexcept;\nvoid to_json(json& /*unused*/, pod_bis /*unused*/);\nvoid from_json(const json& /*unused*/, pod /*unused*/) noexcept;\nvoid from_json(const json& /*unused*/, pod_bis /*unused*/);\nvoid to_json(json& /*unused*/, pod /*unused*/) noexcept {}\nvoid to_json(json& /*unused*/, pod_bis /*unused*/) {}\nvoid from_json(const json& /*unused*/, pod /*unused*/) noexcept {}\nvoid from_json(const json& /*unused*/, pod_bis /*unused*/) {}\n\njson* j = nullptr;\n\nstatic_assert(noexcept(json{}), \"\");\nstatic_assert(noexcept(nlohmann::to_json(*j, 2)), \"\");\nstatic_assert(noexcept(nlohmann::to_json(*j, 2.5)), \"\");\nstatic_assert(noexcept(nlohmann::to_json(*j, true)), \"\");\nstatic_assert(noexcept(nlohmann::to_json(*j, test{})), \"\");\nstatic_assert(noexcept(nlohmann::to_json(*j, pod{})), \"\");\nstatic_assert(!noexcept(nlohmann::to_json(*j, pod_bis{})), \"\");\nstatic_assert(noexcept(json(2)), \"\");\nstatic_assert(noexcept(json(test{})), \"\");\nstatic_assert(noexcept(json(pod{})), \"\");\nstatic_assert(noexcept(j->get<pod>()), \"\");\nstatic_assert(!noexcept(j->get<pod_bis>()), \"\");\nstatic_assert(noexcept(json(pod{})), \"\");\n} // namespace\n\nTEST_CASE(\"runtime checks\")\n{\n    SECTION(\"nothrow-copy-constructible exceptions\")\n    {\n        // for ERR60-CPP (https://github.com/nlohmann/json/issues/531):\n        // Exceptions should be nothrow-copy-constructible. However, compilers\n        // treat std::runtime_exception differently in this regard. Therefore,\n        // we can only demand nothrow-copy-constructibility for our exceptions\n        // if std::runtime_exception is.\n        CHECK(std::is_nothrow_copy_constructible<json::exception>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);\n        CHECK(std::is_nothrow_copy_constructible<json::parse_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);\n        CHECK(std::is_nothrow_copy_constructible<json::invalid_iterator>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);\n        CHECK(std::is_nothrow_copy_constructible<json::type_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);\n        CHECK(std::is_nothrow_copy_constructible<json::out_of_range>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);\n        CHECK(std::is_nothrow_copy_constructible<json::other_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);\n    }\n\n    SECTION(\"silence -Wunneeded-internal-declaration errors\")\n    {\n        j = nullptr;\n        json j2;\n        to_json(j2, pod());\n        to_json(j2, pod_bis());\n        from_json(j2, pod());\n        from_json(j2, pod_bis());\n    }\n}\n\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-ordered_json.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\nusing nlohmann::ordered_json;\n\n\nTEST_CASE(\"ordered_json\")\n{\n    json j;\n    ordered_json oj;\n\n    j[\"element3\"] = 3;\n    j[\"element1\"] = 1;\n    j[\"element2\"] = 2;\n\n    oj[\"element3\"] = 3;\n    oj[\"element1\"] = 1;\n    oj[\"element2\"] = 2;\n\n    CHECK(j.dump() == \"{\\\"element1\\\":1,\\\"element2\\\":2,\\\"element3\\\":3}\");\n    CHECK(oj.dump() == \"{\\\"element3\\\":3,\\\"element1\\\":1,\\\"element2\\\":2}\");\n\n    CHECK(j == json(oj));\n    CHECK(ordered_json(json(oj)) == ordered_json(j));\n\n    j.erase(\"element1\");\n    oj.erase(\"element1\");\n\n    CHECK(j.dump() == \"{\\\"element2\\\":2,\\\"element3\\\":3}\");\n    CHECK(oj.dump() == \"{\\\"element3\\\":3,\\\"element2\\\":2}\");\n\n    // remove again and nothing changes\n    j.erase(\"element1\");\n    oj.erase(\"element1\");\n\n    CHECK(j.dump() == \"{\\\"element2\\\":2,\\\"element3\\\":3}\");\n    CHECK(oj.dump() == \"{\\\"element3\\\":3,\\\"element2\\\":2}\");\n\n    // There are no dup keys cause constructor calls emplace...\n    json multi {{\"z\", 1}, {\"m\", 2}, {\"m\", 3}, {\"y\", 4}, {\"m\", 5}};\n    CHECK(multi.size() == 3);\n    CHECK(multi.dump() == \"{\\\"m\\\":2,\\\"y\\\":4,\\\"z\\\":1}\");\n\n    ordered_json multi_ordered {{\"z\", 1}, {\"m\", 2}, {\"m\", 3}, {\"y\", 4}, {\"m\", 5}};\n    CHECK(multi_ordered.size() == 3);\n    CHECK(multi_ordered.dump() == \"{\\\"z\\\":1,\\\"m\\\":2,\\\"y\\\":4}\");\n    CHECK(multi_ordered.erase(\"m\") == 1);\n    CHECK(multi_ordered.dump() == \"{\\\"z\\\":1,\\\"y\\\":4}\");\n\n    // Ranged insert test.\n    // It seems that values shouldn't be overwritten. Only new values are added\n    json j1 {{\"c\", 1}, {\"b\", 2}, {\"a\", 3}};\n    const json j2 {{\"c\", 77}, {\"d\", 42}, {\"a\", 4}};\n    j1.insert( j2.cbegin(), j2.cend() );\n    CHECK(j1.size() == 4);\n    CHECK(j1.dump() == \"{\\\"a\\\":3,\\\"b\\\":2,\\\"c\\\":1,\\\"d\\\":42}\");\n\n    ordered_json oj1 {{\"c\", 1}, {\"b\", 2}, {\"a\", 3}};\n    const ordered_json oj2 {{\"c\", 77}, {\"d\", 42}, {\"a\", 4}};\n    oj1.insert( oj2.cbegin(), oj2.cend() );\n    CHECK(oj1.size() == 4);\n    CHECK(oj1.dump() == \"{\\\"c\\\":1,\\\"b\\\":2,\\\"a\\\":3,\\\"d\\\":42}\");\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-ordered_map.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::ordered_map;\n\n\nTEST_CASE(\"ordered_map\")\n{\n    SECTION(\"constructor\")\n    {\n        SECTION(\"constructor from iterator range\")\n        {\n            std::map<std::string, std::string> m {{\"eins\", \"one\"}, {\"zwei\", \"two\"}, {\"drei\", \"three\"}};\n            ordered_map<std::string, std::string> om(m.begin(), m.end());\n            CHECK(om.size() == 3);\n        }\n\n        SECTION(\"copy assignment\")\n        {\n            std::map<std::string, std::string> m {{\"eins\", \"one\"}, {\"zwei\", \"two\"}, {\"drei\", \"three\"}};\n            ordered_map<std::string, std::string> om(m.begin(), m.end());\n            const auto com = om;\n            om.clear(); // silence a warning by forbidding having \"const auto& com = om;\"\n            CHECK(com.size() == 3);\n        }\n    }\n\n    SECTION(\"at\")\n    {\n        std::map<std::string, std::string> m {{\"eins\", \"one\"}, {\"zwei\", \"two\"}, {\"drei\", \"three\"}};\n        ordered_map<std::string, std::string> om(m.begin(), m.end());\n        const auto com = om;\n\n        SECTION(\"with Key&&\")\n        {\n            CHECK(om.at(std::string(\"eins\")) == std::string(\"one\"));\n            CHECK(com.at(std::string(\"eins\")) == std::string(\"one\"));\n            CHECK_THROWS_AS(om.at(std::string(\"vier\")), std::out_of_range);\n            CHECK_THROWS_AS(com.at(std::string(\"vier\")), std::out_of_range);\n        }\n\n        SECTION(\"with const Key&&\")\n        {\n            const std::string eins = \"eins\";\n            const std::string vier = \"vier\";\n            CHECK(om.at(eins) == std::string(\"one\"));\n            CHECK(com.at(eins) == std::string(\"one\"));\n            CHECK_THROWS_AS(om.at(vier), std::out_of_range);\n            CHECK_THROWS_AS(com.at(vier), std::out_of_range);\n        }\n\n        SECTION(\"with string literal\")\n        {\n            CHECK(om.at(\"eins\") == std::string(\"one\"));\n            CHECK(com.at(\"eins\") == std::string(\"one\"));\n            CHECK_THROWS_AS(om.at(\"vier\"), std::out_of_range);\n            CHECK_THROWS_AS(com.at(\"vier\"), std::out_of_range);\n        }\n    }\n\n    SECTION(\"operator[]\")\n    {\n        std::map<std::string, std::string> m {{\"eins\", \"one\"}, {\"zwei\", \"two\"}, {\"drei\", \"three\"}};\n        ordered_map<std::string, std::string> om(m.begin(), m.end());\n        const auto com = om;\n\n        SECTION(\"with Key&&\")\n        {\n            CHECK(om[std::string(\"eins\")] == std::string(\"one\"));\n            CHECK(com[std::string(\"eins\")] == std::string(\"one\"));\n\n            CHECK(om[std::string(\"vier\")] == std::string(\"\"));\n            CHECK(om.size() == 4);\n        }\n\n        SECTION(\"with const Key&&\")\n        {\n            const std::string eins = \"eins\";\n            const std::string vier = \"vier\";\n\n            CHECK(om[eins] == std::string(\"one\"));\n            CHECK(com[eins] == std::string(\"one\"));\n\n            CHECK(om[vier] == std::string(\"\"));\n            CHECK(om.size() == 4);\n        }\n\n        SECTION(\"with string literal\")\n        {\n            CHECK(om[\"eins\"] == std::string(\"one\"));\n            CHECK(com[\"eins\"] == std::string(\"one\"));\n\n            CHECK(om[\"vier\"] == std::string(\"\"));\n            CHECK(om.size() == 4);\n        }\n    }\n\n    SECTION(\"erase\")\n    {\n        ordered_map<std::string, std::string> om;\n        om[\"eins\"] = \"one\";\n        om[\"zwei\"] = \"two\";\n        om[\"drei\"] = \"three\";\n\n        {\n            auto it = om.begin();\n            CHECK(it->first == \"eins\");\n            ++it;\n            CHECK(it->first == \"zwei\");\n            ++it;\n            CHECK(it->first == \"drei\");\n            ++it;\n            CHECK(it == om.end());\n        }\n\n        SECTION(\"with Key&&\")\n        {\n            CHECK(om.size() == 3);\n            CHECK(om.erase(std::string(\"eins\")) == 1);\n            CHECK(om.size() == 2);\n            CHECK(om.erase(std::string(\"vier\")) == 0);\n            CHECK(om.size() == 2);\n\n            auto it = om.begin();\n            CHECK(it->first == \"zwei\");\n            ++it;\n            CHECK(it->first == \"drei\");\n            ++it;\n            CHECK(it == om.end());\n        }\n\n        SECTION(\"with const Key&&\")\n        {\n            const std::string eins = \"eins\";\n            const std::string vier = \"vier\";\n            CHECK(om.size() == 3);\n            CHECK(om.erase(eins) == 1);\n            CHECK(om.size() == 2);\n            CHECK(om.erase(vier) == 0);\n            CHECK(om.size() == 2);\n\n            auto it = om.begin();\n            CHECK(it->first == \"zwei\");\n            ++it;\n            CHECK(it->first == \"drei\");\n            ++it;\n            CHECK(it == om.end());\n        }\n\n        SECTION(\"with string literal\")\n        {\n            CHECK(om.size() == 3);\n            CHECK(om.erase(\"eins\") == 1);\n            CHECK(om.size() == 2);\n            CHECK(om.erase(\"vier\") == 0);\n            CHECK(om.size() == 2);\n\n            auto it = om.begin();\n            CHECK(it->first == \"zwei\");\n            ++it;\n            CHECK(it->first == \"drei\");\n            ++it;\n            CHECK(it == om.end());\n        }\n\n        SECTION(\"with iterator\")\n        {\n            CHECK(om.size() == 3);\n            CHECK(om.begin()->first == \"eins\");\n            CHECK(std::next(om.begin(), 1)->first == \"zwei\");\n            CHECK(std::next(om.begin(), 2)->first == \"drei\");\n\n            auto it = om.erase(om.begin());\n            CHECK(it->first == \"zwei\");\n            CHECK(om.size() == 2);\n\n            auto it2 = om.begin();\n            CHECK(it2->first == \"zwei\");\n            ++it2;\n            CHECK(it2->first == \"drei\");\n            ++it2;\n            CHECK(it2 == om.end());\n        }\n\n        SECTION(\"with iterator pair\")\n        {\n            SECTION(\"range in the middle\")\n            {\n                // need more elements\n                om[\"vier\"] = \"four\";\n                om[\"fünf\"] = \"five\";\n\n                // delete \"zwei\" and \"drei\"\n                auto it = om.erase(om.begin() + 1, om.begin() + 3);\n                CHECK(it->first == \"vier\");\n                CHECK(om.size() == 3);\n            }\n\n            SECTION(\"range at the beginning\")\n            {\n                // need more elements\n                om[\"vier\"] = \"four\";\n                om[\"fünf\"] = \"five\";\n\n                // delete \"eins\" and \"zwei\"\n                auto it = om.erase(om.begin(), om.begin() + 2);\n                CHECK(it->first == \"drei\");\n                CHECK(om.size() == 3);\n            }\n\n            SECTION(\"range at the end\")\n            {\n                // need more elements\n                om[\"vier\"] = \"four\";\n                om[\"fünf\"] = \"five\";\n\n                // delete \"vier\" and \"fünf\"\n                auto it = om.erase(om.begin() + 3, om.end());\n                CHECK(it == om.end());\n                CHECK(om.size() == 3);\n            }\n        }\n    }\n\n    SECTION(\"count\")\n    {\n        ordered_map<std::string, std::string> om;\n        om[\"eins\"] = \"one\";\n        om[\"zwei\"] = \"two\";\n        om[\"drei\"] = \"three\";\n\n        const std::string eins(\"eins\");\n        const std::string vier(\"vier\");\n        CHECK(om.count(\"eins\") == 1);\n        CHECK(om.count(std::string(\"eins\")) == 1);\n        CHECK(om.count(eins) == 1);\n        CHECK(om.count(\"vier\") == 0);\n        CHECK(om.count(std::string(\"vier\")) == 0);\n        CHECK(om.count(vier) == 0);\n    }\n\n    SECTION(\"find\")\n    {\n        ordered_map<std::string, std::string> om;\n        om[\"eins\"] = \"one\";\n        om[\"zwei\"] = \"two\";\n        om[\"drei\"] = \"three\";\n        const auto com = om;\n\n        const std::string eins(\"eins\");\n        const std::string vier(\"vier\");\n        CHECK(om.find(\"eins\") == om.begin());\n        CHECK(om.find(std::string(\"eins\")) == om.begin());\n        CHECK(om.find(eins) == om.begin());\n        CHECK(om.find(\"vier\") == om.end());\n        CHECK(om.find(std::string(\"vier\")) == om.end());\n        CHECK(om.find(vier) == om.end());\n\n        CHECK(com.find(\"eins\") == com.begin());\n        CHECK(com.find(std::string(\"eins\")) == com.begin());\n        CHECK(com.find(eins) == com.begin());\n        CHECK(com.find(\"vier\") == com.end());\n        CHECK(com.find(std::string(\"vier\")) == com.end());\n        CHECK(com.find(vier) == com.end());\n    }\n\n    SECTION(\"insert\")\n    {\n        ordered_map<std::string, std::string> om;\n        om[\"eins\"] = \"one\";\n        om[\"zwei\"] = \"two\";\n        om[\"drei\"] = \"three\";\n\n        SECTION(\"const value_type&\")\n        {\n            ordered_map<std::string, std::string>::value_type vt1 {\"eins\", \"1\"};\n            ordered_map<std::string, std::string>::value_type vt4 {\"vier\", \"four\"};\n\n            auto res1 = om.insert(vt1);\n            CHECK(res1.first == om.begin());\n            CHECK(res1.second == false);\n            CHECK(om.size() == 3);\n\n            auto res4 = om.insert(vt4);\n            CHECK(res4.first == om.begin() + 3);\n            CHECK(res4.second == true);\n            CHECK(om.size() == 4);\n        }\n\n        SECTION(\"value_type&&\")\n        {\n            auto res1 = om.insert({\"eins\", \"1\"});\n            CHECK(res1.first == om.begin());\n            CHECK(res1.second == false);\n            CHECK(om.size() == 3);\n\n            auto res4 = om.insert({\"vier\", \"four\"});\n            CHECK(res4.first == om.begin() + 3);\n            CHECK(res4.second == true);\n            CHECK(om.size() == 4);\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-pointer_access.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"pointer access\")\n{\n    SECTION(\"pointer access to object_t\")\n    {\n        using test_type = json::object_t;\n        json value = {{\"one\", 1}, {\"two\", 2}};\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<json::object_t*>() != nullptr);\n        CHECK(value.get_ptr<json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const object_t\")\n    {\n        using test_type = const json::object_t;\n        const json value = {{\"one\", 1}, {\"two\", 2}};\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to array_t\")\n    {\n        using test_type = json::array_t;\n        json value = {1, 2, 3, 4};\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<json::array_t*>() != nullptr);\n        CHECK(value.get_ptr<json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const array_t\")\n    {\n        using test_type = const json::array_t;\n        const json value = {1, 2, 3, 4};\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to string_t\")\n    {\n        using test_type = json::string_t;\n        json value = \"hello\";\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<json::string_t*>() != nullptr);\n        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const string_t\")\n    {\n        using test_type = const json::string_t;\n        const json value = \"hello\";\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to boolean_t\")\n    {\n        using test_type = json::boolean_t;\n        json value = false;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<json::boolean_t*>() != nullptr);\n        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const boolean_t\")\n    {\n        using test_type = const json::boolean_t;\n        const json value = false;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        //CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to number_integer_t\")\n    {\n        using test_type = json::number_integer_t;\n        json value = 23;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);\n        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const number_integer_t\")\n    {\n        using test_type = const json::number_integer_t;\n        const json value = 23;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to number_unsigned_t\")\n    {\n        using test_type = json::number_unsigned_t;\n        json value = 23u;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);\n        CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);\n        CHECK(value.get_ptr<json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const number_unsigned_t\")\n    {\n        using test_type = const json::number_unsigned_t;\n        const json value = 23u;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to number_float_t\")\n    {\n        using test_type = json::number_float_t;\n        json value = 42.23;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == Approx(value.get<test_type>()));\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == Approx(value.get<test_type>()));\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == Approx(value.get<test_type>()));\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<json::number_float_t*>() != nullptr);\n        CHECK(value.get_ptr<json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const number_float_t\")\n    {\n        using test_type = const json::number_float_t;\n        const json value = 42.23;\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == Approx(value.get<test_type>()));\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == Approx(value.get<test_type>()));\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == Approx(value.get<test_type>()));\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() != nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);\n    }\n\n    SECTION(\"pointer access to const binary_t\")\n    {\n        using test_type = const json::binary_t;\n        const json value = json::binary({1, 2, 3});\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() != nullptr);\n    }\n\n    SECTION(\"pointer access to const binary_t\")\n    {\n        using test_type = const json::binary_t;\n        const json value = json::binary({});\n\n        // check if pointers are returned correctly\n        test_type* p1 = value.get_ptr<test_type*>();\n        CHECK(p1 == value.get_ptr<test_type*>());\n        CHECK(*p1 == value.get<test_type>());\n\n        const test_type* p2 = value.get_ptr<const test_type*>();\n        CHECK(p2 == value.get_ptr<const test_type*>());\n        CHECK(*p2 == value.get<test_type>());\n\n        const test_type* const p3 = value.get_ptr<const test_type* const>();\n        CHECK(p3 == value.get_ptr<const test_type* const>());\n        CHECK(*p3 == value.get<test_type>());\n\n        // check if null pointers are returned correctly\n        CHECK(value.get_ptr<const json::object_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::array_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::string_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);\n        CHECK(value.get_ptr<const json::binary_t*>() != nullptr);\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-readme.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <deque>\n#include <forward_list>\n#include <list>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <iostream>\n#include <sstream>\n#include <iomanip>\n\n// local variable is initialized but not referenced\nDOCTEST_MSVC_SUPPRESS_WARNING_PUSH\nDOCTEST_MSVC_SUPPRESS_WARNING(4189)\n\nTEST_CASE(\"README\" * doctest::skip())\n{\n    {\n        // redirect std::cout for the README file\n        auto* old_cout_buffer = std::cout.rdbuf();\n        std::ostringstream new_stream;\n        std::cout.rdbuf(new_stream.rdbuf());\n        {\n            // create an empty structure (null)\n            json j;\n\n            // add a number that is stored as double (note the implicit conversion of j to an object)\n            j[\"pi\"] = 3.141;\n\n            // add a Boolean that is stored as bool\n            j[\"happy\"] = true;\n\n            // add a string that is stored as std::string\n            j[\"name\"] = \"Niels\";\n\n            // add another null object by passing nullptr\n            j[\"nothing\"] = nullptr;\n\n            // add an object inside the object\n            j[\"answer\"][\"everything\"] = 42;\n\n            // add an array that is stored as std::vector (using an initializer list)\n            j[\"list\"] = { 1, 0, 2 };\n\n            // add another object (using an initializer list of pairs)\n            j[\"object\"] = { {\"currency\", \"USD\"}, {\"value\", 42.99} };\n\n            // instead, you could also write (which looks very similar to the JSON above)\n            json j2 =\n            {\n                {\"pi\", 3.141},\n                {\"happy\", true},\n                {\"name\", \"Niels\"},\n                {\"nothing\", nullptr},\n                {\n                    \"answer\", {\n                        {\"everything\", 42}\n                    }\n                },\n                {\"list\", {1, 0, 2}},\n                {\n                    \"object\", {\n                        {\"currency\", \"USD\"},\n                        {\"value\", 42.99}\n                    }\n                }\n            };\n        }\n\n        {\n            // ways to express the empty array []\n            json empty_array_implicit = {{}};\n            CHECK(empty_array_implicit.is_array());\n            json empty_array_explicit = json::array();\n            CHECK(empty_array_explicit.is_array());\n\n            // a way to express the empty object {}\n            json empty_object_explicit = json::object();\n            CHECK(empty_object_explicit.is_object());\n\n            // a way to express an _array_ of key/value pairs [[\"currency\", \"USD\"], [\"value\", 42.99]]\n            json array_not_object = json::array({ {\"currency\", \"USD\"}, {\"value\", 42.99} });\n            CHECK(array_not_object.is_array());\n            CHECK(array_not_object.size() == 2);\n            CHECK(array_not_object[0].is_array());\n            CHECK(array_not_object[1].is_array());\n        }\n\n        {\n            // create object from string literal\n            json j = \"{ \\\"happy\\\": true, \\\"pi\\\": 3.141 }\"_json; // NOLINT(modernize-raw-string-literal)\n\n            // or even nicer with a raw string literal\n            auto j2 = R\"(\n          {\n            \"happy\": true,\n            \"pi\": 3.141\n          }\n        )\"_json;\n\n            // or explicitly\n            auto j3 = json::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\n\n            // explicit conversion to string\n            std::string s = j.dump();    // {\\\"happy\\\":true,\\\"pi\\\":3.141}\n\n            // serialization with pretty printing\n            // pass in the amount of spaces to indent\n            std::cout << j.dump(4) << std::endl;\n            // {\n            //     \"happy\": true,\n            //     \"pi\": 3.141\n            // }\n\n            std::cout << std::setw(2) << j << std::endl;\n        }\n\n        {\n            // create an array using push_back\n            json j;\n            j.push_back(\"foo\");\n            j.push_back(1);\n            j.push_back(true);\n\n            // comparison\n            bool x = (j == R\"([\"foo\", 1, true])\"_json);  // true\n            CHECK(x == true);\n\n            // iterate the array\n            for (json::iterator it = j.begin(); it != j.end(); ++it) // NOLINT(modernize-loop-convert)\n            {\n                std::cout << *it << '\\n';\n            }\n\n            // range-based for\n            for (auto& element : j)\n            {\n                std::cout << element << '\\n';\n            }\n\n            // getter/setter\n            const auto tmp = j[0].get<std::string>();\n            j[1] = 42;\n            bool foo{j.at(2)};\n            CHECK(foo == true);\n\n            // other stuff\n            j.size();     // 3 entries\n            j.empty();    // false\n            j.type();     // json::value_t::array\n            j.clear();    // the array is empty again\n\n            // create an object\n            json o;\n            o[\"foo\"] = 23;\n            o[\"bar\"] = false;\n            o[\"baz\"] = 3.141;\n\n            // find an entry\n            if (o.find(\"foo\") != o.end())\n            {\n                // there is an entry with key \"foo\"\n            }\n        }\n\n        {\n            std::vector<int> c_vector {1, 2, 3, 4};\n            json j_vec(c_vector);\n            // [1, 2, 3, 4]\n\n            std::deque<float> c_deque {1.2f, 2.3f, 3.4f, 5.6f};\n            json j_deque(c_deque);\n            // [1.2, 2.3, 3.4, 5.6]\n\n            std::list<bool> c_list {true, true, false, true};\n            json j_list(c_list);\n            // [true, true, false, true]\n\n            std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};\n            json j_flist(c_flist);\n            // [12345678909876, 23456789098765, 34567890987654, 45678909876543]\n\n            std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};\n            json j_array(c_array);\n            // [1, 2, 3, 4]\n\n            std::set<std::string> c_set {\"one\", \"two\", \"three\", \"four\", \"one\"};\n            json j_set(c_set); // only one entry for \"one\" is used\n            // [\"four\", \"one\", \"three\", \"two\"]\n\n            std::unordered_set<std::string> c_uset {\"one\", \"two\", \"three\", \"four\", \"one\"};\n            json j_uset(c_uset); // only one entry for \"one\" is used\n            // maybe [\"two\", \"three\", \"four\", \"one\"]\n\n            std::multiset<std::string> c_mset {\"one\", \"two\", \"one\", \"four\"};\n            json j_mset(c_mset); // both entries for \"one\" are used\n            // maybe [\"one\", \"two\", \"one\", \"four\"]\n\n            std::unordered_multiset<std::string> c_umset {\"one\", \"two\", \"one\", \"four\"};\n            json j_umset(c_umset); // both entries for \"one\" are used\n            // maybe [\"one\", \"two\", \"one\", \"four\"]\n        }\n\n        {\n            std::map<std::string, int> c_map { {\"one\", 1}, {\"two\", 2}, {\"three\", 3} };\n            json j_map(c_map);\n            // {\"one\": 1, \"two\": 2, \"three\": 3}\n\n            std::unordered_map<const char*, float> c_umap { {\"one\", 1.2f}, {\"two\", 2.3f}, {\"three\", 3.4f} };\n            json j_umap(c_umap);\n            // {\"one\": 1.2, \"two\": 2.3, \"three\": 3.4}\n\n            std::multimap<std::string, bool> c_mmap { {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true} };\n            json j_mmap(c_mmap); // only one entry for key \"three\" is used\n            // maybe {\"one\": true, \"two\": true, \"three\": true}\n\n            std::unordered_multimap<std::string, bool> c_ummap { {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true} };\n            json j_ummap(c_ummap); // only one entry for key \"three\" is used\n            // maybe {\"one\": true, \"two\": true, \"three\": true}\n        }\n\n        {\n            // strings\n            std::string s1 = \"Hello, world!\";\n            json js = s1;\n            auto s2 = js.get<std::string>();\n\n            // Booleans\n            bool b1 = true;\n            json jb = b1;\n            bool b2{jb};\n            CHECK(b2 == true);\n\n            // numbers\n            int i = 42;\n            json jn = i;\n            double f{jn};\n            CHECK(f == 42);\n\n            // etc.\n\n            std::string vs = js.get<std::string>();\n            bool vb = jb.get<bool>();\n            CHECK(vb == true);\n            int vi = jn.get<int>();\n            CHECK(vi == 42);\n\n            // etc.\n        }\n\n        {\n            // a JSON value\n            json j_original = R\"({\n          \"baz\": [\"one\", \"two\", \"three\"],\n          \"foo\": \"bar\"\n        })\"_json;\n\n            // access members with a JSON pointer (RFC 6901)\n            j_original[\"/baz/1\"_json_pointer];\n            // \"two\"\n\n            // a JSON patch (RFC 6902)\n            json j_patch = R\"([\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ])\"_json;\n\n            // apply the patch\n            json j_result = j_original.patch(j_patch);\n            // {\n            //    \"baz\": \"boo\",\n            //    \"hello\": [\"world\"]\n            // }\n\n            // calculate a JSON patch from two JSON values\n            auto res = json::diff(j_result, j_original);\n            // [\n            //   { \"op\":\" replace\", \"path\": \"/baz\", \"value\": [\"one\", \"two\", \"three\"] },\n            //   { \"op\":\"remove\",\"path\":\"/hello\" },\n            //   { \"op\":\"add\",\"path\":\"/foo\",\"value\":\"bar\" }\n            // ]\n        }\n\n        // restore old std::cout\n        std::cout.rdbuf(old_cout_buffer);\n    }\n}\n\nDOCTEST_MSVC_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-reference_access.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nTEST_CASE(\"reference access\")\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    SECTION(\"reference access to object_t\")\n    {\n        using test_type = json::object_t;\n        json value = {{\"one\", 1}, {\"two\", 2}};\n\n        // check if references are returned correctly\n        auto& p1 = value.get_ref<test_type&>();\n        CHECK(&p1 == value.get_ptr<test_type*>());\n        CHECK(p1 == value.get<test_type>());\n\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n\n        // check if mismatching references throw correctly\n        CHECK_NOTHROW(value.get_ref<json::object_t&>());\n        CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\");\n        CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\");\n        CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\");\n        CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\");\n        CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\");\n        CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\");\n    }\n\n    SECTION(\"const reference access to const object_t\")\n    {\n        using test_type = json::object_t;\n        const json value = {{\"one\", 1}, {\"two\", 2}};\n\n        // this should not compile\n        // test_type& p1 = value.get_ref<test_type&>();\n\n        // check if references are returned correctly\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n    }\n\n    SECTION(\"reference access to array_t\")\n    {\n        using test_type = json::array_t;\n        json value = {1, 2, 3, 4};\n\n        // check if references are returned correctly\n        auto& p1 = value.get_ref<test_type&>();\n        CHECK(&p1 == value.get_ptr<test_type*>());\n        CHECK(p1 == value.get<test_type>());\n\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n\n        // check if mismatching references throw correctly\n        CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array\");\n        CHECK_NOTHROW(value.get_ref<json::array_t&>());\n        CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array\");\n        CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array\");\n        CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array\");\n        CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array\");\n        CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array\");\n    }\n\n    SECTION(\"reference access to string_t\")\n    {\n        using test_type = json::string_t;\n        json value = \"hello\";\n\n        // check if references are returned correctly\n        auto& p1 = value.get_ref<test_type&>();\n        CHECK(&p1 == value.get_ptr<test_type*>());\n        CHECK(p1 == value.get<test_type>());\n\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n\n        // check if mismatching references throw correctly\n        CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string\");\n        CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string\");\n        CHECK_NOTHROW(value.get_ref<json::string_t&>());\n        CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string\");\n        CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string\");\n        CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string\");\n        CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string\");\n    }\n\n    SECTION(\"reference access to boolean_t\")\n    {\n        using test_type = json::boolean_t;\n        json value = false;\n\n        // check if references are returned correctly\n        auto& p1 = value.get_ref<test_type&>();\n        CHECK(&p1 == value.get_ptr<test_type*>());\n        CHECK(p1 == value.get<test_type>());\n\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n\n        // check if mismatching references throw correctly\n        CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean\");\n        CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean\");\n        CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean\");\n        CHECK_NOTHROW(value.get_ref<json::boolean_t&>());\n        CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean\");\n        CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean\");\n        CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean\");\n    }\n\n    SECTION(\"reference access to number_integer_t\")\n    {\n        using test_type = json::number_integer_t;\n        json value = -23;\n\n        // check if references are returned correctly\n        auto& p1 = value.get_ref<test_type&>();\n        CHECK(&p1 == value.get_ptr<test_type*>());\n        CHECK(p1 == value.get<test_type>());\n\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n\n        // check if mismatching references throw correctly\n        CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_NOTHROW(value.get_ref<json::number_integer_t&>());\n        CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n    }\n\n    SECTION(\"reference access to number_unsigned_t\")\n    {\n        using test_type = json::number_unsigned_t;\n        json value = 23u;\n\n        // check if references are returned correctly\n        auto& p1 = value.get_ref<test_type&>();\n        CHECK(&p1 == value.get_ptr<test_type*>());\n        CHECK(p1 == value.get<test_type>());\n\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n\n        // check if mismatching references throw correctly\n        CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        //CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);\n        //CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),\n        //    \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>());\n        CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n    }\n\n    SECTION(\"reference access to number_float_t\")\n    {\n        using test_type = json::number_float_t;\n        json value = 42.23;\n\n        // check if references are returned correctly\n        auto& p1 = value.get_ref<test_type&>();\n        CHECK(&p1 == value.get_ptr<test_type*>());\n        CHECK(p1 == value.get<test_type>());\n\n        const auto& p2 = value.get_ref<const test_type&>();\n        CHECK(&p2 == value.get_ptr<const test_type*>());\n        CHECK(p2 == value.get<test_type>());\n\n        // check if mismatching references throw correctly\n        CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);\n        CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),\n                          \"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\");\n        CHECK_NOTHROW(value.get_ref<json::number_float_t&>());\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-regression1.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// for some reason including this after the json header leads to linker errors with VS 2017...\n#include <locale>\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <list>\n#include <cstdio>\n#include <test_data.hpp>\n\n#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464\n    #define JSON_HAS_CPP_17\n#endif\n\n#ifdef JSON_HAS_CPP_17\n    #include <variant>\n#endif\n\n#include \"fifo_map.hpp\"\n\n/////////////////////////////////////////////////////////////////////\n// for #972\n/////////////////////////////////////////////////////////////////////\n\ntemplate<class K, class V, class dummy_compare, class A>\nusing my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;\nusing my_json = nlohmann::basic_json<my_workaround_fifo_map>;\n\n/////////////////////////////////////////////////////////////////////\n// for #977\n/////////////////////////////////////////////////////////////////////\n\nnamespace ns\n{\nstruct foo\n{\n    int x;\n};\n\ntemplate <typename, typename SFINAE = void>\nstruct foo_serializer;\n\ntemplate<typename T>\nstruct foo_serializer<T, typename std::enable_if<std::is_same<foo, T>::value>::type>\n{\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value)\n    {\n        j = BasicJsonType{{\"x\", value.x}};\n    }\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value)     // !!!\n    {\n        nlohmann::from_json(j.at(\"x\"), value.x);\n    }\n};\n\ntemplate<typename T>\nstruct foo_serializer < T, typename std::enable_if < !std::is_same<foo, T>::value >::type >\n{\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) noexcept // NOLINT(bugprone-exception-escape)\n    {\n        ::nlohmann::to_json(j, value);\n    }\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value)   //!!!\n    {\n        ::nlohmann::from_json(j, value);\n    }\n};\n} // namespace ns\n\nusing foo_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,\n      std::uint64_t, double, std::allocator, ns::foo_serializer, std::vector<std::uint8_t>>;\n\n/////////////////////////////////////////////////////////////////////\n// for #805\n/////////////////////////////////////////////////////////////////////\n\nnamespace\n{\nstruct nocopy // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)\n{\n    nocopy() = default;\n    nocopy(const nocopy&) = delete;\n    nocopy(nocopy&&) = delete;\n    nocopy& operator=(const nocopy&) = delete;\n    nocopy& operator=(nocopy&&) = delete;\n\n    int val = 0;\n\n    friend void to_json(json& j, const nocopy& n)\n    {\n        j = {{\"val\", n.val}};\n    }\n};\n} // namespace\n\nTEST_CASE(\"regression tests 1\")\n{\n    SECTION(\"issue #60 - Double quotation mark is not parsed correctly\")\n    {\n        SECTION(\"escape_doublequote\")\n        {\n            const auto* s = R\"([\"\\\"foo\\\"\"])\";\n            json j = json::parse(s);\n            auto expected = R\"([\"\\\"foo\\\"\"])\"_json;\n            CHECK(j == expected);\n        }\n    }\n\n    SECTION(\"issue #70 - Handle infinity and NaN cases\")\n    {\n        // previously, NAN/INFINITY created a null value; now, the values are\n        // properly stored, but are dumped as \"null\"\n        SECTION(\"NAN value\")\n        {\n            CHECK(json(NAN).dump() == \"null\");\n            CHECK(json(json::number_float_t(NAN)).dump() == \"null\");\n        }\n\n        SECTION(\"infinity\")\n        {\n            CHECK(json(INFINITY).dump() == \"null\");\n            CHECK(json(json::number_float_t(INFINITY)).dump() == \"null\");\n        }\n\n        // With 3.0.0, the semantics of this changed: NAN and infinity are\n        // stored properly inside the JSON value (no exception or conversion\n        // to null), but are serialized as null.\n        SECTION(\"NAN value\")\n        {\n            json j1 = NAN;\n            CHECK(j1.is_number_float());\n            json::number_float_t f1{j1};\n            CHECK(std::isnan(f1));\n\n            json j2 = static_cast<json::number_float_t>(NAN);\n            CHECK(j2.is_number_float());\n            json::number_float_t f2{j2};\n            CHECK(std::isnan(f2));\n        }\n\n        SECTION(\"infinity\")\n        {\n            json j1 = INFINITY;\n            CHECK(j1.is_number_float());\n            json::number_float_t f1{j1};\n            CHECK(!std::isfinite(f1));\n\n            json j2 = static_cast<json::number_float_t>(INFINITY);\n            CHECK(j2.is_number_float());\n            json::number_float_t f2{j2};\n            CHECK(!std::isfinite(f2));\n        }\n    }\n\n    SECTION(\"pull request #71 - handle enum type\")\n    {\n        enum { t = 0, u = 102};\n        json j = json::array();\n        j.push_back(t);\n\n        // maybe this is not the place to test this?\n        json j2 = u;\n\n        auto anon_enum_value = j2.get<decltype(u)>();\n        CHECK(u == anon_enum_value);\n\n        // check if the actual value was stored\n        CHECK(j2 == 102);\n\n        static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, \"types must be the same\");\n\n        j.push_back(json::object(\n        {\n            {\"game_type\", t}\n        }));\n    }\n\n    SECTION(\"issue #76 - dump() / parse() not idempotent\")\n    {\n        // create JSON object\n        json fields;\n        fields[\"one\"] = std::string(\"one\");\n        fields[\"two\"] = std::string(\"two three\");\n        fields[\"three\"] = std::string(\"three \\\"four\\\"\");\n\n        // create another JSON object by deserializing the serialization\n        std::string payload = fields.dump();\n        json parsed_fields = json::parse(payload);\n\n        // check individual fields to match both objects\n        CHECK(parsed_fields[\"one\"] == fields[\"one\"]);\n        CHECK(parsed_fields[\"two\"] == fields[\"two\"]);\n        CHECK(parsed_fields[\"three\"] == fields[\"three\"]);\n\n        // check individual fields to match original input\n        CHECK(parsed_fields[\"one\"] == std::string(\"one\"));\n        CHECK(parsed_fields[\"two\"] == std::string(\"two three\"));\n        CHECK(parsed_fields[\"three\"] == std::string(\"three \\\"four\\\"\"));\n\n        // check equality of the objects\n        CHECK(parsed_fields == fields);\n\n        // check equality of the serialized objects\n        CHECK(fields.dump() == parsed_fields.dump());\n\n        // check everything in one line\n        CHECK(fields == json::parse(fields.dump()));\n    }\n\n    SECTION(\"issue #82 - lexer::get_number return NAN\")\n    {\n        const auto* const content = R\"(\n        {\n            \"Test\":\"Test1\",\n            \"Number\":100,\n            \"Foo\":42.42\n        })\";\n\n        std::stringstream ss;\n        ss << content;\n        json j;\n        ss >> j;\n\n        auto test = j[\"Test\"].get<std::string>();\n        CHECK(test == \"Test1\");\n        int number{j[\"Number\"]};\n        CHECK(number == 100);\n        float foo{j[\"Foo\"]};\n        CHECK(static_cast<double>(foo) == Approx(42.42));\n    }\n\n    SECTION(\"issue #89 - nonstandard integer type\")\n    {\n        // create JSON class with nonstandard integer number type\n        using custom_json =\n            nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float>;\n        custom_json j;\n        j[\"int_1\"] = 1;\n        CHECK(j[\"int_1\"] == 1);\n\n        // tests for correct handling of non-standard integers that overflow the type selected by the user\n\n        // unsigned integer object creation - expected to wrap and still be stored as an integer\n        j = 4294967296U; // 2^32\n        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_unsigned));\n        CHECK(j.get<uint32_t>() == 0);  // Wrap\n\n        // unsigned integer parsing - expected to overflow and be stored as a float\n        j = custom_json::parse(\"4294967296\"); // 2^32\n        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));\n        CHECK(j.get<float>() == 4294967296.0f);\n\n        // integer object creation - expected to wrap and still be stored as an integer\n        j = -2147483649LL; // -2^31-1\n        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_integer));\n        CHECK(j.get<int32_t>() == 2147483647);  // Wrap\n\n        // integer parsing - expected to overflow and be stored as a float with rounding\n        j = custom_json::parse(\"-2147483649\"); // -2^31\n        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));\n        CHECK(j.get<float>() == -2147483650.0f);\n    }\n\n    SECTION(\"issue #93 reverse_iterator operator inheritance problem\")\n    {\n        {\n            json a = {1, 2, 3};\n            json::reverse_iterator rit = a.rbegin();\n            ++rit;\n            CHECK(*rit == json(2));\n            CHECK(rit.value() == json(2));\n        }\n        {\n            json a = {1, 2, 3};\n            json::reverse_iterator rit = ++a.rbegin();\n            CHECK(*rit == json(2));\n            CHECK(rit.value() == json(2));\n        }\n        {\n            json a = {1, 2, 3};\n            json::reverse_iterator rit = a.rbegin();\n            ++rit;\n            json b = {0, 0, 0};\n            std::transform(rit, a.rend(), b.rbegin(), [](json el)\n            {\n                return el;\n            });\n            CHECK(b == json({0, 1, 2}));\n        }\n        {\n            json a = {1, 2, 3};\n            json b = {0, 0, 0};\n            std::transform(++a.rbegin(), a.rend(), b.rbegin(), [](json el)\n            {\n                return el;\n            });\n            CHECK(b == json({0, 1, 2}));\n        }\n    }\n\n    SECTION(\"issue #100 - failed to iterator json object with reverse_iterator\")\n    {\n        json config =\n        {\n            { \"111\", 111 },\n            { \"112\", 112 },\n            { \"113\", 113 }\n        };\n\n        std::stringstream ss;\n\n        for (auto it = config.begin(); it != config.end(); ++it)\n        {\n            ss << it.key() << \": \" << it.value() << '\\n';\n        }\n\n        for (auto it = config.rbegin(); it != config.rend(); ++it)\n        {\n            ss << it.key() << \": \" << it.value() << '\\n';\n        }\n\n        CHECK(ss.str() == \"111: 111\\n112: 112\\n113: 113\\n113: 113\\n112: 112\\n111: 111\\n\");\n    }\n\n    SECTION(\"issue #101 - binary string causes numbers to be dumped as hex\")\n    {\n        int64_t number = 10;\n        std::string bytes{\"\\x00\" \"asdf\\n\", 6};\n        json j;\n        j[\"int64\"] = number;\n        j[\"binary string\"] = bytes;\n        // make sure the number is really printed as decimal \"10\" and not as\n        // hexadecimal \"a\"\n        CHECK(j.dump() == \"{\\\"binary string\\\":\\\"\\\\u0000asdf\\\\n\\\",\\\"int64\\\":10}\");\n    }\n\n    SECTION(\"issue #111 - subsequent unicode chars\")\n    {\n        std::string bytes{0x7, 0x7};\n        json j;\n        j[\"string\"] = bytes;\n        CHECK(j[\"string\"] == \"\\u0007\\u0007\");\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"issue #144 - implicit assignment to std::string fails\")\n    {\n        json o = {{\"name\", \"value\"}};\n\n        std::string s1 = o[\"name\"];\n        CHECK(s1 == \"value\");\n\n        std::string s2;\n        s2 = o[\"name\"];\n\n        CHECK(s2 == \"value\");\n\n        // improve coverage\n        o[\"int\"] = 1;\n        CHECK_THROWS_AS(s2 = o[\"int\"], json::type_error);\n#if JSON_DIAGNOSTICS\n        CHECK_THROWS_WITH(s2 = o[\"int\"], \"[json.exception.type_error.302] (/int) type must be string, but is number\");\n#else\n        CHECK_THROWS_WITH(s2 = o[\"int\"], \"[json.exception.type_error.302] type must be string, but is number\");\n#endif\n    }\n#endif\n\n    SECTION(\"issue #146 - character following a surrogate pair is skipped\")\n    {\n        CHECK(json::parse(\"\\\"\\\\ud80c\\\\udc60abc\\\"\").get<json::string_t>() == \"\\xf0\\x93\\x81\\xa0\\x61\\x62\\x63\");\n    }\n\n    SECTION(\"issue #171 - Cannot index by key of type static constexpr const char*\")\n    {\n        json j;\n\n        // Non-const access with key as \"char []\"\n        char array_key[] = \"Key1\"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n        CHECK_NOTHROW(j[array_key] = 1);\n        CHECK(j[array_key] == json(1));\n\n        // Non-const access with key as \"const char[]\"\n        const char const_array_key[] = \"Key2\"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n        CHECK_NOTHROW(j[const_array_key] = 2);\n        CHECK(j[const_array_key] == json(2));\n\n        // Non-const access with key as \"char *\"\n        char _ptr_key[] = \"Key3\"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)\n        char* ptr_key = &_ptr_key[0]; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n        CHECK_NOTHROW(j[ptr_key] = 3);\n        CHECK(j[ptr_key] == json(3));\n\n        // Non-const access with key as \"const char *\"\n        const char* const_ptr_key = \"Key4\";\n        CHECK_NOTHROW(j[const_ptr_key] = 4);\n        CHECK(j[const_ptr_key] == json(4));\n\n        // Non-const access with key as \"static constexpr const char *\"\n        static constexpr const char* constexpr_ptr_key = \"Key5\";\n        CHECK_NOTHROW(j[constexpr_ptr_key] = 5);\n        CHECK(j[constexpr_ptr_key] == json(5));\n\n        const json j_const = j;\n\n        // Const access with key as \"char []\"\n        CHECK(j_const[array_key] == json(1));\n\n        // Const access with key as \"const char[]\"\n        CHECK(j_const[const_array_key] == json(2));\n\n        // Const access with key as \"char *\"\n        CHECK(j_const[ptr_key] == json(3));\n\n        // Const access with key as \"const char *\"\n        CHECK(j_const[const_ptr_key] == json(4));\n\n        // Const access with key as \"static constexpr const char *\"\n        CHECK(j_const[constexpr_ptr_key] == json(5));\n    }\n\n    SECTION(\"issue #186 miloyip/nativejson-benchmark: floating-point parsing\")\n    {\n        json j;\n\n        j = json::parse(\"-0.0\");\n        CHECK(j.get<double>() == -0.0);\n\n        j = json::parse(\"2.22507385850720113605740979670913197593481954635164564e-308\");\n        CHECK(j.get<double>() == 2.2250738585072009e-308);\n\n        j = json::parse(\"0.999999999999999944488848768742172978818416595458984374\");\n        CHECK(j.get<double>() == 0.99999999999999989);\n\n        j = json::parse(\"1.00000000000000011102230246251565404236316680908203126\");\n        CHECK(j.get<double>() == 1.00000000000000022);\n\n        j = json::parse(\"7205759403792793199999e-5\");\n        CHECK(j.get<double>() == 72057594037927928.0);\n\n        j = json::parse(\"922337203685477529599999e-5\");\n        CHECK(j.get<double>() == 9223372036854774784.0);\n\n        j = json::parse(\"1014120480182583464902367222169599999e-5\");\n        CHECK(j.get<double>() == 10141204801825834086073718800384.0);\n\n        j = json::parse(\"5708990770823839207320493820740630171355185151999e-3\");\n        CHECK(j.get<double>() == 5708990770823838890407843763683279797179383808.0);\n\n        // create JSON class with nonstandard float number type\n\n        // float\n        nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float> j_float =\n            1.23e25f;\n        CHECK(j_float.get<float>() == 1.23e25f);\n\n        // double\n        nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double> j_double =\n            1.23e35;\n        CHECK(j_double.get<double>() == 1.23e35);\n\n        // long double\n        nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, long double>\n        j_long_double = 1.23e45L;\n        CHECK(j_long_double.get<long double>() == 1.23e45L);\n    }\n\n    SECTION(\"issue #228 - double values are serialized with commas as decimal points\")\n    {\n        json j1a = 2312.42;\n        json j1b = json::parse(\"2312.42\");\n\n        json j2a = 2342e-2;\n        //issue #230\n        //json j2b = json::parse(\"2342e-2\");\n\n        json j3a = 10E3;\n        json j3b = json::parse(\"10E3\");\n        json j3c = json::parse(\"10e3\");\n\n        // class to create a locale that would use a comma for decimals\n        class CommaDecimalSeparator : public std::numpunct<char>\n        {\n          protected:\n            char do_decimal_point() const override\n            {\n                return ',';\n            }\n\n            char do_thousands_sep() const override\n            {\n                return '.';\n            }\n\n            std::string do_grouping() const override\n            {\n                return \"\\03\";\n            }\n        };\n\n        // change locale to mess with decimal points\n        auto orig_locale = std::locale::global(std::locale(std::locale(), new CommaDecimalSeparator));\n\n        CHECK(j1a.dump() == \"2312.42\");\n        CHECK(j1b.dump() == \"2312.42\");\n\n        // check if locale is properly reset\n        std::stringstream ss;\n        ss.imbue(std::locale(std::locale(), new CommaDecimalSeparator));\n        ss << 4712.11;\n        CHECK(ss.str() == \"4.712,11\");\n        ss << j1a;\n        CHECK(ss.str() == \"4.712,112312.42\");\n        ss << 47.11;\n        CHECK(ss.str() == \"4.712,112312.4247,11\");\n\n        CHECK(j2a.dump() == \"23.42\");\n        //issue #230\n        //CHECK(j2b.dump() == \"23.42\");\n\n        CHECK(j3a.dump() == \"10000.0\");\n        CHECK(j3b.dump() == \"10000.0\");\n        CHECK(j3c.dump() == \"10000.0\");\n        //CHECK(j3b.dump() == \"1E04\"); // roundtrip error\n        //CHECK(j3c.dump() == \"1e04\"); // roundtrip error\n\n        std::locale::global(orig_locale);\n    }\n\n    SECTION(\"issue #378 - locale-independent num-to-str\")\n    {\n        static_cast<void>(setlocale(LC_NUMERIC, \"de_DE.UTF-8\"));\n\n        // verify that dumped correctly with '.' and no grouping\n        const json j1 = 12345.67;\n        CHECK(json(12345.67).dump() == \"12345.67\");\n        static_cast<void>(setlocale(LC_NUMERIC, \"C\"));\n    }\n\n    SECTION(\"issue #379 - locale-independent str-to-num\")\n    {\n        static_cast<void>(setlocale(LC_NUMERIC, \"de_DE.UTF-8\"));\n\n        // verify that parsed correctly despite using strtod internally\n        CHECK(json::parse(\"3.14\").get<double>() == 3.14);\n\n        // check a different code path\n        CHECK(json::parse(\"1.000000000000000000000000000000000000000000000000000000000000000000000000\").get<double>() == 1.0);\n    }\n\n    SECTION(\"issue #233 - Can't use basic_json::iterator as a base iterator for std::move_iterator\")\n    {\n        json source = {\"a\", \"b\", \"c\"};\n        json expected = {\"a\", \"b\"};\n        json dest;\n\n        std::copy_n(std::make_move_iterator(source.begin()), 2, std::back_inserter(dest));\n\n        CHECK(dest == expected);\n    }\n\n    SECTION(\"issue #235 - ambiguous overload for 'push_back' and 'operator+='\")\n    {\n        json data = {{\"key\", \"value\"}};\n        data.push_back({\"key2\", \"value2\"});\n        data += {\"key3\", \"value3\"};\n\n        CHECK(data == json({{\"key\", \"value\"}, {\"key2\", \"value2\"}, {\"key3\", \"value3\"}}));\n    }\n\n    SECTION(\"issue #269 - diff generates incorrect patch when removing multiple array elements\")\n    {\n        json doc = R\"( { \"arr1\": [1, 2, 3, 4] } )\"_json;\n        json expected = R\"( { \"arr1\": [1, 2] } )\"_json;\n\n        // check roundtrip\n        CHECK(doc.patch(json::diff(doc, expected)) == expected);\n    }\n\n    SECTION(\"issue #283 - value() does not work with _json_pointer types\")\n    {\n        json j =\n        {\n            {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        };\n\n        int at_integer{j.at(\"/object/key2\"_json_pointer)};\n        int val_integer = j.value(\"/object/key2\"_json_pointer, 0);\n\n        CHECK(at_integer == val_integer);\n    }\n\n    SECTION(\"issue #304 - Unused variable warning\")\n    {\n        // code triggered a \"warning: unused variable\" warning and is left\n        // here to avoid the warning in the future\n        json object;\n        json patch = json::array();\n        object = object.patch(patch);\n    }\n\n    SECTION(\"issue #306 - Parsing fails without space at end of file\")\n    {\n        for (const auto* filename :\n                {\n                    TEST_DATA_DIRECTORY \"/regression/broken_file.json\",\n                    TEST_DATA_DIRECTORY \"/regression/working_file.json\"\n                })\n        {\n            CAPTURE(filename)\n            json j;\n            std::ifstream f(filename);\n            CHECK_NOTHROW(f >> j);\n        }\n    }\n\n    SECTION(\"issue #310 - make json_benchmarks no longer working in 2.0.4\")\n    {\n        for (const auto* filename :\n                {\n                    TEST_DATA_DIRECTORY \"/regression/floats.json\",\n                    TEST_DATA_DIRECTORY \"/regression/signed_ints.json\",\n                    TEST_DATA_DIRECTORY \"/regression/unsigned_ints.json\",\n                    TEST_DATA_DIRECTORY \"/regression/small_signed_ints.json\"\n                })\n        {\n            CAPTURE(filename)\n            json j;\n            std::ifstream f(filename);\n            CHECK_NOTHROW(f >> j);\n        }\n    }\n\n    SECTION(\"issue #323 - add nested object capabilities to pointers\")\n    {\n        json j;\n        j[\"/this/that/2\"_json_pointer] = 27;\n        CHECK(j == json({{\"this\", {{\"that\", {nullptr, nullptr, 27}}}}}));\n    }\n\n    SECTION(\"issue #329 - serialized value not always can be parsed\")\n    {\n        json _;\n        CHECK_THROWS_AS(_ = json::parse(\"22e2222\"), json::out_of_range&);\n        CHECK_THROWS_WITH(_ = json::parse(\"22e2222\"),\n                          \"[json.exception.out_of_range.406] number overflow parsing '22e2222'\");\n    }\n\n    SECTION(\"issue #360 - Loss of precision when serializing <double>\")\n    {\n        auto check_roundtrip = [](double number)\n        {\n            CAPTURE(number)\n\n            json j = number;\n            CHECK(j.is_number_float());\n\n            std::stringstream ss;\n            ss << j;\n\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j.is_number_float());\n            CHECK(j.get<json::number_float_t>() == number);\n        };\n\n        check_roundtrip(100000000000.1236);\n        check_roundtrip((std::numeric_limits<json::number_float_t>::max)());\n\n        // Some more numbers which fail to roundtrip when serialized with digits10 significand digits (instead of max_digits10)\n        check_roundtrip(1.541888611948064e-17);\n        check_roundtrip(5.418771028591015e-16);\n        check_roundtrip(9.398685592608595e-15);\n        check_roundtrip(8.826843952762347e-14);\n        check_roundtrip(8.143291313475335e-13);\n        check_roundtrip(4.851328172762508e-12);\n        check_roundtrip(6.677850998084358e-11);\n        check_roundtrip(3.995398518174525e-10);\n        check_roundtrip(1.960452605645124e-9);\n        check_roundtrip(3.551812586302883e-8);\n        check_roundtrip(2.947988411689261e-7);\n        check_roundtrip(8.210166748056192e-6);\n        check_roundtrip(6.104889704266753e-5);\n        check_roundtrip(0.0008629954631330876);\n        check_roundtrip(0.004936993881051611);\n        check_roundtrip(0.08309725102608073);\n        check_roundtrip(0.5210494268499783);\n        check_roundtrip(6.382927930939767);\n        check_roundtrip(59.94947245358671);\n        check_roundtrip(361.0838651266122);\n        check_roundtrip(4678.354596181877);\n        check_roundtrip(61412.17658956043);\n        check_roundtrip(725696.0799057782);\n        check_roundtrip(2811732.583399828);\n        check_roundtrip(30178351.07533605);\n        check_roundtrip(689684880.3235844);\n        check_roundtrip(5714887673.555147);\n        check_roundtrip(84652038821.18808);\n        check_roundtrip(156510583431.7721);\n        check_roundtrip(5938450569021.732);\n        check_roundtrip(83623297654460.33);\n        check_roundtrip(701466573254773.6);\n        check_roundtrip(1369013370304513);\n        check_roundtrip(96963648023094720); // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)\n        check_roundtrip(3.478237409280108e+17);\n    }\n\n    SECTION(\"issue #366 - json::parse on failed stream gets stuck\")\n    {\n        std::ifstream f(\"file_not_found.json\");\n        json _;\n        CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::parse(f), \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n    }\n\n    SECTION(\"issue #367 - calling stream at EOF\")\n    {\n        std::stringstream ss;\n        json j;\n        ss << \"123\";\n        CHECK_NOTHROW(ss >> j);\n\n        // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893:\n        // ss is not at EOF; this yielded an error before the fix\n        // (threw basic_string::append). No, it should just throw\n        // a parse error because of the EOF.\n        CHECK_THROWS_AS(ss >> j, json::parse_error&);\n        CHECK_THROWS_WITH(ss >> j,\n                          \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n    }\n\n    SECTION(\"issue #367 - behavior of operator>> should more closely resemble that of built-in overloads\")\n    {\n        SECTION(\"(empty)\")\n        {\n            std::stringstream ss;\n            json j;\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"(whitespace)\")\n        {\n            std::stringstream ss;\n            ss << \"   \";\n            json j;\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"one value\")\n        {\n            std::stringstream ss;\n            ss << \"111\";\n            json j;\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == 111);\n\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"one value + whitespace\")\n        {\n            std::stringstream ss;\n            ss << \"222 \\t\\n\";\n            json j;\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == 222);\n\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"whitespace + one value\")\n        {\n            std::stringstream ss;\n            ss << \"\\n\\t 333\";\n            json j;\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == 333);\n\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"three values\")\n        {\n            std::stringstream ss;\n            ss << \" 111 \\n222\\n \\n  333\";\n            json j;\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == 111);\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == 222);\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == 333);\n\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"literals without whitespace\")\n        {\n            std::stringstream ss;\n            ss << \"truefalsenull\\\"\\\"\";\n            json j;\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == true);\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == false);\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == nullptr);\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == \"\");\n\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"example from #529\")\n        {\n            std::stringstream ss;\n            ss << \"{\\n    \\\"one\\\"   : 1,\\n    \\\"two\\\"   : 2\\n}\\n{\\n    \\\"three\\\" : 3\\n}\";\n            json j;\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == json({{\"one\", 1}, {\"two\", 2}}));\n            CHECK_NOTHROW(ss >> j);\n            CHECK(j == json({{\"three\", 3}}));\n\n            CHECK_THROWS_AS(ss >> j, json::parse_error&);\n            CHECK_THROWS_WITH(ss >> j,\n                              \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal\");\n        }\n\n        SECTION(\"second example from #529\")\n        {\n            std::string str = \"{\\n\\\"one\\\"   : 1,\\n\\\"two\\\"   : 2\\n}\\n{\\n\\\"three\\\" : 3\\n}\";\n\n            {\n                std::ofstream file(\"test.json\");\n                file << str;\n            }\n\n            std::ifstream stream(\"test.json\", std::ifstream::in);\n            json val;\n\n            size_t i = 0;\n            while (stream.peek() != EOF)\n            {\n                CAPTURE(i)\n                CHECK_NOTHROW(stream >> val);\n\n                CHECK(i < 2);\n\n                if (i == 0)\n                {\n                    CHECK(val == json({{\"one\", 1}, {\"two\", 2}}));\n                }\n\n                if (i == 1)\n                {\n                    CHECK(val == json({{\"three\", 3}}));\n                }\n\n                ++i;\n            }\n\n            static_cast<void>(std::remove(\"test.json\"));\n        }\n    }\n\n    SECTION(\"issue #389 - Integer-overflow (OSS-Fuzz issue 267)\")\n    {\n        // original test case\n        json j1 = json::parse(\"-9223372036854775808\");\n        CHECK(j1.is_number_integer());\n        CHECK(j1.get<json::number_integer_t>() == INT64_MIN);\n\n        // edge case (+1; still an integer)\n        json j2 = json::parse(\"-9223372036854775807\");\n        CHECK(j2.is_number_integer());\n        CHECK(j2.get<json::number_integer_t>() == INT64_MIN + 1);\n\n        // edge case (-1; overflow -> floats)\n        json j3 = json::parse(\"-9223372036854775809\");\n        CHECK(j3.is_number_float());\n    }\n\n    SECTION(\"issue #380 - bug in overflow detection when parsing integers\")\n    {\n        json j = json::parse(\"166020696663385964490\");\n        CHECK(j.is_number_float());\n        CHECK(j.get<json::number_float_t>() == 166020696663385964490.0);\n    }\n\n    SECTION(\"issue #405 - Heap-buffer-overflow (OSS-Fuzz issue 342)\")\n    {\n        // original test case\n        std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};\n        json _;\n        CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec),\n                          \"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input\");\n    }\n\n    SECTION(\"issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)\")\n    {\n        json _;\n\n        // original test case: incomplete float64\n        std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a};\n        CHECK_THROWS_AS(_ = json::from_msgpack(vec1), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_msgpack(vec1),\n                          \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input\");\n\n        // related test case: incomplete float32\n        std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a};\n        CHECK_THROWS_AS(_ = json::from_msgpack(vec2), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_msgpack(vec2),\n                          \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input\");\n\n        // related test case: incomplete Half-Precision Float (CBOR)\n        std::vector<uint8_t> vec3 {0xf9, 0x8f};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec3), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec3),\n                          \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input\");\n\n        // related test case: incomplete Single-Precision Float (CBOR)\n        std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec4), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec4),\n                          \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input\");\n\n        // related test case: incomplete Double-Precision Float (CBOR)\n        std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec5), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec5),\n                          \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input\");\n    }\n\n    SECTION(\"issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)\")\n    {\n        json _;\n\n        // original test case\n        std::vector<uint8_t> vec1 {0x87};\n        CHECK_THROWS_AS(_ = json::from_msgpack(vec1), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_msgpack(vec1),\n                          \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input\");\n\n        // more test cases for MessagePack\n        for (auto b :\n                {\n                    0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, // fixmap\n                    0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, // fixarray\n                    0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // fixstr\n                    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf\n                })\n        {\n            std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));\n            CHECK_THROWS_AS(_ = json::from_msgpack(vec), json::parse_error&);\n        }\n\n        // more test cases for CBOR\n        for (auto b :\n                {\n                    0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n                    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // UTF-8 string\n                    0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\n                    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, // array\n                    0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,\n                    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7 // map\n                })\n        {\n            std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));\n            CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);\n        }\n\n        // special case: empty input\n        std::vector<uint8_t> vec2;\n        CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec2),\n                          \"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input\");\n        CHECK_THROWS_AS(_ = json::from_msgpack(vec2), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_msgpack(vec2),\n                          \"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input\");\n    }\n\n    SECTION(\"issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)\")\n    {\n        json _;\n\n        // original test case: empty UTF-8 string (indefinite length)\n        std::vector<uint8_t> vec1 {0x7f};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec1), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec1),\n                          \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input\");\n\n        // related test case: empty array (indefinite length)\n        std::vector<uint8_t> vec2 {0x9f};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec2),\n                          \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input\");\n\n        // related test case: empty map (indefinite length)\n        std::vector<uint8_t> vec3 {0xbf};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec3), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec3),\n                          \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input\");\n    }\n\n    SECTION(\"issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)\")\n    {\n        // original test case\n        std::vector<uint8_t> vec\n        {\n            0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,\n            0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,\n            0x60, 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,\n            0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xa0, 0x9f,\n            0x9f, 0x97, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,\n            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60\n        };\n\n        json _;\n        CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec),\n                          \"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x98\");\n\n        // related test case: nonempty UTF-8 string (indefinite length)\n        std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec1), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec1),\n                          \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input\");\n\n        // related test case: nonempty array (indefinite length)\n        std::vector<uint8_t> vec2 {0x9f, 0x01};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec2),\n                          \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input\");\n\n        // related test case: nonempty map (indefinite length)\n        std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};\n        CHECK_THROWS_AS(_ = json::from_cbor(vec3), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec3),\n                          \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input\");\n    }\n\n    SECTION(\"issue #414 - compare with literal 0)\")\n    {\n#define CHECK_TYPE(v) \\\n    CHECK((json(v) == (v)));\\\n    CHECK(((v) == json(v)));\\\n    CHECK_FALSE((json(v) != (v)));\\\n    CHECK_FALSE(((v) != json(v)));\n\n        CHECK_TYPE(nullptr)\n        CHECK_TYPE(0)\n        CHECK_TYPE(0u)\n        CHECK_TYPE(0L)\n        CHECK_TYPE(0.0)\n        CHECK_TYPE(\"\") // NOLINT(readability-container-size-empty)\n\n#undef CHECK_TYPE\n    }\n\n    SECTION(\"issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)\")\n    {\n        // original test case\n        std::vector<uint8_t> vec1\n        {\n            0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,\n            0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,\n            0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,\n            0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,\n            0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,\n            0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa\n        };\n\n        json _;\n        CHECK_THROWS_AS(_ = json::from_cbor(vec1), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec1),\n                          \"[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4\");\n\n        // related test case: double-precision\n        std::vector<uint8_t> vec2\n        {\n            0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,\n            0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,\n            0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,\n            0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,\n            0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,\n            0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb\n        };\n        CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);\n        CHECK_THROWS_WITH(_ = json::from_cbor(vec2),\n                          \"[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4\");\n    }\n\n    SECTION(\"issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)\")\n    {\n        std::vector<uint8_t> vec = {'-', '0', '1', '2', '2', '7', '4'};\n        json _;\n        CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);\n    }\n\n    SECTION(\"issue #454 - doubles are printed as integers\")\n    {\n        json j = R\"({\"bool_value\":true,\"double_value\":2.0,\"int_value\":10,\"level1\":{\"list_value\":[3,\"hi\",false],\"tmp\":5.0},\"string_value\":\"hello\"})\"_json;\n        CHECK(j[\"double_value\"].is_number_float());\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"issue #464 - VS2017 implicit to std::string conversion fix\")\n    {\n        json v = \"test\";\n        std::string test;\n        test = v;\n        CHECK(v == \"test\");\n    }\n#endif\n\n    SECTION(\"issue #465 - roundtrip error while parsing 1000000000000000010E5\")\n    {\n        json j1 = json::parse(\"1000000000000000010E5\");\n        std::string s1 = j1.dump();\n        json j2 = json::parse(s1);\n        std::string s2 = j2.dump();\n        CHECK(s1 == s2);\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"issue #473 - inconsistent behavior in conversion to array type\")\n    {\n        json j_array = {1, 2, 3, 4};\n        json j_number = 42;\n        json j_null = nullptr;\n\n        SECTION(\"std::vector\")\n        {\n            auto create = [](const json & j)\n            {\n                std::vector<int> v = j;\n            };\n\n            CHECK_NOTHROW(create(j_array));\n            CHECK_THROWS_AS(create(j_number), json::type_error&);\n            CHECK_THROWS_WITH(create(j_number), \"[json.exception.type_error.302] type must be array, but is number\");\n            CHECK_THROWS_AS(create(j_null), json::type_error&);\n            CHECK_THROWS_WITH(create(j_null), \"[json.exception.type_error.302] type must be array, but is null\");\n        }\n\n        SECTION(\"std::list\")\n        {\n            auto create = [](const json & j)\n            {\n                std::list<int> v = j;\n            };\n\n            CHECK_NOTHROW(create(j_array));\n            CHECK_THROWS_AS(create(j_number), json::type_error&);\n            CHECK_THROWS_WITH(create(j_number), \"[json.exception.type_error.302] type must be array, but is number\");\n            CHECK_THROWS_AS(create(j_null), json::type_error&);\n            CHECK_THROWS_WITH(create(j_null), \"[json.exception.type_error.302] type must be array, but is null\");\n        }\n\n        SECTION(\"std::forward_list\")\n        {\n            auto create = [](const json & j)\n            {\n                std::forward_list<int> v = j;\n            };\n\n            CHECK_NOTHROW(create(j_array));\n            CHECK_THROWS_AS(create(j_number), json::type_error&);\n            CHECK_THROWS_WITH(create(j_number), \"[json.exception.type_error.302] type must be array, but is number\");\n            CHECK_THROWS_AS(create(j_null), json::type_error&);\n            CHECK_THROWS_WITH(create(j_null), \"[json.exception.type_error.302] type must be array, but is null\");\n        }\n    }\n#endif\n\n    SECTION(\"issue #486 - json::value_t can't be a map's key type in VC++ 2015\")\n    {\n        // the code below must compile with MSVC\n        std::map<json::value_t, std::string> jsonTypes ;\n        jsonTypes[json::value_t::array] = \"array\";\n    }\n\n    SECTION(\"issue #494 - conversion from vector<bool> to json fails to build\")\n    {\n        std::vector<bool> boolVector = {false, true, false, false};\n        json j;\n        j[\"bool_vector\"] = boolVector;\n\n        CHECK(j[\"bool_vector\"].dump() == \"[false,true,false,false]\");\n    }\n\n    SECTION(\"issue #504 - assertion error (OSS-Fuzz 856)\")\n    {\n        std::vector<uint8_t> vec1 = {0xf9, 0xff, 0xff, 0x4a, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x37, 0x02, 0x38};\n        json j1 = json::from_cbor(vec1, false);\n\n        // step 2: round trip\n        std::vector<uint8_t> vec2 = json::to_cbor(j1);\n\n        // parse serialization\n        json j2 = json::from_cbor(vec2);\n\n        // NaN is dumped to \"null\"\n        CHECK(j2.is_number_float());\n        CHECK(std::isnan(j2.get<json::number_float_t>()));\n        CHECK(j2.dump() == \"null\");\n\n        // check if serializations match\n        CHECK(json::to_cbor(j2) == vec2);\n    }\n\n    SECTION(\"issue #512 - use of overloaded operator '<=' is ambiguous\")\n    {\n        json j;\n        j[\"a\"] = 5;\n\n        // json op scalar\n        CHECK(j[\"a\"] == 5);\n        CHECK(j[\"a\"] != 4);\n\n        CHECK(j[\"a\"] <= 7);\n        CHECK(j[\"a\"] <  7);\n        CHECK(j[\"a\"] >= 3);\n        CHECK(j[\"a\"] >  3);\n\n\n        CHECK(!(j[\"a\"] <= 4));\n        CHECK(!(j[\"a\"] <  4));\n        CHECK(!(j[\"a\"] >= 6));\n        CHECK(!(j[\"a\"] >  6));\n\n        // scalar op json\n        CHECK(5 == j[\"a\"]);\n        CHECK(4 != j[\"a\"]);\n\n        CHECK(7 >= j[\"a\"]);\n        CHECK(7 >  j[\"a\"]);\n        CHECK(3 <= j[\"a\"]);\n        CHECK(3 <  j[\"a\"]);\n\n        CHECK(!(4 >= j[\"a\"]));\n        CHECK(!(4 >  j[\"a\"]));\n        CHECK(!(6 <= j[\"a\"]));\n        CHECK(!(6 <  j[\"a\"]));\n    }\n\n    SECTION(\"issue #575 - heap-buffer-overflow (OSS-Fuzz 1400)\")\n    {\n        json _;\n        std::vector<uint8_t> vec = {'\"', '\\\\', '\"', 'X', '\"', '\"'};\n        CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"issue #600 - how does one convert a map in Json back to std::map?\")\n    {\n        SECTION(\"example 1\")\n        {\n            // create a map\n            std::map<std::string, int> m1 {{\"key\", 1}};\n\n            // create and print a JSON from the map\n            json j = m1;\n\n            // get the map out of JSON\n            std::map<std::string, int> m2 = j;\n\n            // make sure the roundtrip succeeds\n            CHECK(m1 == m2);\n        }\n\n        SECTION(\"example 2\")\n        {\n            // create a map\n            std::map<std::string, std::string> m1 {{\"key\", \"val\"}};\n\n            // create and print a JSON from the map\n            json j = m1;\n\n            // get the map out of JSON\n            std::map<std::string, std::string> m2 = j;\n\n            // make sure the roundtrip succeeds\n            CHECK(m1 == m2);\n        }\n    }\n#endif\n\n    SECTION(\"issue #602 - BOM not skipped when using json:parse(iterator)\")\n    {\n        std::string i = \"\\xef\\xbb\\xbf{\\n   \\\"foo\\\": true\\n}\";\n        json _;\n        CHECK_NOTHROW(_ = json::parse(i.begin(), i.end()));\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"issue #702 - conversion from valarray<double> to json fails to build\")\n    {\n        SECTION(\"original example\")\n        {\n            std::valarray<double> v;\n            nlohmann::json j;\n            j[\"test\"] = v;\n        }\n\n        SECTION(\"full example\")\n        {\n            std::valarray<double> v = {1.2, 2.3, 3.4, 4.5};\n            json j = v;\n            std::valarray<double> vj = j;\n\n            CHECK(j == json(vj));\n            CHECK(v.size() == vj.size());\n            for (size_t i = 0; i < v.size(); ++i)\n            {\n                CHECK(v[i] == vj[i]);\n                CHECK(v[i] == j[i]);\n            }\n\n            CHECK_THROWS_AS(json().get<std::valarray<double>>(), json::type_error&);\n            CHECK_THROWS_WITH(json().get<std::valarray<double>>(),\n                              \"[json.exception.type_error.302] type must be array, but is null\");\n        }\n    }\n#endif\n\n    SECTION(\"issue #367 - Behavior of operator>> should more closely resemble that of built-in overloads.\")\n    {\n        SECTION(\"example 1\")\n        {\n            std::istringstream i1_2_3( R\"({\"first\": \"one\" }{\"second\": \"two\"}3)\" );\n            json j1;\n            json j2;\n            json j3;\n            i1_2_3 >> j1;\n            i1_2_3 >> j2;\n            i1_2_3 >> j3;\n\n            auto m1 = j1.get<std::map<std::string, std::string>>();\n            auto m2 = j2.get<std::map<std::string, std::string>>();\n            int i3{j3};\n\n            CHECK( m1 == ( std::map<std::string, std::string> {{ \"first\",  \"one\" }} ));\n            CHECK( m2 == ( std::map<std::string, std::string> {{ \"second\", \"two\" }} ));\n            CHECK( i3 == 3 );\n        }\n    }\n\n    SECTION(\"issue #714 - throw std::ios_base::failure exception when failbit set to true\")\n    {\n        {\n            std::ifstream is;\n            is.exceptions(\n                is.exceptions()\n                | std::ios_base::failbit\n                | std::ios_base::badbit\n            ); // handle different exceptions as 'file not found', 'permission denied'\n\n            is.open(TEST_DATA_DIRECTORY \"/regression/working_file.json\");\n            json _;\n            CHECK_NOTHROW(_ = nlohmann::json::parse(is));\n        }\n\n        {\n            std::ifstream is;\n            is.exceptions(\n                is.exceptions()\n                | std::ios_base::failbit\n                | std::ios_base::badbit\n            ); // handle different exceptions as 'file not found', 'permission denied'\n\n            is.open(TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode.json.cbor\",\n                    std::ios_base::in | std::ios_base::binary);\n            json _;\n            CHECK_NOTHROW(_ = nlohmann::json::from_cbor(is));\n        }\n    }\n\n    SECTION(\"issue #805 - copy constructor is used with std::initializer_list constructor.\")\n    {\n        nocopy n;\n        json j;\n        j = {{\"nocopy\", n}};\n        CHECK(j[\"nocopy\"][\"val\"] == 0);\n    }\n\n    SECTION(\"issue #838 - incorrect parse error with binary data in keys\")\n    {\n        std::array<uint8_t, 28> key1 = {{ 103, 92, 117, 48, 48, 48, 55, 92, 114, 215, 126, 214, 95, 92, 34, 174, 40, 71, 38, 174, 40, 71, 38, 223, 134, 247, 127, 0 }};\n        std::string key1_str(reinterpret_cast<char*>(key1.data()));\n        json j = key1_str;\n        CHECK_THROWS_AS(j.dump(), json::type_error&);\n        CHECK_THROWS_WITH(j.dump(), \"[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E\");\n    }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n    SECTION(\"issue #843 - converting to array not working\")\n    {\n        json j;\n        std::array<int, 4> ar = {{1, 1, 1, 1}};\n        j = ar;\n        ar = j;\n    }\n#endif\n\n    SECTION(\"issue #894 - invalid RFC6902 copy operation succeeds\")\n    {\n        auto model = R\"({\n            \"one\": {\n                \"two\": {\n                    \"three\": \"hello\",\n                    \"four\": 42\n                }\n            }\n        })\"_json;\n\n        auto p1 = R\"([{\"op\": \"move\",\n                       \"from\": \"/one/two/three\",\n                       \"path\": \"/a/b/c\"}])\"_json;\n        CHECK_THROWS_AS(model.patch(p1), json::out_of_range&);\n\n        auto p2 = R\"([{\"op\": \"move\",\n                       \"from\": \"/one/two/three\",\n                       \"path\": \"/a/b/c\"}])\"_json;\n        CHECK_THROWS_WITH(model.patch(p2),\n                          \"[json.exception.out_of_range.403] key 'a' not found\");\n\n        auto p3 = R\"([{\"op\": \"copy\",\n                       \"from\": \"/one/two/three\",\n                       \"path\": \"/a/b/c\"}])\"_json;\n        CHECK_THROWS_AS(model.patch(p3), json::out_of_range&);\n\n        auto p4 = R\"([{\"op\": \"copy\",\n                                 \"from\": \"/one/two/three\",\n                                 \"path\": \"/a/b/c\"}])\"_json;\n        CHECK_THROWS_WITH(model.patch(p4),\n                          \"[json.exception.out_of_range.403] key 'a' not found\");\n    }\n\n    SECTION(\"issue #961 - incorrect parsing of indefinite length CBOR strings\")\n    {\n        std::vector<uint8_t> v_cbor =\n        {\n            0x7F,\n            0x64,\n            'a', 'b', 'c', 'd',\n            0x63,\n            '1', '2', '3',\n            0xFF\n        };\n        json j = json::from_cbor(v_cbor);\n        CHECK(j == \"abcd123\");\n    }\n\n    SECTION(\"issue #962 - Timeout (OSS-Fuzz 6034)\")\n    {\n        json _;\n        std::vector<uint8_t> v_ubjson = {'[', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};\n        CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);\n        //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),\n        //                  \"[json.exception.out_of_range.408] excessive array size: 8658170730974374167\");\n\n        v_ubjson[0] = '{';\n        CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);\n        //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),\n        //                  \"[json.exception.out_of_range.408] excessive object size: 8658170730974374167\");\n    }\n\n    SECTION(\"issue #971 - Add a SAX parser - late bug\")\n    {\n        // a JSON text\n        const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n        // define parser callback\n        json::parser_callback_t cb = [](int /*depth*/, json::parse_event_t event, json & parsed)\n        {\n            // skip object elements with key \"Thumbnail\"\n            return !(event == json::parse_event_t::key && parsed == json(\"Thumbnail\"));\n        };\n\n        // parse (with callback) and serialize JSON\n        json j_filtered = json::parse(text, cb);\n\n        CHECK(j_filtered == R\"({\"Image\":{\"Animated\":false,\"Height\":600,\"IDs\":[116,943,234,38793], \"Title\":\"View from 15th Floor\",\"Width\":800}})\"_json);\n    }\n\n    SECTION(\"issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type\")\n    {\n        my_json foo = R\"([1, 2, 3])\"_json;\n    }\n\n    SECTION(\"issue #977 - Assigning between different json types\")\n    {\n        foo_json lj = ns::foo{3};\n        ns::foo ff(lj);\n        CHECK(lj.is_object());\n        CHECK(lj.size() == 1);\n        CHECK(lj[\"x\"] == 3);\n        CHECK(ff.x == 3);\n        nlohmann::json nj = lj;                // This line works as expected\n    }\n}\n\n#if !defined(JSON_NOEXCEPTION)\nTEST_CASE(\"regression tests, exceptions dependent\")\n{\n    SECTION(\"issue #1340 - eof not set on exhausted input stream\")\n    {\n        std::stringstream s(\"{}{}\");\n        json j;\n        s >> j;\n        s >> j;\n        CHECK_THROWS_AS(s >> j, json::parse_error const&);\n        CHECK(s.eof());\n    }\n}\n#endif\n\n/////////////////////////////////////////////////////////////////////\n// for #1642\n/////////////////////////////////////////////////////////////////////\n\n// the code below fails with Clang on Windows, so we need to exclude it there\n#if defined(__clang__) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__))\n#else\ntemplate <typename T> class array {};\ntemplate <typename T> class object {};\ntemplate <typename T> class string {};\ntemplate <typename T> class number_integer {};\ntemplate <typename T> class number_unsigned {};\ntemplate <typename T> class number_float {};\n#endif\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-regression2.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// for some reason including this after the json header leads to linker errors with VS 2017...\n#include <locale>\n\n#define JSON_TESTS_PRIVATE\n#include <nlohmann/json.hpp>\nusing json = nlohmann::json;\nusing ordered_json = nlohmann::ordered_json;\n\n#include <cstdio>\n#include <list>\n#include <type_traits>\n#include <utility>\n\n#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1)  // fix for issue #464\n    #define JSON_HAS_CPP_17\n#endif\n\n#ifdef JSON_HAS_CPP_17\n    #include <variant>\n\n    #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)\n        #if defined(__cpp_lib_filesystem)\n            #define JSON_HAS_FILESYSTEM 1\n        #elif defined(__cpp_lib_experimental_filesystem)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #elif !defined(__has_include)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #elif __has_include(<filesystem>)\n            #define JSON_HAS_FILESYSTEM 1\n        #elif __has_include(<experimental/filesystem>)\n            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n        #endif\n\n        // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/\n        #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(__clang_major__) && __clang_major__ < 7\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support\n        #if defined(_MSC_VER) && _MSC_VER < 1940\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before iOS 13\n        #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n\n        // no filesystem support before macOS Catalina\n        #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500\n            #undef JSON_HAS_FILESYSTEM\n            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n        #endif\n    #endif\n#endif\n\n#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM\n    #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0\n#endif\n\n#ifndef JSON_HAS_FILESYSTEM\n    #define JSON_HAS_FILESYSTEM 0\n#endif\n\n#if JSON_HAS_EXPERIMENTAL_FILESYSTEM\n#include <experimental/filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::experimental::filesystem;\n} // namespace nlohmann::detail\n#elif JSON_HAS_FILESYSTEM\n#include <filesystem>\nnamespace nlohmann::detail\n{\nnamespace std_fs = std::filesystem;\n} // namespace nlohmann::detail\n#endif\n\n\n#ifdef JSON_HAS_CPP_20\n    #include <span>\n#endif\n\n// NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wexit-time-destructors\")\n\n/////////////////////////////////////////////////////////////////////\n// for #1021\n/////////////////////////////////////////////////////////////////////\n\nusing float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;\n\n/////////////////////////////////////////////////////////////////////\n// for #1647\n/////////////////////////////////////////////////////////////////////\nnamespace\n{\nstruct NonDefaultFromJsonStruct\n{};\n\ninline bool operator==(NonDefaultFromJsonStruct const& /*unused*/, NonDefaultFromJsonStruct const& /*unused*/)\n{\n    return true;\n}\n\nenum class for_1647\n{\n    one,\n    two\n};\n\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays): this is a false positive\nNLOHMANN_JSON_SERIALIZE_ENUM(for_1647,\n{\n    {for_1647::one, \"one\"},\n    {for_1647::two, \"two\"},\n})\n}  // namespace\n\n/////////////////////////////////////////////////////////////////////\n// for #1299\n/////////////////////////////////////////////////////////////////////\n\nstruct Data\n{\n    Data() = default;\n    Data(std::string a_, std::string b_)\n        : a(std::move(a_))\n        , b(std::move(b_))\n    {}\n    std::string a{};\n    std::string b{};\n};\n\nvoid from_json(const json& j, Data& data);\nvoid from_json(const json& j, Data& data)\n{\n    j[\"a\"].get_to(data.a);\n    j[\"b\"].get_to(data.b);\n}\n\nbool operator==(Data const& lhs, Data const& rhs);\nbool operator==(Data const& lhs, Data const& rhs)\n{\n    return lhs.a == rhs.a && lhs.b == rhs.b;\n}\n\n//bool operator!=(Data const& lhs, Data const& rhs)\n//{\n//    return !(lhs == rhs);\n//}\n\nnamespace nlohmann\n{\ntemplate<>\nstruct adl_serializer<NonDefaultFromJsonStruct>\n{\n    static NonDefaultFromJsonStruct from_json(json const& /*unused*/) noexcept\n    {\n        return {};\n    }\n};\n}  // namespace nlohmann\n\n/////////////////////////////////////////////////////////////////////\n// for #1805\n/////////////////////////////////////////////////////////////////////\n\nstruct NotSerializableData\n{\n    int mydata;\n    float myfloat;\n};\n\n/////////////////////////////////////////////////////////////////////\n// for #2574\n/////////////////////////////////////////////////////////////////////\n\nstruct NonDefaultConstructible\n{\n    explicit NonDefaultConstructible(int a)\n        : x(a)\n    {}\n    int x;\n};\n\nnamespace nlohmann\n{\ntemplate<>\nstruct adl_serializer<NonDefaultConstructible>\n{\n    static NonDefaultConstructible from_json(json const& j)\n    {\n        return NonDefaultConstructible(j.get<int>());\n    }\n};\n}  // namespace nlohmann\n\n/////////////////////////////////////////////////////////////////////\n// for #2824\n/////////////////////////////////////////////////////////////////////\n\nclass sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>\n{\n  public:\n    explicit sax_no_exception(json& j)\n        : nlohmann::detail::json_sax_dom_parser<json>(j, false)\n    {}\n\n    static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)\n    {\n        error_string = new std::string(ex.what());  // NOLINT(cppcoreguidelines-owning-memory)\n        return false;\n    }\n\n    static std::string* error_string;\n};\n\nstd::string* sax_no_exception::error_string = nullptr;\n\n/////////////////////////////////////////////////////////////////////\n// for #2982\n/////////////////////////////////////////////////////////////////////\n\ntemplate<class T>\nclass my_allocator : public std::allocator<T>\n{};\n\n/////////////////////////////////////////////////////////////////////\n// for #3077\n/////////////////////////////////////////////////////////////////////\n\nclass FooAlloc\n{};\n\nclass Foo\n{\n  public:\n    explicit Foo(const FooAlloc& /* unused */ = FooAlloc()) {}\n\n    bool value = false;\n};\n\nclass FooBar\n{\n  public:\n    Foo foo{};\n};\n\ninline void from_json(const nlohmann::json& j, FooBar& fb)\n{\n    j.at(\"value\").get_to(fb.foo.value);\n}\n\nTEST_CASE(\"regression tests 2\")\n{\n    SECTION(\"issue #1001 - Fix memory leak during parser callback\")\n    {\n        const auto* geojsonExample = R\"(\n          { \"type\": \"FeatureCollection\",\n            \"features\": [\n              { \"type\": \"Feature\",\n                \"geometry\": {\"type\": \"Point\", \"coordinates\": [102.0, 0.5]},\n                \"properties\": {\"prop0\": \"value0\"}\n                },\n              { \"type\": \"Feature\",\n                \"geometry\": {\n                  \"type\": \"LineString\",\n                  \"coordinates\": [\n                    [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]\n                    ]\n                  },\n                \"properties\": {\n                  \"prop0\": \"value0\",\n                  \"prop1\": 0.0\n                  }\n                },\n              { \"type\": \"Feature\",\n                 \"geometry\": {\n                   \"type\": \"Polygon\",\n                   \"coordinates\": [\n                     [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],\n                       [100.0, 1.0], [100.0, 0.0] ]\n                     ]\n                 },\n                 \"properties\": {\n                   \"prop0\": \"value0\",\n                   \"prop1\": {\"this\": \"that\"}\n                   }\n                 }\n               ]\n             })\";\n\n        json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json & parsed)\n        {\n            // skip uninteresting events\n            if (event == json::parse_event_t::value && !parsed.is_primitive())\n            {\n                return false;\n            }\n\n            switch (event)\n            {\n                case json::parse_event_t::key:\n                {\n                    return true;\n                }\n                case json::parse_event_t::value:\n                {\n                    return false;\n                }\n                case json::parse_event_t::object_start:\n                {\n                    return true;\n                }\n                case json::parse_event_t::object_end:\n                {\n                    return false;\n                }\n                case json::parse_event_t::array_start:\n                {\n                    return true;\n                }\n                case json::parse_event_t::array_end:\n                {\n                    return false;\n                }\n\n                default:\n                {\n                    return true;\n                }\n            }\n        };\n\n        auto j = json::parse(geojsonExample, cb, true);\n        CHECK(j == json());\n    }\n\n    SECTION(\"issue #1021 - to/from_msgpack only works with standard typization\")\n    {\n        float_json j = 1000.0;\n        CHECK(float_json::from_cbor(float_json::to_cbor(j)) == j);\n        CHECK(float_json::from_msgpack(float_json::to_msgpack(j)) == j);\n        CHECK(float_json::from_ubjson(float_json::to_ubjson(j)) == j);\n\n        float_json j2 = {1000.0, 2000.0, 3000.0};\n        CHECK(float_json::from_ubjson(float_json::to_ubjson(j2, true, true)) == j2);\n    }\n\n    SECTION(\"issue #1045 - Using STL algorithms with JSON containers with expected results?\")\n    {\n        json diffs = nlohmann::json::array();\n        json m1{{\"key1\", 42}};\n        json m2{{\"key2\", 42}};\n        auto p1 = m1.items();\n        auto p2 = m2.items();\n\n        using it_type = decltype(p1.begin());\n\n        std::set_difference(\n            p1.begin(),\n            p1.end(),\n            p2.begin(),\n            p2.end(),\n            std::inserter(diffs, diffs.end()),\n            [&](const it_type & e1, const it_type & e2) -> bool\n        {\n            using comper_pair = std::pair<std::string, decltype(e1.value())>;              // Trying to avoid unneeded copy\n            return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value());  // Using pair comper\n        });\n\n        CHECK(diffs.size() == 1);  // Note the change here, was 2\n    }\n\n#ifdef JSON_HAS_CPP_17\n    SECTION(\"issue #1292 - Serializing std::variant causes stack overflow\")\n    {\n        static_assert(!std::is_constructible<json, std::variant<int, float>>::value, \"unexpected value\");\n    }\n#endif\n\n    SECTION(\"issue #1299 - compile error in from_json converting to container \"\n            \"with std::pair\")\n    {\n        json j =\n        {\n            {\"1\", {{\"a\", \"testa_1\"}, {\"b\", \"testb_1\"}}},\n            {\"2\", {{\"a\", \"testa_2\"}, {\"b\", \"testb_2\"}}},\n            {\"3\", {{\"a\", \"testa_3\"}, {\"b\", \"testb_3\"}}},\n        };\n\n        std::map<std::string, Data> expected\n        {\n            {\"1\", {\"testa_1\", \"testb_1\"}},\n            {\"2\", {\"testa_2\", \"testb_2\"}},\n            {\"3\", {\"testa_3\", \"testb_3\"}},\n        };\n        const auto data = j.get<decltype(expected)>();\n        CHECK(expected == data);\n    }\n\n    SECTION(\"issue #1445 - buffer overflow in dumping invalid utf-8 strings\")\n    {\n        SECTION(\"a bunch of -1, ensure_ascii=true\")\n        {\n            const auto length = 300;\n\n            json dump_test;\n            dump_test[\"1\"] = std::string(length, -1);\n\n            std::string expected = R\"({\"1\":\")\";\n            for (int i = 0; i < length; ++i)\n            {\n                expected += \"\\\\ufffd\";\n            }\n            expected += \"\\\"}\";\n\n            auto s = dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);\n            CHECK(s == expected);\n        }\n        SECTION(\"a bunch of -2, ensure_ascii=false\")\n        {\n            const auto length = 500;\n\n            json dump_test;\n            dump_test[\"1\"] = std::string(length, -2);\n\n            std::string expected = R\"({\"1\":\")\";\n            for (int i = 0; i < length; ++i)\n            {\n                expected += \"\\xEF\\xBF\\xBD\";\n            }\n            expected += \"\\\"}\";\n\n            auto s = dump_test.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace);\n            CHECK(s == expected);\n        }\n        SECTION(\"test case in issue #1445\")\n        {\n            nlohmann::json dump_test;\n            const std::array<int, 108> data =\n            {\n                {109, 108, 103, 125, -122, -53, 115, 18, 3, 0, 102, 19, 1, 15, -110, 13, -3, -1, -81, 32, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -80, 2, 0, 0, 96, -118, 46, -116, 46, 109, -84, -87, 108, 14, 109, -24, -83, 13, -18, -51, -83, -52, -115, 14, 6, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 3, 0, 0, 0, 35, -74, -73, 55, 57, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, -96, -54, -28, -26}\n            };\n            std::string s;\n            for (int i : data)\n            {\n                s += static_cast<char>(i);\n            }\n            dump_test[\"1\"] = s;\n            dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);\n        }\n    }\n\n    SECTION(\"issue #1447 - Integer Overflow (OSS-Fuzz 12506)\")\n    {\n        json j = json::parse(\"[-9223372036854775808]\");\n        CHECK(j.dump() == \"[-9223372036854775808]\");\n    }\n\n    SECTION(\"issue #1708 - minimum value of int64_t can be outputted\")\n    {\n        constexpr auto smallest = (std::numeric_limits<int64_t>::min)();\n        json j = smallest;\n        CHECK(j.dump() == std::to_string(smallest));\n    }\n\n    SECTION(\"issue #1727 - Contains with non-const lvalue json_pointer picks the wrong overload\")\n    {\n        json j = {{\"root\", {{\"settings\", {{\"logging\", true}}}}}};\n\n        auto jptr1 = \"/root/settings/logging\"_json_pointer;\n        auto jptr2 = json::json_pointer{\"/root/settings/logging\"};\n\n        CHECK(j.contains(jptr1));\n        CHECK(j.contains(jptr2));\n    }\n\n    SECTION(\"issue #1647 - compile error when deserializing enum if both non-default from_json and non-member operator== exists for other type\")\n    {\n        {\n            json j;\n            NonDefaultFromJsonStruct x(j);\n            NonDefaultFromJsonStruct y;\n            CHECK(x == y);\n        }\n\n        auto val = nlohmann::json(\"one\").get<for_1647>();\n        CHECK(val == for_1647::one);\n        json j = val;\n    }\n\n    SECTION(\"issue #1715 - json::from_cbor does not respect allow_exceptions = false when input is string literal\")\n    {\n        SECTION(\"string literal\")\n        {\n            json cbor = json::from_cbor(\"B\", true, false);\n            CHECK(cbor.is_discarded());\n        }\n\n        SECTION(\"string array\")\n        {\n            const std::array<char, 2> input = {{'B', 0x00}};\n            json cbor = json::from_cbor(input, true, false);\n            CHECK(cbor.is_discarded());\n        }\n\n        SECTION(\"std::string\")\n        {\n            json cbor = json::from_cbor(std::string(\"B\"), true, false);\n            CHECK(cbor.is_discarded());\n        }\n    }\n\n    SECTION(\"issue #1805 - A pair<T1, T2> is json constructible only if T1 and T2 are json constructible\")\n    {\n        static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, \"unexpected result\");\n        static_assert(!std::is_constructible<json, std::pair<NotSerializableData, std::string>>::value, \"unexpected result\");\n        static_assert(std::is_constructible<json, std::pair<int, std::string>>::value, \"unexpected result\");\n    }\n    SECTION(\"issue #1825 - A tuple<Args..> is json constructible only if all T in Args are json constructible\")\n    {\n        static_assert(!std::is_constructible<json, std::tuple<std::string, NotSerializableData>>::value, \"unexpected result\");\n        static_assert(!std::is_constructible<json, std::tuple<NotSerializableData, std::string>>::value, \"unexpected result\");\n        static_assert(std::is_constructible<json, std::tuple<int, std::string>>::value, \"unexpected result\");\n    }\n\n    SECTION(\"issue #1983 - JSON patch diff for op=add formation is not as per standard (RFC 6902)\")\n    {\n        const auto source = R\"({ \"foo\": [ \"1\", \"2\" ] })\"_json;\n        const auto target = R\"({\"foo\": [ \"1\", \"2\", \"3\" ]})\"_json;\n        const auto result = json::diff(source, target);\n        CHECK(result.dump() == R\"([{\"op\":\"add\",\"path\":\"/foo/-\",\"value\":\"3\"}])\");\n    }\n\n    SECTION(\"issue #2067 - cannot serialize binary data to text JSON\")\n    {\n        const std::array<unsigned char, 23> data = {{0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32, 0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30}};\n        json j = json::from_msgpack(data.data(), data.size());\n        CHECK_NOTHROW(\n            j.dump(4,                             // Indent\n                   ' ',                           // Indent char\n                   false,                         // Ensure ascii\n                   json::error_handler_t::strict  // Error\n                  ));\n    }\n\n    SECTION(\"PR #2181 - regression bug with lvalue\")\n    {\n        // see https://github.com/nlohmann/json/pull/2181#issuecomment-653326060\n        json j{{\"x\", \"test\"}};\n        std::string defval = \"default value\";\n        auto val = j.value(\"x\", defval);\n        auto val2 = j.value(\"y\", defval);\n    }\n\n    SECTION(\"issue #2293 - eof doesn't cause parsing to stop\")\n    {\n        std::vector<uint8_t> data =\n        {\n            0x7B,\n            0x6F,\n            0x62,\n            0x6A,\n            0x65,\n            0x63,\n            0x74,\n            0x20,\n            0x4F,\n            0x42\n        };\n        json result = json::from_cbor(data, true, false);\n        CHECK(result.is_discarded());\n    }\n\n    SECTION(\"issue #2315 - json.update and vector<pair>does not work with ordered_json\")\n    {\n        nlohmann::ordered_json jsonAnimals = {{\"animal\", \"dog\"}};\n        nlohmann::ordered_json jsonCat = {{\"animal\", \"cat\"}};\n        jsonAnimals.update(jsonCat);\n        CHECK(jsonAnimals[\"animal\"] == \"cat\");\n\n        auto jsonAnimals_parsed = nlohmann::ordered_json::parse(jsonAnimals.dump());\n        CHECK(jsonAnimals == jsonAnimals_parsed);\n\n        std::vector<std::pair<std::string, int64_t>> intData = {std::make_pair(\"aaaa\", 11),\n                                                                std::make_pair(\"bbb\", 222)\n                                                               };\n        nlohmann::ordered_json jsonObj;\n        for (const auto& data : intData)\n        {\n            jsonObj[data.first] = data.second;\n        }\n        CHECK(jsonObj[\"aaaa\"] == 11);\n        CHECK(jsonObj[\"bbb\"] == 222);\n    }\n\n    SECTION(\"issue #2330 - ignore_comment=true fails on multiple consecutive lines starting with comments\")\n    {\n        std::string ss = \"//\\n//\\n{\\n}\\n\";\n        json j = json::parse(ss, nullptr, true, true);\n        CHECK(j.dump() == \"{}\");\n    }\n\n#ifdef JSON_HAS_CPP_20\n    SECTION(\"issue #2546 - parsing containers of std::byte\")\n    {\n        const char DATA[] = R\"(\"Hello, world!\")\";\n        const auto s = std::as_bytes(std::span(DATA));\n        json j = json::parse(s);\n        CHECK(j.dump() == \"\\\"Hello, world!\\\"\");\n    }\n#endif\n\n    SECTION(\"issue #2574 - Deserialization to std::array, std::pair, and std::tuple with non-default constructable types fails\")\n    {\n        SECTION(\"std::array\")\n        {\n            {\n                json j = {7, 4};\n                auto arr = j.get<std::array<NonDefaultConstructible, 2>>();\n                CHECK(arr[0].x == 7);\n                CHECK(arr[1].x == 4);\n            }\n\n            {\n                json j = 7;\n                CHECK_THROWS_AS((j.get<std::array<NonDefaultConstructible, 1>>()), json::type_error);\n            }\n        }\n\n        SECTION(\"std::pair\")\n        {\n            {\n                json j = {3, 8};\n                auto p = j.get<std::pair<NonDefaultConstructible, NonDefaultConstructible>>();\n                CHECK(p.first.x == 3);\n                CHECK(p.second.x == 8);\n            }\n\n            {\n                json j = {4, 1};\n                auto p = j.get<std::pair<int, NonDefaultConstructible>>();\n                CHECK(p.first == 4);\n                CHECK(p.second.x == 1);\n            }\n\n            {\n                json j = {6, 7};\n                auto p = j.get<std::pair<NonDefaultConstructible, int>>();\n                CHECK(p.first.x == 6);\n                CHECK(p.second == 7);\n            }\n\n            {\n                json j = 7;\n                CHECK_THROWS_AS((j.get<std::pair<NonDefaultConstructible, int>>()), json::type_error);\n            }\n        }\n\n        SECTION(\"std::tuple\")\n        {\n            {\n                json j = {9};\n                auto t = j.get<std::tuple<NonDefaultConstructible>>();\n                CHECK(std::get<0>(t).x == 9);\n            }\n\n            {\n                json j = {9, 8, 7};\n                auto t = j.get<std::tuple<NonDefaultConstructible, int, NonDefaultConstructible>>();\n                CHECK(std::get<0>(t).x == 9);\n                CHECK(std::get<1>(t) == 8);\n                CHECK(std::get<2>(t).x == 7);\n            }\n\n            {\n                json j = 7;\n                CHECK_THROWS_AS((j.get<std::tuple<NonDefaultConstructible>>()), json::type_error);\n            }\n        }\n    }\n\n    SECTION(\"issue #2865 - ASAN detects memory leaks\")\n    {\n        // the code below is expected to not leak memory\n        {\n            nlohmann::json o;\n            std::string s = \"bar\";\n\n            nlohmann::to_json(o[\"foo\"], s);\n\n            nlohmann::json p = o;\n\n            // call to_json with a non-null JSON value\n            nlohmann::to_json(p[\"foo\"], s);\n        }\n\n        {\n            nlohmann::json o;\n            std::string s = \"bar\";\n\n            nlohmann::to_json(o[\"foo\"], s);\n\n            // call to_json with a non-null JSON value\n            nlohmann::to_json(o[\"foo\"], s);\n        }\n    }\n\n    SECTION(\"issue #2824 - encoding of json::exception::what()\")\n    {\n        json j;\n        sax_no_exception sax(j);\n\n        CHECK(!json::sax_parse(\"xyz\", &sax));\n        CHECK(*sax_no_exception::error_string == \"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'\");\n        delete sax_no_exception::error_string;  // NOLINT(cppcoreguidelines-owning-memory)\n    }\n\n    SECTION(\"issue #2825 - Properly constrain the basic_json conversion operator\")\n    {\n        static_assert(std::is_copy_assignable<nlohmann::ordered_json>::value, \"ordered_json must be copy assignable\");\n    }\n\n    SECTION(\"issue #2958 - Inserting in unordered json using a pointer retains the leading slash\")\n    {\n        std::string p = \"/root\";\n\n        // matching types\n        json test1;\n        test1[json::json_pointer(p)] = json::object();\n        CHECK(test1.dump() == \"{\\\"root\\\":{}}\");\n\n        ordered_json test2;\n        test2[ordered_json::json_pointer(p)] = json::object();\n        CHECK(test2.dump() == \"{\\\"root\\\":{}}\");\n\n        // mixed type - the JSON Pointer is implicitly converted into a string \"/root\"\n        ordered_json test3;\n        test3[json::json_pointer(p)] = json::object();\n        CHECK(test3.dump() == \"{\\\"/root\\\":{}}\");\n    }\n\n    SECTION(\"issue #2982 - to_{binary format} does not provide a mechanism for specifying a custom allocator for the returned type\")\n    {\n        std::vector<std::uint8_t, my_allocator<std::uint8_t>> my_vector;\n        json j = {1, 2, 3, 4};\n        json::to_cbor(j, my_vector);\n        json k = json::from_cbor(my_vector);\n        CHECK(j == k);\n    }\n\n#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM\n    SECTION(\"issue #3070 - Version 3.10.3 breaks backward-compatibility with 3.10.2 \")\n    {\n        nlohmann::detail::std_fs::path text_path(\"/tmp/text.txt\");\n        json j(text_path);\n\n        const auto j_path = j.get<nlohmann::detail::std_fs::path>();\n        CHECK(j_path == text_path);\n\n        CHECK_THROWS_WITH_AS(nlohmann::detail::std_fs::path(json(1)), \"[json.exception.type_error.302] type must be string, but is number\", json::type_error);\n    }\n#endif\n\n    SECTION(\"issue #3077 - explicit constructor with default does not compile\")\n    {\n        json j;\n        j[0][\"value\"] = true;\n        std::vector<FooBar> foo;\n        j.get_to(foo);\n    }\n\n    SECTION(\"issue #3108 - ordered_json doesn't support range based erase\")\n    {\n        ordered_json j = {1, 2, 2, 4};\n\n        auto last = std::unique(j.begin(), j.end());\n        j.erase(last, j.end());\n\n        CHECK(j.dump() == \"[1,2,4]\");\n\n        j.erase(std::remove_if(j.begin(), j.end(), [](const ordered_json & val)\n        {\n            return val == 2;\n        }), j.end());\n\n        CHECK(j.dump() == \"[1,4]\");\n    }\n}\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-serialization.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <sstream>\n#include <iomanip>\n\nTEST_CASE(\"serialization\")\n{\n    SECTION(\"operator<<\")\n    {\n        SECTION(\"no given width\")\n        {\n            std::stringstream ss;\n            json j = {\"foo\", 1, 2, 3, false, {{\"one\", 1}}};\n            ss << j;\n            CHECK(ss.str() == \"[\\\"foo\\\",1,2,3,false,{\\\"one\\\":1}]\");\n        }\n\n        SECTION(\"given width\")\n        {\n            std::stringstream ss;\n            json j = {\"foo\", 1, 2, 3, false, {{\"one\", 1}}};\n            ss << std::setw(4) << j;\n            CHECK(ss.str() ==\n                  \"[\\n    \\\"foo\\\",\\n    1,\\n    2,\\n    3,\\n    false,\\n    {\\n        \\\"one\\\": 1\\n    }\\n]\");\n        }\n\n        SECTION(\"given fill\")\n        {\n            std::stringstream ss;\n            json j = {\"foo\", 1, 2, 3, false, {{\"one\", 1}}};\n            ss << std::setw(1) << std::setfill('\\t') << j;\n            CHECK(ss.str() ==\n                  \"[\\n\\t\\\"foo\\\",\\n\\t1,\\n\\t2,\\n\\t3,\\n\\tfalse,\\n\\t{\\n\\t\\t\\\"one\\\": 1\\n\\t}\\n]\");\n        }\n    }\n\n    SECTION(\"operator>>\")\n    {\n        SECTION(\"no given width\")\n        {\n            std::stringstream ss;\n            json j = {\"foo\", 1, 2, 3, false, {{\"one\", 1}}};\n            j >> ss;\n            CHECK(ss.str() == \"[\\\"foo\\\",1,2,3,false,{\\\"one\\\":1}]\");\n        }\n\n        SECTION(\"given width\")\n        {\n            std::stringstream ss;\n            json j = {\"foo\", 1, 2, 3, false, {{\"one\", 1}}};\n            ss.width(4);\n            j >> ss;\n            CHECK(ss.str() ==\n                  \"[\\n    \\\"foo\\\",\\n    1,\\n    2,\\n    3,\\n    false,\\n    {\\n        \\\"one\\\": 1\\n    }\\n]\");\n        }\n\n        SECTION(\"given fill\")\n        {\n            std::stringstream ss;\n            json j = {\"foo\", 1, 2, 3, false, {{\"one\", 1}}};\n            ss.width(1);\n            ss.fill('\\t');\n            j >> ss;\n            CHECK(ss.str() ==\n                  \"[\\n\\t\\\"foo\\\",\\n\\t1,\\n\\t2,\\n\\t3,\\n\\tfalse,\\n\\t{\\n\\t\\t\\\"one\\\": 1\\n\\t}\\n]\");\n        }\n    }\n\n    SECTION(\"dump\")\n    {\n        SECTION(\"invalid character\")\n        {\n            json j = \"ä\\xA9ü\";\n\n            CHECK_THROWS_AS(j.dump(), json::type_error&);\n            CHECK_THROWS_WITH(j.dump(), \"[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\");\n            CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);\n            CHECK_THROWS_WITH(j.dump(1, ' ', false, json::error_handler_t::strict), \"[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\");\n            CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == \"\\\"äü\\\"\");\n            CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == \"\\\"ä\\xEF\\xBF\\xBDü\\\"\");\n            CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == \"\\\"\\\\u00e4\\\\ufffd\\\\u00fc\\\"\");\n        }\n\n        SECTION(\"ending with incomplete character\")\n        {\n            json j = \"123\\xC2\";\n\n            CHECK_THROWS_AS(j.dump(), json::type_error&);\n            CHECK_THROWS_WITH(j.dump(), \"[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2\");\n            CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);\n            CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == \"\\\"123\\\"\");\n            CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == \"\\\"123\\xEF\\xBF\\xBD\\\"\");\n            CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == \"\\\"123\\\\ufffd\\\"\");\n        }\n\n        SECTION(\"unexpected character\")\n        {\n            json j = \"123\\xF1\\xB0\\x34\\x35\\x36\";\n\n            CHECK_THROWS_AS(j.dump(), json::type_error&);\n            CHECK_THROWS_WITH(j.dump(), \"[json.exception.type_error.316] invalid UTF-8 byte at index 5: 0x34\");\n            CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);\n            CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == \"\\\"123456\\\"\");\n            CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == \"\\\"123\\xEF\\xBF\\xBD\\x34\\x35\\x36\\\"\");\n            CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == \"\\\"123\\\\ufffd456\\\"\");\n        }\n\n        SECTION(\"U+FFFD Substitution of Maximal Subparts\")\n        {\n            // Some tests (mostly) from\n            // https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf\n            // Section 3.9 -- U+FFFD Substitution of Maximal Subparts\n\n            auto test = [&](std::string const & input, std::string const & expected)\n            {\n                json j = input;\n                CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == \"\\\"\" + expected + \"\\\"\");\n            };\n\n            test(\"\\xC2\", \"\\\\ufffd\");\n            test(\"\\xC2\\x41\\x42\", \"\\\\ufffd\" \"\\x41\" \"\\x42\");\n            test(\"\\xC2\\xF4\", \"\\\\ufffd\" \"\\\\ufffd\");\n\n            test(\"\\xF0\\x80\\x80\\x41\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF1\\x80\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF2\\x80\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF3\\x80\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF4\\x80\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF5\\x80\\x80\\x41\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\");\n\n            test(\"\\xF0\\x90\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF1\\x90\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF2\\x90\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF3\\x90\\x80\\x41\", \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF4\\x90\\x80\\x41\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF5\\x90\\x80\\x41\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\");\n\n            test(\"\\xC0\\xAF\\xE0\\x80\\xBF\\xF0\\x81\\x82\\x41\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xED\\xA0\\x80\\xED\\xBF\\xBF\\xED\\xAF\\x41\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\");\n            test(\"\\xF4\\x91\\x92\\x93\\xFF\\x41\\x80\\xBF\\x42\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\" \"\\\\ufffd\"\"\\\\ufffd\" \"\\x42\");\n            test(\"\\xE1\\x80\\xE2\\xF0\\x91\\x92\\xF1\\xBF\\x41\", \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\\\ufffd\" \"\\x41\");\n        }\n    }\n\n    SECTION(\"to_string\")\n    {\n        auto test = [&](std::string const & input, std::string const & expected)\n        {\n            using std::to_string;\n            json j = input;\n            CHECK(to_string(j) == \"\\\"\" + expected + \"\\\"\");\n        };\n\n        test(R\"({\"x\":5,\"y\":6})\", R\"({\\\"x\\\":5,\\\"y\\\":6})\");\n        test(\"{\\\"x\\\":[10,null,null,null]}\", R\"({\\\"x\\\":[10,null,null,null]})\");\n        test(\"test\", \"test\");\n        test(\"[3,\\\"false\\\",false]\", R\"([3,\\\"false\\\",false])\");\n    }\n}\n\nTEST_CASE_TEMPLATE(\"serialization for extreme integer values\", T, int32_t, uint32_t, int64_t, uint64_t)\n{\n    SECTION(\"minimum\")\n    {\n        constexpr auto minimum = (std::numeric_limits<T>::min)();\n        json j = minimum;\n        CHECK(j.dump() == std::to_string(minimum));\n    }\n\n    SECTION(\"maximum\")\n    {\n        constexpr auto maximum = (std::numeric_limits<T>::max)();\n        json j = maximum;\n        CHECK(j.dump() == std::to_string(maximum));\n    }\n}\n\nTEST_CASE(\"dump with binary values\")\n{\n    auto binary = json::binary({1, 2, 3, 4});\n    auto binary_empty = json::binary({});\n    auto binary_with_subtype = json::binary({1, 2, 3, 4}, 128);\n    auto binary_empty_with_subtype = json::binary({}, 128);\n\n    json object = {{\"key\", binary}};\n    json object_empty = {{\"key\", binary_empty}};\n    json object_with_subtype = {{\"key\", binary_with_subtype}};\n    json object_empty_with_subtype = {{\"key\", binary_empty_with_subtype}};\n\n    json array = {\"value\", 1, binary};\n    json array_empty = {\"value\", 1, binary_empty};\n    json array_with_subtype = {\"value\", 1, binary_with_subtype};\n    json array_empty_with_subtype = {\"value\", 1, binary_empty_with_subtype};\n\n    SECTION(\"normal\")\n    {\n        CHECK(binary.dump() == \"{\\\"bytes\\\":[1,2,3,4],\\\"subtype\\\":null}\");\n        CHECK(binary_empty.dump() == \"{\\\"bytes\\\":[],\\\"subtype\\\":null}\");\n        CHECK(binary_with_subtype.dump() == \"{\\\"bytes\\\":[1,2,3,4],\\\"subtype\\\":128}\");\n        CHECK(binary_empty_with_subtype.dump() == \"{\\\"bytes\\\":[],\\\"subtype\\\":128}\");\n\n        CHECK(object.dump() == \"{\\\"key\\\":{\\\"bytes\\\":[1,2,3,4],\\\"subtype\\\":null}}\");\n        CHECK(object_empty.dump() == \"{\\\"key\\\":{\\\"bytes\\\":[],\\\"subtype\\\":null}}\");\n        CHECK(object_with_subtype.dump() == \"{\\\"key\\\":{\\\"bytes\\\":[1,2,3,4],\\\"subtype\\\":128}}\");\n        CHECK(object_empty_with_subtype.dump() == \"{\\\"key\\\":{\\\"bytes\\\":[],\\\"subtype\\\":128}}\");\n\n        CHECK(array.dump() == \"[\\\"value\\\",1,{\\\"bytes\\\":[1,2,3,4],\\\"subtype\\\":null}]\");\n        CHECK(array_empty.dump() == \"[\\\"value\\\",1,{\\\"bytes\\\":[],\\\"subtype\\\":null}]\");\n        CHECK(array_with_subtype.dump() == \"[\\\"value\\\",1,{\\\"bytes\\\":[1,2,3,4],\\\"subtype\\\":128}]\");\n        CHECK(array_empty_with_subtype.dump() == \"[\\\"value\\\",1,{\\\"bytes\\\":[],\\\"subtype\\\":128}]\");\n    }\n\n    SECTION(\"pretty-printed\")\n    {\n        CHECK(binary.dump(4) == \"{\\n\"\n              \"    \\\"bytes\\\": [1, 2, 3, 4],\\n\"\n              \"    \\\"subtype\\\": null\\n\"\n              \"}\");\n        CHECK(binary_empty.dump(4) == \"{\\n\"\n              \"    \\\"bytes\\\": [],\\n\"\n              \"    \\\"subtype\\\": null\\n\"\n              \"}\");\n        CHECK(binary_with_subtype.dump(4) == \"{\\n\"\n              \"    \\\"bytes\\\": [1, 2, 3, 4],\\n\"\n              \"    \\\"subtype\\\": 128\\n\"\n              \"}\");\n        CHECK(binary_empty_with_subtype.dump(4) == \"{\\n\"\n              \"    \\\"bytes\\\": [],\\n\"\n              \"    \\\"subtype\\\": 128\\n\"\n              \"}\");\n\n        CHECK(object.dump(4) == \"{\\n\"\n              \"    \\\"key\\\": {\\n\"\n              \"        \\\"bytes\\\": [1, 2, 3, 4],\\n\"\n              \"        \\\"subtype\\\": null\\n\"\n              \"    }\\n\"\n              \"}\");\n        CHECK(object_empty.dump(4) == \"{\\n\"\n              \"    \\\"key\\\": {\\n\"\n              \"        \\\"bytes\\\": [],\\n\"\n              \"        \\\"subtype\\\": null\\n\"\n              \"    }\\n\"\n              \"}\");\n        CHECK(object_with_subtype.dump(4) == \"{\\n\"\n              \"    \\\"key\\\": {\\n\"\n              \"        \\\"bytes\\\": [1, 2, 3, 4],\\n\"\n              \"        \\\"subtype\\\": 128\\n\"\n              \"    }\\n\"\n              \"}\");\n        CHECK(object_empty_with_subtype.dump(4) == \"{\\n\"\n              \"    \\\"key\\\": {\\n\"\n              \"        \\\"bytes\\\": [],\\n\"\n              \"        \\\"subtype\\\": 128\\n\"\n              \"    }\\n\"\n              \"}\");\n\n        CHECK(array.dump(4) == \"[\\n\"\n              \"    \\\"value\\\",\\n\"\n              \"    1,\\n\"\n              \"    {\\n\"\n              \"        \\\"bytes\\\": [1, 2, 3, 4],\\n\"\n              \"        \\\"subtype\\\": null\\n\"\n              \"    }\\n\"\n              \"]\");\n        CHECK(array_empty.dump(4) == \"[\\n\"\n              \"    \\\"value\\\",\\n\"\n              \"    1,\\n\"\n              \"    {\\n\"\n              \"        \\\"bytes\\\": [],\\n\"\n              \"        \\\"subtype\\\": null\\n\"\n              \"    }\\n\"\n              \"]\");\n        CHECK(array_with_subtype.dump(4) == \"[\\n\"\n              \"    \\\"value\\\",\\n\"\n              \"    1,\\n\"\n              \"    {\\n\"\n              \"        \\\"bytes\\\": [1, 2, 3, 4],\\n\"\n              \"        \\\"subtype\\\": 128\\n\"\n              \"    }\\n\"\n              \"]\");\n        CHECK(array_empty_with_subtype.dump(4) == \"[\\n\"\n              \"    \\\"value\\\",\\n\"\n              \"    1,\\n\"\n              \"    {\\n\"\n              \"        \\\"bytes\\\": [],\\n\"\n              \"        \\\"subtype\\\": 128\\n\"\n              \"    }\\n\"\n              \"]\");\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-testsuites.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <test_data.hpp>\n\nTEST_CASE(\"compliance tests from json.org\")\n{\n    // test cases are from https://json.org/JSON_checker/\n\n    SECTION(\"expected failures\")\n    {\n        for (const auto* filename :\n                {\n                    //TEST_DATA_DIRECTORY \"/json_tests/fail1.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail2.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail3.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail4.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail5.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail6.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail7.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail8.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail9.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail10.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail11.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail12.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail13.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail14.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail15.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail16.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail17.json\",\n                    //TEST_DATA_DIRECTORY \"/json_tests/fail18.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail19.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail20.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail21.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail22.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail23.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail24.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail25.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail26.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail27.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail28.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail29.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail30.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail31.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail32.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail33.json\"\n                })\n        {\n            CAPTURE(filename)\n            std::ifstream f(filename);\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);\n        }\n    }\n\n    SECTION(\"no failures with trailing literals (relaxed)\")\n    {\n        // these tests fail above, because the parser does not end on EOF;\n        // they succeed when the operator>> is used, because it does not\n        // have this constraint\n        for (const auto* filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json_tests/fail7.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail8.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/fail10.json\",\n                })\n        {\n            CAPTURE(filename)\n            std::ifstream f(filename);\n            json j;\n            CHECK_NOTHROW(f >> j);\n        }\n    }\n\n    SECTION(\"expected passes\")\n    {\n        for (const auto* filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json_tests/pass1.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass2.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass3.json\"\n                })\n        {\n            CAPTURE(filename)\n            std::ifstream f(filename);\n            json j;\n            CHECK_NOTHROW(f >> j);\n        }\n    }\n}\n\nTEST_CASE(\"compliance tests from nativejson-benchmark\")\n{\n    // test cases from https://github.com/miloyip/nativejson-benchmark/blob/master/src/main.cpp\n\n    SECTION(\"doubles\")\n    {\n        auto TEST_DOUBLE = [](const std::string & json_string, const double expected)\n        {\n            CAPTURE(json_string)\n            CAPTURE(expected)\n            CHECK(json::parse(json_string)[0].get<double>() == Approx(expected));\n        };\n\n        TEST_DOUBLE(\"[0.0]\", 0.0);\n        TEST_DOUBLE(\"[-0.0]\", -0.0);\n        TEST_DOUBLE(\"[1.0]\", 1.0);\n        TEST_DOUBLE(\"[-1.0]\", -1.0);\n        TEST_DOUBLE(\"[1.5]\", 1.5);\n        TEST_DOUBLE(\"[-1.5]\", -1.5);\n        TEST_DOUBLE(\"[3.1416]\", 3.1416);\n        TEST_DOUBLE(\"[1E10]\", 1E10);\n        TEST_DOUBLE(\"[1e10]\", 1e10);\n        TEST_DOUBLE(\"[1E+10]\", 1E+10);\n        TEST_DOUBLE(\"[1E-10]\", 1E-10);\n        TEST_DOUBLE(\"[-1E10]\", -1E10);\n        TEST_DOUBLE(\"[-1e10]\", -1e10);\n        TEST_DOUBLE(\"[-1E+10]\", -1E+10);\n        TEST_DOUBLE(\"[-1E-10]\", -1E-10);\n        TEST_DOUBLE(\"[1.234E+10]\", 1.234E+10);\n        TEST_DOUBLE(\"[1.234E-10]\", 1.234E-10);\n        TEST_DOUBLE(\"[1.79769e+308]\", 1.79769e+308);\n        TEST_DOUBLE(\"[2.22507e-308]\", 2.22507e-308);\n        TEST_DOUBLE(\"[-1.79769e+308]\", -1.79769e+308);\n        TEST_DOUBLE(\"[-2.22507e-308]\", -2.22507e-308);\n        TEST_DOUBLE(\"[4.9406564584124654e-324]\", 4.9406564584124654e-324); // minimum denormal\n        TEST_DOUBLE(\"[2.2250738585072009e-308]\", 2.2250738585072009e-308); // Max subnormal double\n        TEST_DOUBLE(\"[2.2250738585072014e-308]\", 2.2250738585072014e-308); // Min normal positive double\n        TEST_DOUBLE(\"[1.7976931348623157e+308]\", 1.7976931348623157e+308); // Max double\n        TEST_DOUBLE(\"[1e-10000]\", 0.0);                                   // must underflow\n        TEST_DOUBLE(\"[18446744073709551616]\",\n                    18446744073709551616.0);    // 2^64 (max of uint64_t + 1, force to use double)\n        TEST_DOUBLE(\"[-9223372036854775809]\",\n                    -9223372036854775809.0);    // -2^63 - 1(min of int64_t + 1, force to use double)\n        TEST_DOUBLE(\"[0.9868011474609375]\",\n                    0.9868011474609375);          // https://github.com/miloyip/rapidjson/issues/120\n        TEST_DOUBLE(\"[123e34]\", 123e34);                                  // Fast Path Cases In Disguise\n        TEST_DOUBLE(\"[45913141877270640000.0]\", 45913141877270640000.0);\n        TEST_DOUBLE(\"[2.2250738585072011e-308]\",\n                    2.2250738585072011e-308);\n        //TEST_DOUBLE(\"[1e-00011111111111]\", 0.0);\n        //TEST_DOUBLE(\"[-1e-00011111111111]\", -0.0);\n        TEST_DOUBLE(\"[1e-214748363]\", 0.0);\n        TEST_DOUBLE(\"[1e-214748364]\", 0.0);\n        //TEST_DOUBLE(\"[1e-21474836311]\", 0.0);\n        TEST_DOUBLE(\"[0.017976931348623157e+310]\", 1.7976931348623157e+308); // Max double in another form\n\n        // Since\n        // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... ¡Á 10^-324\n        // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... ¡Á 10 ^ -324\n        // So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308\n        TEST_DOUBLE(\"[2.2250738585072012e-308]\",\n                    2.2250738585072014e-308);\n\n        // More closer to normal/subnormal boundary\n        // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... ¡Á 10^-308\n        TEST_DOUBLE(\"[2.22507385850720113605740979670913197593481954635164564e-308]\",\n                    2.2250738585072009e-308);\n        TEST_DOUBLE(\"[2.22507385850720113605740979670913197593481954635164565e-308]\",\n                    2.2250738585072014e-308);\n\n        // 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)\n        // 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375\n        TEST_DOUBLE(\"[0.999999999999999944488848768742172978818416595458984375]\", 1.0); // round to even\n        TEST_DOUBLE(\"[0.999999999999999944488848768742172978818416595458984374]\",\n                    0.99999999999999989); // previous double\n        TEST_DOUBLE(\"[0.999999999999999944488848768742172978818416595458984376]\", 1.0); // next double\n        // 1.0 + 2^-53 = 1.00000000000000011102230246251565404236316680908203125\n        TEST_DOUBLE(\"[1.00000000000000011102230246251565404236316680908203125]\", 1.0); // round to even\n        TEST_DOUBLE(\"[1.00000000000000011102230246251565404236316680908203124]\", 1.0); // previous double\n        TEST_DOUBLE(\"[1.00000000000000011102230246251565404236316680908203126]\",\n                    1.00000000000000022); // next double\n\n        // Numbers from https://github.com/floitsch/double-conversion/blob/master/test/cctest/test-strtod.cc\n\n        TEST_DOUBLE(\"[72057594037927928.0]\", 72057594037927928.0);\n        TEST_DOUBLE(\"[72057594037927936.0]\", 72057594037927936.0);\n        TEST_DOUBLE(\"[72057594037927932.0]\", 72057594037927936.0);\n        TEST_DOUBLE(\"[7205759403792793199999e-5]\", 72057594037927928.0);\n        TEST_DOUBLE(\"[7205759403792793200001e-5]\", 72057594037927936.0);\n\n        TEST_DOUBLE(\"[9223372036854774784.0]\", 9223372036854774784.0);\n        TEST_DOUBLE(\"[9223372036854775808.0]\", 9223372036854775808.0);\n        TEST_DOUBLE(\"[9223372036854775296.0]\", 9223372036854775808.0);\n        TEST_DOUBLE(\"[922337203685477529599999e-5]\", 9223372036854774784.0);\n        TEST_DOUBLE(\"[922337203685477529600001e-5]\", 9223372036854775808.0);\n\n        TEST_DOUBLE(\"[10141204801825834086073718800384]\", 10141204801825834086073718800384.0);\n        TEST_DOUBLE(\"[10141204801825835211973625643008]\", 10141204801825835211973625643008.0);\n        TEST_DOUBLE(\"[10141204801825834649023672221696]\", 10141204801825835211973625643008.0);\n        TEST_DOUBLE(\"[1014120480182583464902367222169599999e-5]\", 10141204801825834086073718800384.0);\n        TEST_DOUBLE(\"[1014120480182583464902367222169600001e-5]\", 10141204801825835211973625643008.0);\n\n        TEST_DOUBLE(\"[5708990770823838890407843763683279797179383808]\",\n                    5708990770823838890407843763683279797179383808.0);\n        TEST_DOUBLE(\"[5708990770823839524233143877797980545530986496]\",\n                    5708990770823839524233143877797980545530986496.0);\n        TEST_DOUBLE(\"[5708990770823839207320493820740630171355185152]\",\n                    5708990770823839524233143877797980545530986496.0);\n        TEST_DOUBLE(\"[5708990770823839207320493820740630171355185151999e-3]\",\n                    5708990770823838890407843763683279797179383808.0);\n        TEST_DOUBLE(\"[5708990770823839207320493820740630171355185152001e-3]\",\n                    5708990770823839524233143877797980545530986496.0);\n\n        {\n            std::string n1e308(312, '0');   // '1' followed by 308 '0'\n            n1e308[0] = '[';\n            n1e308[1] = '1';\n            n1e308[310] = ']';\n            n1e308[311] = '\\0';\n            TEST_DOUBLE(n1e308, 1E308);\n        }\n\n        // Cover trimming\n        TEST_DOUBLE(\n            \"[2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508\"\n            \"7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012\"\n            \"9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306\"\n            \"6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505\"\n            \"1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621\"\n            \"5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844\"\n            \"2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042\"\n            \"7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901\"\n            \"e-308]\",\n            2.2250738585072014e-308);\n    }\n\n    SECTION(\"strings\")\n    {\n        auto TEST_STRING = [](const std::string & json_string, const std::string & expected)\n        {\n            CAPTURE(json_string)\n            CAPTURE(expected)\n            CHECK(json::parse(json_string)[0].get<std::string>() == expected);\n        };\n\n        TEST_STRING(\"[\\\"\\\"]\", \"\");\n        TEST_STRING(\"[\\\"Hello\\\"]\", \"Hello\");\n        TEST_STRING(R\"([\"Hello\\nWorld\"])\", \"Hello\\nWorld\");\n        //TEST_STRING(\"[\\\"Hello\\\\u0000World\\\"]\", \"Hello\\0World\");\n        TEST_STRING(R\"([\"\\\"\\\\/\\b\\f\\n\\r\\t\"])\", \"\\\"\\\\/\\b\\f\\n\\r\\t\");\n        TEST_STRING(R\"([\"\\u0024\"])\", \"$\");         // Dollar sign U+0024\n        TEST_STRING(R\"([\"\\u00A2\"])\", \"\\xC2\\xA2\");     // Cents sign U+00A2\n        TEST_STRING(R\"([\"\\u20AC\"])\", \"\\xE2\\x82\\xAC\"); // Euro sign U+20AC\n        TEST_STRING(R\"([\"\\uD834\\uDD1E\"])\", \"\\xF0\\x9D\\x84\\x9E\");  // G clef sign U+1D11E\n    }\n\n    SECTION(\"roundtrip\")\n    {\n        // test cases are from https://github.com/miloyip/nativejson-benchmark/tree/master/test/data/roundtrip\n\n        for (const auto* filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip01.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip02.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip03.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip04.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip05.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip06.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip07.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip08.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip09.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip10.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip11.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip12.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip13.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip14.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip15.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip16.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip17.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip18.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip19.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip20.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip21.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip22.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip23.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip24.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip25.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip26.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip27.json\",\n                    //TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip28.json\", // incompatible with roundtrip24\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip29.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip30.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip31.json\"\n                    //TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip32.json\" // same as roundtrip31\n                })\n        {\n            CAPTURE(filename)\n            std::ifstream f(filename);\n            std::string json_string( (std::istreambuf_iterator<char>(f) ),\n                                     (std::istreambuf_iterator<char>()) );\n\n            CAPTURE(json_string)\n            json j = json::parse(json_string);\n            CHECK(j.dump() == json_string);\n        }\n    }\n}\n\nTEST_CASE(\"test suite from json-test-suite\")\n{\n    SECTION(\"read all sample.json\")\n    {\n        // read a file with all unicode characters stored as single-character\n        // strings in a JSON array\n        std::ifstream f(TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n\n        // the array has 3 elements\n        CHECK(j.size() == 3);\n    }\n}\n\nTEST_CASE(\"json.org examples\")\n{\n    // here, we list all JSON values from https://json.org/example\n\n    SECTION(\"1.json\")\n    {\n        std::ifstream f(TEST_DATA_DIRECTORY \"/json.org/1.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n    }\n\n    SECTION(\"2.json\")\n    {\n        std::ifstream f(TEST_DATA_DIRECTORY \"/json.org/2.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n    }\n\n    SECTION(\"3.json\")\n    {\n        std::ifstream f(TEST_DATA_DIRECTORY \"/json.org/3.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n    }\n\n    SECTION(\"4.json\")\n    {\n        std::ifstream f(TEST_DATA_DIRECTORY \"/json.org/4.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n    }\n\n    SECTION(\"5.json\")\n    {\n        std::ifstream f(TEST_DATA_DIRECTORY \"/json.org/5.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n    }\n    SECTION(\"FILE 1.json\")\n    {\n        std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen(TEST_DATA_DIRECTORY \"/json.org/1.json\", \"r\"), &std::fclose);\n        json _;\n        CHECK_NOTHROW(_ = json::parse(f.get()));\n    }\n\n    SECTION(\"FILE 2.json\")\n    {\n        std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen(TEST_DATA_DIRECTORY \"/json.org/2.json\", \"r\"), &std::fclose);\n        json _;\n        CHECK_NOTHROW(_ = json::parse(f.get()));\n    }\n\n    SECTION(\"FILE 3.json\")\n    {\n        std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen(TEST_DATA_DIRECTORY \"/json.org/3.json\", \"r\"), &std::fclose);\n        json _;\n        CHECK_NOTHROW(_ = json::parse(f.get()));\n    }\n\n    SECTION(\"FILE 4.json\")\n    {\n        std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen(TEST_DATA_DIRECTORY \"/json.org/4.json\", \"r\"), &std::fclose);\n        json _;\n        CHECK_NOTHROW(_ = json::parse(f.get()));\n    }\n\n    SECTION(\"FILE 5.json\")\n    {\n        std::unique_ptr<std::FILE, decltype(&std::fclose)> f(std::fopen(TEST_DATA_DIRECTORY \"/json.org/5.json\", \"r\"), &std::fclose);\n        json _;\n        CHECK_NOTHROW(_ = json::parse(f.get()));\n    }\n}\n\nTEST_CASE(\"RFC 8259 examples\")\n{\n    // here, we list all JSON values from the RFC 8259 document\n\n    SECTION(\"7. Strings\")\n    {\n        CHECK(json::parse(\"\\\"\\\\u005C\\\"\") == json(\"\\\\\"));\n        CHECK(json::parse(\"\\\"\\\\uD834\\\\uDD1E\\\"\") == json(\"𝄞\"));\n        CHECK(json::parse(\"\\\"𝄞\\\"\") == json(\"𝄞\"));\n    }\n\n    SECTION(\"8.3 String Comparison\")\n    {\n        CHECK(json::parse(\"\\\"a\\\\b\\\"\") == json::parse(\"\\\"a\\u005Cb\\\"\"));\n    }\n\n    SECTION(\"13 Examples\")\n    {\n        {\n            const auto* json_contents = R\"(\n            {\n                 \"Image\": {\n                     \"Width\":  800,\n                     \"Height\": 600,\n                     \"Title\":  \"View from 15th Floor\",\n                     \"Thumbnail\": {\n                         \"Url\":    \"http://www.example.com/image/481989943\",\n                         \"Height\": 125,\n                         \"Width\":  100\n                     },\n                     \"Animated\" : false,\n                     \"IDs\": [116, 943, 234, 38793]\n                   }\n               }\n            )\";\n\n            CHECK_NOTHROW(json(json_contents));\n        }\n\n        {\n            const auto* json_contents = R\"(\n                [\n                    {\n                       \"precision\": \"zip\",\n                       \"Latitude\":  37.7668,\n                       \"Longitude\": -122.3959,\n                       \"Address\":   \"\",\n                       \"City\":      \"SAN FRANCISCO\",\n                       \"State\":     \"CA\",\n                       \"Zip\":       \"94107\",\n                       \"Country\":   \"US\"\n                    },\n                    {\n                       \"precision\": \"zip\",\n                       \"Latitude\":  37.371991,\n                       \"Longitude\": -122.026020,\n                       \"Address\":   \"\",\n                       \"City\":      \"SUNNYVALE\",\n                       \"State\":     \"CA\",\n                       \"Zip\":       \"94085\",\n                       \"Country\":   \"US\"\n                    }\n            ])\";\n            CHECK_NOTHROW(json(json_contents));\n        }\n\n        CHECK(json::parse(\"\\\"Hello world!\\\"\") == json(\"Hello world!\"));\n        CHECK(json::parse(\"42\") == json(42));\n        CHECK(json::parse(\"true\") == json(true));\n    }\n}\n\nTEST_CASE(\"nst's JSONTestSuite\")\n{\n    SECTION(\"test_parsing\")\n    {\n        SECTION(\"y\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_arraysWithSpaces.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_empty-string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_empty.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_ending_with_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_heterogeneous.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_1_and_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_leading_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_several_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_array_with_trailing_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_0e+1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_0e1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_after_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_int_with_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_minus_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_one.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_negative_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e_neg_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_capital_e_pos_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_underflow.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_simple_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_simple_real.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_too_big_neg_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_too_big_pos_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_very_big_negative_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_basic.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_duplicated_key_and_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_empty.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_empty_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_escaped_null_in_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_extreme_numbers.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_long_strings.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_simple.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_string_unicode.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_object_with_newlines.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pair.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pairs.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_allowed_escapes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_backslash_and_u_escaped_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_backslash_doublequotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_comments.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_double_escape_a.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_double_escape_n.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_escaped_control_character.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_escaped_noncharacter.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_in_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_in_array_with_leading_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_last_surrogates_1_and_2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_newline_uescaped.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_null_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_one-byte-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_pi.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_simple_ascii.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_three-byte-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_two-byte-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_u+2028_line_sep.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_u+2029_par_sep.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_uEscape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unescaped_char_delete.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicodeEscapedBackslash.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_unicode_escaped_double_quote.json\",\n                        // TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_utf16.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_utf8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_string_with_del_character.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_negative_real.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_lonely_true.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_string_empty.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_true_in_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json j;\n                CHECK_NOTHROW(f >> j);\n            }\n        }\n\n        SECTION(\"n\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_1_true_without_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_a_invalid_utf8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_colon_instead_of_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_comma_after_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_comma_and_number.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_double_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_double_extra_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_extra_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_extra_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_incomplete.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_incomplete_invalid_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_inner_array_no_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_invalid_utf8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_items_separated_by_semicolon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_just_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_just_minus.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_missing_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_newlines_unclosed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_number_and_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_number_and_several_commas.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_spaces_vertical_tab_formfeed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_star_inside.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_unclosed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_unclosed_trailing_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_unclosed_with_new_lines.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_unclosed_with_object_inside.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_incomplete_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_incomplete_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_incomplete_true.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_++.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_+1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_+Inf.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_-01.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_-1.0..json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_-2..json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_-NaN.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_.-1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_.2e-3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0.1.2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0.3e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0.3e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0.e1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0_capital_E+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0_capital_E.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_0e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_1.0e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_1.0e-.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_1.0e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_1_000.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_1eE2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_2.e+3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_2.e-3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_2.e3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_9.e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_Inf.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_NaN.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_expression.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_hex_1_digit.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_hex_2_digits.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_infinity.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_invalid+-.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_invalid-negative-real.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_invalid-utf-8-in-exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_invalid-utf-8-in-int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_minus_infinity.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_minus_sign_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_minus_space_1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_neg_int_starting_with_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_neg_real_without_int_part.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_neg_with_garbage_at_end.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_real_garbage_after_e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_real_with_invalid_utf8_after_e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_real_without_fractional_part.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_starting_with_dot.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_then_00.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_with_alpha.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_with_alpha_char.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_number_with_leading_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_bad_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_bracket_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_comma_instead_of_colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_double_colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_emoji.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_garbage_at_end.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_key_with_single_quotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_missing_colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_missing_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_missing_semicolon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_missing_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_no-colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_non_string_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_non_string_key_but_huge_number_instead.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_pi_in_key_and_trailing_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_repeated_null_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_several_trailing_commas.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_single_quote.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment_slash_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_two_commas_in_a_row.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_unquoted_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_unterminated-value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_with_single_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_single_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape u.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape u1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape u1x.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_UTF-16_incomplete_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_UTF8_surrogate_U+D800.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_accentuated_char_no_quotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_backslash_00.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_escape_x.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_escaped_backslash_bad.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_escaped_ctrl_char_tab.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_escaped_emoji.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_incomplete_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_incomplete_escaped_character.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_invalid-utf-8-in-escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_invalid_backslash_esc.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_invalid_unicode_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_invalid_utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_invalid_utf8_after_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_iso_latin_1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_leading_uescaped_thinspace.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_lone_utf8_continuation_byte.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_no_quotes_with_bad_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_overlong_sequence_2_bytes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_overlong_sequence_6_bytes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_overlong_sequence_6_bytes_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_single_doublequote.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_single_quote.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_single_string_no_double_quotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_start_escape_unclosed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_unescaped_crtl_char.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_unescaped_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_unescaped_tab.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_unicode_CapitalU.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_with_trailing_garbage.json\",\n                        //!TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_100000_opening_arrays.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_3C.3E.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_3Cnull3E.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_U+2060_word_joined.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_UTF8_BOM_no_data.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_array_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_array_with_extra_array_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_array_with_unclosed_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_ascii-unicode-identifier.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_capitalized_True.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_close_unopened_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_comma_instead_of_closing_brace.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_double_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_end_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_incomplete_UTF8_BOM.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_lone-invalid-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_lone-open-bracket.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_no_data.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_null-byte-outside-string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_object_followed_by_closing_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_object_unclosed_no_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_object_with_comment.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_object_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_array_apostrophe.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_array_comma.json\",\n                        //!TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_array_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_array_open_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_array_open_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_array_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_object_close_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_object_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_object_open_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_object_open_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_object_string_with_apostrophes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_open_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_single_point.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_single_star.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_trailing_#.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_uescaped_LF_before_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_unclosed_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_unclosed_array_partial_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_unclosed_array_unfinished_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_unclosed_array_unfinished_true.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_unclosed_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_unicode-identifier.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_whitespace_formfeed.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);\n            }\n        }\n\n        SECTION(\"n -> y (relaxed)\")\n        {\n            // these tests fail above, because the parser does not end on EOF;\n            // they succeed when the operator>> is used, because it does not\n            // have this constraint\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_comma_after_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_array_extra_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment_slash_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_object_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_string_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_array_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_array_with_extra_array_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_close_unopened_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_double_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_object_followed_by_closing_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_object_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/n_structure_trailing_#.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json j;\n                CHECK_NOTHROW(f >> j);\n            }\n        }\n\n        SECTION(\"i -> y\")\n        {\n            for (const auto* filename :\n                    {\n                        // we do not pose a limit on nesting\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_structure_500_nested_arrays.json\",\n                        // we silently ignore BOMs\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json\",\n                        // we accept and forward non-characters\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_unicode_U+FDD0_nonchar.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_unicode_U+FFFE_nonchar.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json j;\n                CHECK_NOTHROW(f >> j);\n            }\n        }\n\n        // numbers that overflow during parsing\n        SECTION(\"i/y -> n (out of range)\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_number_neg_int_huge_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_number_pos_double_huge_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_huge_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json j;\n                CHECK_THROWS_AS(f >> j, json::out_of_range&);\n            }\n        }\n\n        SECTION(\"i -> n\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_object_key_lone_2nd_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_UTF-16_invalid_lonely_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_UTF-16_invalid_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_UTF-8_invalid_sequence.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_incomplete_surrogate_pair.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_incomplete_surrogates_escape_valid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_lone_second_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_not_in_unicode_range.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite/test_parsing/i_string_truncated-utf-8.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json j;\n                CHECK_THROWS_AS(f >> j, json::parse_error&);\n            }\n        }\n    }\n}\n\nTEST_CASE(\"nst's JSONTestSuite (2)\")\n{\n    SECTION(\"test_parsing\")\n    {\n        SECTION(\"y\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_arraysWithSpaces.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_empty-string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_empty.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_ending_with_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_heterogeneous.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_with_1_and_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_with_leading_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_with_several_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_array_with_trailing_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_0e+1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_0e1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_after_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_double_close_to_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_int_with_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_minus_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_negative_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_negative_one.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_negative_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_real_capital_e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_real_capital_e_neg_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_real_capital_e_pos_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_real_exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_real_fraction_exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_real_neg_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_real_pos_exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_simple_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_number_simple_real.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_basic.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_duplicated_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_duplicated_key_and_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_empty.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_empty_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_escaped_null_in_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_extreme_numbers.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_long_strings.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_simple.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_string_unicode.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_object_with_newlines.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_allowed_escapes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_backslash_and_u_escaped_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_backslash_doublequotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_comments.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_double_escape_a.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_double_escape_n.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_escaped_control_character.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_escaped_noncharacter.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_in_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_in_array_with_leading_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_last_surrogates_1_and_2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_nbsp_uescaped.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_null_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_one-byte-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_pi.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_simple_ascii.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_three-byte-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_two-byte-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_u+2028_line_sep.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_u+2029_par_sep.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_uEscape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_uescaped_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unescaped_char_delete.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicodeEscapedBackslash.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_U+10FFFE_nonchar.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_U+1FFFE_nonchar.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_U+2064_invisible_plus.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_U+FDD0_nonchar.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_U+FFFE_nonchar.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_unicode_escaped_double_quote.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_utf8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_string_with_del_character.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_lonely_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_lonely_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_lonely_negative_real.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_lonely_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_lonely_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_lonely_true.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_string_empty.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_trailing_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_true_in_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/y_structure_whitespace_array.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json _;\n                CHECK_NOTHROW(_ = json::parse(f));\n                std::ifstream f2(filename);\n                CHECK(json::accept(f2));\n            }\n        }\n\n        SECTION(\"n\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_1_true_without_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_a_invalid_utf8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_colon_instead_of_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_comma_after_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_comma_and_number.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_double_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_double_extra_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_extra_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_extra_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_incomplete.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_incomplete_invalid_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_inner_array_no_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_invalid_utf8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_items_separated_by_semicolon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_just_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_just_minus.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_missing_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_newlines_unclosed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_number_and_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_number_and_several_commas.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_spaces_vertical_tab_formfeed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_star_inside.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_unclosed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_unclosed_trailing_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_unclosed_with_new_lines.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_array_unclosed_with_object_inside.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_incomplete_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_incomplete_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_incomplete_true.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_multidigit_number_then_00.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_++.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_+1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_+Inf.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_-01.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_-1.0..json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_-2..json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_-NaN.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_.-1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_.2e-3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0.1.2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0.3e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0.3e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0.e1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0_capital_E+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0_capital_E.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_0e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_1.0e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_1.0e-.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_1.0e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_1_000.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_1eE2.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_2.e+3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_2.e-3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_2.e3.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_9.e+.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_Inf.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_NaN.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_U+FF11_fullwidth_digit_one.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_expression.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_infinity.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_invalid+-.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_invalid-negative-real.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-bigger-int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-exponent.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_minus_infinity.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_minus_sign_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_minus_space_1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_neg_real_without_int_part.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_neg_with_garbage_at_end.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_real_garbage_after_e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_real_with_invalid_utf8_after_e.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_real_without_fractional_part.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_starting_with_dot.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_with_alpha.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_with_alpha_char.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_number_with_leading_zero.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_bad_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_bracket_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_comma_instead_of_colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_double_colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_emoji.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_garbage_at_end.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_key_with_single_quotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_missing_colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_missing_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_missing_semicolon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_missing_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_no-colon.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_non_string_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_repeated_null_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_several_trailing_commas.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_single_quote.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_trailing_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_trailing_comment.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_trailing_comment_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_trailing_comment_slash_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_trailing_comment_slash_open_incomplete.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_two_commas_in_a_row.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_unquoted_key.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_unterminated-value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_with_single_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_object_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_single_space.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1x.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_accentuated_char_no_quotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_backslash_00.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_escape_x.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_escaped_backslash_bad.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_escaped_ctrl_char_tab.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_escaped_emoji.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_incomplete_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_incomplete_escaped_character.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate_escape_invalid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_invalid-utf-8-in-escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_invalid_backslash_esc.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_invalid_unicode_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_invalid_utf8_after_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_leading_uescaped_thinspace.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_no_quotes_with_bad_escape.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_single_doublequote.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_single_quote.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_single_string_no_double_quotes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_start_escape_unclosed.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_unescaped_crtl_char.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_unescaped_newline.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_unescaped_tab.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_unicode_CapitalU.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_string_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_U+2060_word_joined.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_UTF8_BOM_no_data.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_angle_bracket_..json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_angle_bracket_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_array_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_array_with_extra_array_close.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_array_with_unclosed_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_ascii-unicode-identifier.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_capitalized_True.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_close_unopened_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_comma_instead_of_closing_brace.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_double_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_end_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_incomplete_UTF8_BOM.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_lone-open-bracket.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_no_data.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_null-byte-outside-string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_number_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_object_followed_by_closing_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_object_unclosed_no_value.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_object_with_comment.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_object_with_trailing_garbage.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_array_apostrophe.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_array_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_array_open_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_array_open_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_array_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_object_close_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_object_comma.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_object_open_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_object_open_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_object_string_with_apostrophes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_open.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_single_eacute.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_single_star.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_trailing_#.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_uescaped_LF_before_string.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_unclosed_array.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_partial_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_false.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_true.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_unclosed_object.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_unicode-identifier.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_whitespace_U+2060_word_joiner.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_whitespace_formfeed.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);\n                std::ifstream f2(filename);\n                CHECK(!json::accept(f2));\n            }\n        }\n\n        SECTION(\"n (previously overflowed)\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_100000_opening_arrays.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/n_structure_open_array_object.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                CHECK(!json::accept(f));\n            }\n        }\n\n        SECTION(\"i -> y\")\n        {\n            for (const auto* filename :\n                    {\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_double_huge_neg_exp.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_huge_exp.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_neg_int_huge_exp.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_pos_double_huge_exp.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_real_neg_overflow.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_real_pos_overflow.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_real_underflow.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_too_big_neg_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_too_big_pos_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_very_big_negative_int.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_object_key_lone_2nd_surrogate.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_1st_surrogate_but_2nd_missing.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_UTF-16LE_with_BOM.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_UTF-8_invalid_sequence.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_UTF8_surrogate_U+D800.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_incomplete_surrogate_pair.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_incomplete_surrogates_escape_valid.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_invalid_lonely_surrogate.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_invalid_surrogate.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_invalid_utf-8.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_inverted_surrogates_U+1D11E.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_iso_latin_1.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_lone_second_surrogate.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_lone_utf8_continuation_byte.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_not_in_unicode_range.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_overlong_sequence_2_bytes.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_overlong_sequence_6_bytes.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_overlong_sequence_6_bytes_null.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_truncated-utf-8.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_utf16BE_no_BOM.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_utf16LE_no_BOM.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_structure_UTF-8_BOM_empty_object.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json _;\n                CHECK_NOTHROW(_ = json::parse(f));\n                std::ifstream f2(filename);\n                CHECK(json::accept(f2));\n            }\n        }\n\n        SECTION(\"i -> n\")\n        {\n            for (const auto* filename :\n                    {\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_double_huge_neg_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_huge_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_neg_int_huge_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_pos_double_huge_exp.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_real_neg_overflow.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_real_pos_overflow.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_real_underflow.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_too_big_neg_int.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_too_big_pos_int.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_number_very_big_negative_int.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_object_key_lone_2nd_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_1st_surrogate_but_2nd_missing.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_UTF-16LE_with_BOM.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_UTF-8_invalid_sequence.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_UTF8_surrogate_U+D800.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_incomplete_surrogate_pair.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_incomplete_surrogates_escape_valid.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_invalid_lonely_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_invalid_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_invalid_utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_inverted_surrogates_U+1D11E.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_iso_latin_1.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_lone_second_surrogate.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_lone_utf8_continuation_byte.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_not_in_unicode_range.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_overlong_sequence_2_bytes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_overlong_sequence_6_bytes.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_overlong_sequence_6_bytes_null.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_truncated-utf-8.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_utf16BE_no_BOM.json\",\n                        TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_string_utf16LE_no_BOM.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json\",\n                        //TEST_DATA_DIRECTORY \"/nst_json_testsuite2/test_parsing/i_structure_UTF-8_BOM_empty_object.json\"\n                    }\n                )\n            {\n                CAPTURE(filename)\n                std::ifstream f(filename);\n                json _;\n                CHECK_THROWS_AS(_ = json::parse(f), json::exception&); // could be parse_error or out_of_range\n                std::ifstream f2(filename);\n                CHECK(!json::accept(f2));\n            }\n        }\n    }\n}\n\nnamespace\n{\nstd::string trim(const std::string& str);\n\n// from https://stackoverflow.com/a/25829178/266378\nstd::string trim(const std::string& str)\n{\n    size_t first = str.find_first_not_of(' ');\n    if (std::string::npos == first)\n    {\n        return str;\n    }\n    size_t last = str.find_last_not_of(' ');\n    return str.substr(first, (last - first + 1));\n}\n} // namespace\n\nTEST_CASE(\"Big List of Naughty Strings\")\n{\n    // test from https://github.com/minimaxir/big-list-of-naughty-strings\n    SECTION(\"parsing blns.json\")\n    {\n        std::ifstream f(TEST_DATA_DIRECTORY \"/big-list-of-naughty-strings/blns.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n    }\n\n    // check if parsed strings roundtrip\n    // https://www.reddit.com/r/cpp/comments/5qpbie/json_form_modern_c_version_210/dd12mpq/\n    SECTION(\"roundtripping\")\n    {\n        std::ifstream f(TEST_DATA_DIRECTORY \"/big-list-of-naughty-strings/blns.json\");\n        std::string line;\n\n        // read lines one by one, bail out on error or eof\n        while (getline(f, line))\n        {\n            // trim whitespace\n            line = trim(line);\n\n            // remove trailing comma\n            line = line.substr(0, line.find_last_of(','));\n\n            // discard lines without at least two characters (quotes)\n            if (line.size() < 2)\n            {\n                continue;\n            }\n\n            // check roundtrip\n            CAPTURE(line)\n            json j = json::parse(line);\n            CHECK(j.dump() == line);\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-to_chars.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n// XXX:\n// Only compile these tests if 'float' and 'double' are IEEE-754 single- and\n// double-precision numbers, resp.\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::detail::dtoa_impl::reinterpret_bits;\n\nnamespace\n{\nfloat make_float(uint32_t sign_bit, uint32_t biased_exponent, uint32_t significand)\n{\n    assert(sign_bit == 0 || sign_bit == 1);\n    assert(biased_exponent <= 0xFF);\n    assert(significand <= 0x007FFFFF);\n\n    uint32_t bits = 0;\n\n    bits |= sign_bit << 31;\n    bits |= biased_exponent << 23;\n    bits |= significand;\n\n    return reinterpret_bits<float>(bits);\n}\n\n// ldexp -- convert f * 2^e to IEEE single precision\nfloat make_float(uint64_t f, int e)\n{\n    constexpr uint64_t kHiddenBit               = 0x00800000;\n    constexpr uint64_t kSignificandMask         = 0x007FFFFF;\n    constexpr int      kPhysicalSignificandSize = 23;  // Excludes the hidden bit.\n    constexpr int      kExponentBias            = 0x7F + kPhysicalSignificandSize;\n    constexpr int      kDenormalExponent        = 1 -    kExponentBias;\n    constexpr int      kMaxExponent             = 0xFF - kExponentBias;\n\n    while (f > kHiddenBit + kSignificandMask)\n    {\n        f >>= 1;\n        e++;\n    }\n    if (e >= kMaxExponent)\n    {\n        return std::numeric_limits<float>::infinity();\n    }\n    if (e < kDenormalExponent)\n    {\n        return 0.0;\n    }\n    while (e > kDenormalExponent && (f & kHiddenBit) == 0)\n    {\n        f <<= 1;\n        e--;\n    }\n\n    uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)\n                               ? 0\n                               : static_cast<uint64_t>(e + kExponentBias);\n\n    uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);\n    return reinterpret_bits<float>(static_cast<uint32_t>(bits));\n}\n\ndouble make_double(uint64_t sign_bit, uint64_t biased_exponent, uint64_t significand)\n{\n    assert(sign_bit == 0 || sign_bit == 1);\n    assert(biased_exponent <= 0x7FF);\n    assert(significand <= 0x000FFFFFFFFFFFFF);\n\n    uint64_t bits = 0;\n\n    bits |= sign_bit << 63;\n    bits |= biased_exponent << 52;\n    bits |= significand;\n\n    return reinterpret_bits<double>(bits);\n}\n\n// ldexp -- convert f * 2^e to IEEE double precision\ndouble make_double(uint64_t f, int e)\n{\n    constexpr uint64_t kHiddenBit               = 0x0010000000000000;\n    constexpr uint64_t kSignificandMask         = 0x000FFFFFFFFFFFFF;\n    constexpr int      kPhysicalSignificandSize = 52;  // Excludes the hidden bit.\n    constexpr int      kExponentBias            = 0x3FF + kPhysicalSignificandSize;\n    constexpr int      kDenormalExponent        = 1     - kExponentBias;\n    constexpr int      kMaxExponent             = 0x7FF - kExponentBias;\n\n    while (f > kHiddenBit + kSignificandMask)\n    {\n        f >>= 1;\n        e++;\n    }\n    if (e >= kMaxExponent)\n    {\n        return std::numeric_limits<double>::infinity();\n    }\n    if (e < kDenormalExponent)\n    {\n        return 0.0;\n    }\n    while (e > kDenormalExponent && (f & kHiddenBit) == 0)\n    {\n        f <<= 1;\n        e--;\n    }\n\n    uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)\n                               ? 0\n                               : static_cast<uint64_t>(e + kExponentBias);\n\n    uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);\n    return reinterpret_bits<double>(bits);\n}\n} // namespace\n\nTEST_CASE(\"digit gen\")\n{\n    SECTION(\"single precision\")\n    {\n        auto check_float = [](float number, const std::string & digits, int expected_exponent)\n        {\n            CAPTURE(number)\n            CAPTURE(digits)\n            CAPTURE(expected_exponent)\n\n            std::array<char, 32> buf{};\n            int len = 0;\n            int exponent = 0;\n            nlohmann::detail::dtoa_impl::grisu2(buf.data(), len, exponent, number);\n\n            CHECK(digits == std::string(buf.data(), buf.data() + len));\n            CHECK(expected_exponent == exponent);\n        };\n\n        check_float(make_float(0,   0, 0x00000001),        \"1\", -45); // min denormal\n        check_float(make_float(0,   0, 0x007FFFFF), \"11754942\", -45); // max denormal\n        check_float(make_float(0,   1, 0x00000000), \"11754944\", -45); // min normal\n        check_float(make_float(0,   1, 0x00000001), \"11754945\", -45);\n        check_float(make_float(0,   1, 0x007FFFFF), \"23509886\", -45);\n        check_float(make_float(0,   2, 0x00000000), \"23509887\", -45);\n        check_float(make_float(0,   2, 0x00000001),  \"2350989\", -44);\n        check_float(make_float(0,  24, 0x00000000), \"98607613\", -39); // fail if no special case in normalized boundaries\n        check_float(make_float(0,  30, 0x00000000), \"63108872\", -37); // fail if no special case in normalized boundaries\n        check_float(make_float(0,  31, 0x00000000), \"12621775\", -36); // fail if no special case in normalized boundaries\n        check_float(make_float(0,  57, 0x00000000), \"84703295\", -29); // fail if no special case in normalized boundaries\n        check_float(make_float(0, 254, 0x007FFFFE), \"34028233\",  31);\n        check_float(make_float(0, 254, 0x007FFFFF), \"34028235\",  31); // max normal\n\n        // V. Paxson and W. Kahan, \"A Program for Testing IEEE Binary-Decimal Conversion\", manuscript, May 1991,\n        // ftp://ftp.ee.lbl.gov/testbase-report.ps.Z    (report)\n        // ftp://ftp.ee.lbl.gov/testbase.tar.Z          (program)\n\n        // Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP\n        check_float(make_float(12676506, -102),       \"25\", -25);\n        check_float(make_float(12676506, -103),      \"125\", -26);\n        check_float(make_float(15445013,   86),     \"1195\",  30);\n        check_float(make_float(13734123, -138),    \"39415\", -39);\n        check_float(make_float(12428269, -130),   \"913085\", -38);\n        check_float(make_float(15334037, -146),  \"1719005\", -43);\n        check_float(make_float(11518287,  -41), \"52379105\", -13);\n        check_float(make_float(12584953, -145),  \"2821644\", -43);\n        check_float(make_float(15961084, -125), \"37524328\", -38);\n        check_float(make_float(14915817, -146), \"16721209\", -44);\n        check_float(make_float(10845484, -102), \"21388946\", -31);\n        check_float(make_float(16431059,  -61),  \"7125836\", -18);\n\n        // Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP\n        check_float(make_float(16093626,   69),       \"95\",  26);\n        check_float(make_float( 9983778,   25),      \"335\",  12);\n        check_float(make_float(12745034,  104),     \"2585\",  35);\n        check_float(make_float(12706553,   72),    \"60005\",  24);\n        check_float(make_float(11005028,   45),   \"387205\",  15);\n        check_float(make_float(15059547,   71),  \"3555835\",  22);\n        check_float(make_float(16015691,  -99), \"25268305\", -30);\n        check_float(make_float( 8667859,   56),  \"6245851\",  17);\n        check_float(make_float(14855922,  -82), \"30721327\", -25);\n        check_float(make_float(14855922,  -83), \"15360663\", -25);\n        check_float(make_float(10144164, -110),   \"781478\", -32);\n        check_float(make_float(13248074,   95), \"52481028\",  28);\n    }\n\n    SECTION(\"double precision\")\n    {\n        auto check_double = [](double number, const std::string & digits, int expected_exponent)\n        {\n            CAPTURE(number)\n            CAPTURE(digits)\n            CAPTURE(expected_exponent)\n\n            std::array<char, 32> buf{};\n            int len = 0;\n            int exponent = 0;\n            nlohmann::detail::dtoa_impl::grisu2(buf.data(), len, exponent, number);\n\n            CHECK(digits == std::string(buf.data(), buf.data() + len));\n            CHECK(expected_exponent == exponent);\n        };\n\n        check_double(make_double(0,    0, 0x0000000000000001),                 \"5\", -324); // min denormal\n        check_double(make_double(0,    0, 0x000FFFFFFFFFFFFF),  \"2225073858507201\", -323); // max denormal\n        check_double(make_double(0,    1, 0x0000000000000000), \"22250738585072014\", -324); // min normal\n        check_double(make_double(0,    1, 0x0000000000000001),  \"2225073858507202\", -323);\n        check_double(make_double(0,    1, 0x000FFFFFFFFFFFFF), \"44501477170144023\", -324);\n        check_double(make_double(0,    2, 0x0000000000000000),  \"4450147717014403\", -323);\n        check_double(make_double(0,    2, 0x0000000000000001),  \"4450147717014404\", -323);\n        check_double(make_double(0,    4, 0x0000000000000000), \"17800590868057611\", -323); // fail if no special case in normalized boundaries\n        check_double(make_double(0,    5, 0x0000000000000000), \"35601181736115222\", -323); // fail if no special case in normalized boundaries\n        check_double(make_double(0,    6, 0x0000000000000000),  \"7120236347223045\", -322); // fail if no special case in normalized boundaries\n        check_double(make_double(0,   10, 0x0000000000000000), \"11392378155556871\", -321); // fail if no special case in normalized boundaries\n        check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFE), \"17976931348623155\",  292);\n        check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFF), \"17976931348623157\",  292); // max normal\n\n        // Test different paths in DigitGen\n        check_double(                  10000,                 \"1\",    4);\n        check_double(                1200000,                \"12\",    5);\n        check_double(4.9406564584124654e-324,                 \"5\", -324); // exit integral loop\n        check_double(2.2250738585072009e-308,  \"2225073858507201\", -323); // exit fractional loop\n        check_double(   1.82877982605164e-99,   \"182877982605164\", -113);\n        check_double( 1.1505466208671903e-09, \"11505466208671903\",  -25);\n        check_double( 5.5645893133766722e+20,  \"5564589313376672\",    5);\n        check_double(     53.034830388866226, \"53034830388866226\",  -15);\n        check_double(  0.0021066531670178605, \"21066531670178605\",  -19);\n\n        // V. Paxson and W. Kahan, \"A Program for Testing IEEE Binary-Decimal Conversion\", manuscript, May 1991,\n        // ftp://ftp.ee.lbl.gov/testbase-report.ps.Z    (report)\n        // ftp://ftp.ee.lbl.gov/testbase.tar.Z          (program)\n\n        // Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP\n        check_double(make_double(8511030020275656,  -342) /*                9.5e-088 */,                \"95\",  -89);\n        check_double(make_double(5201988407066741,  -824) /*               4.65e-233 */,               \"465\", -235);\n        check_double(make_double(6406892948269899,  +237) /*              1.415e+087 */,              \"1415\",   84);\n        check_double(make_double(8431154198732492,   +72) /*             3.9815e+037 */,             \"39815\",   33);\n        check_double(make_double(6475049196144587,   +99) /*            4.10405e+045 */,            \"410405\",   40);\n        check_double(make_double(8274307542972842,  +726) /*           2.920845e+234 */,           \"2920845\",  228);\n        check_double(make_double(5381065484265332,  -456) /*          2.8919465e-122 */,          \"28919465\", -129);\n        check_double(make_double(6761728585499734, -1057) /*         4.37877185e-303 */,         \"437877185\", -311);\n        check_double(make_double(7976538478610756,  +376) /*        1.227701635e+129 */,        \"1227701635\",  120);\n        check_double(make_double(5982403858958067,  +377) /*       1.8415524525e+129 */,       \"18415524525\",  119);\n        check_double(make_double(5536995190630837,   +93) /*      5.48357443505e+043 */,      \"548357443505\",   32);\n        check_double(make_double(7225450889282194,  +710) /*     3.891901811465e+229 */,     \"3891901811465\",  217);\n        check_double(make_double(7225450889282194,  +709) /*    1.9459509057325e+229 */,    \"19459509057325\",  216);\n        check_double(make_double(8703372741147379,  +117) /*   1.44609583816055e+051 */,   \"144609583816055\",   37);\n        check_double(make_double(8944262675275217, -1001) /*  4.173677474585315e-286 */,  \"4173677474585315\", -301);\n        check_double(make_double(7459803696087692,  -707) /* 1.1079507728788885e-197 */, \"11079507728788885\", -213);\n        check_double(make_double(6080469016670379,  -381) /*  1.234550136632744e-099 */,  \"1234550136632744\", -114);\n        check_double(make_double(8385515147034757,  +721) /* 9.2503171196036502e+232 */,   \"925031711960365\",  218);\n        check_double(make_double(7514216811389786,  -828) /* 4.1980471502848898e-234 */,   \"419804715028489\", -248);\n        check_double(make_double(8397297803260511,  -345) /* 1.1716315319786511e-088 */, \"11716315319786511\", -104);\n        check_double(make_double(6733459239310543,  +202) /* 4.3281007284461249e+076 */,  \"4328100728446125\",   61);\n        check_double(make_double(8091450587292794,  -473) /* 3.3177101181600311e-127 */,  \"3317710118160031\", -142);\n\n        // Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP\n        check_double(make_double(6567258882077402,  +952) /*                2.5e+302 */,                \"25\",  301);\n        check_double(make_double(6712731423444934,  +535) /*               7.55e+176 */,               \"755\",  174);\n        check_double(make_double(6712731423444934,  +534) /*              3.775e+176 */,              \"3775\",  173);\n        check_double(make_double(5298405411573037,  -957) /*             4.3495e-273 */,             \"43495\", -277);\n        check_double(make_double(5137311167659507,  -144) /*            2.30365e-028 */,            \"230365\",  -33);\n        check_double(make_double(6722280709661868,  +363) /*           1.263005e+125 */,           \"1263005\",  119);\n        check_double(make_double(5344436398034927,  -169) /*          7.1422105e-036 */,          \"71422105\",  -43);\n        check_double(make_double(8369123604277281,  -853) /*         1.39345735e-241 */,         \"139345735\", -249);\n        check_double(make_double(8995822108487663,  -780) /*        1.414634485e-219 */,        \"1414634485\", -228);\n        check_double(make_double(8942832835564782,  -383) /*       4.5392779195e-100 */,       \"45392779195\", -110);\n        check_double(make_double(8942832835564782,  -384) /*      2.26963895975e-100 */,      \"226963895975\", -111);\n        check_double(make_double(8942832835564782,  -385) /*     1.134819479875e-100 */,     \"1134819479875\", -112);\n        check_double(make_double(6965949469487146,  -249) /*    7.7003665618895e-060 */,    \"77003665618895\",  -73);\n        check_double(make_double(6965949469487146,  -250) /*   3.85018328094475e-060 */,   \"385018328094475\",  -74);\n        check_double(make_double(6965949469487146,  -251) /*  1.925091640472375e-060 */,  \"1925091640472375\",  -75);\n        check_double(make_double(7487252720986826,  +548) /* 6.8985865317742005e+180 */, \"68985865317742005\",  164);\n        check_double(make_double(5592117679628511,  +164) /* 1.3076622631878654e+065 */, \"13076622631878654\",   49);\n        check_double(make_double(8887055249355788,  +665) /* 1.3605202075612124e+216 */, \"13605202075612124\",  200);\n        check_double(make_double(6994187472632449,  +690) /* 3.5928102174759597e+223 */, \"35928102174759597\",  207);\n        check_double(make_double(8797576579012143,  +588) /* 8.9125197712484552e+192 */,  \"8912519771248455\",  177);\n        check_double(make_double(7363326733505337,  +272) /* 5.5876975736230114e+097 */, \"55876975736230114\",   81);\n        check_double(make_double(8549497411294502,  -448) /* 1.1762578307285404e-119 */, \"11762578307285404\", -135);\n\n        // Table 20: Stress Inputs for Converting 56-bit Binary to Decimal, < 1/2 ULP\n        check_double(make_double(50883641005312716, -172) /* 8.4999999999999993e-036 */,  \"8499999999999999\",  -51);\n        check_double(make_double(38162730753984537, -170) /* 2.5499999999999999e-035 */,               \"255\",  -37);\n        check_double(make_double(50832789069151999, -101) /* 2.0049999999999997e-014 */, \"20049999999999997\",  -30);\n        check_double(make_double(51822367833714164, -109) /* 7.9844999999999994e-017 */,  \"7984499999999999\",  -32);\n        check_double(make_double(66840152193508133, -172) /* 1.1165499999999999e-035 */, \"11165499999999999\",  -51);\n        check_double(make_double(55111239245584393, -138) /*           1.581615e-025 */,           \"1581615\",  -31);\n        check_double(make_double(71704866733321482, -112) /*          1.3809855e-017 */,          \"13809855\",  -24);\n        check_double(make_double(67160949328233173, -142) /* 1.2046404499999999e-026 */, \"12046404499999999\",  -42);\n        check_double(make_double(53237141308040189, -152) /* 9.3251405449999991e-030 */,  \"9325140544999999\",  -45);\n        check_double(make_double(62785329394975786, -112) /*       1.2092014595e-017 */,       \"12092014595\",  -27);\n        check_double(make_double(48367680154689523,  -77) /* 3.2007045838499998e-007 */,      \"320070458385\",  -18);\n        check_double(make_double(42552223180606797, -102) /*  8.391946324354999e-015 */,  \"8391946324354999\",  -30);\n        check_double(make_double(63626356173011241, -112) /*    1.2253990460585e-017 */,    \"12253990460585\",  -30);\n        check_double(make_double(43566388595783643,  -99) /* 6.8735641489760495e-014 */,   \"687356414897605\",  -28);\n        check_double(make_double(54512669636675272, -159) /*  7.459816430480385e-032 */,  \"7459816430480385\",  -47);\n        check_double(make_double(52306490527514614, -167) /* 2.7960588398142552e-034 */,  \"2796058839814255\",  -49);\n        check_double(make_double(52306490527514614, -168) /* 1.3980294199071276e-034 */, \"13980294199071276\",  -50);\n        check_double(make_double(41024721590449423,  -89) /* 6.6279012373057359e-011 */,  \"6627901237305736\",  -26);\n        check_double(make_double(37664020415894738, -132) /* 6.9177880043968072e-024 */,  \"6917788004396807\",  -39);\n        check_double(make_double(37549883692866294,  -93) /* 3.7915693108349708e-012 */,  \"3791569310834971\",  -27);\n        check_double(make_double(69124110374399839, -104) /* 3.4080817676591365e-015 */, \"34080817676591365\",  -31);\n        check_double(make_double(69124110374399839, -105) /* 1.7040408838295683e-015 */, \"17040408838295683\",  -31);\n\n        // Table 21: Stress Inputs for Converting 56-bit Binary to Decimal, > 1/2 ULP\n        check_double(make_double(49517601571415211,  -94) /* 2.4999999999999998e-012 */,                \"25\",  -13);\n        check_double(make_double(49517601571415211,  -95) /* 1.2499999999999999e-012 */,               \"125\",  -14);\n        check_double(make_double(54390733528642804, -133) /* 4.9949999999999996e-024 */, \"49949999999999996\",  -40); // shortest: 4995e-27\n        check_double(make_double(71805402319113924, -157) /* 3.9304999999999998e-031 */, \"39304999999999998\",  -47); // shortest: 39305e-35\n        check_double(make_double(40435277969631694, -179) /* 5.2770499999999992e-038 */,  \"5277049999999999\",  -53);\n        check_double(make_double(57241991568619049, -165) /*           1.223955e-033 */,           \"1223955\",  -39);\n        check_double(make_double(65224162876242886,  +58) /* 1.8799584999999998e+034 */, \"18799584999999998\",   18);\n        check_double(make_double(70173376848895368, -138) /*         2.01387715e-025 */,         \"201387715\",  -33);\n        check_double(make_double(37072848117383207,  -99) /* 5.8490641049999989e-014 */,  \"5849064104999999\",  -29);\n        check_double(make_double(56845051585389697, -176) /* 5.9349003054999999e-037 */,       \"59349003055\",  -47);\n        check_double(make_double(54791673366936431, -145) /* 1.2284718039499998e-027 */, \"12284718039499998\",  -43);\n        check_double(make_double(66800318669106231, -169) /* 8.9270767180849991e-035 */,  \"8927076718084999\",  -50);\n        check_double(make_double(66800318669106231, -170) /* 4.4635383590424995e-035 */, \"44635383590424995\",  -51);\n        check_double(make_double(66574323440112438, -119) /* 1.0016990862549499e-019 */, \"10016990862549499\",  -35);\n        check_double(make_double(65645179969330963, -173) /* 5.4829412628024647e-036 */,  \"5482941262802465\",  -51);\n        check_double(make_double(61847254334681076, -109) /* 9.5290783281036439e-017 */,  \"9529078328103644\",  -32);\n        check_double(make_double(39990712921393606, -145) /* 8.9662279366405553e-028 */,  \"8966227936640555\",  -43);\n        check_double(make_double(59292318184400283, -149) /* 8.3086234418058538e-029 */,  \"8308623441805854\",  -44);\n        check_double(make_double(69116558615326153, -143) /* 6.1985873566126555e-027 */, \"61985873566126555\",  -43);\n        check_double(make_double(69116558615326153, -144) /* 3.0992936783063277e-027 */, \"30992936783063277\",  -43);\n        check_double(make_double(39462549494468513, -152) /* 6.9123512506176015e-030 */,  \"6912351250617602\",  -45);\n        check_double(make_double(39462549494468513, -153) /* 3.4561756253088008e-030 */,  \"3456175625308801\",  -45);\n    }\n}\n\nTEST_CASE(\"formatting\")\n{\n    SECTION(\"single precision\")\n    {\n        auto check_float = [](float number, const std::string & expected)\n        {\n            std::array<char, 33> buf{};\n            char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n            std::string actual(buf.data(), end);\n\n            CHECK(actual == expected);\n        };\n        // %.9g\n        check_float( -1.2345e-22f, \"-1.2345e-22\"  ); // -1.23450004e-22\n        check_float( -1.2345e-21f, \"-1.2345e-21\"  ); // -1.23450002e-21\n        check_float( -1.2345e-20f, \"-1.2345e-20\"  ); // -1.23450002e-20\n        check_float( -1.2345e-19f, \"-1.2345e-19\"  ); // -1.23449999e-19\n        check_float( -1.2345e-18f, \"-1.2345e-18\"  ); // -1.23449996e-18\n        check_float( -1.2345e-17f, \"-1.2345e-17\"  ); // -1.23449998e-17\n        check_float( -1.2345e-16f, \"-1.2345e-16\"  ); // -1.23449996e-16\n        check_float( -1.2345e-15f, \"-1.2345e-15\"  ); // -1.23450002e-15\n        check_float( -1.2345e-14f, \"-1.2345e-14\"  ); // -1.23450004e-14\n        check_float( -1.2345e-13f, \"-1.2345e-13\"  ); // -1.23449997e-13\n        check_float( -1.2345e-12f, \"-1.2345e-12\"  ); // -1.23450002e-12\n        check_float( -1.2345e-11f, \"-1.2345e-11\"  ); // -1.2345e-11\n        check_float( -1.2345e-10f, \"-1.2345e-10\"  ); // -1.2345e-10\n        check_float( -1.2345e-9f,  \"-1.2345e-09\"  ); // -1.23449995e-09\n        check_float( -1.2345e-8f,  \"-1.2345e-08\"  ); // -1.23449997e-08\n        check_float( -1.2345e-7f,  \"-1.2345e-07\"  ); // -1.23449993e-07\n        check_float( -1.2345e-6f,  \"-1.2345e-06\"  ); // -1.23450002e-06\n        check_float( -1.2345e-5f,  \"-1.2345e-05\"  ); // -1.2345e-05\n        check_float( -1.2345e-4f,  \"-0.00012345\"  ); // -0.000123449994\n        check_float( -1.2345e-3f,  \"-0.0012345\"   ); // -0.00123449997\n        check_float( -1.2345e-2f,  \"-0.012345\"    ); // -0.0123450002\n        check_float( -1.2345e-1f,  \"-0.12345\"     ); // -0.123450004\n        check_float( -0.0f,        \"-0.0\"         ); // -0\n        check_float(  0.0f,         \"0.0\"         ); //  0\n        check_float(  1.2345e+0f,   \"1.2345\"      ); //  1.23450005\n        check_float(  1.2345e+1f,   \"12.345\"      ); //  12.3450003\n        check_float(  1.2345e+2f,   \"123.45\"      ); //  123.449997\n        check_float(  1.2345e+3f,   \"1234.5\"      ); //  1234.5\n        check_float(  1.2345e+4f,   \"12345.0\"     ); //  12345\n        check_float(  1.2345e+5f,   \"123450.0\"    ); //  123450\n        check_float(  1.2345e+6f,   \"1.2345e+06\"  ); //  1234500\n        check_float(  1.2345e+7f,   \"1.2345e+07\"  ); //  12345000\n        check_float(  1.2345e+8f,   \"1.2345e+08\"  ); //  123450000\n        check_float(  1.2345e+9f,   \"1.2345e+09\"  ); //  1.23449997e+09\n        check_float(  1.2345e+10f,  \"1.2345e+10\"  ); //  1.23449999e+10\n        check_float(  1.2345e+11f,  \"1.2345e+11\"  ); //  1.23449999e+11\n        check_float(  1.2345e+12f,  \"1.2345e+12\"  ); //  1.23450006e+12\n        check_float(  1.2345e+13f,  \"1.2345e+13\"  ); //  1.23449995e+13\n        check_float(  1.2345e+14f,  \"1.2345e+14\"  ); //  1.23450002e+14\n        check_float(  1.2345e+15f,  \"1.2345e+15\"  ); //  1.23450003e+15\n        check_float(  1.2345e+16f,  \"1.2345e+16\"  ); //  1.23449998e+16\n        check_float(  1.2345e+17f,  \"1.2345e+17\"  ); //  1.23449996e+17\n        check_float(  1.2345e+18f,  \"1.2345e+18\"  ); //  1.23450004e+18\n        check_float(  1.2345e+19f,  \"1.2345e+19\"  ); //  1.23449999e+19\n        check_float(  1.2345e+20f,  \"1.2345e+20\"  ); //  1.23449999e+20\n        check_float(  1.2345e+21f,  \"1.2345e+21\"  ); //  1.23449999e+21\n        check_float(  1.2345e+22f,  \"1.2345e+22\"  ); //  1.23450005e+22\n    }\n\n    SECTION(\"double precision\")\n    {\n        auto check_double = [](double number, const std::string & expected)\n        {\n            std::array<char, 33> buf{};\n            char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)\n            std::string actual(buf.data(), end);\n\n            CHECK(actual == expected);\n        };\n        //                           dtoa                           %.15g                     %.17g                     shortest\n        check_double( -1.2345e-22,  \"-1.2345e-22\"             ); // -1.2345e-22               -1.2345000000000001e-22   -1.2345e-22\n        check_double( -1.2345e-21,  \"-1.2345e-21\"             ); // -1.2345e-21               -1.2345000000000001e-21   -1.2345e-21\n        check_double( -1.2345e-20,  \"-1.2345e-20\"             ); // -1.2345e-20               -1.2345e-20               -1.2345e-20\n        check_double( -1.2345e-19,  \"-1.2345e-19\"             ); // -1.2345e-19               -1.2345000000000001e-19   -1.2345e-19\n        check_double( -1.2345e-18,  \"-1.2345e-18\"             ); // -1.2345e-18               -1.2345000000000001e-18   -1.2345e-18\n        check_double( -1.2345e-17,  \"-1.2345e-17\"             ); // -1.2345e-17               -1.2345e-17               -1.2345e-17\n        check_double( -1.2345e-16,  \"-1.2345e-16\"             ); // -1.2345e-16               -1.2344999999999999e-16   -1.2345e-16\n        check_double( -1.2345e-15,  \"-1.2345e-15\"             ); // -1.2345e-15               -1.2345e-15               -1.2345e-15\n        check_double( -1.2345e-14,  \"-1.2345e-14\"             ); // -1.2345e-14               -1.2345e-14               -1.2345e-14\n        check_double( -1.2345e-13,  \"-1.2345e-13\"             ); // -1.2345e-13               -1.2344999999999999e-13   -1.2345e-13\n        check_double( -1.2345e-12,  \"-1.2345e-12\"             ); // -1.2345e-12               -1.2345e-12               -1.2345e-12\n        check_double( -1.2345e-11,  \"-1.2345e-11\"             ); // -1.2345e-11               -1.2345e-11               -1.2345e-11\n        check_double( -1.2345e-10,  \"-1.2345e-10\"             ); // -1.2345e-10               -1.2345e-10               -1.2345e-10\n        check_double( -1.2345e-9,   \"-1.2345e-09\"             ); // -1.2345e-09               -1.2345e-09               -1.2345e-9\n        check_double( -1.2345e-8,   \"-1.2345e-08\"             ); // -1.2345e-08               -1.2345000000000001e-08   -1.2345e-8\n        check_double( -1.2345e-7,   \"-1.2345e-07\"             ); // -1.2345e-07               -1.2345000000000001e-07   -1.2345e-7\n        check_double( -1.2345e-6,   \"-1.2345e-06\"             ); // -1.2345e-06               -1.2345e-06               -1.2345e-6\n        check_double( -1.2345e-5,   \"-1.2345e-05\"             ); // -1.2345e-05               -1.2345e-05               -1.2345e-5\n        check_double( -1.2345e-4,   \"-0.00012345\"             ); // -0.00012345               -0.00012344999999999999   -0.00012345\n        check_double( -1.2345e-3,   \"-0.0012345\"              ); // -0.0012345                -0.0012344999999999999    -0.0012345\n        check_double( -1.2345e-2,   \"-0.012345\"               ); // -0.012345                 -0.012345                 -0.012345\n        check_double( -1.2345e-1,   \"-0.12345\"                ); // -0.12345                  -0.12345                  -0.12345\n        check_double( -0.0,         \"-0.0\"                    ); // -0                        -0                        -0\n        check_double(  0.0,          \"0.0\"                    ); //  0                         0                         0\n        check_double(  1.2345e+0,    \"1.2345\"                 ); //  1.2345                    1.2344999999999999        1.2345\n        check_double(  1.2345e+1,    \"12.345\"                 ); //  12.345                    12.345000000000001        12.345\n        check_double(  1.2345e+2,    \"123.45\"                 ); //  123.45                    123.45                    123.45\n        check_double(  1.2345e+3,    \"1234.5\"                 ); //  1234.5                    1234.5                    1234.5\n        check_double(  1.2345e+4,    \"12345.0\"                ); //  12345                     12345                     12345\n        check_double(  1.2345e+5,    \"123450.0\"               ); //  123450                    123450                    123450\n        check_double(  1.2345e+6,    \"1234500.0\"              ); //  1234500                   1234500                   1234500\n        check_double(  1.2345e+7,    \"12345000.0\"             ); //  12345000                  12345000                  12345000\n        check_double(  1.2345e+8,    \"123450000.0\"            ); //  123450000                 123450000                 123450000\n        check_double(  1.2345e+9,    \"1234500000.0\"           ); //  1234500000                1234500000                1234500000\n        check_double(  1.2345e+10,   \"12345000000.0\"          ); //  12345000000               12345000000               12345000000\n        check_double(  1.2345e+11,   \"123450000000.0\"         ); //  123450000000              123450000000              123450000000\n        check_double(  1.2345e+12,   \"1234500000000.0\"        ); //  1234500000000             1234500000000             1234500000000\n        check_double(  1.2345e+13,   \"12345000000000.0\"       ); //  12345000000000            12345000000000            12345000000000\n        check_double(  1.2345e+14,   \"123450000000000.0\"      ); //  123450000000000           123450000000000           123450000000000\n        check_double(  1.2345e+15,   \"1.2345e+15\"             ); //  1.2345e+15                1234500000000000          1.2345e15\n        check_double(  1.2345e+16,   \"1.2345e+16\"             ); //  1.2345e+16                12345000000000000         1.2345e16\n        check_double(  1.2345e+17,   \"1.2345e+17\"             ); //  1.2345e+17                1.2345e+17                1.2345e17\n        check_double(  1.2345e+18,   \"1.2345e+18\"             ); //  1.2345e+18                1.2345e+18                1.2345e18\n        check_double(  1.2345e+19,   \"1.2345e+19\"             ); //  1.2345e+19                1.2345e+19                1.2345e19\n        check_double(  1.2345e+20,   \"1.2345e+20\"             ); //  1.2345e+20                1.2345e+20                1.2345e20\n        check_double(  1.2345e+21,   \"1.2344999999999999e+21\" ); //  1.2345e+21                1.2344999999999999e+21    1.2345e21\n        check_double(  1.2345e+22,   \"1.2345e+22\"             ); //  1.2345e+22                1.2345e+22                1.2345e22\n    }\n\n    SECTION(\"integer\")\n    {\n        auto check_integer = [](std::int64_t number, const std::string & expected)\n        {\n            nlohmann::json j = number;\n            CHECK(j.dump() == expected);\n        };\n\n        // edge cases\n        check_integer(INT64_MIN, \"-9223372036854775808\");\n        check_integer(INT64_MAX, \"9223372036854775807\");\n\n        // few random big integers\n        check_integer(-3456789012345678901LL, \"-3456789012345678901\");\n        check_integer(3456789012345678901LL, \"3456789012345678901\");\n        check_integer(-5678901234567890123LL, \"-5678901234567890123\");\n        check_integer(5678901234567890123LL, \"5678901234567890123\");\n\n        // integers with various digit counts\n        check_integer(-1000000000000000000LL, \"-1000000000000000000\");\n        check_integer(-100000000000000000LL, \"-100000000000000000\");\n        check_integer(-10000000000000000LL, \"-10000000000000000\");\n        check_integer(-1000000000000000LL, \"-1000000000000000\");\n        check_integer(-100000000000000LL, \"-100000000000000\");\n        check_integer(-10000000000000LL, \"-10000000000000\");\n        check_integer(-1000000000000LL, \"-1000000000000\");\n        check_integer(-100000000000LL, \"-100000000000\");\n        check_integer(-10000000000LL, \"-10000000000\");\n        check_integer(-1000000000LL, \"-1000000000\");\n        check_integer(-100000000LL, \"-100000000\");\n        check_integer(-10000000LL, \"-10000000\");\n        check_integer(-1000000LL, \"-1000000\");\n        check_integer(-100000LL, \"-100000\");\n        check_integer(-10000LL, \"-10000\");\n        check_integer(-1000LL, \"-1000\");\n        check_integer(-100LL, \"-100\");\n        check_integer(-10LL, \"-10\");\n        check_integer(-1LL, \"-1\");\n        check_integer(0, \"0\");\n        check_integer(1LL, \"1\");\n        check_integer(10LL, \"10\");\n        check_integer(100LL, \"100\");\n        check_integer(1000LL, \"1000\");\n        check_integer(10000LL, \"10000\");\n        check_integer(100000LL, \"100000\");\n        check_integer(1000000LL, \"1000000\");\n        check_integer(10000000LL, \"10000000\");\n        check_integer(100000000LL, \"100000000\");\n        check_integer(1000000000LL, \"1000000000\");\n        check_integer(10000000000LL, \"10000000000\");\n        check_integer(100000000000LL, \"100000000000\");\n        check_integer(1000000000000LL, \"1000000000000\");\n        check_integer(10000000000000LL, \"10000000000000\");\n        check_integer(100000000000000LL, \"100000000000000\");\n        check_integer(1000000000000000LL, \"1000000000000000\");\n        check_integer(10000000000000000LL, \"10000000000000000\");\n        check_integer(100000000000000000LL, \"100000000000000000\");\n        check_integer(1000000000000000000LL, \"1000000000000000000\");\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-ubjson.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <iostream>\n#include <fstream>\n#include <set>\n#include <test_data.hpp>\n#include \"test_utils.hpp\"\n\nnamespace\n{\nclass SaxCountdown\n{\n  public:\n    explicit SaxCountdown(const int count) : events_left(count)\n    {}\n\n    bool null()\n    {\n        return events_left-- > 0;\n    }\n\n    bool boolean(bool /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_integer(json::number_integer_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_unsigned(json::number_unsigned_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool string(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool binary(std::vector<std::uint8_t>& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_object(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool key(std::string& /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_object()\n    {\n        return events_left-- > 0;\n    }\n\n    bool start_array(std::size_t /*unused*/)\n    {\n        return events_left-- > 0;\n    }\n\n    bool end_array()\n    {\n        return events_left-- > 0;\n    }\n\n    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)\n    {\n        return false;\n    }\n\n  private:\n    int events_left = 0;\n};\n} // namespace\n\nTEST_CASE(\"UBJSON\")\n{\n    SECTION(\"individual values\")\n    {\n        SECTION(\"discarded\")\n        {\n            // discarded values are not serialized\n            json j = json::value_t::discarded;\n            const auto result = json::to_ubjson(j);\n            CHECK(result.empty());\n        }\n\n        SECTION(\"null\")\n        {\n            json j = nullptr;\n            std::vector<uint8_t> expected = {'Z'};\n            const auto result = json::to_ubjson(j);\n            CHECK(result == expected);\n\n            // roundtrip\n            CHECK(json::from_ubjson(result) == j);\n            CHECK(json::from_ubjson(result, true, false) == j);\n        }\n\n        SECTION(\"boolean\")\n        {\n            SECTION(\"true\")\n            {\n                json j = true;\n                std::vector<uint8_t> expected = {'T'};\n                const auto result = json::to_ubjson(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_ubjson(result) == j);\n                CHECK(json::from_ubjson(result, true, false) == j);\n            }\n\n            SECTION(\"false\")\n            {\n                json j = false;\n                std::vector<uint8_t> expected = {'F'};\n                const auto result = json::to_ubjson(j);\n                CHECK(result == expected);\n\n                // roundtrip\n                CHECK(json::from_ubjson(result) == j);\n                CHECK(json::from_ubjson(result, true, false) == j);\n            }\n        }\n\n        SECTION(\"number\")\n        {\n            SECTION(\"signed\")\n            {\n                SECTION(\"-9223372036854775808..-2147483649 (int64)\")\n                {\n                    std::vector<int64_t> numbers;\n                    numbers.push_back((std::numeric_limits<int64_t>::min)());\n                    numbers.push_back(-1000000000000000000LL);\n                    numbers.push_back(-100000000000000000LL);\n                    numbers.push_back(-10000000000000000LL);\n                    numbers.push_back(-1000000000000000LL);\n                    numbers.push_back(-100000000000000LL);\n                    numbers.push_back(-10000000000000LL);\n                    numbers.push_back(-1000000000000LL);\n                    numbers.push_back(-100000000000LL);\n                    numbers.push_back(-10000000000LL);\n                    numbers.push_back(-2147483649LL);\n                    for (auto i : numbers)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>('L'));\n                        expected.push_back(static_cast<uint8_t>((i >> 56) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 48) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 40) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 32) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'L');\n                        int64_t restored = (static_cast<int64_t>(result[1]) << 070) +\n                                           (static_cast<int64_t>(result[2]) << 060) +\n                                           (static_cast<int64_t>(result[3]) << 050) +\n                                           (static_cast<int64_t>(result[4]) << 040) +\n                                           (static_cast<int64_t>(result[5]) << 030) +\n                                           (static_cast<int64_t>(result[6]) << 020) +\n                                           (static_cast<int64_t>(result[7]) << 010) +\n                                           static_cast<int64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-2147483648..-32769 (int32)\")\n                {\n                    std::vector<int32_t> numbers;\n                    numbers.push_back(-32769);\n                    numbers.push_back(-100000);\n                    numbers.push_back(-1000000);\n                    numbers.push_back(-10000000);\n                    numbers.push_back(-100000000);\n                    numbers.push_back(-1000000000);\n                    numbers.push_back(-2147483647 - 1); // https://stackoverflow.com/a/29356002/266378\n                    for (auto i : numbers)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>('l'));\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'l');\n                        int32_t restored = (static_cast<int32_t>(result[1]) << 030) +\n                                           (static_cast<int32_t>(result[2]) << 020) +\n                                           (static_cast<int32_t>(result[3]) << 010) +\n                                           static_cast<int32_t>(result[4]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-32768..-129 (int16)\")\n                {\n                    for (int32_t i = -32768; i <= -129; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>('I'));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'I');\n                        auto restored = static_cast<int16_t>(((result[1] << 8) + result[2]));\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"-9263 (int16)\")\n                {\n                    json j = -9263;\n                    std::vector<uint8_t> expected = {'I', 0xdb, 0xd1};\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == 3);\n\n                    // check individual bytes\n                    CHECK(result[0] == 'I');\n                    auto restored = static_cast<int16_t>(((result[1] << 8) + result[2]));\n                    CHECK(restored == -9263);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"-128..-1 (int8)\")\n                {\n                    for (auto i = -128; i <= -1; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('i');\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'i');\n                        CHECK(static_cast<int8_t>(result[1]) == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"0..127 (int8)\")\n                {\n                    for (size_t i = 0; i <= 127; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>('i'));\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'i');\n                        CHECK(result[1] == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"128..255 (uint8)\")\n                {\n                    for (size_t i = 128; i <= 255; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>('U'));\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'U');\n                        CHECK(result[1] == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"256..32767 (int16)\")\n                {\n                    for (size_t i = 256; i <= 32767; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back(static_cast<uint8_t>('I'));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'I');\n                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"65536..2147483647 (int32)\")\n                {\n                    for (uint32_t i :\n                            {\n                                65536u, 77777u, 1048576u\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('l');\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'l');\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"2147483648..9223372036854775807 (int64)\")\n                {\n                    std::vector<uint64_t> v = {2147483648ul, 9223372036854775807ul};\n                    for (uint64_t i : v)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = -1;\n                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);\n\n                        // check type\n                        CHECK(j.is_number_integer());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('L');\n                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'L');\n                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +\n                                            (static_cast<uint64_t>(result[2]) << 060) +\n                                            (static_cast<uint64_t>(result[3]) << 050) +\n                                            (static_cast<uint64_t>(result[4]) << 040) +\n                                            (static_cast<uint64_t>(result[5]) << 030) +\n                                            (static_cast<uint64_t>(result[6]) << 020) +\n                                            (static_cast<uint64_t>(result[7]) << 010) +\n                                            static_cast<uint64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n            }\n\n            SECTION(\"unsigned\")\n            {\n                SECTION(\"0..127 (int8)\")\n                {\n                    for (size_t i = 0; i <= 127; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('i');\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'i');\n                        auto restored = static_cast<uint8_t>(result[1]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"128..255 (uint8)\")\n                {\n                    for (size_t i = 128; i <= 255; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('U');\n                        expected.push_back(static_cast<uint8_t>(i));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 2);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'U');\n                        auto restored = static_cast<uint8_t>(result[1]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"256..32767 (int16)\")\n                {\n                    for (size_t i = 256; i <= 32767; ++i)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('I');\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 3);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'I');\n                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"65536..2147483647 (int32)\")\n                {\n                    for (uint32_t i :\n                            {\n                                65536u, 77777u, 1048576u\n                            })\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with unsigned integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('l');\n                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 5);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'l');\n                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +\n                                            (static_cast<uint32_t>(result[2]) << 020) +\n                                            (static_cast<uint32_t>(result[3]) << 010) +\n                                            static_cast<uint32_t>(result[4]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n\n                SECTION(\"2147483648..9223372036854775807 (int64)\")\n                {\n                    std::vector<uint64_t> v = {2147483648ul, 9223372036854775807ul};\n                    for (uint64_t i : v)\n                    {\n                        CAPTURE(i)\n\n                        // create JSON value with integer number\n                        json j = i;\n\n                        // check type\n                        CHECK(j.is_number_unsigned());\n\n                        // create expected byte vector\n                        std::vector<uint8_t> expected;\n                        expected.push_back('L');\n                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));\n                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));\n                        expected.push_back(static_cast<uint8_t>(i & 0xff));\n\n                        // compare result + size\n                        const auto result = json::to_ubjson(j);\n                        CHECK(result == expected);\n                        CHECK(result.size() == 9);\n\n                        // check individual bytes\n                        CHECK(result[0] == 'L');\n                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +\n                                            (static_cast<uint64_t>(result[2]) << 060) +\n                                            (static_cast<uint64_t>(result[3]) << 050) +\n                                            (static_cast<uint64_t>(result[4]) << 040) +\n                                            (static_cast<uint64_t>(result[5]) << 030) +\n                                            (static_cast<uint64_t>(result[6]) << 020) +\n                                            (static_cast<uint64_t>(result[7]) << 010) +\n                                            static_cast<uint64_t>(result[8]);\n                        CHECK(restored == i);\n\n                        // roundtrip\n                        CHECK(json::from_ubjson(result) == j);\n                        CHECK(json::from_ubjson(result, true, false) == j);\n                    }\n                }\n            }\n\n            SECTION(\"float64\")\n            {\n                SECTION(\"3.1415925\")\n                {\n                    double v = 3.1415925;\n                    json j = v;\n                    std::vector<uint8_t> expected =\n                    {\n                        'D', 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc\n                    };\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result) == v);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"high-precision number\")\n            {\n                SECTION(\"unsigned integer number\")\n                {\n                    std::vector<uint8_t> vec = {'H', 'i', 0x14, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};\n                    const auto j = json::from_ubjson(vec);\n                    CHECK(j.is_number_unsigned());\n                    CHECK(j.dump() == \"12345678901234567890\");\n                }\n\n                SECTION(\"signed integer number\")\n                {\n                    std::vector<uint8_t> vec = {'H', 'i', 0x13, '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'};\n                    const auto j = json::from_ubjson(vec);\n                    CHECK(j.is_number_integer());\n                    CHECK(j.dump() == \"-123456789012345678\");\n                }\n\n                SECTION(\"floating-point number\")\n                {\n                    std::vector<uint8_t> vec = {'H', 'i', 0x16, '3', '.', '1', '4', '1', '5', '9',  '2', '6', '5', '3', '5', '8', '9',  '7', '9', '3', '2', '3', '8', '4',  '6'};\n                    const auto j = json::from_ubjson(vec);\n                    CHECK(j.is_number_float());\n                    CHECK(j.dump() == \"3.141592653589793\");\n                }\n\n                SECTION(\"errors\")\n                {\n                    // error while parsing length\n                    std::vector<uint8_t> vec0 = {'H', 'i'};\n                    CHECK(json::from_ubjson(vec0, true, false).is_discarded());\n                    // error while parsing string\n                    std::vector<uint8_t> vec1 = {'H', 'i', '1'};\n                    CHECK(json::from_ubjson(vec1, true, false).is_discarded());\n\n                    json _;\n                    std::vector<uint8_t> vec2 = {'H', 'i', 2, '1', 'A', '3'};\n                    CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec2), \"[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A\", json::parse_error);\n                    std::vector<uint8_t> vec3 = {'H', 'i', 2, '1', '.'};\n                    CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec3), \"[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1.\", json::parse_error);\n                    std::vector<uint8_t> vec4 = {'H', 2, '1', '0'};\n                    CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec4), \"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x02\", json::parse_error);\n                }\n\n                SECTION(\"serialization\")\n                {\n                    // number that does not fit int64\n                    json j = 11111111111111111111ULL;\n                    CHECK(j.is_number_unsigned());\n\n                    // number will be serialized to high-precision number\n                    const auto vec = json::to_ubjson(j);\n                    std::vector<uint8_t> expected = {'H', 'i', 0x14, '1',  '1',  '1',  '1',  '1', '1',  '1',  '1',  '1',  '1', '1',  '1',  '1',  '1',  '1', '1',  '1',  '1',  '1',  '1'};\n                    CHECK(vec == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(vec) == j);\n                }\n            }\n        }\n\n        SECTION(\"string\")\n        {\n            SECTION(\"N = 0..127\")\n            {\n                for (size_t N = 0; N <= 127; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back('S');\n                    expected.push_back('i');\n                    expected.push_back(static_cast<uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back('x');\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 3);\n                    // check that no null byte is appended\n                    if (N > 0)\n                    {\n                        CHECK(result.back() != '\\x00');\n                    }\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 128..255\")\n            {\n                for (size_t N = 128; N <= 255; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back('S');\n                    expected.push_back('U');\n                    expected.push_back(static_cast<uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back('x');\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 3);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 256..32767\")\n            {\n                for (size_t N :\n                        {\n                            256u, 999u, 1025u, 3333u, 2048u, 32767u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), 'I');\n                    expected.insert(expected.begin(), 'S');\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 4);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"N = 65536..2147483647\")\n            {\n                for (size_t N :\n                        {\n                            65536u, 77777u, 1048576u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with string containing of N * 'x'\n                    const auto s = std::string(N, 'x');\n                    json j = s;\n\n                    // create expected byte vector (hack: create string first)\n                    std::vector<uint8_t> expected(N, 'x');\n                    // reverse order of commands, because we insert at begin()\n                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));\n                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));\n                    expected.insert(expected.begin(), 'l');\n                    expected.insert(expected.begin(), 'S');\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 6);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n        }\n\n        SECTION(\"binary\")\n        {\n            SECTION(\"N = 0..127\")\n            {\n                for (std::size_t N = 0; N <= 127; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with byte array containing of N * 'x'\n                    const auto s = std::vector<std::uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector\n                    std::vector<std::uint8_t> expected;\n                    expected.push_back(static_cast<std::uint8_t>('['));\n                    if (N != 0)\n                    {\n                        expected.push_back(static_cast<std::uint8_t>('$'));\n                        expected.push_back(static_cast<std::uint8_t>('U'));\n                    }\n                    expected.push_back(static_cast<std::uint8_t>('#'));\n                    expected.push_back(static_cast<std::uint8_t>('i'));\n                    expected.push_back(static_cast<std::uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back(0x78);\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n                    if (N == 0)\n                    {\n                        CHECK(result.size() == N + 4);\n                    }\n                    else\n                    {\n                        CHECK(result.size() == N + 6);\n                    }\n\n                    // check that no null byte is appended\n                    if (N > 0)\n                    {\n                        CHECK(result.back() != '\\x00');\n                    }\n\n                    // roundtrip only works to an array of numbers\n                    json j_out = s;\n                    CHECK(json::from_ubjson(result) == j_out);\n                    CHECK(json::from_ubjson(result, true, false) == j_out);\n                }\n            }\n\n            SECTION(\"N = 128..255\")\n            {\n                for (std::size_t N = 128; N <= 255; ++N)\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with byte array containing of N * 'x'\n                    const auto s = std::vector<std::uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector\n                    std::vector<uint8_t> expected;\n                    expected.push_back(static_cast<std::uint8_t>('['));\n                    expected.push_back(static_cast<std::uint8_t>('$'));\n                    expected.push_back(static_cast<std::uint8_t>('U'));\n                    expected.push_back(static_cast<std::uint8_t>('#'));\n                    expected.push_back(static_cast<std::uint8_t>('U'));\n                    expected.push_back(static_cast<std::uint8_t>(N));\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back(0x78);\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 6);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip only works to an array of numbers\n                    json j_out = s;\n                    CHECK(json::from_ubjson(result) == j_out);\n                    CHECK(json::from_ubjson(result, true, false) == j_out);\n                }\n            }\n\n            SECTION(\"N = 256..32767\")\n            {\n                for (std::size_t N :\n                        {\n                            256u, 999u, 1025u, 3333u, 2048u, 32767u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with byte array containing of N * 'x'\n                    const auto s = std::vector<std::uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector\n                    std::vector<std::uint8_t> expected(N + 7, 'x');\n                    expected[0] = '[';\n                    expected[1] = '$';\n                    expected[2] = 'U';\n                    expected[3] = '#';\n                    expected[4] = 'I';\n                    expected[5] = static_cast<std::uint8_t>((N >> 8) & 0xFF);\n                    expected[6] = static_cast<std::uint8_t>(N & 0xFF);\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 7);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip only works to an array of numbers\n                    json j_out = s;\n                    CHECK(json::from_ubjson(result) == j_out);\n                    CHECK(json::from_ubjson(result, true, false) == j_out);\n                }\n            }\n\n            SECTION(\"N = 32768..2147483647\")\n            {\n                for (std::size_t N :\n                        {\n                            32768u, 77777u, 1048576u\n                        })\n                {\n                    CAPTURE(N)\n\n                    // create JSON value with byte array containing of N * 'x'\n                    const auto s = std::vector<std::uint8_t>(N, 'x');\n                    json j = json::binary(s);\n\n                    // create expected byte vector\n                    std::vector<std::uint8_t> expected(N + 9, 'x');\n                    expected[0] = '[';\n                    expected[1] = '$';\n                    expected[2] = 'U';\n                    expected[3] = '#';\n                    expected[4] = 'l';\n                    expected[5] = static_cast<std::uint8_t>((N >> 24) & 0xFF);\n                    expected[6] = static_cast<std::uint8_t>((N >> 16) & 0xFF);\n                    expected[7] = static_cast<std::uint8_t>((N >> 8) & 0xFF);\n                    expected[8] = static_cast<std::uint8_t>(N & 0xFF);\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 9);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip only works to an array of numbers\n                    json j_out = s;\n                    CHECK(json::from_ubjson(result) == j_out);\n                    CHECK(json::from_ubjson(result, true, false) == j_out);\n                }\n            }\n\n            SECTION(\"Other Serializations\")\n            {\n                const std::size_t N = 10;\n                const auto s = std::vector<std::uint8_t>(N, 'x');\n                json j = json::binary(s);\n\n                SECTION(\"No Count No Type\")\n                {\n                    std::vector<uint8_t> expected;\n                    expected.push_back(static_cast<std::uint8_t>('['));\n                    for (std::size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back(static_cast<std::uint8_t>('U'));\n                        expected.push_back(static_cast<std::uint8_t>(0x78));\n                    }\n                    expected.push_back(static_cast<std::uint8_t>(']'));\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j, false, false);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 12);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip only works to an array of numbers\n                    json j_out = s;\n                    CHECK(json::from_ubjson(result) == j_out);\n                    CHECK(json::from_ubjson(result, true, false) == j_out);\n                }\n\n                SECTION(\"Yes Count No Type\")\n                {\n                    std::vector<std::uint8_t> expected;\n                    expected.push_back(static_cast<std::uint8_t>('['));\n                    expected.push_back(static_cast<std::uint8_t>('#'));\n                    expected.push_back(static_cast<std::uint8_t>('i'));\n                    expected.push_back(static_cast<std::uint8_t>(N));\n\n                    for (size_t i = 0; i < N; ++i)\n                    {\n                        expected.push_back(static_cast<std::uint8_t>('U'));\n                        expected.push_back(static_cast<std::uint8_t>(0x78));\n                    }\n\n                    // compare result + size\n                    const auto result = json::to_ubjson(j, true, false);\n                    CHECK(result == expected);\n                    CHECK(result.size() == N + 14);\n                    // check that no null byte is appended\n                    CHECK(result.back() != '\\x00');\n\n                    // roundtrip only works to an array of numbers\n                    json j_out = s;\n                    CHECK(json::from_ubjson(result) == j_out);\n                    CHECK(json::from_ubjson(result, true, false) == j_out);\n                }\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"empty\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j = json::array();\n                    std::vector<uint8_t> expected = {'[', ']'};\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j = json::array();\n                    std::vector<uint8_t> expected = {'[', '#', 'i', 0};\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j = json::array();\n                    std::vector<uint8_t> expected = {'[', '#', 'i', 0};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"[null]\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j = {nullptr};\n                    std::vector<uint8_t> expected = {'[', 'Z', ']'};\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j = {nullptr};\n                    std::vector<uint8_t> expected = {'[', '#', 'i', 1, 'Z'};\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j = {nullptr};\n                    std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'i', 1};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"[1,2,3,4,5]\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j = json::parse(\"[1,2,3,4,5]\");\n                    std::vector<uint8_t> expected = {'[', 'i', 1, 'i', 2, 'i', 3, 'i', 4, 'i', 5, ']'};\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j = json::parse(\"[1,2,3,4,5]\");\n                    std::vector<uint8_t> expected = {'[', '#', 'i', 5, 'i', 1, 'i', 2, 'i', 3, 'i', 4, 'i', 5};\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j = json::parse(\"[1,2,3,4,5]\");\n                    std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 5, 1, 2, 3, 4, 5};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"[[[[]]]]\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j = json::parse(\"[[[[]]]]\");\n                    std::vector<uint8_t> expected = {'[', '[', '[', '[', ']', ']', ']', ']'};\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j = json::parse(\"[[[[]]]]\");\n                    std::vector<uint8_t> expected = {'[', '#', 'i', 1, '[', '#', 'i', 1, '[', '#', 'i', 1, '[', '#', 'i', 0};\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j = json::parse(\"[[[[]]]]\");\n                    std::vector<uint8_t> expected = {'[', '$', '[', '#', 'i', 1, '$', '[', '#', 'i', 1, '$', '[', '#', 'i', 1, '#', 'i', 0};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"array with uint16_t elements\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j(257, nullptr);\n                    std::vector<uint8_t> expected(j.size() + 2, 'Z'); // all null\n                    expected[0] = '['; // opening array\n                    expected[258] = ']'; // closing array\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j(257, nullptr);\n                    std::vector<uint8_t> expected(j.size() + 5, 'Z'); // all null\n                    expected[0] = '['; // opening array\n                    expected[1] = '#'; // array size\n                    expected[2] = 'I'; // int16\n                    expected[3] = 0x01; // 0x0101, first byte\n                    expected[4] = 0x01; // 0x0101, second byte\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j(257, nullptr);\n                    std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'I', 0x01, 0x01};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"array with uint32_t elements\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j(65793, nullptr);\n                    std::vector<uint8_t> expected(j.size() + 2, 'Z'); // all null\n                    expected[0] = '['; // opening array\n                    expected[65794] = ']'; // closing array\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j(65793, nullptr);\n                    std::vector<uint8_t> expected(j.size() + 7, 'Z'); // all null\n                    expected[0] = '['; // opening array\n                    expected[1] = '#'; // array size\n                    expected[2] = 'l'; // int32\n                    expected[3] = 0x00; // 0x00010101, first byte\n                    expected[4] = 0x01; // 0x00010101, second byte\n                    expected[5] = 0x01; // 0x00010101, third byte\n                    expected[6] = 0x01; // 0x00010101, fourth byte\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j(65793, nullptr);\n                    std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'l', 0x00, 0x01, 0x01, 0x01};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n        }\n\n        SECTION(\"object\")\n        {\n            SECTION(\"empty\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j = json::object();\n                    std::vector<uint8_t> expected = {'{', '}'};\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j = json::object();\n                    std::vector<uint8_t> expected = {'{', '#', 'i', 0};\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j = json::object();\n                    std::vector<uint8_t> expected = {'{', '#', 'i', 0};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"{\\\"\\\":null}\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j = {{\"\", nullptr}};\n                    std::vector<uint8_t> expected = {'{', 'i', 0, 'Z', '}'};\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j = {{\"\", nullptr}};\n                    std::vector<uint8_t> expected = {'{', '#', 'i', 1, 'i', 0, 'Z'};\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j = {{\"\", nullptr}};\n                    std::vector<uint8_t> expected = {'{', '$', 'Z', '#', 'i', 1, 'i', 0};\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n\n            SECTION(\"{\\\"a\\\": {\\\"b\\\": {\\\"c\\\": {}}}}\")\n            {\n                SECTION(\"size=false type=false\")\n                {\n                    json j = json::parse(R\"({\"a\": {\"b\": {\"c\": {}}}})\");\n                    std::vector<uint8_t> expected =\n                    {\n                        '{', 'i', 1, 'a', '{', 'i', 1, 'b', '{', 'i', 1, 'c', '{', '}', '}', '}', '}'\n                    };\n                    const auto result = json::to_ubjson(j);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=false\")\n                {\n                    json j = json::parse(R\"({\"a\": {\"b\": {\"c\": {}}}})\");\n                    std::vector<uint8_t> expected =\n                    {\n                        '{', '#', 'i', 1, 'i', 1, 'a', '{', '#', 'i', 1, 'i', 1, 'b', '{', '#', 'i', 1, 'i', 1, 'c', '{', '#', 'i', 0\n                    };\n                    const auto result = json::to_ubjson(j, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n\n                SECTION(\"size=true type=true\")\n                {\n                    json j = json::parse(R\"({\"a\": {\"b\": {\"c\": {}}}})\");\n                    std::vector<uint8_t> expected =\n                    {\n                        '{', '$', '{', '#', 'i', 1, 'i', 1, 'a', '$', '{', '#', 'i', 1, 'i', 1, 'b', '$', '{', '#', 'i', 1, 'i', 1, 'c', '#', 'i', 0\n                    };\n                    const auto result = json::to_ubjson(j, true, true);\n                    CHECK(result == expected);\n\n                    // roundtrip\n                    CHECK(json::from_ubjson(result) == j);\n                    CHECK(json::from_ubjson(result, true, false) == j);\n                }\n            }\n        }\n    }\n\n    SECTION(\"errors\")\n    {\n        SECTION(\"strict mode\")\n        {\n            std::vector<uint8_t> vec = {'Z', 'Z'};\n            SECTION(\"non-strict mode\")\n            {\n                const auto result = json::from_ubjson(vec, false);\n                CHECK(result == json());\n            }\n\n            SECTION(\"strict mode\")\n            {\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(vec), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_ubjson(vec),\n                                  \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A\");\n            }\n        }\n\n        SECTION(\"excessive size\")\n        {\n            SECTION(\"array\")\n            {\n                std::vector<uint8_t> v_ubjson = {'[', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);\n\n                json j;\n                nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)\n                {\n                    return true;\n                });\n                CHECK_THROWS_AS(_ = json::sax_parse(v_ubjson, &scp, json::input_format_t::ubjson), json::out_of_range&);\n            }\n\n            SECTION(\"object\")\n            {\n                std::vector<uint8_t> v_ubjson = {'{', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);\n\n                json j;\n                nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/)\n                {\n                    return true;\n                });\n                CHECK_THROWS_AS(_ = json::sax_parse(v_ubjson, &scp, json::input_format_t::ubjson), json::out_of_range&);\n            }\n        }\n    }\n\n    SECTION(\"SAX aborts\")\n    {\n        SECTION(\"start_array()\")\n        {\n            std::vector<uint8_t> v = {'[', 'T', 'F', ']'};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));\n        }\n\n        SECTION(\"start_object()\")\n        {\n            std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));\n        }\n\n        SECTION(\"key() in object\")\n        {\n            std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};\n            SaxCountdown scp(1);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));\n        }\n\n        SECTION(\"start_array(len)\")\n        {\n            std::vector<uint8_t> v = {'[', '#', 'i', '2', 'T', 'F'};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));\n        }\n\n        SECTION(\"start_object(len)\")\n        {\n            std::vector<uint8_t> v = {'{', '#', 'i', '1', 3, 'f', 'o', 'o', 'F'};\n            SaxCountdown scp(0);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));\n        }\n\n        SECTION(\"key() in object with length\")\n        {\n            std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};\n            SaxCountdown scp(1);\n            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));\n        }\n    }\n\n    SECTION(\"parsing values\")\n    {\n        SECTION(\"strings\")\n        {\n            // create a single-character string for all number types\n            std::vector<uint8_t> s_i = {'S', 'i', 1, 'a'};\n            std::vector<uint8_t> s_U = {'S', 'U', 1, 'a'};\n            std::vector<uint8_t> s_I = {'S', 'I', 0, 1, 'a'};\n            std::vector<uint8_t> s_l = {'S', 'l', 0, 0, 0, 1, 'a'};\n            std::vector<uint8_t> s_L = {'S', 'L', 0, 0, 0, 0, 0, 0, 0, 1, 'a'};\n\n            // check if string is parsed correctly to \"a\"\n            CHECK(json::from_ubjson(s_i) == \"a\");\n            CHECK(json::from_ubjson(s_U) == \"a\");\n            CHECK(json::from_ubjson(s_I) == \"a\");\n            CHECK(json::from_ubjson(s_l) == \"a\");\n            CHECK(json::from_ubjson(s_L) == \"a\");\n\n            // roundtrip: output should be optimized\n            CHECK(json::to_ubjson(json::from_ubjson(s_i)) == s_i);\n            CHECK(json::to_ubjson(json::from_ubjson(s_U)) == s_i);\n            CHECK(json::to_ubjson(json::from_ubjson(s_I)) == s_i);\n            CHECK(json::to_ubjson(json::from_ubjson(s_l)) == s_i);\n            CHECK(json::to_ubjson(json::from_ubjson(s_L)) == s_i);\n        }\n\n        SECTION(\"number\")\n        {\n            SECTION(\"float\")\n            {\n                // float32\n                std::vector<uint8_t> v_d = {'d', 0x40, 0x49, 0x0f, 0xd0};\n                CHECK(json::from_ubjson(v_d) == 3.14159f);\n\n                // float64\n                std::vector<uint8_t> v_D = {'D', 0x40, 0x09, 0x21, 0xf9, 0xf0, 0x1b, 0x86, 0x6e};\n                CHECK(json::from_ubjson(v_D) == 3.14159);\n\n                // float32 is serialized as float64 as the library does not support float32\n                CHECK(json::to_ubjson(json::from_ubjson(v_d)) == json::to_ubjson(3.14159f));\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"optimized version (length only)\")\n            {\n                // create vector with two elements of the same type\n                std::vector<uint8_t> v_TU = {'[', '#', 'U', 2, 'T', 'T'};\n                std::vector<uint8_t> v_T = {'[', '#', 'i', 2, 'T', 'T'};\n                std::vector<uint8_t> v_F = {'[', '#', 'i', 2, 'F', 'F'};\n                std::vector<uint8_t> v_Z = {'[', '#', 'i', 2, 'Z', 'Z'};\n                std::vector<uint8_t> v_i = {'[', '#', 'i', 2, 'i', 0x7F, 'i', 0x7F};\n                std::vector<uint8_t> v_U = {'[', '#', 'i', 2, 'U', 0xFF, 'U', 0xFF};\n                std::vector<uint8_t> v_I = {'[', '#', 'i', 2, 'I', 0x7F, 0xFF, 'I', 0x7F, 0xFF};\n                std::vector<uint8_t> v_l = {'[', '#', 'i', 2, 'l', 0x7F, 0xFF, 0xFF, 0xFF, 'l', 0x7F, 0xFF, 0xFF, 0xFF};\n                std::vector<uint8_t> v_L = {'[', '#', 'i', 2, 'L', 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'L', 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\n                std::vector<uint8_t> v_D = {'[', '#', 'i', 2, 'D', 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a, 'D', 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a};\n                std::vector<uint8_t> v_S = {'[', '#', 'i', 2, 'S', 'i', 1, 'a', 'S', 'i', 1, 'a'};\n                std::vector<uint8_t> v_C = {'[', '#', 'i', 2, 'C', 'a', 'C', 'a'};\n\n                // check if vector is parsed correctly\n                CHECK(json::from_ubjson(v_TU) == json({true, true}));\n                CHECK(json::from_ubjson(v_T) == json({true, true}));\n                CHECK(json::from_ubjson(v_F) == json({false, false}));\n                CHECK(json::from_ubjson(v_Z) == json({nullptr, nullptr}));\n                CHECK(json::from_ubjson(v_i) == json({127, 127}));\n                CHECK(json::from_ubjson(v_U) == json({255, 255}));\n                CHECK(json::from_ubjson(v_I) == json({32767, 32767}));\n                CHECK(json::from_ubjson(v_l) == json({2147483647, 2147483647}));\n                CHECK(json::from_ubjson(v_L) == json({9223372036854775807, 9223372036854775807}));\n                CHECK(json::from_ubjson(v_D) == json({3.1415926, 3.1415926}));\n                CHECK(json::from_ubjson(v_S) == json({\"a\", \"a\"}));\n                CHECK(json::from_ubjson(v_C) == json({\"a\", \"a\"}));\n\n                // roundtrip: output should be optimized\n                CHECK(json::to_ubjson(json::from_ubjson(v_T), true) == v_T);\n                CHECK(json::to_ubjson(json::from_ubjson(v_F), true) == v_F);\n                CHECK(json::to_ubjson(json::from_ubjson(v_Z), true) == v_Z);\n                CHECK(json::to_ubjson(json::from_ubjson(v_i), true) == v_i);\n                CHECK(json::to_ubjson(json::from_ubjson(v_U), true) == v_U);\n                CHECK(json::to_ubjson(json::from_ubjson(v_I), true) == v_I);\n                CHECK(json::to_ubjson(json::from_ubjson(v_l), true) == v_l);\n                CHECK(json::to_ubjson(json::from_ubjson(v_L), true) == v_L);\n                CHECK(json::to_ubjson(json::from_ubjson(v_D), true) == v_D);\n                CHECK(json::to_ubjson(json::from_ubjson(v_S), true) == v_S);\n                CHECK(json::to_ubjson(json::from_ubjson(v_C), true) == v_S); // char is serialized to string\n            }\n\n            SECTION(\"optimized version (type and length)\")\n            {\n                // create vector with two elements of the same type\n                std::vector<uint8_t> v_N = {'[', '$', 'N', '#', 'i', 2};\n                std::vector<uint8_t> v_T = {'[', '$', 'T', '#', 'i', 2};\n                std::vector<uint8_t> v_F = {'[', '$', 'F', '#', 'i', 2};\n                std::vector<uint8_t> v_Z = {'[', '$', 'Z', '#', 'i', 2};\n                std::vector<uint8_t> v_i = {'[', '$', 'i', '#', 'i', 2, 0x7F, 0x7F};\n                std::vector<uint8_t> v_U = {'[', '$', 'U', '#', 'i', 2, 0xFF, 0xFF};\n                std::vector<uint8_t> v_I = {'[', '$', 'I', '#', 'i', 2, 0x7F, 0xFF, 0x7F, 0xFF};\n                std::vector<uint8_t> v_l = {'[', '$', 'l', '#', 'i', 2, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF};\n                std::vector<uint8_t> v_L = {'[', '$', 'L', '#', 'i', 2, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\n                std::vector<uint8_t> v_D = {'[', '$', 'D', '#', 'i', 2, 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a, 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a};\n                std::vector<uint8_t> v_S = {'[', '$', 'S', '#', 'i', 2, 'i', 1, 'a', 'i', 1, 'a'};\n                std::vector<uint8_t> v_C = {'[', '$', 'C', '#', 'i', 2, 'a', 'a'};\n\n                // check if vector is parsed correctly\n                CHECK(json::from_ubjson(v_N) == json::array());\n                CHECK(json::from_ubjson(v_T) == json({true, true}));\n                CHECK(json::from_ubjson(v_F) == json({false, false}));\n                CHECK(json::from_ubjson(v_Z) == json({nullptr, nullptr}));\n                CHECK(json::from_ubjson(v_i) == json({127, 127}));\n                CHECK(json::from_ubjson(v_U) == json({255, 255}));\n                CHECK(json::from_ubjson(v_I) == json({32767, 32767}));\n                CHECK(json::from_ubjson(v_l) == json({2147483647, 2147483647}));\n                CHECK(json::from_ubjson(v_L) == json({9223372036854775807, 9223372036854775807}));\n                CHECK(json::from_ubjson(v_D) == json({3.1415926, 3.1415926}));\n                CHECK(json::from_ubjson(v_S) == json({\"a\", \"a\"}));\n                CHECK(json::from_ubjson(v_C) == json({\"a\", \"a\"}));\n\n                // roundtrip: output should be optimized\n                std::vector<uint8_t> v_empty = {'[', '#', 'i', 0};\n                CHECK(json::to_ubjson(json::from_ubjson(v_N), true, true) == v_empty);\n                CHECK(json::to_ubjson(json::from_ubjson(v_T), true, true) == v_T);\n                CHECK(json::to_ubjson(json::from_ubjson(v_F), true, true) == v_F);\n                CHECK(json::to_ubjson(json::from_ubjson(v_Z), true, true) == v_Z);\n                CHECK(json::to_ubjson(json::from_ubjson(v_i), true, true) == v_i);\n                CHECK(json::to_ubjson(json::from_ubjson(v_U), true, true) == v_U);\n                CHECK(json::to_ubjson(json::from_ubjson(v_I), true, true) == v_I);\n                CHECK(json::to_ubjson(json::from_ubjson(v_l), true, true) == v_l);\n                CHECK(json::to_ubjson(json::from_ubjson(v_L), true, true) == v_L);\n                CHECK(json::to_ubjson(json::from_ubjson(v_D), true, true) == v_D);\n                CHECK(json::to_ubjson(json::from_ubjson(v_S), true, true) == v_S);\n                CHECK(json::to_ubjson(json::from_ubjson(v_C), true, true) == v_S); // char is serialized to string\n            }\n        }\n    }\n\n    SECTION(\"parse errors\")\n    {\n        SECTION(\"empty byte vector\")\n        {\n            json _;\n            CHECK_THROWS_AS(_ = json::from_ubjson(std::vector<uint8_t>()), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(std::vector<uint8_t>()),\n                              \"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing UBJSON value: unexpected end of input\");\n        }\n\n        SECTION(\"char\")\n        {\n            SECTION(\"eof after C byte\")\n            {\n                std::vector<uint8_t> v = {'C'};\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input\");\n            }\n\n            SECTION(\"byte out of range\")\n            {\n                std::vector<uint8_t> v = {'C', 130};\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82\");\n            }\n        }\n\n        SECTION(\"strings\")\n        {\n            SECTION(\"eof after S byte\")\n            {\n                std::vector<uint8_t> v = {'S'};\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input\");\n            }\n\n            SECTION(\"invalid byte\")\n            {\n                std::vector<uint8_t> v = {'S', '1', 'a'};\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x31\");\n            }\n        }\n\n        SECTION(\"array\")\n        {\n            SECTION(\"optimized array: no size following type\")\n            {\n                std::vector<uint8_t> v = {'[', '$', 'i', 2};\n                json _;\n                CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02\");\n            }\n        }\n\n        SECTION(\"strings\")\n        {\n            std::vector<uint8_t> vS = {'S'};\n            json _;\n            CHECK_THROWS_AS(_ = json::from_ubjson(vS), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vS), \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(vS, true, false).is_discarded());\n\n            std::vector<uint8_t> v = {'S', 'i', '2', 'a'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON string: unexpected end of input\");\n            CHECK(json::from_ubjson(v, true, false).is_discarded());\n\n            std::vector<uint8_t> vC = {'C'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vC), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vC), \"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input\");\n            CHECK(json::from_ubjson(vC, true, false).is_discarded());\n        }\n\n        SECTION(\"sizes\")\n        {\n            std::vector<uint8_t> vU = {'[', '#', 'U'};\n            json _;\n            CHECK_THROWS_AS(_ = json::from_ubjson(vU), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vU), \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(vU, true, false).is_discarded());\n\n            std::vector<uint8_t> vi = {'[', '#', 'i'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vi), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vi), \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(vi, true, false).is_discarded());\n\n            std::vector<uint8_t> vI = {'[', '#', 'I'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vI), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vI), \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(vI, true, false).is_discarded());\n\n            std::vector<uint8_t> vl = {'[', '#', 'l'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vl), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vl), \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(vl, true, false).is_discarded());\n\n            std::vector<uint8_t> vL = {'[', '#', 'L'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vL), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vL), \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(vL, true, false).is_discarded());\n\n            std::vector<uint8_t> v0 = {'[', '#', 'T', ']'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(v0), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(v0), \"[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x54\");\n            CHECK(json::from_ubjson(v0, true, false).is_discarded());\n        }\n\n        SECTION(\"types\")\n        {\n            std::vector<uint8_t> v0 = {'[', '$'};\n            json _;\n            CHECK_THROWS_AS(_ = json::from_ubjson(v0), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(v0), \"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing UBJSON type: unexpected end of input\");\n            CHECK(json::from_ubjson(v0, true, false).is_discarded());\n\n            std::vector<uint8_t> vi = {'[', '$', '#'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vi), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vi), \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(vi, true, false).is_discarded());\n\n            std::vector<uint8_t> vT = {'[', '$', 'T'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vT), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vT), \"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(vT, true, false).is_discarded());\n        }\n\n        SECTION(\"arrays\")\n        {\n            std::vector<uint8_t> vST = {'[', '$', 'i', '#', 'i', 2, 1};\n            json _;\n            CHECK_THROWS_AS(_ = json::from_ubjson(vST), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vST), \"[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(vST, true, false).is_discarded());\n\n            std::vector<uint8_t> vS = {'[', '#', 'i', 2, 'i', 1};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vS), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vS), \"[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(vS, true, false).is_discarded());\n\n            std::vector<uint8_t> v = {'[', 'i', 2, 'i', 1};\n            CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(v, true, false).is_discarded());\n        }\n\n        SECTION(\"objects\")\n        {\n            std::vector<uint8_t> vST = {'{', '$', 'i', '#', 'i', 2, 'i', 1, 'a', 1};\n            json _;\n            CHECK_THROWS_AS(_ = json::from_ubjson(vST), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vST), \"[json.exception.parse_error.110] parse error at byte 11: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(vST, true, false).is_discarded());\n\n            std::vector<uint8_t> vT = {'{', '$', 'i', 'i', 1, 'a', 1};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vT), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vT), \"[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x69\");\n            CHECK(json::from_ubjson(vT, true, false).is_discarded());\n\n            std::vector<uint8_t> vS = {'{', '#', 'i', 2, 'i', 1, 'a', 'i', 1};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vS), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vS), \"[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(vS, true, false).is_discarded());\n\n            std::vector<uint8_t> v = {'{', 'i', 1, 'a', 'i', 1};\n            CHECK_THROWS_AS(_ = json::from_ubjson(v), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(v), \"[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(v, true, false).is_discarded());\n\n            std::vector<uint8_t> v2 = {'{', 'i', 1, 'a', 'i', 1, 'i'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(v2), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(v2), \"[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(v2, true, false).is_discarded());\n\n            std::vector<uint8_t> v3 = {'{', 'i', 1, 'a'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(v3), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(v3), \"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(v3, true, false).is_discarded());\n\n            std::vector<uint8_t> vST1 = {'{', '$', 'd', '#', 'i', 2, 'i', 1, 'a'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vST1), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vST1), \"[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON number: unexpected end of input\");\n            CHECK(json::from_ubjson(vST1, true, false).is_discarded());\n\n            std::vector<uint8_t> vST2 = {'{', '#', 'i', 2, 'i', 1, 'a'};\n            CHECK_THROWS_AS(_ = json::from_ubjson(vST2), json::parse_error&);\n            CHECK_THROWS_WITH(_ = json::from_ubjson(vST2), \"[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON value: unexpected end of input\");\n            CHECK(json::from_ubjson(vST2, true, false).is_discarded());\n        }\n    }\n\n    SECTION(\"writing optimized values\")\n    {\n        SECTION(\"integer\")\n        {\n            SECTION(\"array of i\")\n            {\n                json j = {1, -1};\n                std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 2, 1, 0xff};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n            }\n\n            SECTION(\"array of U\")\n            {\n                json j = {200, 201};\n                std::vector<uint8_t> expected = {'[', '$', 'U', '#', 'i', 2, 0xC8, 0xC9};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n            }\n\n            SECTION(\"array of I\")\n            {\n                json j = {30000, -30000};\n                std::vector<uint8_t> expected = {'[', '$', 'I', '#', 'i', 2, 0x75, 0x30, 0x8a, 0xd0};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n            }\n\n            SECTION(\"array of l\")\n            {\n                json j = {70000, -70000};\n                std::vector<uint8_t> expected = {'[', '$', 'l', '#', 'i', 2, 0x00, 0x01, 0x11, 0x70, 0xFF, 0xFE, 0xEE, 0x90};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n            }\n\n            SECTION(\"array of L\")\n            {\n                json j = {5000000000, -5000000000};\n                std::vector<uint8_t> expected = {'[', '$', 'L', '#', 'i', 2, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0xD5, 0xFA, 0x0E, 0x00};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n            }\n        }\n\n        SECTION(\"unsigned integer\")\n        {\n            SECTION(\"array of i\")\n            {\n                json j = {1u, 2u};\n                std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 2, 1, 2};\n                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'i', 1, 'i', 2};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n                CHECK(json::to_ubjson(j, true) == expected_size);\n            }\n\n            SECTION(\"array of U\")\n            {\n                json j = {200u, 201u};\n                std::vector<uint8_t> expected = {'[', '$', 'U', '#', 'i', 2, 0xC8, 0xC9};\n                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'U', 0xC8, 'U', 0xC9};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n                CHECK(json::to_ubjson(j, true) == expected_size);\n            }\n\n            SECTION(\"array of I\")\n            {\n                json j = {30000u, 30001u};\n                std::vector<uint8_t> expected = {'[', '$', 'I', '#', 'i', 2, 0x75, 0x30, 0x75, 0x31};\n                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'I', 0x75, 0x30, 'I', 0x75, 0x31};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n                CHECK(json::to_ubjson(j, true) == expected_size);\n            }\n\n            SECTION(\"array of l\")\n            {\n                json j = {70000u, 70001u};\n                std::vector<uint8_t> expected = {'[', '$', 'l', '#', 'i', 2, 0x00, 0x01, 0x11, 0x70, 0x00, 0x01, 0x11, 0x71};\n                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'l', 0x00, 0x01, 0x11, 0x70, 'l', 0x00, 0x01, 0x11, 0x71};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n                CHECK(json::to_ubjson(j, true) == expected_size);\n            }\n\n            SECTION(\"array of L\")\n            {\n                json j = {5000000000u, 5000000001u};\n                std::vector<uint8_t> expected = {'[', '$', 'L', '#', 'i', 2, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x01};\n                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'L', 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 'L', 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x01};\n                CHECK(json::to_ubjson(j, true, true) == expected);\n                CHECK(json::to_ubjson(j, true) == expected_size);\n            }\n        }\n\n        SECTION(\"discarded\")\n        {\n            json j = {json::value_t::discarded, json::value_t::discarded};\n            std::vector<uint8_t> expected = {'[', '$', 'N', '#', 'i', 2};\n            CHECK(json::to_ubjson(j, true, true) == expected);\n        }\n    }\n}\n\nTEST_CASE(\"Universal Binary JSON Specification Examples 1\")\n{\n    SECTION(\"Null Value\")\n    {\n        json j = {{\"passcode\", nullptr}};\n        std::vector<uint8_t> v = {'{', 'i', 8, 'p', 'a', 's', 's', 'c', 'o', 'd', 'e', 'Z', '}'};\n        CHECK(json::to_ubjson(j) == v);\n        CHECK(json::from_ubjson(v) == j);\n    }\n\n    SECTION(\"No-Op Value\")\n    {\n        json j = {\"foo\", \"bar\", \"baz\"};\n        std::vector<uint8_t> v = {'[', 'S', 'i', 3, 'f', 'o', 'o',\n                                  'S', 'i', 3, 'b', 'a', 'r',\n                                  'S', 'i', 3, 'b', 'a', 'z', ']'\n                                 };\n        std::vector<uint8_t> v2 = {'[', 'S', 'i', 3, 'f', 'o', 'o', 'N',\n                                   'S', 'i', 3, 'b', 'a', 'r', 'N', 'N', 'N',\n                                   'S', 'i', 3, 'b', 'a', 'z', 'N', 'N', ']'\n                                  };\n        CHECK(json::to_ubjson(j) == v);\n        CHECK(json::from_ubjson(v) == j);\n        CHECK(json::from_ubjson(v2) == j);\n    }\n\n    SECTION(\"Boolean Types\")\n    {\n        json j = {{\"authorized\", true}, {\"verified\", false}};\n        std::vector<uint8_t> v = {'{', 'i', 10, 'a', 'u', 't', 'h', 'o', 'r', 'i', 'z', 'e', 'd', 'T',\n                                  'i', 8, 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', 'F', '}'\n                                 };\n        CHECK(json::to_ubjson(j) == v);\n        CHECK(json::from_ubjson(v) == j);\n    }\n\n    SECTION(\"Numeric Types\")\n    {\n        json j =\n        {\n            {\"int8\", 16},\n            {\"uint8\", 255},\n            {\"int16\", 32767},\n            {\"int32\", 2147483647},\n            {\"int64\", 9223372036854775807},\n            {\"float64\", 113243.7863123}\n        };\n        std::vector<uint8_t> v = {'{',\n                                  'i', 7, 'f', 'l', 'o', 'a', 't', '6', '4', 'D', 0x40, 0xfb, 0xa5, 0xbc, 0x94, 0xbc, 0x34, 0xcf,\n                                  'i', 5, 'i', 'n', 't', '1', '6', 'I', 0x7f, 0xff,\n                                  'i', 5, 'i', 'n', 't', '3', '2', 'l', 0x7f, 0xff, 0xff, 0xff,\n                                  'i', 5, 'i', 'n', 't', '6', '4', 'L', 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n                                  'i', 4, 'i', 'n', 't', '8', 'i', 16,\n                                  'i', 5, 'u', 'i', 'n', 't', '8', 'U', 0xff,\n                                  '}'\n                                 };\n        CHECK(json::to_ubjson(j) == v);\n        CHECK(json::from_ubjson(v) == j);\n    }\n\n    SECTION(\"Char Type\")\n    {\n        json j = {{\"rolecode\", \"a\"}, {\"delim\", \";\"}};\n        std::vector<uint8_t> v = {'{', 'i', 5, 'd', 'e', 'l', 'i', 'm', 'C', ';', 'i', 8, 'r', 'o', 'l', 'e', 'c', 'o', 'd', 'e', 'C', 'a', '}'};\n        //CHECK(json::to_ubjson(j) == v);\n        CHECK(json::from_ubjson(v) == j);\n    }\n\n    SECTION(\"String Type\")\n    {\n        SECTION(\"English\")\n        {\n            json j = \"hello\";\n            std::vector<uint8_t> v = {'S', 'i', 5, 'h', 'e', 'l', 'l', 'o'};\n            CHECK(json::to_ubjson(j) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n\n        SECTION(\"Russian\")\n        {\n            json j = \"привет\";\n            std::vector<uint8_t> v = {'S', 'i', 12, 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x82};\n            CHECK(json::to_ubjson(j) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n\n        SECTION(\"Russian\")\n        {\n            json j = \"مرحبا\";\n            std::vector<uint8_t> v = {'S', 'i', 10, 0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7};\n            CHECK(json::to_ubjson(j) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n    }\n\n    SECTION(\"Array Type\")\n    {\n        SECTION(\"size=false type=false\")\n        {\n            // note the float has been replaced by a double\n            json j = {nullptr, true, false, 4782345193, 153.132, \"ham\"};\n            std::vector<uint8_t> v = {'[', 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm', ']'};\n            CHECK(json::to_ubjson(j) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n\n        SECTION(\"size=true type=false\")\n        {\n            // note the float has been replaced by a double\n            json j = {nullptr, true, false, 4782345193, 153.132, \"ham\"};\n            std::vector<uint8_t> v = {'[', '#', 'i', 6, 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm'};\n            CHECK(json::to_ubjson(j, true) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n\n        SECTION(\"size=true type=true\")\n        {\n            // note the float has been replaced by a double\n            json j = {nullptr, true, false, 4782345193, 153.132, \"ham\"};\n            std::vector<uint8_t> v = {'[', '#', 'i', 6, 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm'};\n            CHECK(json::to_ubjson(j, true, true) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n    }\n\n    SECTION(\"Object Type\")\n    {\n        SECTION(\"size=false type=false\")\n        {\n            json j =\n            {\n                {\n                    \"post\", {\n                        {\"id\", 1137},\n                        {\"author\", \"rkalla\"},\n                        {\"timestamp\", 1364482090592},\n                        {\"body\", \"I totally agree!\"}\n                    }\n                }\n            };\n            std::vector<uint8_t> v = {'{', 'i', 4, 'p', 'o', 's', 't', '{',\n                                      'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',\n                                      'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',\n                                      'i', 2, 'i', 'd', 'I', 0x04, 0x71,\n                                      'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60,\n                                      '}', '}'\n                                     };\n            CHECK(json::to_ubjson(j) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n\n        SECTION(\"size=true type=false\")\n        {\n            json j =\n            {\n                {\n                    \"post\", {\n                        {\"id\", 1137},\n                        {\"author\", \"rkalla\"},\n                        {\"timestamp\", 1364482090592},\n                        {\"body\", \"I totally agree!\"}\n                    }\n                }\n            };\n            std::vector<uint8_t> v = {'{', '#', 'i', 1, 'i', 4, 'p', 'o', 's', 't', '{', '#', 'i', 4,\n                                      'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',\n                                      'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',\n                                      'i', 2, 'i', 'd', 'I', 0x04, 0x71,\n                                      'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60\n                                     };\n            CHECK(json::to_ubjson(j, true) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n\n        SECTION(\"size=true type=true\")\n        {\n            json j =\n            {\n                {\n                    \"post\", {\n                        {\"id\", 1137},\n                        {\"author\", \"rkalla\"},\n                        {\"timestamp\", 1364482090592},\n                        {\"body\", \"I totally agree!\"}\n                    }\n                }\n            };\n            std::vector<uint8_t> v = {'{', '$', '{', '#', 'i', 1, 'i', 4, 'p', 'o', 's', 't', '#', 'i', 4,\n                                      'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',\n                                      'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',\n                                      'i', 2, 'i', 'd', 'I', 0x04, 0x71,\n                                      'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60\n                                     };\n            CHECK(json::to_ubjson(j, true, true) == v);\n            CHECK(json::from_ubjson(v) == j);\n        }\n    }\n\n    SECTION(\"Optimized Format\")\n    {\n        SECTION(\"Array Example\")\n        {\n            SECTION(\"No Optimization\")\n            {\n                // note the floats have been replaced by doubles\n                json j = {29.97, 31.13, 67.0, 2.113, 23.888};\n                std::vector<uint8_t> v = {'[',\n                                          'D', 0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,\n                                          'D', 0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,\n                                          'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                          'D', 0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,\n                                          'D', 0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17,\n                                          ']'\n                                         };\n                CHECK(json::to_ubjson(j) == v);\n                CHECK(json::from_ubjson(v) == j);\n            }\n\n            SECTION(\"Optimized with count\")\n            {\n                // note the floats have been replaced by doubles\n                json j = {29.97, 31.13, 67.0, 2.113, 23.888};\n                std::vector<uint8_t> v = {'[', '#', 'i', 5,\n                                          'D', 0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,\n                                          'D', 0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,\n                                          'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                          'D', 0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,\n                                          'D', 0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17\n                                         };\n                CHECK(json::to_ubjson(j, true) == v);\n                CHECK(json::from_ubjson(v) == j);\n            }\n\n            SECTION(\"Optimized with type & count\")\n            {\n                // note the floats have been replaced by doubles\n                json j = {29.97, 31.13, 67.0, 2.113, 23.888};\n                std::vector<uint8_t> v = {'[', '$', 'D', '#', 'i', 5,\n                                          0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,\n                                          0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,\n                                          0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                          0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,\n                                          0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17\n                                         };\n                CHECK(json::to_ubjson(j, true, true) == v);\n                CHECK(json::from_ubjson(v) == j);\n            }\n        }\n\n        SECTION(\"Object Example\")\n        {\n            SECTION(\"No Optimization\")\n            {\n                // note the floats have been replaced by doubles\n                json j = { {\"lat\", 29.976}, {\"long\", 31.131}, {\"alt\", 67.0} };\n                std::vector<uint8_t> v = {'{',\n                                          'i', 3, 'a', 'l', 't', 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                          'i', 3, 'l', 'a', 't', 'D', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,\n                                          'i', 4, 'l', 'o', 'n', 'g', 'D', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8,\n                                          '}'\n                                         };\n                CHECK(json::to_ubjson(j) == v);\n                CHECK(json::from_ubjson(v) == j);\n            }\n\n            SECTION(\"Optimized with count\")\n            {\n                // note the floats have been replaced by doubles\n                json j = { {\"lat\", 29.976}, {\"long\", 31.131}, {\"alt\", 67.0} };\n                std::vector<uint8_t> v = {'{', '#', 'i', 3,\n                                          'i', 3, 'a', 'l', 't', 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                          'i', 3, 'l', 'a', 't', 'D', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,\n                                          'i', 4, 'l', 'o', 'n', 'g', 'D', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8\n                                         };\n                CHECK(json::to_ubjson(j, true) == v);\n                CHECK(json::from_ubjson(v) == j);\n            }\n\n            SECTION(\"Optimized with type & count\")\n            {\n                // note the floats have been replaced by doubles\n                json j = { {\"lat\", 29.976}, {\"long\", 31.131}, {\"alt\", 67.0} };\n                std::vector<uint8_t> v = {'{', '$', 'D', '#', 'i', 3,\n                                          'i', 3, 'a', 'l', 't', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                          'i', 3, 'l', 'a', 't', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,\n                                          'i', 4, 'l', 'o', 'n', 'g', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8\n                                         };\n                CHECK(json::to_ubjson(j, true, true) == v);\n                CHECK(json::from_ubjson(v) == j);\n            }\n        }\n\n        SECTION(\"Special Cases (Null, No-Op and Boolean)\")\n        {\n            SECTION(\"Array\")\n            {\n                std::vector<uint8_t> v = {'[', '$', 'N', '#', 'I', 0x02, 0x00};\n                CHECK(json::from_ubjson(v) == json::array());\n            }\n\n            SECTION(\"Object\")\n            {\n                std::vector<uint8_t> v = {'{', '$', 'Z', '#', 'i', 3, 'i', 4, 'n', 'a', 'm', 'e', 'i', 8, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd', 'i', 5, 'e', 'm', 'a', 'i', 'l'};\n                CHECK(json::from_ubjson(v) == json({ {\"name\", nullptr}, {\"password\", nullptr}, {\"email\", nullptr} }));\n            }\n        }\n    }\n}\n\n#if !defined(JSON_NOEXCEPTION)\nTEST_CASE(\"all UBJSON first bytes\")\n{\n    // these bytes will fail immediately with exception parse_error.112\n    std::set<uint8_t> supported =\n    {\n        'T', 'F', 'Z', 'U', 'i', 'I', 'l', 'L', 'd', 'D', 'C', 'S', '[', '{', 'N', 'H'\n    };\n\n    for (auto i = 0; i < 256; ++i)\n    {\n        const auto byte = static_cast<uint8_t>(i);\n        CAPTURE(byte)\n\n        try\n        {\n            auto res = json::from_ubjson(std::vector<uint8_t>(1, byte));\n        }\n        catch (const json::parse_error& e)\n        {\n            // check that parse_error.112 is only thrown if the\n            // first byte is not in the supported set\n            INFO_WITH_TEMP(e.what());\n            if (supported.find(byte) == supported.end())\n            {\n                CHECK(e.id == 112);\n            }\n            else\n            {\n                CHECK(e.id != 112);\n            }\n        }\n    }\n}\n#endif\n\nTEST_CASE(\"UBJSON roundtrips\" * doctest::skip())\n{\n    SECTION(\"input from self-generated UBJSON files\")\n    {\n        for (std::string filename :\n                {\n                    TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/1.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/2.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/3.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/4.json\",\n                    TEST_DATA_DIRECTORY \"/json.org/5.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip01.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip02.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip03.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip04.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip05.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip06.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip07.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip08.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip09.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip10.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip11.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip12.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip13.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip14.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip15.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip16.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip17.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip18.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip19.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip20.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip21.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip22.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip23.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip24.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip25.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip26.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip27.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip28.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip29.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip30.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip31.json\",\n                    TEST_DATA_DIRECTORY \"/json_roundtrip/roundtrip32.json\",\n                    TEST_DATA_DIRECTORY \"/json_testsuite/sample.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass1.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass2.json\",\n                    TEST_DATA_DIRECTORY \"/json_tests/pass3.json\"\n                })\n        {\n            CAPTURE(filename)\n\n            {\n                INFO_WITH_TEMP(filename + \": std::vector<uint8_t>\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse UBJSON file\n                auto packed = utils::read_binary_file(filename + \".ubjson\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_ubjson(packed));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": std::ifstream\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse UBJSON file\n                std::ifstream f_ubjson(filename + \".ubjson\", std::ios::binary);\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_ubjson(f_ubjson));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": uint8_t* and size\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse UBJSON file\n                auto packed = utils::read_binary_file(filename + \".ubjson\");\n                json j2;\n                CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()}));\n\n                // compare parsed JSON values\n                CHECK(j1 == j2);\n            }\n\n            {\n                INFO_WITH_TEMP(filename + \": output to output adapters\");\n                // parse JSON file\n                std::ifstream f_json(filename);\n                json j1 = json::parse(f_json);\n\n                // parse UBJSON file\n                auto packed = utils::read_binary_file(filename + \".ubjson\");\n\n                {\n                    INFO_WITH_TEMP(filename + \": output adapters: std::vector<uint8_t>\");\n                    std::vector<uint8_t> vec;\n                    json::to_ubjson(j1, vec);\n                    CHECK(vec == packed);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-udt.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// disable -Wnoexcept due to class Evil\nDOCTEST_GCC_SUPPRESS_WARNING_PUSH\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wnoexcept\")\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <map>\n#include <memory>\n#include <string>\n#include <memory>\n#include <utility>\n\nnamespace udt\n{\nenum class country\n{\n    china,\n    france,\n    russia\n};\n\nstruct age\n{\n    int m_val;\n    age(int rhs = 0) : m_val(rhs) {}\n};\n\nstruct name\n{\n    std::string m_val;\n    name(std::string rhs = \"\") : m_val(std::move(rhs)) {}\n};\n\nstruct address\n{\n    std::string m_val;\n    address(std::string rhs = \"\") : m_val(std::move(rhs)) {}\n};\n\nstruct person\n{\n    age m_age{};\n    name m_name{};\n    country m_country{};\n    person() = default;\n    person(const age& a, name  n, const country& c) : m_age(a), m_name(std::move(n)), m_country(c) {}\n};\n\nstruct contact\n{\n    person m_person{};\n    address m_address{};\n    contact() = default;\n    contact(person p, address a) : m_person(std::move(p)), m_address(std::move(a)) {}\n};\n\nstruct contact_book\n{\n    name m_book_name{};\n    std::vector<contact> m_contacts{};\n    contact_book() = default;\n    contact_book(name n, std::vector<contact> c) : m_book_name(std::move(n)), m_contacts(std::move(c)) {}\n};\n} // namespace udt\n\n// to_json methods\nnamespace udt\n{\n// templates because of the custom_json tests (see below)\ntemplate <typename BasicJsonType>\nstatic void to_json(BasicJsonType& j, age a)\n{\n    j = a.m_val;\n}\n\ntemplate <typename BasicJsonType>\nstatic void to_json(BasicJsonType& j, const name& n)\n{\n    j = n.m_val;\n}\n\ntemplate <typename BasicJsonType>\nstatic void to_json(BasicJsonType& j, country c)\n{\n    switch (c)\n    {\n        case country::china:\n            j = \"中华人民共和国\";\n            return;\n        case country::france:\n            j = \"France\";\n            return;\n        case country::russia:\n            j = \"Российская Федерация\";\n            return;\n        default:\n            break;\n    }\n}\n\ntemplate <typename BasicJsonType>\nstatic void to_json(BasicJsonType& j, const person& p)\n{\n    j = BasicJsonType{{\"age\", p.m_age}, {\"name\", p.m_name}, {\"country\", p.m_country}};\n}\n\nstatic void to_json(nlohmann::json& j, const address& a)\n{\n    j = a.m_val;\n}\n\nstatic void to_json(nlohmann::json& j, const contact& c)\n{\n    j = json{{\"person\", c.m_person}, {\"address\", c.m_address}};\n}\n\nstatic void to_json(nlohmann::json& j, const contact_book& cb)\n{\n    j = json{{\"name\", cb.m_book_name}, {\"contacts\", cb.m_contacts}};\n}\n\n// operators\nstatic bool operator==(age lhs, age rhs)\n{\n    return lhs.m_val == rhs.m_val;\n}\n\nstatic bool operator==(const address& lhs, const address& rhs)\n{\n    return lhs.m_val == rhs.m_val;\n}\n\nstatic bool operator==(const name& lhs, const name& rhs)\n{\n    return lhs.m_val == rhs.m_val;\n}\n\nstatic bool operator==(const person& lhs, const person& rhs)\n{\n    return std::tie(lhs.m_name, lhs.m_age) == std::tie(rhs.m_name, rhs.m_age);\n}\n\nstatic bool operator==(const contact& lhs, const contact& rhs)\n{\n    return std::tie(lhs.m_person, lhs.m_address) ==\n           std::tie(rhs.m_person, rhs.m_address);\n}\n\nstatic bool operator==(const contact_book& lhs, const contact_book& rhs)\n{\n    return std::tie(lhs.m_book_name, lhs.m_contacts) ==\n           std::tie(rhs.m_book_name, rhs.m_contacts);\n}\n} // namespace udt\n\n// from_json methods\nnamespace udt\n{\ntemplate <typename BasicJsonType>\nstatic void from_json(const BasicJsonType& j, age& a)\n{\n    a.m_val = j.template get<int>();\n}\n\ntemplate <typename BasicJsonType>\nstatic void from_json(const BasicJsonType& j, name& n)\n{\n    n.m_val = j.template get<std::string>();\n}\n\ntemplate <typename BasicJsonType>\nstatic void from_json(const BasicJsonType& j, country& c)\n{\n    const auto str = j.template get<std::string>();\n    const std::map<std::string, country> m =\n    {\n        {\"中华人民共和国\", country::china},\n        {\"France\", country::france},\n        {\"Российская Федерация\", country::russia}\n    };\n\n    const auto it = m.find(str);\n    // TODO(nlohmann) test exceptions\n    c = it->second;\n}\n\ntemplate <typename BasicJsonType>\nstatic void from_json(const BasicJsonType& j, person& p)\n{\n    p.m_age = j[\"age\"].template get<age>();\n    p.m_name = j[\"name\"].template get<name>();\n    p.m_country = j[\"country\"].template get<country>();\n}\n\nstatic void from_json(const nlohmann::json& j, address& a)\n{\n    a.m_val = j.get<std::string>();\n}\n\nstatic void from_json(const nlohmann::json& j, contact& c)\n{\n    c.m_person = j[\"person\"].get<person>();\n    c.m_address = j[\"address\"].get<address>();\n}\n\nstatic void from_json(const nlohmann::json& j, contact_book& cb)\n{\n    cb.m_book_name = j[\"name\"].get<name>();\n    cb.m_contacts = j[\"contacts\"].get<std::vector<contact>>();\n}\n} // namespace udt\n\nTEST_CASE(\"basic usage\" * doctest::test_suite(\"udt\"))\n{\n\n    // a bit narcissistic maybe :) ?\n    const udt::age a\n    {\n        23\n    };\n    const udt::name n{\"theo\"};\n    const udt::country c{udt::country::france};\n    const udt::person sfinae_addict{a, n, c};\n    const udt::person senior_programmer{{42}, {\"王芳\"}, udt::country::china};\n    const udt::address addr{\"Paris\"};\n    const udt::contact cpp_programmer{sfinae_addict, addr};\n    const udt::contact_book book{{\"C++\"}, {cpp_programmer, {senior_programmer, addr}}};\n\n    SECTION(\"conversion to json via free-functions\")\n    {\n        CHECK(json(a) == json(23));\n        CHECK(json(n) == json(\"theo\"));\n        CHECK(json(c) == json(\"France\"));\n        CHECK(json(sfinae_addict) == R\"({\"name\":\"theo\", \"age\":23, \"country\":\"France\"})\"_json);\n        CHECK(json(\"Paris\") == json(addr));\n        CHECK(json(cpp_programmer) ==\n              R\"({\"person\" : {\"age\":23, \"name\":\"theo\", \"country\":\"France\"}, \"address\":\"Paris\"})\"_json);\n\n        CHECK(\n            json(book) ==\n            R\"({\"name\":\"C++\", \"contacts\" : [{\"person\" : {\"age\":23, \"name\":\"theo\", \"country\":\"France\"}, \"address\":\"Paris\"}, {\"person\" : {\"age\":42, \"country\":\"中华人民共和国\", \"name\":\"王芳\"}, \"address\":\"Paris\"}]})\"_json);\n\n    }\n\n    SECTION(\"conversion from json via free-functions\")\n    {\n        const auto big_json =\n            R\"({\"name\":\"C++\", \"contacts\" : [{\"person\" : {\"age\":23, \"name\":\"theo\", \"country\":\"France\"}, \"address\":\"Paris\"}, {\"person\" : {\"age\":42, \"country\":\"中华人民共和国\", \"name\":\"王芳\"}, \"address\":\"Paris\"}]})\"_json;\n        SECTION(\"via explicit calls to get\")\n        {\n            const auto parsed_book = big_json.get<udt::contact_book>();\n            const auto book_name = big_json[\"name\"].get<udt::name>();\n            const auto contacts =\n                big_json[\"contacts\"].get<std::vector<udt::contact>>();\n            const auto contact_json = big_json[\"contacts\"].at(0);\n            const auto contact = contact_json.get<udt::contact>();\n            const auto person = contact_json[\"person\"].get<udt::person>();\n            const auto address = contact_json[\"address\"].get<udt::address>();\n            const auto age = contact_json[\"person\"][\"age\"].get<udt::age>();\n            const auto country =\n                contact_json[\"person\"][\"country\"].get<udt::country>();\n            const auto name = contact_json[\"person\"][\"name\"].get<udt::name>();\n\n            CHECK(age == a);\n            CHECK(name == n);\n            CHECK(country == c);\n            CHECK(address == addr);\n            CHECK(person == sfinae_addict);\n            CHECK(contact == cpp_programmer);\n            CHECK(contacts == book.m_contacts);\n            CHECK(book_name == udt::name{\"C++\"});\n            CHECK(book == parsed_book);\n        }\n\n        SECTION(\"via explicit calls to get_to\")\n        {\n            udt::person person;\n            udt::name name;\n\n            json person_json = big_json[\"contacts\"][0][\"person\"];\n            CHECK(person_json.get_to(person) == sfinae_addict);\n\n            // correct reference gets returned\n            person_json[\"name\"].get_to(name).m_val = \"new name\";\n            CHECK(name.m_val == \"new name\");\n        }\n\n#if JSON_USE_IMPLICIT_CONVERSIONS\n        SECTION(\"implicit conversions\")\n        {\n            const udt::contact_book parsed_book = big_json;\n            const udt::name book_name = big_json[\"name\"];\n            const std::vector<udt::contact> contacts = big_json[\"contacts\"];\n            const auto contact_json = big_json[\"contacts\"].at(0);\n            const udt::contact contact = contact_json;\n            const udt::person person = contact_json[\"person\"];\n            const udt::address address = contact_json[\"address\"];\n            const udt::age age = contact_json[\"person\"][\"age\"];\n            const udt::country country = contact_json[\"person\"][\"country\"];\n            const udt::name name = contact_json[\"person\"][\"name\"];\n\n            CHECK(age == a);\n            CHECK(name == n);\n            CHECK(country == c);\n            CHECK(address == addr);\n            CHECK(person == sfinae_addict);\n            CHECK(contact == cpp_programmer);\n            CHECK(contacts == book.m_contacts);\n            CHECK(book_name == udt::name{\"C++\"});\n            CHECK(book == parsed_book);\n        }\n#endif\n    }\n}\n\nnamespace udt\n{\nstruct legacy_type\n{\n    std::string number{};\n    legacy_type() = default;\n    legacy_type(std::string n) : number(std::move(n)) {}\n};\n} // namespace udt\n\nnamespace nlohmann\n{\ntemplate <typename T>\nstruct adl_serializer<std::shared_ptr<T>>\n{\n    static void to_json(json& j, const std::shared_ptr<T>& opt)\n    {\n        if (opt)\n        {\n            j = *opt;\n        }\n        else\n        {\n            j = nullptr;\n        }\n    }\n\n    static void from_json(const json& j, std::shared_ptr<T>& opt)\n    {\n        if (j.is_null())\n        {\n            opt = nullptr;\n        }\n        else\n        {\n            opt.reset(new T(j.get<T>())); // NOLINT(cppcoreguidelines-owning-memory)\n        }\n    }\n};\n\ntemplate <>\nstruct adl_serializer<udt::legacy_type>\n{\n    static void to_json(json& j, const udt::legacy_type& l)\n    {\n        j = std::stoi(l.number);\n    }\n\n    static void from_json(const json& j, udt::legacy_type& l)\n    {\n        l.number = std::to_string(j.get<int>());\n    }\n};\n} // namespace nlohmann\n\nTEST_CASE(\"adl_serializer specialization\" * doctest::test_suite(\"udt\"))\n{\n    SECTION(\"partial specialization\")\n    {\n        SECTION(\"to_json\")\n        {\n            std::shared_ptr<udt::person> optPerson;\n\n            json j = optPerson;\n            CHECK(j.is_null());\n\n            optPerson.reset(new udt::person{{42}, {\"John Doe\"}, udt::country::russia}); // NOLINT(cppcoreguidelines-owning-memory,modernize-make-shared)\n            j = optPerson;\n            CHECK_FALSE(j.is_null());\n\n            CHECK(j.get<udt::person>() == *optPerson);\n        }\n\n        SECTION(\"from_json\")\n        {\n            auto person = udt::person{{42}, {\"John Doe\"}, udt::country::russia};\n            json j = person;\n\n            auto optPerson = j.get<std::shared_ptr<udt::person>>();\n            REQUIRE(optPerson);\n            CHECK(*optPerson == person);\n\n            j = nullptr;\n            optPerson = j.get<std::shared_ptr<udt::person>>();\n            CHECK(!optPerson);\n        }\n    }\n\n    SECTION(\"total specialization\")\n    {\n        SECTION(\"to_json\")\n        {\n            udt::legacy_type lt{\"4242\"};\n\n            json j = lt;\n            CHECK(j.get<int>() == 4242);\n        }\n\n        SECTION(\"from_json\")\n        {\n            json j = 4242;\n            auto lt = j.get<udt::legacy_type>();\n            CHECK(lt.number == \"4242\");\n        }\n    }\n}\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<std::vector<float>>\n{\n    using type = std::vector<float>;\n    static void to_json(json& j, const type& /*type*/)\n    {\n        j = \"hijacked!\";\n    }\n\n    static void from_json(const json& /*unnamed*/, type& opt)\n    {\n        opt = {42.0, 42.0, 42.0};\n    }\n\n    // preferred version\n    static type from_json(const json& /*unnamed*/)\n    {\n        return {4.0, 5.0, 6.0};\n    }\n};\n} // namespace nlohmann\n\nTEST_CASE(\"even supported types can be specialized\" * doctest::test_suite(\"udt\"))\n{\n    json j = std::vector<float> {1.0, 2.0, 3.0};\n    CHECK(j.dump() == R\"(\"hijacked!\")\");\n    auto f = j.get<std::vector<float>>();\n    // the single argument from_json method is preferred\n    CHECK((f == std::vector<float> {4.0, 5.0, 6.0}));\n}\n\nnamespace nlohmann\n{\ntemplate <typename T>\nstruct adl_serializer<std::unique_ptr<T>>\n{\n    static void to_json(json& j, const std::unique_ptr<T>& opt)\n    {\n        if (opt)\n        {\n            j = *opt;\n        }\n        else\n        {\n            j = nullptr;\n        }\n    }\n\n    // this is the overload needed for non-copyable types,\n    static std::unique_ptr<T> from_json(const json& j)\n    {\n        if (j.is_null())\n        {\n            return nullptr;\n        }\n\n        return std::unique_ptr<T>(new T(j.get<T>()));\n    }\n};\n} // namespace nlohmann\n\nTEST_CASE(\"Non-copyable types\" * doctest::test_suite(\"udt\"))\n{\n    SECTION(\"to_json\")\n    {\n        std::unique_ptr<udt::person> optPerson;\n\n        json j = optPerson;\n        CHECK(j.is_null());\n\n        optPerson.reset(new udt::person{{42}, {\"John Doe\"}, udt::country::russia}); // NOLINT(cppcoreguidelines-owning-memory,modernize-make-unique)\n        j = optPerson;\n        CHECK_FALSE(j.is_null());\n\n        CHECK(j.get<udt::person>() == *optPerson);\n    }\n\n    SECTION(\"from_json\")\n    {\n        auto person = udt::person{{42}, {\"John Doe\"}, udt::country::russia};\n        json j = person;\n\n        auto optPerson = j.get<std::unique_ptr<udt::person>>();\n        REQUIRE(optPerson);\n        CHECK(*optPerson == person);\n\n        j = nullptr;\n        optPerson = j.get<std::unique_ptr<udt::person>>();\n        CHECK(!optPerson);\n    }\n}\n\n// custom serializer - advanced usage\n// pack structs that are pod-types (but not scalar types)\n// relies on adl for any other type\ntemplate <typename T, typename = void>\nstruct pod_serializer\n{\n    // use adl for non-pods, or scalar types\n    template <\n        typename BasicJsonType, typename U = T,\n        typename std::enable_if <\n            !(std::is_pod<U>::value && std::is_class<U>::value), int >::type = 0 >\n    static void from_json(const BasicJsonType& j, U& t)\n    {\n        using nlohmann::from_json;\n        from_json(j, t);\n    }\n\n    // special behaviour for pods\n    template < typename BasicJsonType, typename U = T,\n               typename std::enable_if <\n                   std::is_pod<U>::value && std::is_class<U>::value, int >::type = 0 >\n    static void from_json(const  BasicJsonType& j, U& t)\n    {\n        std::uint64_t value = 0;\n        // The following block is no longer relevant in this serializer, make another one that shows the issue\n        // the problem arises only when one from_json method is defined without any constraint\n        //\n        // Why cannot we simply use: j.get<std::uint64_t>() ?\n        // Well, with the current experiment, the get method looks for a from_json\n        // function, which we are currently defining!\n        // This would end up in a stack overflow. Calling nlohmann::from_json is a\n        // workaround (is it?).\n        // I shall find a good way to avoid this once all constructors are converted\n        // to free methods\n        //\n        // In short, constructing a json by constructor calls to_json\n        // calling get calls from_json, for now, we cannot do this in custom\n        // serializers\n        nlohmann::from_json(j, value);\n        auto* bytes = static_cast<char*>(static_cast<void*>(&value));\n        std::memcpy(&t, bytes, sizeof(value));\n    }\n\n    template <\n        typename BasicJsonType, typename U = T,\n        typename std::enable_if <\n            !(std::is_pod<U>::value && std::is_class<U>::value), int >::type = 0 >\n    static void to_json(BasicJsonType& j, const  T& t)\n    {\n        using nlohmann::to_json;\n        to_json(j, t);\n    }\n\n    template < typename BasicJsonType, typename U = T,\n               typename std::enable_if <\n                   std::is_pod<U>::value && std::is_class<U>::value, int >::type = 0 >\n    static void to_json(BasicJsonType& j, const  T& t) noexcept\n    {\n        const auto* bytes = static_cast< const unsigned char*>(static_cast<const void*>(&t));\n        std::uint64_t value = 0;\n        std::memcpy(&value, bytes, sizeof(value));\n        nlohmann::to_json(j, value);\n    }\n};\n\nnamespace udt\n{\nstruct small_pod\n{\n    int begin;\n    char middle;\n    short end;\n};\n\nstruct non_pod\n{\n    std::string s{};\n    non_pod() = default;\n    non_pod(std::string S) : s(std::move(S)) {}\n};\n\ntemplate <typename BasicJsonType>\nstatic void to_json(BasicJsonType& j, const non_pod& np)\n{\n    j = np.s;\n}\n\ntemplate <typename BasicJsonType>\nstatic void from_json(const BasicJsonType& j, non_pod& np)\n{\n    np.s = j.template get<std::string>();\n}\n\nstatic bool operator==(small_pod lhs, small_pod rhs) noexcept\n{\n    return std::tie(lhs.begin, lhs.middle, lhs.end) ==\n           std::tie(rhs.begin, rhs.middle, rhs.end);\n}\n\nstatic bool operator==(const  non_pod& lhs, const  non_pod& rhs) noexcept\n{\n    return lhs.s == rhs.s;\n}\n\nstatic std::ostream& operator<<(std::ostream& os, small_pod l)\n{\n    return os << \"begin: \" << l.begin << \", middle: \" << l.middle << \", end: \" << l.end;\n}\n} // namespace udt\n\nTEST_CASE(\"custom serializer for pods\" * doctest::test_suite(\"udt\"))\n{\n    using custom_json =\n        nlohmann::basic_json<std::map, std::vector, std::string, bool,\n        std::int64_t, std::uint64_t, double, std::allocator, pod_serializer>;\n\n    auto p = udt::small_pod{42, '/', 42};\n    custom_json j = p;\n\n    auto p2 = j.get<udt::small_pod>();\n\n    CHECK(p == p2);\n\n    auto np = udt::non_pod{{\"non-pod\"}};\n    custom_json j2 = np;\n    auto np2 = j2.get<udt::non_pod>();\n    CHECK(np == np2);\n}\n\ntemplate <typename T, typename>\nstruct another_adl_serializer;\n\nusing custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, another_adl_serializer>;\n\ntemplate <typename T, typename>\nstruct another_adl_serializer\n{\n    static void from_json(const custom_json& j, T& t)\n    {\n        using nlohmann::from_json;\n        from_json(j, t);\n    }\n\n    static void to_json(custom_json& j, const T& t)\n    {\n        using nlohmann::to_json;\n        to_json(j, t);\n    }\n};\n\nTEST_CASE(\"custom serializer that does adl by default\" * doctest::test_suite(\"udt\"))\n{\n    auto me = udt::person{{23}, {\"theo\"}, udt::country::france};\n\n    json j = me;\n    custom_json cj = me;\n\n    CHECK(j.dump() == cj.dump());\n\n    CHECK(me == j.get<udt::person>());\n    CHECK(me == cj.get<udt::person>());\n}\n\nTEST_CASE(\"different basic_json types conversions\")\n{\n    SECTION(\"null\")\n    {\n        json j;\n        custom_json cj = j;\n        CHECK(cj == nullptr);\n    }\n\n    SECTION(\"boolean\")\n    {\n        json j = true;\n        custom_json cj = j;\n        CHECK(cj == true);\n    }\n\n    SECTION(\"discarded\")\n    {\n        json j(json::value_t::discarded);\n        custom_json cj;\n        CHECK_NOTHROW(cj = j);\n        CHECK(cj.type() == custom_json::value_t::discarded);\n    }\n\n    SECTION(\"array\")\n    {\n        json j = {1, 2, 3};\n        custom_json cj = j;\n        CHECK((cj == std::vector<int> {1, 2, 3}));\n    }\n\n    SECTION(\"integer\")\n    {\n        json j = 42;\n        custom_json cj = j;\n        CHECK(cj == 42);\n    }\n\n    SECTION(\"float\")\n    {\n        json j = 42.0;\n        custom_json cj = j;\n        CHECK(cj == 42.0);\n    }\n\n    SECTION(\"unsigned\")\n    {\n        json j = 42u;\n        custom_json cj = j;\n        CHECK(cj == 42u);\n    }\n\n    SECTION(\"string\")\n    {\n        json j = \"forty-two\";\n        custom_json cj = j;\n        CHECK(cj == \"forty-two\");\n    }\n\n    SECTION(\"binary\")\n    {\n        json j = json::binary({1, 2, 3}, 42);\n        custom_json cj = j;\n        CHECK(cj.get_binary().subtype() == 42);\n        std::vector<std::uint8_t> cv = cj.get_binary();\n        std::vector<std::uint8_t> v = j.get_binary();\n        CHECK(cv == v);\n    }\n\n    SECTION(\"object\")\n    {\n        json j = {{\"forty\", \"two\"}};\n        custom_json cj = j;\n        auto m = j.get<std::map<std::string, std::string>>();\n        CHECK(cj == m);\n    }\n\n    SECTION(\"get<custom_json>\")\n    {\n        json j = 42;\n        custom_json cj = j.get<custom_json>();\n        CHECK(cj == 42);\n    }\n}\n\nnamespace\n{\nstruct incomplete;\n\n// std::is_constructible is broken on macOS' libc++\n// use the cppreference implementation\n\ntemplate <typename T, typename = void>\nstruct is_constructible_patched : std::false_type {};\n\ntemplate <typename T>\nstruct is_constructible_patched<T, decltype(void(json(std::declval<T>())))> : std::true_type {};\n} // namespace\n\nTEST_CASE(\"an incomplete type does not trigger a compiler error in non-evaluated context\" * doctest::test_suite(\"udt\"))\n{\n    static_assert(!is_constructible_patched<json, incomplete>::value, \"\");\n}\n\nnamespace\n{\nclass Evil\n{\n  public:\n    Evil() = default;\n    template <typename T>\n    Evil(T t) : m_i(sizeof(t))\n    {\n        static_cast<void>(t); // fix MSVC's C4100 warning\n    }\n\n    int m_i = 0;\n};\n\nvoid from_json(const json& /*unused*/, Evil& /*unused*/) {}\n} // namespace\n\nTEST_CASE(\"Issue #924\")\n{\n    // Prevent get<std::vector<Evil>>() to throw\n    auto j = json::array();\n\n    CHECK_NOTHROW(j.get<Evil>());\n    CHECK_NOTHROW(j.get<std::vector<Evil>>());\n\n    // silence Wunused-template warnings\n    Evil e(1);\n    CHECK(e.m_i >= 0);\n}\n\nTEST_CASE(\"Issue #1237\")\n{\n    struct non_convertible_type {};\n    static_assert(!std::is_convertible<json, non_convertible_type>::value, \"\");\n}\n\nnamespace\n{\nclass no_iterator_type\n{\n  public:\n    no_iterator_type(std::initializer_list<int> l)\n        : _v(l)\n    {}\n\n    std::vector<int>::const_iterator begin() const\n    {\n        return _v.begin();\n    }\n\n    std::vector<int>::const_iterator end() const\n    {\n        return _v.end();\n    }\n\n  private:\n    std::vector<int> _v;\n};\n}  // namespace\n\nTEST_CASE(\"compatible array type, without iterator type alias\")\n{\n    no_iterator_type vec{1, 2, 3};\n    json j = vec;\n}\n\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-udt_macro.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include <string>\n#include <vector>\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nnamespace persons\n{\nclass person_with_private_data\n{\n  private:\n    std::string name{};\n    int age = 0;\n    json metadata = nullptr;\n\n  public:\n    bool operator==(const person_with_private_data& rhs) const\n    {\n        return name == rhs.name && age == rhs.age && metadata == rhs.metadata;\n    }\n\n    person_with_private_data() = default;\n    person_with_private_data(std::string name_, int age_, json metadata_)\n        : name(std::move(name_))\n        , age(age_)\n        , metadata(std::move(metadata_))\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)\n};\n\nclass person_without_private_data_1\n{\n  public:\n    std::string name{};\n    int age = 0;\n    json metadata = nullptr;\n\n    bool operator==(const person_without_private_data_1& rhs) const\n    {\n        return name == rhs.name && age == rhs.age && metadata == rhs.metadata;\n    }\n\n    person_without_private_data_1() = default;\n    person_without_private_data_1(std::string name_, int age_, json metadata_)\n        : name(std::move(name_))\n        , age(age_)\n        , metadata(std::move(metadata_))\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_without_private_data_1, age, name, metadata)\n};\n\nclass person_without_private_data_2\n{\n  public:\n    std::string name{};\n    int age = 0;\n    json metadata = nullptr;\n\n    bool operator==(const person_without_private_data_2& rhs) const\n    {\n        return name == rhs.name && age == rhs.age && metadata == rhs.metadata;\n    }\n\n    person_without_private_data_2() = default;\n    person_without_private_data_2(std::string name_, int age_, json metadata_)\n        : name(std::move(name_))\n        , age(age_)\n        , metadata(std::move(metadata_))\n    {}\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)\n\nclass person_with_private_alphabet\n{\n  public:\n    bool operator==(const person_with_private_alphabet& other) const\n    {\n        return  a == other.a &&\n                b == other.b &&\n                c == other.c &&\n                d == other.d &&\n                e == other.e &&\n                f == other.f &&\n                g == other.g &&\n                h == other.h &&\n                i == other.i &&\n                j == other.j &&\n                k == other.k &&\n                l == other.l &&\n                m == other.m &&\n                n == other.n &&\n                o == other.o &&\n                p == other.p &&\n                q == other.q &&\n                r == other.r &&\n                s == other.s &&\n                t == other.t &&\n                u == other.u &&\n                v == other.v &&\n                w == other.w &&\n                x == other.x &&\n                y == other.y &&\n                z == other.z;\n    }\n\n  private:\n    int a = 0;\n    int b = 0;\n    int c = 0;\n    int d = 0;\n    int e = 0;\n    int f = 0;\n    int g = 0;\n    int h = 0;\n    int i = 0;\n    int j = 0;\n    int k = 0;\n    int l = 0;\n    int m = 0;\n    int n = 0;\n    int o = 0;\n    int p = 0;\n    int q = 0;\n    int r = 0;\n    int s = 0;\n    int t = 0;\n    int u = 0;\n    int v = 0;\n    int w = 0;\n    int x = 0;\n    int y = 0;\n    int z = 0;\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)\n};\n\nclass person_with_public_alphabet\n{\n  public:\n    bool operator==(const person_with_public_alphabet& other) const\n    {\n        return  a == other.a &&\n                b == other.b &&\n                c == other.c &&\n                d == other.d &&\n                e == other.e &&\n                f == other.f &&\n                g == other.g &&\n                h == other.h &&\n                i == other.i &&\n                j == other.j &&\n                k == other.k &&\n                l == other.l &&\n                m == other.m &&\n                n == other.n &&\n                o == other.o &&\n                p == other.p &&\n                q == other.q &&\n                r == other.r &&\n                s == other.s &&\n                t == other.t &&\n                u == other.u &&\n                v == other.v &&\n                w == other.w &&\n                x == other.x &&\n                y == other.y &&\n                z == other.z;\n    }\n\n    int a = 0;\n    int b = 0;\n    int c = 0;\n    int d = 0;\n    int e = 0;\n    int f = 0;\n    int g = 0;\n    int h = 0;\n    int i = 0;\n    int j = 0;\n    int k = 0;\n    int l = 0;\n    int m = 0;\n    int n = 0;\n    int o = 0;\n    int p = 0;\n    int q = 0;\n    int r = 0;\n    int s = 0;\n    int t = 0;\n    int u = 0;\n    int v = 0;\n    int w = 0;\n    int x = 0;\n    int y = 0;\n    int z = 0;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)\n\n} // namespace persons\n\nTEST_CASE_TEMPLATE(\"Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE\", T,\n                   persons::person_with_private_data,\n                   persons::person_without_private_data_1,\n                   persons::person_without_private_data_2)\n{\n    SECTION(\"person\")\n    {\n        // serialization\n        T p1(\"Erik\", 1, {{\"haircuts\", 2}});\n        CHECK(json(p1).dump() == \"{\\\"age\\\":1,\\\"metadata\\\":{\\\"haircuts\\\":2},\\\"name\\\":\\\"Erik\\\"}\");\n\n        // deserialization\n        auto p2 = json(p1).get<T>();\n        CHECK(p2 == p1);\n\n        // roundtrip\n        CHECK(T(json(p1)) == p1);\n        CHECK(json(T(json(p1))) == json(p1));\n\n        // check exception in case of missing field\n        json j = json(p1);\n        j.erase(\"age\");\n        CHECK_THROWS_WITH_AS(j.get<T>(), \"[json.exception.out_of_range.403] key 'age' not found\", json::out_of_range);\n    }\n}\n\nTEST_CASE_TEMPLATE(\"Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE\", T,\n                   persons::person_with_private_alphabet,\n                   persons::person_with_public_alphabet)\n{\n    SECTION(\"alphabet\")\n    {\n        {\n            T obj1;\n            nlohmann::json j = obj1; //via json object\n            T obj2;\n            j.get_to(obj2);\n            bool ok = (obj1 == obj2);\n            CHECK(ok);\n        }\n\n        {\n            T obj1;\n            nlohmann::json j1 = obj1; //via json string\n            std::string s = j1.dump();\n            nlohmann::json j2 = nlohmann::json::parse(s);\n            T obj2;\n            j2.get_to(obj2);\n            bool ok = (obj1 == obj2);\n            CHECK(ok);\n        }\n\n        {\n            T obj1;\n            nlohmann::json j1 = obj1; //via msgpack\n            std::vector<uint8_t> buf = nlohmann::json::to_msgpack(j1);\n            nlohmann::json j2 = nlohmann::json::from_msgpack(buf);\n            T obj2;\n            j2.get_to(obj2);\n            bool ok = (obj1 == obj2);\n            CHECK(ok);\n        }\n\n        {\n            T obj1;\n            nlohmann::json j1 = obj1; //via bson\n            std::vector<uint8_t> buf = nlohmann::json::to_bson(j1);\n            nlohmann::json j2 = nlohmann::json::from_bson(buf);\n            T obj2;\n            j2.get_to(obj2);\n            bool ok = (obj1 == obj2);\n            CHECK(ok);\n        }\n\n        {\n            T obj1;\n            nlohmann::json j1 = obj1; //via cbor\n            std::vector<uint8_t> buf = nlohmann::json::to_cbor(j1);\n            nlohmann::json j2 = nlohmann::json::from_cbor(buf);\n            T obj2;\n            j2.get_to(obj2);\n            bool ok = (obj1 == obj2);\n            CHECK(ok);\n        }\n\n        {\n            T obj1;\n            nlohmann::json j1 = obj1; //via ubjson\n            std::vector<uint8_t> buf = nlohmann::json::to_ubjson(j1);\n            nlohmann::json j2 = nlohmann::json::from_ubjson(buf);\n            T obj2;\n            j2.get_to(obj2);\n            bool ok = (obj1 == obj2);\n            CHECK(ok);\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-unicode1.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// for some reason including this after the json header leads to linker errors with VS 2017...\n#include <locale>\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <iomanip>\n#include <test_data.hpp>\n\nTEST_CASE(\"Unicode (1/5)\" * doctest::skip())\n{\n    SECTION(\"\\\\uxxxx sequences\")\n    {\n        // create an escaped string from a code point\n        const auto codepoint_to_unicode = [](std::size_t cp)\n        {\n            // code points are represented as a six-character sequence: a\n            // reverse solidus, followed by the lowercase letter u, followed\n            // by four hexadecimal digits that encode the character's code\n            // point\n            std::stringstream ss;\n            ss << \"\\\\u\" << std::setw(4) << std::setfill('0') << std::hex << cp;\n            return ss.str();\n        };\n\n        SECTION(\"correct sequences\")\n        {\n            // generate all UTF-8 code points; in total, 1112064 code points are\n            // generated: 0x1FFFFF code points - 2048 invalid values between\n            // 0xD800 and 0xDFFF.\n            for (std::size_t cp = 0; cp <= 0x10FFFFu; ++cp)\n            {\n                // string to store the code point as in \\uxxxx format\n                std::string json_text = \"\\\"\";\n\n                // decide whether to use one or two \\uxxxx sequences\n                if (cp < 0x10000u)\n                {\n                    // The Unicode standard permanently reserves these code point\n                    // values for UTF-16 encoding of the high and low surrogates, and\n                    // they will never be assigned a character, so there should be no\n                    // reason to encode them. The official Unicode standard says that\n                    // no UTF forms, including UTF-16, can encode these code points.\n                    if (cp >= 0xD800u && cp <= 0xDFFFu)\n                    {\n                        // if we would not skip these code points, we would get a\n                        // \"missing low surrogate\" exception\n                        continue;\n                    }\n\n                    // code points in the Basic Multilingual Plane can be\n                    // represented with one \\uxxxx sequence\n                    json_text += codepoint_to_unicode(cp);\n                }\n                else\n                {\n                    // To escape an extended character that is not in the Basic\n                    // Multilingual Plane, the character is represented as a\n                    // 12-character sequence, encoding the UTF-16 surrogate pair\n                    const auto codepoint1 = 0xd800u + (((cp - 0x10000u) >> 10) & 0x3ffu);\n                    const auto codepoint2 = 0xdc00u + ((cp - 0x10000u) & 0x3ffu);\n                    json_text += codepoint_to_unicode(codepoint1) + codepoint_to_unicode(codepoint2);\n                }\n\n                json_text += \"\\\"\";\n                CAPTURE(json_text)\n                json _;\n                CHECK_NOTHROW(_ = json::parse(json_text));\n            }\n        }\n\n        SECTION(\"incorrect sequences\")\n        {\n            SECTION(\"incorrect surrogate values\")\n            {\n                json _;\n\n                CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uDC00\\\\uDC00\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uDC00\\\\uDC00\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\\\"\\\\uDC00'\");\n\n                CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD7FF\\\\uDC00\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD7FF\\\\uDC00\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\\\"\\\\uD7FF\\\\uDC00'\");\n\n                CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD800]\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD800]\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD800]'\");\n\n                CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD800\\\\v\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD800\\\\v\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 9: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD800\\\\v'\");\n\n                CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD800\\\\u123\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD800\\\\u123\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: '\\\\u' must be followed by 4 hex digits; last read: '\\\"\\\\uD800\\\\u123\\\"'\");\n\n                CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD800\\\\uDBFF\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD800\\\\uDBFF\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD800\\\\uDBFF'\");\n\n                CHECK_THROWS_AS(_ = json::parse(\"\\\"\\\\uD800\\\\uE000\\\"\"), json::parse_error&);\n                CHECK_THROWS_WITH(_ = json::parse(\"\\\"\\\\uD800\\\\uE000\\\"\"),\n                                  \"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\uD800\\\\uE000'\");\n            }\n        }\n\n#if 0\n        SECTION(\"incorrect sequences\")\n        {\n            SECTION(\"high surrogate without low surrogate\")\n            {\n                // D800..DBFF are high surrogates and must be followed by low\n                // surrogates DC00..DFFF; here, nothing follows\n                for (std::size_t cp = 0xD800u; cp <= 0xDBFFu; ++cp)\n                {\n                    std::string json_text = \"\\\"\" + codepoint_to_unicode(cp) + \"\\\"\";\n                    CAPTURE(json_text)\n                    CHECK_THROWS_AS(json::parse(json_text), json::parse_error&);\n                }\n            }\n\n            SECTION(\"high surrogate with wrong low surrogate\")\n            {\n                // D800..DBFF are high surrogates and must be followed by low\n                // surrogates DC00..DFFF; here a different sequence follows\n                for (std::size_t cp1 = 0xD800u; cp1 <= 0xDBFFu; ++cp1)\n                {\n                    for (std::size_t cp2 = 0x0000u; cp2 <= 0xFFFFu; ++cp2)\n                    {\n                        if (0xDC00u <= cp2 && cp2 <= 0xDFFFu)\n                        {\n                            continue;\n                        }\n\n                        std::string json_text = \"\\\"\" + codepoint_to_unicode(cp1) + codepoint_to_unicode(cp2) + \"\\\"\";\n                        CAPTURE(json_text)\n                        CHECK_THROWS_AS(json::parse(json_text), json::parse_error&);\n                    }\n                }\n            }\n\n            SECTION(\"low surrogate without high surrogate\")\n            {\n                // low surrogates DC00..DFFF must follow high surrogates; here,\n                // they occur alone\n                for (std::size_t cp = 0xDC00u; cp <= 0xDFFFu; ++cp)\n                {\n                    std::string json_text = \"\\\"\" + codepoint_to_unicode(cp) + \"\\\"\";\n                    CAPTURE(json_text)\n                    CHECK_THROWS_AS(json::parse(json_text), json::parse_error&);\n                }\n            }\n\n        }\n#endif\n    }\n\n    SECTION(\"read all unicode characters\")\n    {\n        // read a file with all unicode characters stored as single-character\n        // strings in a JSON array\n        std::ifstream f(TEST_DATA_DIRECTORY \"/json_nlohmann_tests/all_unicode.json\");\n        json j;\n        CHECK_NOTHROW(f >> j);\n\n        // the array has 1112064 + 1 elements (a terminating \"null\" value)\n        // Note: 1112064 = 0x1FFFFF code points - 2048 invalid values between\n        // 0xD800 and 0xDFFF.\n        CHECK(j.size() == 1112065);\n\n        SECTION(\"check JSON Pointers\")\n        {\n            for (const auto& s : j)\n            {\n                // skip non-string JSON values\n                if (!s.is_string())\n                {\n                    continue;\n                }\n\n                auto ptr = s.get<std::string>();\n\n                // tilde must be followed by 0 or 1\n                if (ptr == \"~\")\n                {\n                    ptr += \"0\";\n                }\n\n                // JSON Pointers must begin with \"/\"\n                ptr.insert(0, \"/\");\n\n                CHECK_NOTHROW(json::json_pointer(\"/\" + ptr));\n\n                // check escape/unescape roundtrip\n                auto escaped = nlohmann::detail::escape(ptr);\n                nlohmann::detail::unescape(escaped);\n                CHECK(escaped == ptr);\n            }\n        }\n    }\n\n    SECTION(\"ignore byte-order-mark\")\n    {\n        SECTION(\"in a stream\")\n        {\n            // read a file with a UTF-8 BOM\n            std::ifstream f(TEST_DATA_DIRECTORY \"/json_nlohmann_tests/bom.json\");\n            json j;\n            CHECK_NOTHROW(f >> j);\n        }\n\n        SECTION(\"with an iterator\")\n        {\n            std::string i = \"\\xef\\xbb\\xbf{\\n   \\\"foo\\\": true\\n}\";\n            json _;\n            CHECK_NOTHROW(_ = json::parse(i.begin(), i.end()));\n        }\n    }\n\n    SECTION(\"error for incomplete/wrong BOM\")\n    {\n        json _;\n        CHECK_THROWS_AS(_ = json::parse(\"\\xef\\xbb\"), json::parse_error&);\n        CHECK_THROWS_AS(_ = json::parse(\"\\xef\\xbb\\xbb\"), json::parse_error&);\n    }\n}\n\nnamespace\n{\nvoid roundtrip(bool success_expected, const std::string& s);\n\nvoid roundtrip(bool success_expected, const std::string& s)\n{\n    CAPTURE(s)\n    json _;\n\n    // create JSON string value\n    json j = s;\n    // create JSON text\n    std::string ps = std::string(\"\\\"\") + s + \"\\\"\";\n\n    if (success_expected)\n    {\n        // serialization succeeds\n        CHECK_NOTHROW(j.dump());\n\n        // exclude parse test for U+0000\n        if (s[0] != '\\0')\n        {\n            // parsing JSON text succeeds\n            CHECK_NOTHROW(_ = json::parse(ps));\n        }\n\n        // roundtrip succeeds\n        CHECK_NOTHROW(_ = json::parse(j.dump()));\n\n        // after roundtrip, the same string is stored\n        json jr = json::parse(j.dump());\n        CHECK(jr.get<std::string>() == s);\n    }\n    else\n    {\n        // serialization fails\n        CHECK_THROWS_AS(j.dump(), json::type_error&);\n\n        // parsing JSON text fails\n        CHECK_THROWS_AS(_ = json::parse(ps), json::parse_error&);\n    }\n}\n} // namespace\n\nTEST_CASE(\"Markus Kuhn's UTF-8 decoder capability and stress test\")\n{\n    // Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> - 2015-08-28 - CC BY 4.0\n    // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt\n\n    SECTION(\"1  Some correct UTF-8 text\")\n    {\n        roundtrip(true, \"κόσμε\");\n    }\n\n    SECTION(\"2  Boundary condition test cases\")\n    {\n        SECTION(\"2.1  First possible sequence of a certain length\")\n        {\n            // 2.1.1  1 byte  (U-00000000)\n            roundtrip(true, std::string(\"\\0\", 1));\n            // 2.1.2  2 bytes (U-00000080)\n            roundtrip(true, \"\\xc2\\x80\");\n            // 2.1.3  3 bytes (U-00000800)\n            roundtrip(true, \"\\xe0\\xa0\\x80\");\n            // 2.1.4  4 bytes (U-00010000)\n            roundtrip(true, \"\\xf0\\x90\\x80\\x80\");\n\n            // 2.1.5  5 bytes (U-00200000)\n            roundtrip(false, \"\\xF8\\x88\\x80\\x80\\x80\");\n            // 2.1.6  6 bytes (U-04000000)\n            roundtrip(false, \"\\xFC\\x84\\x80\\x80\\x80\\x80\");\n        }\n\n        SECTION(\"2.2  Last possible sequence of a certain length\")\n        {\n            // 2.2.1  1 byte  (U-0000007F)\n            roundtrip(true, \"\\x7f\");\n            // 2.2.2  2 bytes (U-000007FF)\n            roundtrip(true, \"\\xdf\\xbf\");\n            // 2.2.3  3 bytes (U-0000FFFF)\n            roundtrip(true, \"\\xef\\xbf\\xbf\");\n\n            // 2.2.4  4 bytes (U-001FFFFF)\n            roundtrip(false, \"\\xF7\\xBF\\xBF\\xBF\");\n            // 2.2.5  5 bytes (U-03FFFFFF)\n            roundtrip(false, \"\\xFB\\xBF\\xBF\\xBF\\xBF\");\n            // 2.2.6  6 bytes (U-7FFFFFFF)\n            roundtrip(false, \"\\xFD\\xBF\\xBF\\xBF\\xBF\\xBF\");\n        }\n\n        SECTION(\"2.3  Other boundary conditions\")\n        {\n            // 2.3.1  U-0000D7FF = ed 9f bf\n            roundtrip(true, \"\\xed\\x9f\\xbf\");\n            // 2.3.2  U-0000E000 = ee 80 80\n            roundtrip(true, \"\\xee\\x80\\x80\");\n            // 2.3.3  U-0000FFFD = ef bf bd\n            roundtrip(true, \"\\xef\\xbf\\xbd\");\n            // 2.3.4  U-0010FFFF = f4 8f bf bf\n            roundtrip(true, \"\\xf4\\x8f\\xbf\\xbf\");\n\n            // 2.3.5  U-00110000 = f4 90 80 80\n            roundtrip(false, \"\\xf4\\x90\\x80\\x80\");\n        }\n    }\n\n    SECTION(\"3  Malformed sequences\")\n    {\n        SECTION(\"3.1  Unexpected continuation bytes\")\n        {\n            // Each unexpected continuation byte should be separately signalled as a\n            // malformed sequence of its own.\n\n            // 3.1.1  First continuation byte 0x80\n            roundtrip(false, \"\\x80\");\n            // 3.1.2  Last  continuation byte 0xbf\n            roundtrip(false, \"\\xbf\");\n\n            // 3.1.3  2 continuation bytes\n            roundtrip(false, \"\\x80\\xbf\");\n            // 3.1.4  3 continuation bytes\n            roundtrip(false, \"\\x80\\xbf\\x80\");\n            // 3.1.5  4 continuation bytes\n            roundtrip(false, \"\\x80\\xbf\\x80\\xbf\");\n            // 3.1.6  5 continuation bytes\n            roundtrip(false, \"\\x80\\xbf\\x80\\xbf\\x80\");\n            // 3.1.7  6 continuation bytes\n            roundtrip(false, \"\\x80\\xbf\\x80\\xbf\\x80\\xbf\");\n            // 3.1.8  7 continuation bytes\n            roundtrip(false, \"\\x80\\xbf\\x80\\xbf\\x80\\xbf\\x80\");\n\n            // 3.1.9  Sequence of all 64 possible continuation bytes (0x80-0xbf)\n            roundtrip(false, \"\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\");\n        }\n\n        SECTION(\"3.2  Lonely start characters\")\n        {\n            // 3.2.1  All 32 first bytes of 2-byte sequences (0xc0-0xdf)\n            roundtrip(false, \"\\xc0 \\xc1 \\xc2 \\xc3 \\xc4 \\xc5 \\xc6 \\xc7 \\xc8 \\xc9 \\xca \\xcb \\xcc \\xcd \\xce \\xcf \\xd0 \\xd1 \\xd2 \\xd3 \\xd4 \\xd5 \\xd6 \\xd7 \\xd8 \\xd9 \\xda \\xdb \\xdc \\xdd \\xde \\xdf\");\n            // 3.2.2  All 16 first bytes of 3-byte sequences (0xe0-0xef)\n            roundtrip(false, \"\\xe0 \\xe1 \\xe2 \\xe3 \\xe4 \\xe5 \\xe6 \\xe7 \\xe8 \\xe9 \\xea \\xeb \\xec \\xed \\xee \\xef\");\n            // 3.2.3  All 8 first bytes of 4-byte sequences (0xf0-0xf7)\n            roundtrip(false, \"\\xf0 \\xf1 \\xf2 \\xf3 \\xf4 \\xf5 \\xf6 \\xf7\");\n            // 3.2.4  All 4 first bytes of 5-byte sequences (0xf8-0xfb)\n            roundtrip(false, \"\\xf8 \\xf9 \\xfa \\xfb\");\n            // 3.2.5  All 2 first bytes of 6-byte sequences (0xfc-0xfd)\n            roundtrip(false, \"\\xfc \\xfd\");\n        }\n\n        SECTION(\"3.3  Sequences with last continuation byte missing\")\n        {\n            // All bytes of an incomplete sequence should be signalled as a single\n            // malformed sequence, i.e., you should see only a single replacement\n            // character in each of the next 10 tests. (Characters as in section 2)\n\n            // 3.3.1  2-byte sequence with last byte missing (U+0000)\n            roundtrip(false, \"\\xc0\");\n            // 3.3.2  3-byte sequence with last byte missing (U+0000)\n            roundtrip(false, \"\\xe0\\x80\");\n            // 3.3.3  4-byte sequence with last byte missing (U+0000)\n            roundtrip(false, \"\\xf0\\x80\\x80\");\n            // 3.3.4  5-byte sequence with last byte missing (U+0000)\n            roundtrip(false, \"\\xf8\\x80\\x80\\x80\");\n            // 3.3.5  6-byte sequence with last byte missing (U+0000)\n            roundtrip(false, \"\\xfc\\x80\\x80\\x80\\x80\");\n            // 3.3.6  2-byte sequence with last byte missing (U-000007FF)\n            roundtrip(false, \"\\xdf\");\n            // 3.3.7  3-byte sequence with last byte missing (U-0000FFFF)\n            roundtrip(false, \"\\xef\\xbf\");\n            // 3.3.8  4-byte sequence with last byte missing (U-001FFFFF)\n            roundtrip(false, \"\\xf7\\xbf\\xbf\");\n            // 3.3.9  5-byte sequence with last byte missing (U-03FFFFFF)\n            roundtrip(false, \"\\xfb\\xbf\\xbf\\xbf\");\n            // 3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF)\n            roundtrip(false, \"\\xfd\\xbf\\xbf\\xbf\\xbf\");\n        }\n\n        SECTION(\"3.4  Concatenation of incomplete sequences\")\n        {\n            // All the 10 sequences of 3.3 concatenated, you should see 10 malformed\n            // sequences being signalled:\n            roundtrip(false, \"\\xc0\\xe0\\x80\\xf0\\x80\\x80\\xf8\\x80\\x80\\x80\\xfc\\x80\\x80\\x80\\x80\\xdf\\xef\\xbf\\xf7\\xbf\\xbf\\xfb\\xbf\\xbf\\xbf\\xfd\\xbf\\xbf\\xbf\\xbf\");\n        }\n\n        SECTION(\"3.5  Impossible bytes\")\n        {\n            // The following two bytes cannot appear in a correct UTF-8 string\n\n            // 3.5.1  fe\n            roundtrip(false, \"\\xfe\");\n            // 3.5.2  ff\n            roundtrip(false, \"\\xff\");\n            // 3.5.3  fe fe ff ff\n            roundtrip(false, \"\\xfe\\xfe\\xff\\xff\");\n        }\n    }\n\n    SECTION(\"4  Overlong sequences\")\n    {\n        // The following sequences are not malformed according to the letter of\n        // the Unicode 2.0 standard. However, they are longer then necessary and\n        // a correct UTF-8 encoder is not allowed to produce them. A \"safe UTF-8\n        // decoder\" should reject them just like malformed sequences for two\n        // reasons: (1) It helps to debug applications if overlong sequences are\n        // not treated as valid representations of characters, because this helps\n        // to spot problems more quickly. (2) Overlong sequences provide\n        // alternative representations of characters, that could maliciously be\n        // used to bypass filters that check only for ASCII characters. For\n        // instance, a 2-byte encoded line feed (LF) would not be caught by a\n        // line counter that counts only 0x0a bytes, but it would still be\n        // processed as a line feed by an unsafe UTF-8 decoder later in the\n        // pipeline. From a security point of view, ASCII compatibility of UTF-8\n        // sequences means also, that ASCII characters are *only* allowed to be\n        // represented by ASCII bytes in the range 0x00-0x7f. To ensure this\n        // aspect of ASCII compatibility, use only \"safe UTF-8 decoders\" that\n        // reject overlong UTF-8 sequences for which a shorter encoding exists.\n\n        SECTION(\"4.1  Examples of an overlong ASCII character\")\n        {\n            // With a safe UTF-8 decoder, all of the following five overlong\n            // representations of the ASCII character slash (\"/\") should be rejected\n            // like a malformed UTF-8 sequence, for instance by substituting it with\n            // a replacement character. If you see a slash below, you do not have a\n            // safe UTF-8 decoder!\n\n            // 4.1.1 U+002F = c0 af\n            roundtrip(false, \"\\xc0\\xaf\");\n            // 4.1.2 U+002F = e0 80 af\n            roundtrip(false, \"\\xe0\\x80\\xaf\");\n            // 4.1.3 U+002F = f0 80 80 af\n            roundtrip(false, \"\\xf0\\x80\\x80\\xaf\");\n            // 4.1.4 U+002F = f8 80 80 80 af\n            roundtrip(false, \"\\xf8\\x80\\x80\\x80\\xaf\");\n            // 4.1.5 U+002F = fc 80 80 80 80 af\n            roundtrip(false, \"\\xfc\\x80\\x80\\x80\\x80\\xaf\");\n        }\n\n        SECTION(\"4.2  Maximum overlong sequences\")\n        {\n            // Below you see the highest Unicode value that is still resulting in an\n            // overlong sequence if represented with the given number of bytes. This\n            // is a boundary test for safe UTF-8 decoders. All five characters should\n            // be rejected like malformed UTF-8 sequences.\n\n            // 4.2.1  U-0000007F = c1 bf\n            roundtrip(false, \"\\xc1\\xbf\");\n            // 4.2.2  U-000007FF = e0 9f bf\n            roundtrip(false, \"\\xe0\\x9f\\xbf\");\n            // 4.2.3  U-0000FFFF = f0 8f bf bf\n            roundtrip(false, \"\\xf0\\x8f\\xbf\\xbf\");\n            // 4.2.4  U-001FFFFF = f8 87 bf bf bf\n            roundtrip(false, \"\\xf8\\x87\\xbf\\xbf\\xbf\");\n            // 4.2.5  U-03FFFFFF = fc 83 bf bf bf bf\n            roundtrip(false, \"\\xfc\\x83\\xbf\\xbf\\xbf\\xbf\");\n        }\n\n        SECTION(\"4.3  Overlong representation of the NUL character\")\n        {\n            // The following five sequences should also be rejected like malformed\n            // UTF-8 sequences and should not be treated like the ASCII NUL\n            // character.\n\n            // 4.3.1  U+0000 = c0 80\n            roundtrip(false, \"\\xc0\\x80\");\n            // 4.3.2  U+0000 = e0 80 80\n            roundtrip(false, \"\\xe0\\x80\\x80\");\n            // 4.3.3  U+0000 = f0 80 80 80\n            roundtrip(false, \"\\xf0\\x80\\x80\\x80\");\n            // 4.3.4  U+0000 = f8 80 80 80 80\n            roundtrip(false, \"\\xf8\\x80\\x80\\x80\\x80\");\n            // 4.3.5  U+0000 = fc 80 80 80 80 80\n            roundtrip(false, \"\\xfc\\x80\\x80\\x80\\x80\\x80\");\n        }\n    }\n\n    SECTION(\"5  Illegal code positions\")\n    {\n        // The following UTF-8 sequences should be rejected like malformed\n        // sequences, because they never represent valid ISO 10646 characters and\n        // a UTF-8 decoder that accepts them might introduce security problems\n        // comparable to overlong UTF-8 sequences.\n\n        SECTION(\"5.1 Single UTF-16 surrogates\")\n        {\n            // 5.1.1  U+D800 = ed a0 80\n            roundtrip(false, \"\\xed\\xa0\\x80\");\n            // 5.1.2  U+DB7F = ed ad bf\n            roundtrip(false, \"\\xed\\xad\\xbf\");\n            // 5.1.3  U+DB80 = ed ae 80\n            roundtrip(false, \"\\xed\\xae\\x80\");\n            // 5.1.4  U+DBFF = ed af bf\n            roundtrip(false, \"\\xed\\xaf\\xbf\");\n            // 5.1.5  U+DC00 = ed b0 80\n            roundtrip(false, \"\\xed\\xb0\\x80\");\n            // 5.1.6  U+DF80 = ed be 80\n            roundtrip(false, \"\\xed\\xbe\\x80\");\n            // 5.1.7  U+DFFF = ed bf bf\n            roundtrip(false, \"\\xed\\xbf\\xbf\");\n        }\n\n        SECTION(\"5.2 Paired UTF-16 surrogates\")\n        {\n            // 5.2.1  U+D800 U+DC00 = ed a0 80 ed b0 80\n            roundtrip(false, \"\\xed\\xa0\\x80\\xed\\xb0\\x80\");\n            // 5.2.2  U+D800 U+DFFF = ed a0 80 ed bf bf\n            roundtrip(false, \"\\xed\\xa0\\x80\\xed\\xbf\\xbf\");\n            // 5.2.3  U+DB7F U+DC00 = ed ad bf ed b0 80\n            roundtrip(false, \"\\xed\\xad\\xbf\\xed\\xb0\\x80\");\n            // 5.2.4  U+DB7F U+DFFF = ed ad bf ed bf bf\n            roundtrip(false, \"\\xed\\xad\\xbf\\xed\\xbf\\xbf\");\n            // 5.2.5  U+DB80 U+DC00 = ed ae 80 ed b0 80\n            roundtrip(false, \"\\xed\\xae\\x80\\xed\\xb0\\x80\");\n            // 5.2.6  U+DB80 U+DFFF = ed ae 80 ed bf bf\n            roundtrip(false, \"\\xed\\xae\\x80\\xed\\xbf\\xbf\");\n            // 5.2.7  U+DBFF U+DC00 = ed af bf ed b0 80\n            roundtrip(false, \"\\xed\\xaf\\xbf\\xed\\xb0\\x80\");\n            // 5.2.8  U+DBFF U+DFFF = ed af bf ed bf bf\n            roundtrip(false, \"\\xed\\xaf\\xbf\\xed\\xbf\\xbf\");\n        }\n\n        SECTION(\"5.3 Noncharacter code positions\")\n        {\n            // The following \"noncharacters\" are \"reserved for internal use\" by\n            // applications, and according to older versions of the Unicode Standard\n            // \"should never be interchanged\". Unicode Corrigendum #9 dropped the\n            // latter restriction. Nevertheless, their presence in incoming UTF-8 data\n            // can remain a potential security risk, depending on what use is made of\n            // these codes subsequently. Examples of such internal use:\n            //\n            //  - Some file APIs with 16-bit characters may use the integer value -1\n            //    = U+FFFF to signal an end-of-file (EOF) or error condition.\n            //\n            //  - In some UTF-16 receivers, code point U+FFFE might trigger a\n            //    byte-swap operation (to convert between UTF-16LE and UTF-16BE).\n            //\n            // With such internal use of noncharacters, it may be desirable and safer\n            // to block those code points in UTF-8 decoders, as they should never\n            // occur legitimately in incoming UTF-8 data, and could trigger unsafe\n            // behaviour in subsequent processing.\n\n            // Particularly problematic noncharacters in 16-bit applications:\n\n            // 5.3.1  U+FFFE = ef bf be\n            roundtrip(true, \"\\xef\\xbf\\xbe\");\n            // 5.3.2  U+FFFF = ef bf bf\n            roundtrip(true, \"\\xef\\xbf\\xbf\");\n\n            // 5.3.3  U+FDD0 .. U+FDEF\n            roundtrip(true, \"\\xEF\\xB7\\x90\");\n            roundtrip(true, \"\\xEF\\xB7\\x91\");\n            roundtrip(true, \"\\xEF\\xB7\\x92\");\n            roundtrip(true, \"\\xEF\\xB7\\x93\");\n            roundtrip(true, \"\\xEF\\xB7\\x94\");\n            roundtrip(true, \"\\xEF\\xB7\\x95\");\n            roundtrip(true, \"\\xEF\\xB7\\x96\");\n            roundtrip(true, \"\\xEF\\xB7\\x97\");\n            roundtrip(true, \"\\xEF\\xB7\\x98\");\n            roundtrip(true, \"\\xEF\\xB7\\x99\");\n            roundtrip(true, \"\\xEF\\xB7\\x9A\");\n            roundtrip(true, \"\\xEF\\xB7\\x9B\");\n            roundtrip(true, \"\\xEF\\xB7\\x9C\");\n            roundtrip(true, \"\\xEF\\xB7\\x9D\");\n            roundtrip(true, \"\\xEF\\xB7\\x9E\");\n            roundtrip(true, \"\\xEF\\xB7\\x9F\");\n            roundtrip(true, \"\\xEF\\xB7\\xA0\");\n            roundtrip(true, \"\\xEF\\xB7\\xA1\");\n            roundtrip(true, \"\\xEF\\xB7\\xA2\");\n            roundtrip(true, \"\\xEF\\xB7\\xA3\");\n            roundtrip(true, \"\\xEF\\xB7\\xA4\");\n            roundtrip(true, \"\\xEF\\xB7\\xA5\");\n            roundtrip(true, \"\\xEF\\xB7\\xA6\");\n            roundtrip(true, \"\\xEF\\xB7\\xA7\");\n            roundtrip(true, \"\\xEF\\xB7\\xA8\");\n            roundtrip(true, \"\\xEF\\xB7\\xA9\");\n            roundtrip(true, \"\\xEF\\xB7\\xAA\");\n            roundtrip(true, \"\\xEF\\xB7\\xAB\");\n            roundtrip(true, \"\\xEF\\xB7\\xAC\");\n            roundtrip(true, \"\\xEF\\xB7\\xAD\");\n            roundtrip(true, \"\\xEF\\xB7\\xAE\");\n            roundtrip(true, \"\\xEF\\xB7\\xAF\");\n\n            // 5.3.4  U+nFFFE U+nFFFF (for n = 1..10)\n            roundtrip(true, \"\\xF0\\x9F\\xBF\\xBF\");\n            roundtrip(true, \"\\xF0\\xAF\\xBF\\xBF\");\n            roundtrip(true, \"\\xF0\\xBF\\xBF\\xBF\");\n            roundtrip(true, \"\\xF1\\x8F\\xBF\\xBF\");\n            roundtrip(true, \"\\xF1\\x9F\\xBF\\xBF\");\n            roundtrip(true, \"\\xF1\\xAF\\xBF\\xBF\");\n            roundtrip(true, \"\\xF1\\xBF\\xBF\\xBF\");\n            roundtrip(true, \"\\xF2\\x8F\\xBF\\xBF\");\n            roundtrip(true, \"\\xF2\\x9F\\xBF\\xBF\");\n            roundtrip(true, \"\\xF2\\xAF\\xBF\\xBF\");\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-unicode2.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// for some reason including this after the json header leads to linker errors with VS 2017...\n#include <locale>\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <iostream>\n#include <iomanip>\n#include <test_data.hpp>\n\n// this test suite uses static variables with non-trivial destructors\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wexit-time-destructors\")\n\nnamespace\n{\nextern size_t calls;\nsize_t calls = 0;\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    static std::string json_string;\n    json_string.clear();\n\n    CAPTURE(byte1)\n    CAPTURE(byte2)\n    CAPTURE(byte3)\n    CAPTURE(byte4)\n\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    CAPTURE(json_string)\n\n    // store the string in a JSON value\n    static json j;\n    static json j2;\n    j = json_string;\n    j2 = \"abc\" + json_string + \"xyz\";\n\n    static std::string s_ignored;\n    static std::string s_ignored2;\n    static std::string s_ignored_ascii;\n    static std::string s_ignored2_ascii;\n    static std::string s_replaced;\n    static std::string s_replaced2;\n    static std::string s_replaced_ascii;\n    static std::string s_replaced2_ascii;\n\n    // dumping with ignore/replace must not throw in any case\n    s_ignored = j.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored2 = j2.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored_ascii = j.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_ignored2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_replaced = j.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced2 = j2.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced_ascii = j.dump(-1, ' ', true, json::error_handler_t::replace);\n    s_replaced2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::replace);\n\n    if (success_expected)\n    {\n        static std::string s_strict;\n        // strict mode must not throw if success is expected\n        s_strict = j.dump();\n        // all dumps should agree on the string\n        CHECK(s_strict == s_ignored);\n        CHECK(s_strict == s_replaced);\n    }\n    else\n    {\n        // strict mode must throw if success is not expected\n        CHECK_THROWS_AS(j.dump(), json::type_error&);\n        // ignore and replace must create different dumps\n        CHECK(s_ignored != s_replaced);\n\n        // check that replace string contains a replacement character\n        CHECK(s_replaced.find(\"\\xEF\\xBF\\xBD\") != std::string::npos);\n    }\n\n    // check that prefix and suffix are preserved\n    CHECK(s_ignored2.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2.substr(s_ignored2.size() - 4, 3) == \"xyz\");\n    CHECK(s_ignored2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2_ascii.substr(s_ignored2_ascii.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2.substr(s_replaced2.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2_ascii.substr(s_replaced2_ascii.size() - 4, 3) == \"xyz\");\n}\n\nvoid check_utf8string(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\n// create and check a JSON string with up to four UTF-8 bytes\nvoid check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    if (++calls % 100000 == 0)\n    {\n        std::cout << calls << \" of 455355 UTF-8 strings checked\" << std::endl;\n    }\n\n    static std::string json_string;\n    json_string = \"\\\"\";\n\n    CAPTURE(byte1)\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        CAPTURE(byte2)\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        CAPTURE(byte3)\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        CAPTURE(byte4)\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    json_string += \"\\\"\";\n\n    CAPTURE(json_string)\n\n    json _;\n    if (success_expected)\n    {\n        CHECK_NOTHROW(_ = json::parse(json_string));\n    }\n    else\n    {\n        CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);\n    }\n}\n} // namespace\n\nTEST_CASE(\"Unicode (2/5)\" * doctest::skip())\n{\n    SECTION(\"RFC 3629\")\n    {\n        /*\n        RFC 3629 describes in Sect. 4 the syntax of UTF-8 byte sequences as\n        follows:\n\n            A UTF-8 string is a sequence of octets representing a sequence of UCS\n            characters.  An octet sequence is valid UTF-8 only if it matches the\n            following syntax, which is derived from the rules for encoding UTF-8\n            and is expressed in the ABNF of [RFC2234].\n\n            UTF8-octets = *( UTF8-char )\n            UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4\n            UTF8-1      = %x00-7F\n            UTF8-2      = %xC2-DF UTF8-tail\n            UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /\n                          %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )\n            UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /\n                          %xF4 %x80-8F 2( UTF8-tail )\n            UTF8-tail   = %x80-BF\n        */\n\n        SECTION(\"ill-formed first byte\")\n        {\n            for (int byte1 = 0x80; byte1 <= 0xC1; ++byte1)\n            {\n                check_utf8string(false, byte1);\n                check_utf8dump(false, byte1);\n            }\n\n            for (int byte1 = 0xF5; byte1 <= 0xFF; ++byte1)\n            {\n                check_utf8string(false, byte1);\n                check_utf8dump(false, byte1);\n            }\n        }\n\n        SECTION(\"UTF8-1 (x00-x7F)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0x00; byte1 <= 0x7F; ++byte1)\n                {\n                    // unescaped control characters are parse errors in JSON\n                    if (0x00 <= byte1 && byte1 <= 0x1F)\n                    {\n                        check_utf8string(false, byte1);\n                        continue;\n                    }\n\n                    // a single quote is a parse error in JSON\n                    if (byte1 == 0x22)\n                    {\n                        check_utf8string(false, byte1);\n                        continue;\n                    }\n\n                    // a single backslash is a parse error in JSON\n                    if (byte1 == 0x5C)\n                    {\n                        check_utf8string(false, byte1);\n                        continue;\n                    }\n\n                    // all other characters are OK\n                    check_utf8string(true, byte1);\n                    check_utf8dump(true, byte1);\n                }\n            }\n        }\n\n        SECTION(\"UTF8-2 (xC2-xDF UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xC2; byte1 <= 0xDF; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        check_utf8string(true, byte1, byte2);\n                        check_utf8dump(true, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xC2; byte1 <= 0xDF; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xC2; byte1 <= 0xDF; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0x80 <= byte2 && byte2 <= 0xBF)\n                        {\n                            continue;\n                        }\n\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n        }\n\n        SECTION(\"UTF8-3 (xE0 xA0-BF UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1)\n                {\n                    for (int byte2 = 0xA0; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(true, byte1, byte2, byte3);\n                            check_utf8dump(true, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: missing third byte\")\n            {\n                for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1)\n                {\n                    for (int byte2 = 0xA0; byte2 <= 0xBF; ++byte2)\n                    {\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0xA0 <= byte2 && byte2 <= 0xBF)\n                        {\n                            continue;\n                        }\n\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong third byte\")\n            {\n                for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1)\n                {\n                    for (int byte2 = 0xA0; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3)\n                        {\n                            // skip correct third byte\n                            if (0x80 <= byte3 && byte3 <= 0xBF)\n                            {\n                                continue;\n                            }\n\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n        }\n\n        SECTION(\"UTF8-3 (xE1-xEC UTF8-tail UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(true, byte1, byte2, byte3);\n                            check_utf8dump(true, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: missing third byte\")\n            {\n                for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0x80 <= byte2 && byte2 <= 0xBF)\n                        {\n                            continue;\n                        }\n\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong third byte\")\n            {\n                for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3)\n                        {\n                            // skip correct third byte\n                            if (0x80 <= byte3 && byte3 <= 0xBF)\n                            {\n                                continue;\n                            }\n\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n        }\n\n        SECTION(\"UTF8-3 (xED x80-9F UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xED; byte1 <= 0xED; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x9F; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(true, byte1, byte2, byte3);\n                            check_utf8dump(true, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xED; byte1 <= 0xED; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: missing third byte\")\n            {\n                for (int byte1 = 0xED; byte1 <= 0xED; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x9F; ++byte2)\n                    {\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xED; byte1 <= 0xED; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0x80 <= byte2 && byte2 <= 0x9F)\n                        {\n                            continue;\n                        }\n\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong third byte\")\n            {\n                for (int byte1 = 0xED; byte1 <= 0xED; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x9F; ++byte2)\n                    {\n                        for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3)\n                        {\n                            // skip correct third byte\n                            if (0x80 <= byte3 && byte3 <= 0xBF)\n                            {\n                                continue;\n                            }\n\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n        }\n\n        SECTION(\"UTF8-3 (xEE-xEF UTF8-tail UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(true, byte1, byte2, byte3);\n                            check_utf8dump(true, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: missing third byte\")\n            {\n                for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0x80 <= byte2 && byte2 <= 0xBF)\n                        {\n                            continue;\n                        }\n\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong third byte\")\n            {\n                for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3)\n                        {\n                            // skip correct third byte\n                            if (0x80 <= byte3 && byte3 <= 0xBF)\n                            {\n                                continue;\n                            }\n\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-unicode3.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// for some reason including this after the json header leads to linker errors with VS 2017...\n#include <locale>\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <iostream>\n#include <iomanip>\n#include <test_data.hpp>\n\n// this test suite uses static variables with non-trivial destructors\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wexit-time-destructors\")\n\nnamespace\n{\nextern size_t calls;\nsize_t calls = 0;\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    static std::string json_string;\n    json_string.clear();\n\n    CAPTURE(byte1)\n    CAPTURE(byte2)\n    CAPTURE(byte3)\n    CAPTURE(byte4)\n\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    CAPTURE(json_string)\n\n    // store the string in a JSON value\n    static json j;\n    static json j2;\n    j = json_string;\n    j2 = \"abc\" + json_string + \"xyz\";\n\n    static std::string s_ignored;\n    static std::string s_ignored2;\n    static std::string s_ignored_ascii;\n    static std::string s_ignored2_ascii;\n    static std::string s_replaced;\n    static std::string s_replaced2;\n    static std::string s_replaced_ascii;\n    static std::string s_replaced2_ascii;\n\n    // dumping with ignore/replace must not throw in any case\n    s_ignored = j.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored2 = j2.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored_ascii = j.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_ignored2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_replaced = j.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced2 = j2.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced_ascii = j.dump(-1, ' ', true, json::error_handler_t::replace);\n    s_replaced2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::replace);\n\n    if (success_expected)\n    {\n        static std::string s_strict;\n        // strict mode must not throw if success is expected\n        s_strict = j.dump();\n        // all dumps should agree on the string\n        CHECK(s_strict == s_ignored);\n        CHECK(s_strict == s_replaced);\n    }\n    else\n    {\n        // strict mode must throw if success is not expected\n        CHECK_THROWS_AS(j.dump(), json::type_error&);\n        // ignore and replace must create different dumps\n        CHECK(s_ignored != s_replaced);\n\n        // check that replace string contains a replacement character\n        CHECK(s_replaced.find(\"\\xEF\\xBF\\xBD\") != std::string::npos);\n    }\n\n    // check that prefix and suffix are preserved\n    CHECK(s_ignored2.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2.substr(s_ignored2.size() - 4, 3) == \"xyz\");\n    CHECK(s_ignored2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2_ascii.substr(s_ignored2_ascii.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2.substr(s_replaced2.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2_ascii.substr(s_replaced2_ascii.size() - 4, 3) == \"xyz\");\n}\n\nvoid check_utf8string(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\n// create and check a JSON string with up to four UTF-8 bytes\nvoid check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    if (++calls % 100000 == 0)\n    {\n        std::cout << calls << \" of 1641521 UTF-8 strings checked\" << std::endl;\n    }\n\n    static std::string json_string;\n    json_string = \"\\\"\";\n\n    CAPTURE(byte1)\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        CAPTURE(byte2)\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        CAPTURE(byte3)\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        CAPTURE(byte4)\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    json_string += \"\\\"\";\n\n    CAPTURE(json_string)\n\n    json _;\n    if (success_expected)\n    {\n        CHECK_NOTHROW(_ = json::parse(json_string));\n    }\n    else\n    {\n        CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);\n    }\n}\n} // namespace\n\nTEST_CASE(\"Unicode (3/5)\" * doctest::skip())\n{\n    SECTION(\"RFC 3629\")\n    {\n        /*\n        RFC 3629 describes in Sect. 4 the syntax of UTF-8 byte sequences as\n        follows:\n\n            A UTF-8 string is a sequence of octets representing a sequence of UCS\n            characters.  An octet sequence is valid UTF-8 only if it matches the\n            following syntax, which is derived from the rules for encoding UTF-8\n            and is expressed in the ABNF of [RFC2234].\n\n            UTF8-octets = *( UTF8-char )\n            UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4\n            UTF8-1      = %x00-7F\n            UTF8-2      = %xC2-DF UTF8-tail\n            UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /\n                          %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )\n            UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /\n                          %xF4 %x80-8F 2( UTF8-tail )\n            UTF8-tail   = %x80-BF\n        */\n\n        SECTION(\"UTF8-4 (xF0 x90-BF UTF8-tail UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xF0; byte1 <= 0xF0; ++byte1)\n                {\n                    for (int byte2 = 0x90; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(true, byte1, byte2, byte3, byte4);\n                                check_utf8dump(true, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xF0; byte1 <= 0xF0; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: missing third byte\")\n            {\n                for (int byte1 = 0xF0; byte1 <= 0xF0; ++byte1)\n                {\n                    for (int byte2 = 0x90; byte2 <= 0xBF; ++byte2)\n                    {\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing fourth byte\")\n            {\n                for (int byte1 = 0xF0; byte1 <= 0xF0; ++byte1)\n                {\n                    for (int byte2 = 0x90; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xF0; byte1 <= 0xF0; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0x90 <= byte2 && byte2 <= 0xBF)\n                        {\n                            continue;\n                        }\n\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong third byte\")\n            {\n                for (int byte1 = 0xF0; byte1 <= 0xF0; ++byte1)\n                {\n                    for (int byte2 = 0x90; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3)\n                        {\n                            // skip correct third byte\n                            if (0x80 <= byte3 && byte3 <= 0xBF)\n                            {\n                                continue;\n                            }\n\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong fourth byte\")\n            {\n                for (int byte1 = 0xF0; byte1 <= 0xF0; ++byte1)\n                {\n                    for (int byte2 = 0x90; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x00; byte4 <= 0xFF; ++byte4)\n                            {\n                                // skip fourth second byte\n                                if (0x80 <= byte3 && byte3 <= 0xBF)\n                                {\n                                    continue;\n                                }\n\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-unicode4.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// for some reason including this after the json header leads to linker errors with VS 2017...\n#include <locale>\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <iostream>\n#include <iomanip>\n#include <test_data.hpp>\n\n// this test suite uses static variables with non-trivial destructors\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wexit-time-destructors\")\n\nnamespace\n{\nextern size_t calls;\nsize_t calls = 0;\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    static std::string json_string;\n    json_string.clear();\n\n    CAPTURE(byte1)\n    CAPTURE(byte2)\n    CAPTURE(byte3)\n    CAPTURE(byte4)\n\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    CAPTURE(json_string)\n\n    // store the string in a JSON value\n    static json j;\n    static json j2;\n    j = json_string;\n    j2 = \"abc\" + json_string + \"xyz\";\n\n    static std::string s_ignored;\n    static std::string s_ignored2;\n    static std::string s_ignored_ascii;\n    static std::string s_ignored2_ascii;\n    static std::string s_replaced;\n    static std::string s_replaced2;\n    static std::string s_replaced_ascii;\n    static std::string s_replaced2_ascii;\n\n    // dumping with ignore/replace must not throw in any case\n    s_ignored = j.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored2 = j2.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored_ascii = j.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_ignored2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_replaced = j.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced2 = j2.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced_ascii = j.dump(-1, ' ', true, json::error_handler_t::replace);\n    s_replaced2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::replace);\n\n    if (success_expected)\n    {\n        static std::string s_strict;\n        // strict mode must not throw if success is expected\n        s_strict = j.dump();\n        // all dumps should agree on the string\n        CHECK(s_strict == s_ignored);\n        CHECK(s_strict == s_replaced);\n    }\n    else\n    {\n        // strict mode must throw if success is not expected\n        CHECK_THROWS_AS(j.dump(), json::type_error&);\n        // ignore and replace must create different dumps\n        CHECK(s_ignored != s_replaced);\n\n        // check that replace string contains a replacement character\n        CHECK(s_replaced.find(\"\\xEF\\xBF\\xBD\") != std::string::npos);\n    }\n\n    // check that prefix and suffix are preserved\n    CHECK(s_ignored2.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2.substr(s_ignored2.size() - 4, 3) == \"xyz\");\n    CHECK(s_ignored2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2_ascii.substr(s_ignored2_ascii.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2.substr(s_replaced2.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2_ascii.substr(s_replaced2_ascii.size() - 4, 3) == \"xyz\");\n}\n\nvoid check_utf8string(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\n// create and check a JSON string with up to four UTF-8 bytes\nvoid check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    if (++calls % 100000 == 0)\n    {\n        std::cout << calls << \" of 5517507 UTF-8 strings checked\" << std::endl;\n    }\n\n    static std::string json_string;\n    json_string = \"\\\"\";\n\n    CAPTURE(byte1)\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        CAPTURE(byte2)\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        CAPTURE(byte3)\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        CAPTURE(byte4)\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    json_string += \"\\\"\";\n\n    CAPTURE(json_string)\n\n    json _;\n    if (success_expected)\n    {\n        CHECK_NOTHROW(_ = json::parse(json_string));\n    }\n    else\n    {\n        CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);\n    }\n}\n} // namespace\n\nTEST_CASE(\"Unicode (4/5)\" * doctest::skip())\n{\n    SECTION(\"RFC 3629\")\n    {\n        /*\n        RFC 3629 describes in Sect. 4 the syntax of UTF-8 byte sequences as\n        follows:\n\n            A UTF-8 string is a sequence of octets representing a sequence of UCS\n            characters.  An octet sequence is valid UTF-8 only if it matches the\n            following syntax, which is derived from the rules for encoding UTF-8\n            and is expressed in the ABNF of [RFC2234].\n\n            UTF8-octets = *( UTF8-char )\n            UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4\n            UTF8-1      = %x00-7F\n            UTF8-2      = %xC2-DF UTF8-tail\n            UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /\n                          %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )\n            UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /\n                          %xF4 %x80-8F 2( UTF8-tail )\n            UTF8-tail   = %x80-BF\n        */\n\n        SECTION(\"UTF8-4 (xF1-F3 UTF8-tail UTF8-tail UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xF1; byte1 <= 0xF3; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(true, byte1, byte2, byte3, byte4);\n                                check_utf8dump(true, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xF1; byte1 <= 0xF3; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: missing third byte\")\n            {\n                for (int byte1 = 0xF1; byte1 <= 0xF3; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing fourth byte\")\n            {\n                for (int byte1 = 0xF1; byte1 <= 0xF3; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xF1; byte1 <= 0xF3; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0x80 <= byte2 && byte2 <= 0xBF)\n                        {\n                            continue;\n                        }\n\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong third byte\")\n            {\n                for (int byte1 = 0xF1; byte1 <= 0xF3; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3)\n                        {\n                            // skip correct third byte\n                            if (0x80 <= byte3 && byte3 <= 0xBF)\n                            {\n                                continue;\n                            }\n\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong fourth byte\")\n            {\n                for (int byte1 = 0xF1; byte1 <= 0xF3; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x00; byte4 <= 0xFF; ++byte4)\n                            {\n                                // skip correct fourth byte\n                                if (0x80 <= byte3 && byte3 <= 0xBF)\n                                {\n                                    continue;\n                                }\n\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-unicode5.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n// for some reason including this after the json header leads to linker errors with VS 2017...\n#include <locale>\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <fstream>\n#include <sstream>\n#include <iostream>\n#include <iomanip>\n#include <test_data.hpp>\n\n// this test suite uses static variables with non-trivial destructors\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wexit-time-destructors\")\n\nnamespace\n{\nextern size_t calls;\nsize_t calls = 0;\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\nvoid check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    static std::string json_string;\n    json_string.clear();\n\n    CAPTURE(byte1)\n    CAPTURE(byte2)\n    CAPTURE(byte3)\n    CAPTURE(byte4)\n\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    CAPTURE(json_string)\n\n    // store the string in a JSON value\n    static json j;\n    static json j2;\n    j = json_string;\n    j2 = \"abc\" + json_string + \"xyz\";\n\n    static std::string s_ignored;\n    static std::string s_ignored2;\n    static std::string s_ignored_ascii;\n    static std::string s_ignored2_ascii;\n    static std::string s_replaced;\n    static std::string s_replaced2;\n    static std::string s_replaced_ascii;\n    static std::string s_replaced2_ascii;\n\n    // dumping with ignore/replace must not throw in any case\n    s_ignored = j.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored2 = j2.dump(-1, ' ', false, json::error_handler_t::ignore);\n    s_ignored_ascii = j.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_ignored2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::ignore);\n    s_replaced = j.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced2 = j2.dump(-1, ' ', false, json::error_handler_t::replace);\n    s_replaced_ascii = j.dump(-1, ' ', true, json::error_handler_t::replace);\n    s_replaced2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::replace);\n\n    if (success_expected)\n    {\n        static std::string s_strict;\n        // strict mode must not throw if success is expected\n        s_strict = j.dump();\n        // all dumps should agree on the string\n        CHECK(s_strict == s_ignored);\n        CHECK(s_strict == s_replaced);\n    }\n    else\n    {\n        // strict mode must throw if success is not expected\n        CHECK_THROWS_AS(j.dump(), json::type_error&);\n        // ignore and replace must create different dumps\n        CHECK(s_ignored != s_replaced);\n\n        // check that replace string contains a replacement character\n        CHECK(s_replaced.find(\"\\xEF\\xBF\\xBD\") != std::string::npos);\n    }\n\n    // check that prefix and suffix are preserved\n    CHECK(s_ignored2.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2.substr(s_ignored2.size() - 4, 3) == \"xyz\");\n    CHECK(s_ignored2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_ignored2_ascii.substr(s_ignored2_ascii.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2.substr(s_replaced2.size() - 4, 3) == \"xyz\");\n    CHECK(s_replaced2_ascii.substr(1, 3) == \"abc\");\n    CHECK(s_replaced2_ascii.substr(s_replaced2_ascii.size() - 4, 3) == \"xyz\");\n}\n\nvoid check_utf8string(bool success_expected, int byte1, int byte2, int byte3, int byte4);\n\n// create and check a JSON string with up to four UTF-8 bytes\nvoid check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1)\n{\n    if (++calls % 100000 == 0)\n    {\n        std::cout << calls << \" of 1246225 UTF-8 strings checked\" << std::endl;\n    }\n\n    static std::string json_string;\n    json_string = \"\\\"\";\n\n    CAPTURE(byte1)\n    json_string += std::string(1, static_cast<char>(byte1));\n\n    if (byte2 != -1)\n    {\n        CAPTURE(byte2)\n        json_string += std::string(1, static_cast<char>(byte2));\n    }\n\n    if (byte3 != -1)\n    {\n        CAPTURE(byte3)\n        json_string += std::string(1, static_cast<char>(byte3));\n    }\n\n    if (byte4 != -1)\n    {\n        CAPTURE(byte4)\n        json_string += std::string(1, static_cast<char>(byte4));\n    }\n\n    json_string += \"\\\"\";\n\n    CAPTURE(json_string)\n\n    json _;\n    if (success_expected)\n    {\n        CHECK_NOTHROW(_ = json::parse(json_string));\n    }\n    else\n    {\n        CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);\n    }\n}\n} // namespace\n\nTEST_CASE(\"Unicode (5/5)\" * doctest::skip())\n{\n    SECTION(\"RFC 3629\")\n    {\n        /*\n        RFC 3629 describes in Sect. 4 the syntax of UTF-8 byte sequences as\n        follows:\n\n            A UTF-8 string is a sequence of octets representing a sequence of UCS\n            characters.  An octet sequence is valid UTF-8 only if it matches the\n            following syntax, which is derived from the rules for encoding UTF-8\n            and is expressed in the ABNF of [RFC2234].\n\n            UTF8-octets = *( UTF8-char )\n            UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4\n            UTF8-1      = %x00-7F\n            UTF8-2      = %xC2-DF UTF8-tail\n            UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /\n                          %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )\n            UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /\n                          %xF4 %x80-8F 2( UTF8-tail )\n            UTF8-tail   = %x80-BF\n        */\n\n        SECTION(\"UTF8-4 (xF4 x80-8F UTF8-tail UTF8-tail)\")\n        {\n            SECTION(\"well-formed\")\n            {\n                for (int byte1 = 0xF4; byte1 <= 0xF4; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x8F; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(true, byte1, byte2, byte3, byte4);\n                                check_utf8dump(true, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing second byte\")\n            {\n                for (int byte1 = 0xF4; byte1 <= 0xF4; ++byte1)\n                {\n                    check_utf8string(false, byte1);\n                    check_utf8dump(false, byte1);\n                }\n            }\n\n            SECTION(\"ill-formed: missing third byte\")\n            {\n                for (int byte1 = 0xF4; byte1 <= 0xF4; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x8F; ++byte2)\n                    {\n                        check_utf8string(false, byte1, byte2);\n                        check_utf8dump(false, byte1, byte2);\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: missing fourth byte\")\n            {\n                for (int byte1 = 0xF4; byte1 <= 0xF4; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x8F; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            check_utf8string(false, byte1, byte2, byte3);\n                            check_utf8dump(false, byte1, byte2, byte3);\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong second byte\")\n            {\n                for (int byte1 = 0xF4; byte1 <= 0xF4; ++byte1)\n                {\n                    for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2)\n                    {\n                        // skip correct second byte\n                        if (0x80 <= byte2 && byte2 <= 0x8F)\n                        {\n                            continue;\n                        }\n\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong third byte\")\n            {\n                for (int byte1 = 0xF4; byte1 <= 0xF4; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x8F; ++byte2)\n                    {\n                        for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3)\n                        {\n                            // skip correct third byte\n                            if (0x80 <= byte3 && byte3 <= 0xBF)\n                            {\n                                continue;\n                            }\n\n                            for (int byte4 = 0x80; byte4 <= 0xBF; ++byte4)\n                            {\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n\n            SECTION(\"ill-formed: wrong fourth byte\")\n            {\n                for (int byte1 = 0xF4; byte1 <= 0xF4; ++byte1)\n                {\n                    for (int byte2 = 0x80; byte2 <= 0x8F; ++byte2)\n                    {\n                        for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3)\n                        {\n                            for (int byte4 = 0x00; byte4 <= 0xFF; ++byte4)\n                            {\n                                // skip correct fourth byte\n                                if (0x80 <= byte3 && byte3 <= 0xBF)\n                                {\n                                    continue;\n                                }\n\n                                check_utf8string(false, byte1, byte2, byte3, byte4);\n                                check_utf8dump(false, byte1, byte2, byte3, byte4);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-user_defined_input.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\n#include <list>\n\nnamespace\n{\nTEST_CASE(\"Use arbitrary stdlib container\")\n{\n    std::string raw_data = \"[1,2,3,4]\";\n    std::list<char> data(raw_data.begin(), raw_data.end());\n\n    json as_json = json::parse(data.begin(), data.end());\n    CHECK(as_json.at(0) == 1);\n    CHECK(as_json.at(1) == 2);\n    CHECK(as_json.at(2) == 3);\n    CHECK(as_json.at(3) == 4);\n}\n\nstruct MyContainer\n{\n    const char* data;\n};\n\nconst char* begin(const MyContainer& c)\n{\n    return c.data;\n}\n\nconst char* end(const MyContainer& c)\n{\n    return c.data + strlen(c.data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)\n}\n\nTEST_CASE(\"Custom container non-member begin/end\")\n{\n\n    MyContainer data{\"[1,2,3,4]\"};\n    json as_json = json::parse(data);\n    CHECK(as_json.at(0) == 1);\n    CHECK(as_json.at(1) == 2);\n    CHECK(as_json.at(2) == 3);\n    CHECK(as_json.at(3) == 4);\n\n}\n\nTEST_CASE(\"Custom container member begin/end\")\n{\n    struct MyContainer2\n    {\n        const char* data;\n\n        const char* begin() const\n        {\n            return data;\n        }\n\n        const char* end() const\n        {\n            return data + strlen(data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)\n        }\n    };\n\n    MyContainer2 data{\"[1,2,3,4]\"};\n    json as_json = json::parse(data);\n    CHECK(as_json.at(0) == 1);\n    CHECK(as_json.at(1) == 2);\n    CHECK(as_json.at(2) == 3);\n    CHECK(as_json.at(3) == 4);\n}\n\nTEST_CASE(\"Custom iterator\")\n{\n    const char* raw_data = \"[1,2,3,4]\";\n\n    struct MyIterator\n    {\n        using difference_type = std::size_t;\n        using value_type = char;\n        using pointer = const char*;\n        using reference = const char&;\n        using iterator_category = std::input_iterator_tag;\n\n        MyIterator& operator++()\n        {\n            ++ptr; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)\n            return *this;\n        }\n\n        reference operator*() const\n        {\n            return *ptr;\n        }\n\n        bool operator!=(const MyIterator& rhs) const\n        {\n            return ptr != rhs.ptr;\n        }\n\n        const char* ptr;\n    };\n\n    // avoid -Wunused-local-typedefs\n    CHECK(std::is_same<MyIterator::difference_type, std::size_t>::value);\n    CHECK(std::is_same<MyIterator::value_type, char>::value);\n    CHECK(std::is_same<MyIterator::pointer, const char*>::value);\n    CHECK(std::is_same<MyIterator::reference, const char&>::value);\n    CHECK(std::is_same<MyIterator::iterator_category, std::input_iterator_tag>::value);\n\n    MyIterator begin{raw_data};\n    MyIterator end{raw_data + strlen(raw_data)}; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)\n\n    json as_json = json::parse(begin, end);\n    CHECK(as_json.at(0) == 1);\n    CHECK(as_json.at(1) == 2);\n    CHECK(as_json.at(2) == 3);\n    CHECK(as_json.at(3) == 4);\n}\n\n} // namespace\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit-wstring.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include \"doctest_compatibility.h\"\n\n#include <nlohmann/json.hpp>\nusing nlohmann::json;\n\nnamespace\n{\nbool wstring_is_utf16();\nbool wstring_is_utf16()\n{\n    return (std::wstring(L\"💩\") == std::wstring(L\"\\U0001F4A9\"));\n}\n\nbool u16string_is_utf16();\nbool u16string_is_utf16()\n{\n    return (std::u16string(u\"💩\") == std::u16string(u\"\\U0001F4A9\"));\n}\n\nbool u32string_is_utf32();\nbool u32string_is_utf32()\n{\n    return (std::u32string(U\"💩\") == std::u32string(U\"\\U0001F4A9\"));\n}\n} // namespace\n\nTEST_CASE(\"wide strings\")\n{\n    SECTION(\"std::wstring\")\n    {\n        if (wstring_is_utf16())\n        {\n            std::wstring w = L\"[12.2,\\\"Ⴥaäö💤🧢\\\"]\";\n            json j = json::parse(w);\n            CHECK(j.dump() == \"[12.2,\\\"Ⴥaäö💤🧢\\\"]\");\n        }\n    }\n\n    SECTION(\"invalid std::wstring\")\n    {\n        if (wstring_is_utf16())\n        {\n            std::wstring w = L\"\\\"\\xDBFF\";\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(w), json::parse_error&);\n        }\n    }\n\n    SECTION(\"std::u16string\")\n    {\n        if (u16string_is_utf16())\n        {\n            std::u16string w = u\"[12.2,\\\"Ⴥaäö💤🧢\\\"]\";\n            json j = json::parse(w);\n            CHECK(j.dump() == \"[12.2,\\\"Ⴥaäö💤🧢\\\"]\");\n        }\n    }\n\n    SECTION(\"invalid std::u16string\")\n    {\n        if (wstring_is_utf16())\n        {\n            std::u16string w = u\"\\\"\\xDBFF\";\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(w), json::parse_error&);\n        }\n    }\n\n    SECTION(\"std::u32string\")\n    {\n        if (u32string_is_utf32())\n        {\n            std::u32string w = U\"[12.2,\\\"Ⴥaäö💤🧢\\\"]\";\n            json j = json::parse(w);\n            CHECK(j.dump() == \"[12.2,\\\"Ⴥaäö💤🧢\\\"]\");\n        }\n    }\n\n    SECTION(\"invalid std::u32string\")\n    {\n        if (u32string_is_utf32())\n        {\n            std::u32string w = U\"\\\"\\x110000\";\n            json _;\n            CHECK_THROWS_AS(_ = json::parse(w), json::parse_error&);\n        }\n    }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/src/unit.cpp",
    "content": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++ (test suite)\n|  |  |__   |  |  | | | |  version 3.10.5\n|_____|_____|_____|_|___|  https://github.com/nlohmann/json\n\nLicensed under the MIT License <http://opensource.org/licenses/MIT>.\nSPDX-License-Identifier: MIT\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.\n\nPermission is hereby  granted, free of charge, to any  person obtaining a copy\nof this software and associated  documentation files (the \"Software\"), to deal\nin the Software  without restriction, including without  limitation the rights\nto  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\ncopies  of  the Software,  and  to  permit persons  to  whom  the Software  is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE  IS PROVIDED \"AS  IS\", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\nIMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\nFITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE\nAUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\nLIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN\n#include \"doctest_compatibility.h\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/CMakeLists.txt",
    "content": "set(LIBFUZZER_FLAGS_BASE \"${CMAKE_CXX_FLAGS}\")\n# Disable the coverage and sanitizer instrumentation for the fuzzer itself.\nset(CMAKE_CXX_FLAGS \"${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=trace-pc-guard,edge,trace-cmp,indirect-calls,8bit-counters -Werror\")\nif( LLVM_USE_SANITIZE_COVERAGE )\n  if(NOT \"${LLVM_USE_SANITIZER}\" STREQUAL \"Address\")\n    message(FATAL_ERROR\n      \"LibFuzzer and its tests require LLVM_USE_SANITIZER=Address and \"\n      \"LLVM_USE_SANITIZE_COVERAGE=YES to be set.\"\n      )\n  endif()\n  add_library(LLVMFuzzerNoMainObjects OBJECT\n    FuzzerCrossOver.cpp\n    FuzzerDriver.cpp\n    FuzzerExtFunctionsDlsym.cpp\n    FuzzerExtFunctionsWeak.cpp\n    FuzzerExtFunctionsWeakAlias.cpp\n    FuzzerIO.cpp\n    FuzzerIOPosix.cpp\n    FuzzerIOWindows.cpp\n    FuzzerLoop.cpp\n    FuzzerMerge.cpp\n    FuzzerMutate.cpp\n    FuzzerSHA1.cpp\n    FuzzerTracePC.cpp\n    FuzzerTraceState.cpp\n    FuzzerUtil.cpp\n    FuzzerUtilDarwin.cpp\n    FuzzerUtilLinux.cpp\n    FuzzerUtilPosix.cpp\n    FuzzerUtilWindows.cpp\n    )\n  add_library(LLVMFuzzerNoMain STATIC\n    $<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>\n    )\n  target_link_libraries(LLVMFuzzerNoMain ${PTHREAD_LIB})\n  add_library(LLVMFuzzer STATIC\n    FuzzerMain.cpp\n    $<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>\n    )\n  target_link_libraries(LLVMFuzzer ${PTHREAD_LIB})\n\n  if( LLVM_INCLUDE_TESTS )\n    add_subdirectory(test)\n  endif()\nendif()\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerCorpus.h",
    "content": "//===- FuzzerCorpus.h - Internal header for the Fuzzer ----------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// fuzzer::InputCorpus\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_CORPUS\n#define LLVM_FUZZER_CORPUS\n\n#include \"FuzzerDefs.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerRandom.h\"\n#include \"FuzzerSHA1.h\"\n#include \"FuzzerTracePC.h\"\n#include <numeric>\n#include <random>\n#include <unordered_set>\n\nnamespace fuzzer {\n\nstruct InputInfo {\n  Unit U;  // The actual input data.\n  uint8_t Sha1[kSHA1NumBytes];  // Checksum.\n  // Number of features that this input has and no smaller input has.\n  size_t NumFeatures = 0;\n  size_t Tmp = 0; // Used by ValidateFeatureSet.\n  // Stats.\n  size_t NumExecutedMutations = 0;\n  size_t NumSuccessfullMutations = 0;\n  bool MayDeleteFile = false;\n};\n\nclass InputCorpus {\n public:\n  static const size_t kFeatureSetSize = 1 << 16;\n  InputCorpus(const std::string &OutputCorpus) : OutputCorpus(OutputCorpus) {\n    memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));\n    memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));\n  }\n  ~InputCorpus() {\n    for (auto II : Inputs)\n      delete II;\n  }\n  size_t size() const { return Inputs.size(); }\n  size_t SizeInBytes() const {\n    size_t Res = 0;\n    for (auto II : Inputs)\n      Res += II->U.size();\n    return Res;\n  }\n  size_t NumActiveUnits() const {\n    size_t Res = 0;\n    for (auto II : Inputs)\n      Res += !II->U.empty();\n    return Res;\n  }\n  bool empty() const { return Inputs.empty(); }\n  const Unit &operator[] (size_t Idx) const { return Inputs[Idx]->U; }\n  void AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile = false) {\n    assert(!U.empty());\n    uint8_t Hash[kSHA1NumBytes];\n    if (FeatureDebug)\n      Printf(\"ADD_TO_CORPUS %zd NF %zd\\n\", Inputs.size(), NumFeatures);\n    ComputeSHA1(U.data(), U.size(), Hash);\n    Hashes.insert(Sha1ToString(Hash));\n    Inputs.push_back(new InputInfo());\n    InputInfo &II = *Inputs.back();\n    II.U = U;\n    II.NumFeatures = NumFeatures;\n    II.MayDeleteFile = MayDeleteFile;\n    memcpy(II.Sha1, Hash, kSHA1NumBytes);\n    UpdateCorpusDistribution();\n    ValidateFeatureSet();\n  }\n\n  bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }\n  bool HasUnit(const std::string &H) { return Hashes.count(H); }\n  InputInfo &ChooseUnitToMutate(Random &Rand) {\n    InputInfo &II = *Inputs[ChooseUnitIdxToMutate(Rand)];\n    assert(!II.U.empty());\n    return II;\n  };\n\n  // Returns an index of random unit from the corpus to mutate.\n  // Hypothesis: units added to the corpus last are more likely to be\n  // interesting. This function gives more weight to the more recent units.\n  size_t ChooseUnitIdxToMutate(Random &Rand) {\n    size_t Idx = static_cast<size_t>(CorpusDistribution(Rand.Get_mt19937()));\n    assert(Idx < Inputs.size());\n    return Idx;\n  }\n\n  void PrintStats() {\n    for (size_t i = 0; i < Inputs.size(); i++) {\n      const auto &II = *Inputs[i];\n      Printf(\"  [%zd %s]\\tsz: %zd\\truns: %zd\\tsucc: %zd\\n\", i,\n             Sha1ToString(II.Sha1).c_str(), II.U.size(),\n             II.NumExecutedMutations, II.NumSuccessfullMutations);\n    }\n  }\n\n  void PrintFeatureSet() {\n    for (size_t i = 0; i < kFeatureSetSize; i++) {\n      if(size_t Sz = GetFeature(i))\n        Printf(\"[%zd: id %zd sz%zd] \", i, SmallestElementPerFeature[i], Sz);\n    }\n    Printf(\"\\n\\t\");\n    for (size_t i = 0; i < Inputs.size(); i++)\n      if (size_t N = Inputs[i]->NumFeatures)\n        Printf(\" %zd=>%zd \", i, N);\n    Printf(\"\\n\");\n  }\n\n  void DeleteInput(size_t Idx) {\n    InputInfo &II = *Inputs[Idx];\n    if (!OutputCorpus.empty() && II.MayDeleteFile)\n      RemoveFile(DirPlusFile(OutputCorpus, Sha1ToString(II.Sha1)));\n    Unit().swap(II.U);\n    if (FeatureDebug)\n      Printf(\"EVICTED %zd\\n\", Idx);\n  }\n\n  bool AddFeature(size_t Idx, uint32_t NewSize, bool Shrink) {\n    assert(NewSize);\n    Idx = Idx % kFeatureSetSize;\n    uint32_t OldSize = GetFeature(Idx);\n    if (OldSize == 0 || (Shrink && OldSize > NewSize)) {\n      if (OldSize > 0) {\n        size_t OldIdx = SmallestElementPerFeature[Idx];\n        InputInfo &II = *Inputs[OldIdx];\n        assert(II.NumFeatures > 0);\n        II.NumFeatures--;\n        if (II.NumFeatures == 0)\n          DeleteInput(OldIdx);\n      }\n      if (FeatureDebug)\n        Printf(\"ADD FEATURE %zd sz %d\\n\", Idx, NewSize);\n      SmallestElementPerFeature[Idx] = Inputs.size();\n      InputSizesPerFeature[Idx] = NewSize;\n      CountingFeatures = true;\n      return true;\n    }\n    return false;\n  }\n\n  size_t NumFeatures() const {\n    size_t Res = 0;\n    for (size_t i = 0; i < kFeatureSetSize; i++)\n      Res += GetFeature(i) != 0;\n    return Res;\n  }\n\n  void ResetFeatureSet() {\n    assert(Inputs.empty());\n    memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));\n    memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));\n  }\n\nprivate:\n\n  static const bool FeatureDebug = false;\n\n  size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; }\n\n  void ValidateFeatureSet() {\n    if (!CountingFeatures) return;\n    if (FeatureDebug)\n      PrintFeatureSet();\n    for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++)\n      if (GetFeature(Idx))\n        Inputs[SmallestElementPerFeature[Idx]]->Tmp++;\n    for (auto II: Inputs) {\n      if (II->Tmp != II->NumFeatures)\n        Printf(\"ZZZ %zd %zd\\n\", II->Tmp, II->NumFeatures);\n      assert(II->Tmp == II->NumFeatures);\n      II->Tmp = 0;\n    }\n  }\n\n  // Updates the probability distribution for the units in the corpus.\n  // Must be called whenever the corpus or unit weights are changed.\n  void UpdateCorpusDistribution() {\n    size_t N = Inputs.size();\n    Intervals.resize(N + 1);\n    Weights.resize(N);\n    std::iota(Intervals.begin(), Intervals.end(), 0);\n    if (CountingFeatures)\n      for (size_t i = 0; i < N; i++)\n        Weights[i] = Inputs[i]->NumFeatures * (i + 1);\n    else\n      std::iota(Weights.begin(), Weights.end(), 1);\n    CorpusDistribution = std::piecewise_constant_distribution<double>(\n        Intervals.begin(), Intervals.end(), Weights.begin());\n  }\n  std::piecewise_constant_distribution<double> CorpusDistribution;\n\n  std::vector<double> Intervals;\n  std::vector<double> Weights;\n\n  std::unordered_set<std::string> Hashes;\n  std::vector<InputInfo*> Inputs;\n\n  bool CountingFeatures = false;\n  uint32_t InputSizesPerFeature[kFeatureSetSize];\n  uint32_t SmallestElementPerFeature[kFeatureSetSize];\n\n  std::string OutputCorpus;\n};\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_CORPUS\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerCrossOver.cpp",
    "content": "//===- FuzzerCrossOver.cpp - Cross over two test inputs -------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Cross over test inputs.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerDefs.h\"\n#include \"FuzzerMutate.h\"\n#include \"FuzzerRandom.h\"\n#include <cstring>\n\nnamespace fuzzer {\n\n// Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out.\nsize_t MutationDispatcher::CrossOver(const uint8_t *Data1, size_t Size1,\n                                     const uint8_t *Data2, size_t Size2,\n                                     uint8_t *Out, size_t MaxOutSize) {\n  assert(Size1 || Size2);\n  MaxOutSize = Rand(MaxOutSize) + 1;\n  size_t OutPos = 0;\n  size_t Pos1 = 0;\n  size_t Pos2 = 0;\n  size_t *InPos = &Pos1;\n  size_t InSize = Size1;\n  const uint8_t *Data = Data1;\n  bool CurrentlyUsingFirstData = true;\n  while (OutPos < MaxOutSize && (Pos1 < Size1 || Pos2 < Size2)) {\n    // Merge a part of Data into Out.\n    size_t OutSizeLeft = MaxOutSize - OutPos;\n    if (*InPos < InSize) {\n      size_t InSizeLeft = InSize - *InPos;\n      size_t MaxExtraSize = std::min(OutSizeLeft, InSizeLeft);\n      size_t ExtraSize = Rand(MaxExtraSize) + 1;\n      memcpy(Out + OutPos, Data + *InPos, ExtraSize);\n      OutPos += ExtraSize;\n      (*InPos) += ExtraSize;\n    }\n    // Use the other input data on the next iteration.\n    InPos  = CurrentlyUsingFirstData ? &Pos2 : &Pos1;\n    InSize = CurrentlyUsingFirstData ? Size2 : Size1;\n    Data   = CurrentlyUsingFirstData ? Data2 : Data1;\n    CurrentlyUsingFirstData = !CurrentlyUsingFirstData;\n  }\n  return OutPos;\n}\n\n}  // namespace fuzzer\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerDefs.h",
    "content": "//===- FuzzerDefs.h - Internal header for the Fuzzer ------------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Basic definitions.\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_DEFS_H\n#define LLVM_FUZZER_DEFS_H\n\n#include <cassert>\n#include <cstddef>\n#include <cstdint>\n#include <cstring>\n#include <string>\n#include <vector>\n\n// Platform detection.\n#ifdef __linux__\n#define LIBFUZZER_APPLE 0\n#define LIBFUZZER_LINUX 1\n#define LIBFUZZER_WINDOWS 0\n#elif __APPLE__\n#define LIBFUZZER_APPLE 1\n#define LIBFUZZER_LINUX 0\n#define LIBFUZZER_WINDOWS 0\n#elif _WIN32\n#define LIBFUZZER_APPLE 0\n#define LIBFUZZER_LINUX 0\n#define LIBFUZZER_WINDOWS 1\n#else\n#error \"Support for your platform has not been implemented\"\n#endif\n\n#define LIBFUZZER_POSIX LIBFUZZER_APPLE || LIBFUZZER_LINUX\n\n#ifdef __x86_64\n#define ATTRIBUTE_TARGET_POPCNT __attribute__((target(\"popcnt\")))\n#else\n#define ATTRIBUTE_TARGET_POPCNT\n#endif\n\n\n#ifdef __clang__  // avoid gcc warning.\n#  define ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize(\"memory\")))\n#else\n#  define ATTRIBUTE_NO_SANITIZE_MEMORY\n#endif\n\nnamespace fuzzer {\n\ntemplate <class T> T Min(T a, T b) { return a < b ? a : b; }\ntemplate <class T> T Max(T a, T b) { return a > b ? a : b; }\n\nclass Random;\nclass Dictionary;\nclass DictionaryEntry;\nclass MutationDispatcher;\nstruct FuzzingOptions;\nclass InputCorpus;\nstruct InputInfo;\nstruct ExternalFunctions;\n\n// Global interface to functions that may or may not be available.\nextern ExternalFunctions *EF;\n\ntypedef std::vector<uint8_t> Unit;\ntypedef std::vector<Unit> UnitVector;\ntypedef int (*UserCallback)(const uint8_t *Data, size_t Size);\n\nint FuzzerDriver(int *argc, char ***argv, UserCallback Callback);\n\nstruct ScopedDoingMyOwnMemmem {\n  ScopedDoingMyOwnMemmem();\n  ~ScopedDoingMyOwnMemmem();\n};\n\ninline uint8_t  Bswap(uint8_t x)  { return x; }\ninline uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }\ninline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }\ninline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_DEFS_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerDictionary.h",
    "content": "//===- FuzzerDictionary.h - Internal header for the Fuzzer ------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// fuzzer::Dictionary\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_DICTIONARY_H\n#define LLVM_FUZZER_DICTIONARY_H\n\n#include \"FuzzerDefs.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerUtil.h\"\n#include <algorithm>\n#include <limits>\n\nnamespace fuzzer {\n// A simple POD sized array of bytes.\ntemplate <size_t kMaxSize> class FixedWord {\npublic:\n  FixedWord() {}\n  FixedWord(const uint8_t *B, uint8_t S) { Set(B, S); }\n\n  void Set(const uint8_t *B, uint8_t S) {\n    assert(S <= kMaxSize);\n    memcpy(Data, B, S);\n    Size = S;\n  }\n\n  bool operator==(const FixedWord<kMaxSize> &w) const {\n    return Size == w.Size && 0 == memcmp(Data, w.Data, Size);\n  }\n\n  bool operator<(const FixedWord<kMaxSize> &w) const {\n    if (Size != w.Size)\n      return Size < w.Size;\n    return memcmp(Data, w.Data, Size) < 0;\n  }\n\n  static size_t GetMaxSize() { return kMaxSize; }\n  const uint8_t *data() const { return Data; }\n  uint8_t size() const { return Size; }\n\nprivate:\n  uint8_t Size = 0;\n  uint8_t Data[kMaxSize];\n};\n\ntypedef FixedWord<27> Word; // 28 bytes.\n\nclass DictionaryEntry {\n public:\n  DictionaryEntry() {}\n  DictionaryEntry(Word W) : W(W) {}\n  DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}\n  const Word &GetW() const { return W; }\n\n  bool HasPositionHint() const { return PositionHint != std::numeric_limits<size_t>::max(); }\n  size_t GetPositionHint() const {\n    assert(HasPositionHint());\n    return PositionHint;\n  }\n  void IncUseCount() { UseCount++; }\n  void IncSuccessCount() { SuccessCount++; }\n  size_t GetUseCount() const { return UseCount; }\n  size_t GetSuccessCount() const {return SuccessCount; }\n\n  void Print(const char *PrintAfter = \"\\n\") {\n    PrintASCII(W.data(), W.size());\n    if (HasPositionHint())\n      Printf(\"@%zd\", GetPositionHint());\n    Printf(\"%s\", PrintAfter);\n  }\n\nprivate:\n  Word W;\n  size_t PositionHint = std::numeric_limits<size_t>::max();\n  size_t UseCount = 0;\n  size_t SuccessCount = 0;\n};\n\nclass Dictionary {\n public:\n  static const size_t kMaxDictSize = 1 << 14;\n\n  bool ContainsWord(const Word &W) const {\n    return std::any_of(begin(), end(), [&](const DictionaryEntry &DE) {\n      return DE.GetW() == W;\n    });\n  }\n  const DictionaryEntry *begin() const { return &DE[0]; }\n  const DictionaryEntry *end() const { return begin() + Size; }\n  DictionaryEntry & operator[] (size_t Idx) {\n    assert(Idx < Size);\n    return DE[Idx];\n  }\n  void push_back(DictionaryEntry DE) {\n    if (Size < kMaxDictSize)\n      this->DE[Size++] = DE;\n  }\n  void clear() { Size = 0; }\n  bool empty() const { return Size == 0; }\n  size_t size() const { return Size; }\n\nprivate:\n  DictionaryEntry DE[kMaxDictSize];\n  size_t Size = 0;\n};\n\n// Parses one dictionary entry.\n// If successfull, write the enty to Unit and returns true,\n// otherwise returns false.\nbool ParseOneDictionaryEntry(const std::string &Str, Unit *U);\n// Parses the dictionary file, fills Units, returns true iff all lines\n// were parsed succesfully.\nbool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units);\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_DICTIONARY_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerDriver.cpp",
    "content": "//===- FuzzerDriver.cpp - FuzzerDriver function and flags -----------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// FuzzerDriver and flag parsing.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerCorpus.h\"\n#include \"FuzzerInterface.h\"\n#include \"FuzzerInternal.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerMutate.h\"\n#include \"FuzzerRandom.h\"\n#include \"FuzzerTracePC.h\"\n#include <algorithm>\n#include <atomic>\n#include <chrono>\n#include <cstring>\n#include <mutex>\n#include <string>\n#include <thread>\n\n// This function should be present in the libFuzzer so that the client\n// binary can test for its existence.\nextern \"C\" __attribute__((used)) void __libfuzzer_is_present() {}\n\nnamespace fuzzer {\n\n// Program arguments.\nstruct FlagDescription {\n  const char *Name;\n  const char *Description;\n  int   Default;\n  int   *IntFlag;\n  const char **StrFlag;\n  unsigned int *UIntFlag;\n};\n\nstruct {\n#define FUZZER_DEPRECATED_FLAG(Name)\n#define FUZZER_FLAG_INT(Name, Default, Description) int Name;\n#define FUZZER_FLAG_UNSIGNED(Name, Default, Description) unsigned int Name;\n#define FUZZER_FLAG_STRING(Name, Description) const char *Name;\n#include \"FuzzerFlags.def\"\n#undef FUZZER_DEPRECATED_FLAG\n#undef FUZZER_FLAG_INT\n#undef FUZZER_FLAG_UNSIGNED\n#undef FUZZER_FLAG_STRING\n} Flags;\n\nstatic const FlagDescription FlagDescriptions [] {\n#define FUZZER_DEPRECATED_FLAG(Name)                                           \\\n  {#Name, \"Deprecated; don't use\", 0, nullptr, nullptr, nullptr},\n#define FUZZER_FLAG_INT(Name, Default, Description)                            \\\n  {#Name, Description, Default, &Flags.Name, nullptr, nullptr},\n#define FUZZER_FLAG_UNSIGNED(Name, Default, Description)                       \\\n  {#Name,   Description, static_cast<int>(Default),                            \\\n   nullptr, nullptr, &Flags.Name},\n#define FUZZER_FLAG_STRING(Name, Description)                                  \\\n  {#Name, Description, 0, nullptr, &Flags.Name, nullptr},\n#include \"FuzzerFlags.def\"\n#undef FUZZER_DEPRECATED_FLAG\n#undef FUZZER_FLAG_INT\n#undef FUZZER_FLAG_UNSIGNED\n#undef FUZZER_FLAG_STRING\n};\n\nstatic const size_t kNumFlags =\n    sizeof(FlagDescriptions) / sizeof(FlagDescriptions[0]);\n\nstatic std::vector<std::string> *Inputs;\nstatic std::string *ProgName;\n\nstatic void PrintHelp() {\n  Printf(\"Usage:\\n\");\n  auto Prog = ProgName->c_str();\n  Printf(\"\\nTo run fuzzing pass 0 or more directories.\\n\");\n  Printf(\"%s [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\\n\", Prog);\n\n  Printf(\"\\nTo run individual tests without fuzzing pass 1 or more files:\\n\");\n  Printf(\"%s [-flag1=val1 [-flag2=val2 ...] ] file1 [file2 ...]\\n\", Prog);\n\n  Printf(\"\\nFlags: (strictly in form -flag=value)\\n\");\n  size_t MaxFlagLen = 0;\n  for (size_t F = 0; F < kNumFlags; F++)\n    MaxFlagLen = std::max(strlen(FlagDescriptions[F].Name), MaxFlagLen);\n\n  for (size_t F = 0; F < kNumFlags; F++) {\n    const auto &D = FlagDescriptions[F];\n    if (strstr(D.Description, \"internal flag\") == D.Description) continue;\n    Printf(\" %s\", D.Name);\n    for (size_t i = 0, n = MaxFlagLen - strlen(D.Name); i < n; i++)\n      Printf(\" \");\n    Printf(\"\\t\");\n    Printf(\"%d\\t%s\\n\", D.Default, D.Description);\n  }\n  Printf(\"\\nFlags starting with '--' will be ignored and \"\n            \"will be passed verbatim to subprocesses.\\n\");\n}\n\nstatic const char *FlagValue(const char *Param, const char *Name) {\n  size_t Len = strlen(Name);\n  if (Param[0] == '-' && strstr(Param + 1, Name) == Param + 1 &&\n      Param[Len + 1] == '=')\n      return &Param[Len + 2];\n  return nullptr;\n}\n\n// Avoid calling stol as it triggers a bug in clang/glibc build.\nstatic long MyStol(const char *Str) {\n  long Res = 0;\n  long Sign = 1;\n  if (*Str == '-') {\n    Str++;\n    Sign = -1;\n  }\n  for (size_t i = 0; Str[i]; i++) {\n    char Ch = Str[i];\n    if (Ch < '0' || Ch > '9')\n      return Res;\n    Res = Res * 10 + (Ch - '0');\n  }\n  return Res * Sign;\n}\n\nstatic bool ParseOneFlag(const char *Param) {\n  if (Param[0] != '-') return false;\n  if (Param[1] == '-') {\n    static bool PrintedWarning = false;\n    if (!PrintedWarning) {\n      PrintedWarning = true;\n      Printf(\"INFO: libFuzzer ignores flags that start with '--'\\n\");\n    }\n    for (size_t F = 0; F < kNumFlags; F++)\n      if (FlagValue(Param + 1, FlagDescriptions[F].Name))\n        Printf(\"WARNING: did you mean '%s' (single dash)?\\n\", Param + 1);\n    return true;\n  }\n  for (size_t F = 0; F < kNumFlags; F++) {\n    const char *Name = FlagDescriptions[F].Name;\n    const char *Str = FlagValue(Param, Name);\n    if (Str)  {\n      if (FlagDescriptions[F].IntFlag) {\n        int Val = MyStol(Str);\n        *FlagDescriptions[F].IntFlag = Val;\n        if (Flags.verbosity >= 2)\n          Printf(\"Flag: %s %d\\n\", Name, Val);\n        return true;\n      } else if (FlagDescriptions[F].UIntFlag) {\n        unsigned int Val = std::stoul(Str);\n        *FlagDescriptions[F].UIntFlag = Val;\n        if (Flags.verbosity >= 2)\n          Printf(\"Flag: %s %u\\n\", Name, Val);\n        return true;\n      } else if (FlagDescriptions[F].StrFlag) {\n        *FlagDescriptions[F].StrFlag = Str;\n        if (Flags.verbosity >= 2)\n          Printf(\"Flag: %s %s\\n\", Name, Str);\n        return true;\n      } else {  // Deprecated flag.\n        Printf(\"Flag: %s: deprecated, don't use\\n\", Name);\n        return true;\n      }\n    }\n  }\n  Printf(\"\\n\\nWARNING: unrecognized flag '%s'; \"\n         \"use -help=1 to list all flags\\n\\n\", Param);\n  return true;\n}\n\n// We don't use any library to minimize dependencies.\nstatic void ParseFlags(const std::vector<std::string> &Args) {\n  for (size_t F = 0; F < kNumFlags; F++) {\n    if (FlagDescriptions[F].IntFlag)\n      *FlagDescriptions[F].IntFlag = FlagDescriptions[F].Default;\n    if (FlagDescriptions[F].UIntFlag)\n      *FlagDescriptions[F].UIntFlag =\n          static_cast<unsigned int>(FlagDescriptions[F].Default);\n    if (FlagDescriptions[F].StrFlag)\n      *FlagDescriptions[F].StrFlag = nullptr;\n  }\n  Inputs = new std::vector<std::string>;\n  for (size_t A = 1; A < Args.size(); A++) {\n    if (ParseOneFlag(Args[A].c_str())) continue;\n    Inputs->push_back(Args[A]);\n  }\n}\n\nstatic std::mutex Mu;\n\nstatic void PulseThread() {\n  while (true) {\n    SleepSeconds(600);\n    std::lock_guard<std::mutex> Lock(Mu);\n    Printf(\"pulse...\\n\");\n  }\n}\n\nstatic void WorkerThread(const std::string &Cmd, std::atomic<unsigned> *Counter,\n                         unsigned NumJobs, std::atomic<bool> *HasErrors) {\n  while (true) {\n    unsigned C = (*Counter)++;\n    if (C >= NumJobs) break;\n    std::string Log = \"fuzz-\" + std::to_string(C) + \".log\";\n    std::string ToRun = Cmd + \" > \" + Log + \" 2>&1\\n\";\n    if (Flags.verbosity)\n      Printf(\"%s\", ToRun.c_str());\n    int ExitCode = ExecuteCommand(ToRun);\n    if (ExitCode != 0)\n      *HasErrors = true;\n    std::lock_guard<std::mutex> Lock(Mu);\n    Printf(\"================== Job %u exited with exit code %d ============\\n\",\n           C, ExitCode);\n    fuzzer::CopyFileToErr(Log);\n  }\n}\n\nstd::string CloneArgsWithoutX(const std::vector<std::string> &Args,\n                              const char *X1, const char *X2) {\n  std::string Cmd;\n  for (auto &S : Args) {\n    if (FlagValue(S.c_str(), X1) || FlagValue(S.c_str(), X2))\n      continue;\n    Cmd += S + \" \";\n  }\n  return Cmd;\n}\n\nstatic int RunInMultipleProcesses(const std::vector<std::string> &Args,\n                                  unsigned NumWorkers, unsigned NumJobs) {\n  std::atomic<unsigned> Counter(0);\n  std::atomic<bool> HasErrors(false);\n  std::string Cmd = CloneArgsWithoutX(Args, \"jobs\", \"workers\");\n  std::vector<std::thread> V;\n  std::thread Pulse(PulseThread);\n  Pulse.detach();\n  for (unsigned i = 0; i < NumWorkers; i++)\n    V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs, &HasErrors));\n  for (auto &T : V)\n    T.join();\n  return HasErrors ? 1 : 0;\n}\n\nstatic void RssThread(Fuzzer *F, size_t RssLimitMb) {\n  while (true) {\n    SleepSeconds(1);\n    size_t Peak = GetPeakRSSMb();\n    if (Peak > RssLimitMb)\n      F->RssLimitCallback();\n  }\n}\n\nstatic void StartRssThread(Fuzzer *F, size_t RssLimitMb) {\n  if (!RssLimitMb) return;\n  std::thread T(RssThread, F, RssLimitMb);\n  T.detach();\n}\n\nint RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) {\n  Unit U = FileToVector(InputFilePath);\n  if (MaxLen && MaxLen < U.size())\n    U.resize(MaxLen);\n  F->RunOne(U.data(), U.size());\n  F->TryDetectingAMemoryLeak(U.data(), U.size(), true);\n  return 0;\n}\n\nstatic bool AllInputsAreFiles() {\n  if (Inputs->empty()) return false;\n  for (auto &Path : *Inputs)\n    if (!IsFile(Path))\n      return false;\n  return true;\n}\n\nint MinimizeCrashInput(const std::vector<std::string> &Args) {\n  if (Inputs->size() != 1) {\n    Printf(\"ERROR: -minimize_crash should be given one input file\\n\");\n    exit(1);\n  }\n  std::string InputFilePath = Inputs->at(0);\n  std::string BaseCmd =\n      CloneArgsWithoutX(Args, \"minimize_crash\", \"exact_artifact_path\");\n  auto InputPos = BaseCmd.find(\" \" + InputFilePath + \" \");\n  assert(InputPos != std::string::npos);\n  BaseCmd.erase(InputPos, InputFilePath.size() + 1);\n  if (Flags.runs <= 0 && Flags.max_total_time == 0) {\n    Printf(\"INFO: you need to specify -runs=N or \"\n           \"-max_total_time=N with -minimize_crash=1\\n\"\n           \"INFO: defaulting to -max_total_time=600\\n\");\n    BaseCmd += \" -max_total_time=600\";\n  }\n  // BaseCmd += \" >  /dev/null 2>&1 \";\n\n  std::string CurrentFilePath = InputFilePath;\n  while (true) {\n    Unit U = FileToVector(CurrentFilePath);\n    if (U.size() < 2) {\n      Printf(\"CRASH_MIN: '%s' is small enough\\n\", CurrentFilePath.c_str());\n      return 0;\n    }\n    Printf(\"CRASH_MIN: minimizing crash input: '%s' (%zd bytes)\\n\",\n           CurrentFilePath.c_str(), U.size());\n\n    auto Cmd = BaseCmd + \" \" + CurrentFilePath;\n\n    Printf(\"CRASH_MIN: executing: %s\\n\", Cmd.c_str());\n    int ExitCode = ExecuteCommand(Cmd);\n    if (ExitCode == 0) {\n      Printf(\"ERROR: the input %s did not crash\\n\", CurrentFilePath.c_str());\n      exit(1);\n    }\n    Printf(\"CRASH_MIN: '%s' (%zd bytes) caused a crash. Will try to minimize \"\n           \"it further\\n\",\n           CurrentFilePath.c_str(), U.size());\n\n    std::string ArtifactPath = \"minimized-from-\" + Hash(U);\n    Cmd += \" -minimize_crash_internal_step=1 -exact_artifact_path=\" +\n        ArtifactPath;\n    Printf(\"CRASH_MIN: executing: %s\\n\", Cmd.c_str());\n    ExitCode = ExecuteCommand(Cmd);\n    if (ExitCode == 0) {\n      if (Flags.exact_artifact_path) {\n        CurrentFilePath = Flags.exact_artifact_path;\n        WriteToFile(U, CurrentFilePath);\n      }\n      Printf(\"CRASH_MIN: failed to minimize beyond %s (%d bytes), exiting\\n\",\n             CurrentFilePath.c_str(), U.size());\n      return 0;\n    }\n    CurrentFilePath = ArtifactPath;\n    Printf(\"\\n\\n\\n\\n\\n\\n*********************************\\n\");\n  }\n  return 0;\n}\n\nint MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {\n  assert(Inputs->size() == 1);\n  std::string InputFilePath = Inputs->at(0);\n  Unit U = FileToVector(InputFilePath);\n  assert(U.size() > 2);\n  Printf(\"INFO: Starting MinimizeCrashInputInternalStep: %zd\\n\", U.size());\n  Corpus->AddToCorpus(U, 0);\n  F->SetMaxInputLen(U.size());\n  F->SetMaxMutationLen(U.size() - 1);\n  F->MinimizeCrashLoop(U);\n  Printf(\"INFO: Done MinimizeCrashInputInternalStep, no crashes found\\n\");\n  exit(0);\n  return 0;\n}\n\nint FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {\n  using namespace fuzzer;\n  assert(argc && argv && \"Argument pointers cannot be nullptr\");\n  EF = new ExternalFunctions();\n  if (EF->LLVMFuzzerInitialize)\n    EF->LLVMFuzzerInitialize(argc, argv);\n  const std::vector<std::string> Args(*argv, *argv + *argc);\n  assert(!Args.empty());\n  ProgName = new std::string(Args[0]);\n  ParseFlags(Args);\n  if (Flags.help) {\n    PrintHelp();\n    return 0;\n  }\n\n  if (Flags.minimize_crash)\n    return MinimizeCrashInput(Args);\n\n  if (Flags.close_fd_mask & 2)\n    DupAndCloseStderr();\n  if (Flags.close_fd_mask & 1)\n    CloseStdout();\n\n  if (Flags.jobs > 0 && Flags.workers == 0) {\n    Flags.workers = std::min(NumberOfCpuCores() / 2, Flags.jobs);\n    if (Flags.workers > 1)\n      Printf(\"Running %u workers\\n\", Flags.workers);\n  }\n\n  if (Flags.workers > 0 && Flags.jobs > 0)\n    return RunInMultipleProcesses(Args, Flags.workers, Flags.jobs);\n\n  const size_t kMaxSaneLen = 1 << 20;\n  const size_t kMinDefaultLen = 64;\n  FuzzingOptions Options;\n  Options.Verbosity = Flags.verbosity;\n  Options.MaxLen = Flags.max_len;\n  Options.UnitTimeoutSec = Flags.timeout;\n  Options.ErrorExitCode = Flags.error_exitcode;\n  Options.TimeoutExitCode = Flags.timeout_exitcode;\n  Options.MaxTotalTimeSec = Flags.max_total_time;\n  Options.DoCrossOver = Flags.cross_over;\n  Options.MutateDepth = Flags.mutate_depth;\n  Options.UseCounters = Flags.use_counters;\n  Options.UseIndirCalls = Flags.use_indir_calls;\n  Options.UseMemcmp = Flags.use_memcmp;\n  Options.UseMemmem = Flags.use_memmem;\n  Options.UseCmp = Flags.use_cmp;\n  Options.UseValueProfile = Flags.use_value_profile;\n  Options.Shrink = Flags.shrink;\n  Options.ShuffleAtStartUp = Flags.shuffle;\n  Options.PreferSmall = Flags.prefer_small;\n  Options.ReloadIntervalSec = Flags.reload;\n  Options.OnlyASCII = Flags.only_ascii;\n  Options.OutputCSV = Flags.output_csv;\n  Options.DetectLeaks = Flags.detect_leaks;\n  Options.TraceMalloc = Flags.trace_malloc;\n  Options.RssLimitMb = Flags.rss_limit_mb;\n  if (Flags.runs >= 0)\n    Options.MaxNumberOfRuns = Flags.runs;\n  if (!Inputs->empty() && !Flags.minimize_crash_internal_step)\n    Options.OutputCorpus = (*Inputs)[0];\n  Options.ReportSlowUnits = Flags.report_slow_units;\n  if (Flags.artifact_prefix)\n    Options.ArtifactPrefix = Flags.artifact_prefix;\n  if (Flags.exact_artifact_path)\n    Options.ExactArtifactPath = Flags.exact_artifact_path;\n  std::vector<Unit> Dictionary;\n  if (Flags.dict)\n    if (!ParseDictionaryFile(FileToString(Flags.dict), &Dictionary))\n      return 1;\n  if (Flags.verbosity > 0 && !Dictionary.empty())\n    Printf(\"Dictionary: %zd entries\\n\", Dictionary.size());\n  bool DoPlainRun = AllInputsAreFiles();\n  Options.SaveArtifacts =\n      !DoPlainRun || Flags.minimize_crash_internal_step;\n  Options.PrintNewCovPcs = Flags.print_pcs;\n  Options.PrintFinalStats = Flags.print_final_stats;\n  Options.PrintCorpusStats = Flags.print_corpus_stats;\n  Options.PrintCoverage = Flags.print_coverage;\n  Options.DumpCoverage = Flags.dump_coverage;\n  if (Flags.exit_on_src_pos)\n    Options.ExitOnSrcPos = Flags.exit_on_src_pos;\n  if (Flags.exit_on_item)\n    Options.ExitOnItem = Flags.exit_on_item;\n\n  unsigned Seed = Flags.seed;\n  // Initialize Seed.\n  if (Seed == 0)\n    Seed = (std::chrono::system_clock::now().time_since_epoch().count() << 10) +\n           GetPid();\n  if (Flags.verbosity)\n    Printf(\"INFO: Seed: %u\\n\", Seed);\n\n  Random Rand(Seed);\n  auto *MD = new MutationDispatcher(Rand, Options);\n  auto *Corpus = new InputCorpus(Options.OutputCorpus);\n  auto *F = new Fuzzer(Callback, *Corpus, *MD, Options);\n\n  for (auto &U: Dictionary)\n    if (U.size() <= Word::GetMaxSize())\n      MD->AddWordToManualDictionary(Word(U.data(), U.size()));\n\n  StartRssThread(F, Flags.rss_limit_mb);\n\n  Options.HandleAbrt = Flags.handle_abrt;\n  Options.HandleBus = Flags.handle_bus;\n  Options.HandleFpe = Flags.handle_fpe;\n  Options.HandleIll = Flags.handle_ill;\n  Options.HandleInt = Flags.handle_int;\n  Options.HandleSegv = Flags.handle_segv;\n  Options.HandleTerm = Flags.handle_term;\n  SetSignalHandler(Options);\n\n  if (Flags.minimize_crash_internal_step)\n    return MinimizeCrashInputInternalStep(F, Corpus);\n\n  if (DoPlainRun) {\n    Options.SaveArtifacts = false;\n    int Runs = std::max(1, Flags.runs);\n    Printf(\"%s: Running %zd inputs %d time(s) each.\\n\", ProgName->c_str(),\n           Inputs->size(), Runs);\n    for (auto &Path : *Inputs) {\n      auto StartTime = system_clock::now();\n      Printf(\"Running: %s\\n\", Path.c_str());\n      for (int Iter = 0; Iter < Runs; Iter++)\n        RunOneTest(F, Path.c_str(), Options.MaxLen);\n      auto StopTime = system_clock::now();\n      auto MS = duration_cast<milliseconds>(StopTime - StartTime).count();\n      Printf(\"Executed %s in %zd ms\\n\", Path.c_str(), (long)MS);\n    }\n    Printf(\"***\\n\"\n           \"*** NOTE: fuzzing was not performed, you have only\\n\"\n           \"***       executed the target code on a fixed set of inputs.\\n\"\n           \"***\\n\");\n    F->PrintFinalStats();\n    exit(0);\n  }\n\n  if (Flags.merge) {\n    if (Options.MaxLen == 0)\n      F->SetMaxInputLen(kMaxSaneLen);\n    if (TPC.UsingTracePcGuard()) {\n      if (Flags.merge_control_file)\n        F->CrashResistantMergeInternalStep(Flags.merge_control_file);\n      else\n        F->CrashResistantMerge(Args, *Inputs);\n    } else {\n      F->Merge(*Inputs);\n    }\n    exit(0);\n  }\n\n  size_t TemporaryMaxLen = Options.MaxLen ? Options.MaxLen : kMaxSaneLen;\n\n  UnitVector InitialCorpus;\n  for (auto &Inp : *Inputs) {\n    Printf(\"Loading corpus dir: %s\\n\", Inp.c_str());\n    ReadDirToVectorOfUnits(Inp.c_str(), &InitialCorpus, nullptr,\n                           TemporaryMaxLen, /*ExitOnError=*/false);\n  }\n\n  if (Options.MaxLen == 0) {\n    size_t MaxLen = 0;\n    for (auto &U : InitialCorpus)\n      MaxLen = std::max(U.size(), MaxLen);\n    F->SetMaxInputLen(std::min(std::max(kMinDefaultLen, MaxLen), kMaxSaneLen));\n  }\n\n  if (InitialCorpus.empty()) {\n    InitialCorpus.push_back(Unit({'\\n'}));  // Valid ASCII input.\n    if (Options.Verbosity)\n      Printf(\"INFO: A corpus is not provided, starting from an empty corpus\\n\");\n  }\n  F->ShuffleAndMinimize(&InitialCorpus);\n  InitialCorpus.clear();  // Don't need this memory any more.\n  F->Loop();\n\n  if (Flags.verbosity)\n    Printf(\"Done %d runs in %zd second(s)\\n\", F->getTotalNumberOfRuns(),\n           F->secondsSinceProcessStartUp());\n  F->PrintFinalStats();\n\n  exit(0);  // Don't let F destroy itself.\n}\n\n// Storage for global ExternalFunctions object.\nExternalFunctions *EF = nullptr;\n\n}  // namespace fuzzer\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerExtFunctions.def",
    "content": "//===- FuzzerExtFunctions.def - External functions --------------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// This defines the external function pointers that\n// ``fuzzer::ExternalFunctions`` should contain and try to initialize.  The\n// EXT_FUNC macro must be defined at the point of inclusion. The signature of\n// the macro is:\n//\n// EXT_FUNC(<name>, <return_type>, <function_signature>, <warn_if_missing>)\n//===----------------------------------------------------------------------===//\n\n// Optional user functions\nEXT_FUNC(LLVMFuzzerInitialize, int, (int *argc, char ***argv), false);\nEXT_FUNC(LLVMFuzzerCustomMutator, size_t,\n         (uint8_t * Data, size_t Size, size_t MaxSize, unsigned int Seed),\n         false);\nEXT_FUNC(LLVMFuzzerCustomCrossOver, size_t,\n         (const uint8_t * Data1, size_t Size1,\n          const uint8_t * Data2, size_t Size2,\n          uint8_t * Out, size_t MaxOutSize, unsigned int Seed),\n         false);\n\n// Sanitizer functions\nEXT_FUNC(__lsan_enable, void, (), false);\nEXT_FUNC(__lsan_disable, void, (), false);\nEXT_FUNC(__lsan_do_recoverable_leak_check, int, (), false);\nEXT_FUNC(__sanitizer_get_number_of_counters, size_t, (), false);\nEXT_FUNC(__sanitizer_install_malloc_and_free_hooks, int,\n         (void (*malloc_hook)(const volatile void *, size_t),\n          void (*free_hook)(const volatile void *)),\n         false);\nEXT_FUNC(__sanitizer_get_total_unique_caller_callee_pairs, size_t, (), false);\nEXT_FUNC(__sanitizer_get_total_unique_coverage, size_t, (), true);\nEXT_FUNC(__sanitizer_print_memory_profile, int, (size_t), false);\nEXT_FUNC(__sanitizer_print_stack_trace, void, (), true);\nEXT_FUNC(__sanitizer_symbolize_pc, void,\n         (void *, const char *fmt, char *out_buf, size_t out_buf_size), false);\nEXT_FUNC(__sanitizer_get_module_and_offset_for_pc, int,\n         (void *pc, char *module_path,\n         size_t module_path_len,void **pc_offset), false);\nEXT_FUNC(__sanitizer_reset_coverage, void, (), true);\nEXT_FUNC(__sanitizer_set_death_callback, void, (void (*)(void)), true);\nEXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);\nEXT_FUNC(__sanitizer_update_counter_bitset_and_clear_counters, uintptr_t,\n  (uint8_t*), false);\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerExtFunctions.h",
    "content": "//===- FuzzerExtFunctions.h - Interface to external functions ---*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Defines an interface to (possibly optional) functions.\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_EXT_FUNCTIONS_H\n#define LLVM_FUZZER_EXT_FUNCTIONS_H\n\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace fuzzer {\n\nstruct ExternalFunctions {\n  // Initialize function pointers. Functions that are not available will be set\n  // to nullptr.  Do not call this constructor  before ``main()`` has been\n  // entered.\n  ExternalFunctions();\n\n#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \\\n  RETURN_TYPE(*NAME) FUNC_SIG = nullptr\n\n#include \"FuzzerExtFunctions.def\"\n\n#undef EXT_FUNC\n};\n} // namespace fuzzer\n\n#endif\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerExtFunctionsDlsym.cpp",
    "content": "//===- FuzzerExtFunctionsDlsym.cpp - Interface to external functions ------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Implementation for operating systems that support dlsym(). We only use it on\n// Apple platforms for now. We don't use this approach on Linux because it\n// requires that clients of LibFuzzer pass ``--export-dynamic`` to the linker.\n// That is a complication we don't wish to expose to clients right now.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_APPLE\n\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerIO.h\"\n#include <dlfcn.h>\n\nusing namespace fuzzer;\n\ntemplate <typename T>\nstatic T GetFnPtr(const char *FnName, bool WarnIfMissing) {\n  dlerror(); // Clear any previous errors.\n  void *Fn = dlsym(RTLD_DEFAULT, FnName);\n  if (Fn == nullptr) {\n    if (WarnIfMissing) {\n      const char *ErrorMsg = dlerror();\n      Printf(\"WARNING: Failed to find function \\\"%s\\\".\", FnName);\n      if (ErrorMsg)\n        Printf(\" Reason %s.\", ErrorMsg);\n      Printf(\"\\n\");\n    }\n  }\n  return reinterpret_cast<T>(Fn);\n}\n\nnamespace fuzzer {\n\nExternalFunctions::ExternalFunctions() {\n#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \\\n  this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)\n\n#include \"FuzzerExtFunctions.def\"\n\n#undef EXT_FUNC\n}\n\n} // namespace fuzzer\n\n#endif // LIBFUZZER_APPLE\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerExtFunctionsWeak.cpp",
    "content": "//===- FuzzerExtFunctionsWeak.cpp - Interface to external functions -------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Implementation for Linux. This relies on the linker's support for weak\n// symbols. We don't use this approach on Apple platforms because it requires\n// clients of LibFuzzer to pass ``-U _<symbol_name>`` to the linker to allow\n// weak symbols to be undefined. That is a complication we don't want to expose\n// to clients right now.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_LINUX\n\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerIO.h\"\n\nextern \"C\" {\n// Declare these symbols as weak to allow them to be optionally defined.\n#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \\\n  __attribute__((weak)) RETURN_TYPE NAME FUNC_SIG\n\n#include \"FuzzerExtFunctions.def\"\n\n#undef EXT_FUNC\n}\n\nusing namespace fuzzer;\n\nstatic void CheckFnPtr(void *FnPtr, const char *FnName, bool WarnIfMissing) {\n  if (FnPtr == nullptr && WarnIfMissing) {\n    Printf(\"WARNING: Failed to find function \\\"%s\\\".\\n\", FnName);\n  }\n}\n\nnamespace fuzzer {\n\nExternalFunctions::ExternalFunctions() {\n#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \\\n  this->NAME = ::NAME;                                                         \\\n  CheckFnPtr((void *)::NAME, #NAME, WARN);\n\n#include \"FuzzerExtFunctions.def\"\n\n#undef EXT_FUNC\n}\n\n} // namespace fuzzer\n\n#endif // LIBFUZZER_LINUX\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerExtFunctionsWeakAlias.cpp",
    "content": "//===- FuzzerExtFunctionsWeakAlias.cpp - Interface to external functions --===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Implementation using weak aliases. Works for Windows.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_WINDOWS\n\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerIO.h\"\n\nusing namespace fuzzer;\n\nextern \"C\" {\n// Declare these symbols as weak to allow them to be optionally defined.\n#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \\\n  RETURN_TYPE NAME##Def FUNC_SIG {                                             \\\n    Printf(\"ERROR: Function \\\"%s\\\" not defined.\\n\", #NAME);                    \\\n    exit(1);                                                                   \\\n  }                                                                            \\\n  RETURN_TYPE NAME FUNC_SIG __attribute__((weak, alias(#NAME \"Def\")));\n\n#include \"FuzzerExtFunctions.def\"\n\n#undef EXT_FUNC\n}\n\ntemplate <typename T>\nstatic T *GetFnPtr(T *Fun, T *FunDef, const char *FnName, bool WarnIfMissing) {\n  if (Fun == FunDef) {\n    if (WarnIfMissing)\n      Printf(\"WARNING: Failed to find function \\\"%s\\\".\\n\", FnName);\n    return nullptr;\n  }\n  return Fun;\n}\n\nnamespace fuzzer {\n\nExternalFunctions::ExternalFunctions() {\n#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \\\n  this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);\n\n#include \"FuzzerExtFunctions.def\"\n\n#undef EXT_FUNC\n}\n\n} // namespace fuzzer\n\n#endif // LIBFUZZER_WINDOWS\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerFlags.def",
    "content": "//===- FuzzerFlags.def - Run-time flags -------------------------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Flags. FUZZER_FLAG_INT/FUZZER_FLAG_STRING macros should be defined at the\n// point of inclusion. We are not using any flag parsing library for better\n// portability and independence.\n//===----------------------------------------------------------------------===//\nFUZZER_FLAG_INT(verbosity, 1, \"Verbosity level.\")\nFUZZER_FLAG_UNSIGNED(seed, 0, \"Random seed. If 0, seed is generated.\")\nFUZZER_FLAG_INT(runs, -1,\n            \"Number of individual test runs (-1 for infinite runs).\")\nFUZZER_FLAG_INT(max_len, 0, \"Maximum length of the test input. \"\n    \"If 0, libFuzzer tries to guess a good value based on the corpus \"\n    \"and reports it. \")\nFUZZER_FLAG_INT(cross_over, 1, \"If 1, cross over inputs.\")\nFUZZER_FLAG_INT(mutate_depth, 5,\n            \"Apply this number of consecutive mutations to each input.\")\nFUZZER_FLAG_INT(shuffle, 1, \"Shuffle inputs at startup\")\nFUZZER_FLAG_INT(prefer_small, 1,\n    \"If 1, always prefer smaller inputs during the corpus shuffle.\")\nFUZZER_FLAG_INT(\n    timeout, 1200,\n    \"Timeout in seconds (if positive). \"\n    \"If one unit runs more than this number of seconds the process will abort.\")\nFUZZER_FLAG_INT(error_exitcode, 77, \"When libFuzzer itself reports a bug \"\n  \"this exit code will be used.\")\nFUZZER_FLAG_INT(timeout_exitcode, 77, \"When libFuzzer reports a timeout \"\n  \"this exit code will be used.\")\nFUZZER_FLAG_INT(max_total_time, 0, \"If positive, indicates the maximal total \"\n                                   \"time in seconds to run the fuzzer.\")\nFUZZER_FLAG_INT(help, 0, \"Print help.\")\nFUZZER_FLAG_INT(merge, 0, \"If 1, the 2-nd, 3-rd, etc corpora will be \"\n  \"merged into the 1-st corpus. Only interesting units will be taken. \"\n  \"This flag can be used to minimize a corpus.\")\nFUZZER_FLAG_STRING(merge_control_file, \"internal flag\")\nFUZZER_FLAG_INT(minimize_crash, 0, \"If 1, minimizes the provided\"\n  \" crash input. Use with -runs=N or -max_total_time=N to limit \"\n  \"the number attempts\")\nFUZZER_FLAG_INT(minimize_crash_internal_step, 0, \"internal flag\")\nFUZZER_FLAG_INT(use_counters, 1, \"Use coverage counters\")\nFUZZER_FLAG_INT(use_indir_calls, 1, \"Use indirect caller-callee counters\")\nFUZZER_FLAG_INT(use_memcmp, 1,\n                \"Use hints from intercepting memcmp, strcmp, etc\")\nFUZZER_FLAG_INT(use_memmem, 1,\n                \"Use hints from intercepting memmem, strstr, etc\")\nFUZZER_FLAG_INT(use_value_profile, 0,\n                \"Experimental. Use value profile to guide fuzzing.\")\nFUZZER_FLAG_INT(use_cmp, 1, \"Use CMP traces to guide mutations\")\nFUZZER_FLAG_INT(shrink, 0, \"Experimental. Try to shrink corpus elements.\")\nFUZZER_FLAG_UNSIGNED(jobs, 0, \"Number of jobs to run. If jobs >= 1 we spawn\"\n                          \" this number of jobs in separate worker processes\"\n                          \" with stdout/stderr redirected to fuzz-JOB.log.\")\nFUZZER_FLAG_UNSIGNED(workers, 0,\n            \"Number of simultaneous worker processes to run the jobs.\"\n            \" If zero, \\\"min(jobs,NumberOfCpuCores()/2)\\\" is used.\")\nFUZZER_FLAG_INT(reload, 1,\n                \"Reload the main corpus every <N> seconds to get new units\"\n                \" discovered by other processes. If 0, disabled\")\nFUZZER_FLAG_INT(report_slow_units, 10,\n    \"Report slowest units if they run for more than this number of seconds.\")\nFUZZER_FLAG_INT(only_ascii, 0,\n                \"If 1, generate only ASCII (isprint+isspace) inputs.\")\nFUZZER_FLAG_STRING(dict, \"Experimental. Use the dictionary file.\")\nFUZZER_FLAG_STRING(artifact_prefix, \"Write fuzzing artifacts (crash, \"\n                                    \"timeout, or slow inputs) as \"\n                                    \"$(artifact_prefix)file\")\nFUZZER_FLAG_STRING(exact_artifact_path,\n                   \"Write the single artifact on failure (crash, timeout) \"\n                   \"as $(exact_artifact_path). This overrides -artifact_prefix \"\n                   \"and will not use checksum in the file name. Do not \"\n                   \"use the same path for several parallel processes.\")\nFUZZER_FLAG_INT(output_csv, 0, \"Enable pulse output in CSV format.\")\nFUZZER_FLAG_INT(print_pcs, 0, \"If 1, print out newly covered PCs.\")\nFUZZER_FLAG_INT(print_final_stats, 0, \"If 1, print statistics at exit.\")\nFUZZER_FLAG_INT(print_corpus_stats, 0,\n  \"If 1, print statistics on corpus elements at exit.\")\nFUZZER_FLAG_INT(print_coverage, 0, \"If 1, print coverage information at exit.\"\n                                   \" Experimental, only with trace-pc-guard\")\nFUZZER_FLAG_INT(dump_coverage, 0, \"If 1, dump coverage information at exit.\"\n                                  \" Experimental, only with trace-pc-guard\")\nFUZZER_FLAG_INT(handle_segv, 1, \"If 1, try to intercept SIGSEGV.\")\nFUZZER_FLAG_INT(handle_bus, 1, \"If 1, try to intercept SIGSEGV.\")\nFUZZER_FLAG_INT(handle_abrt, 1, \"If 1, try to intercept SIGABRT.\")\nFUZZER_FLAG_INT(handle_ill, 1, \"If 1, try to intercept SIGILL.\")\nFUZZER_FLAG_INT(handle_fpe, 1, \"If 1, try to intercept SIGFPE.\")\nFUZZER_FLAG_INT(handle_int, 1, \"If 1, try to intercept SIGINT.\")\nFUZZER_FLAG_INT(handle_term, 1, \"If 1, try to intercept SIGTERM.\")\nFUZZER_FLAG_INT(close_fd_mask, 0, \"If 1, close stdout at startup; \"\n    \"if 2, close stderr; if 3, close both. \"\n    \"Be careful, this will also close e.g. asan's stderr/stdout.\")\nFUZZER_FLAG_INT(detect_leaks, 1, \"If 1, and if LeakSanitizer is enabled \"\n    \"try to detect memory leaks during fuzzing (i.e. not only at shut down).\")\nFUZZER_FLAG_INT(trace_malloc, 0, \"If >= 1 will print all mallocs/frees. \"\n    \"If >= 2 will also print stack traces.\")\nFUZZER_FLAG_INT(rss_limit_mb, 2048, \"If non-zero, the fuzzer will exit upon\"\n    \"reaching this limit of RSS memory usage.\")\nFUZZER_FLAG_STRING(exit_on_src_pos, \"Exit if a newly found PC originates\"\n    \" from the given source location. Example: -exit_on_src_pos=foo.cc:123. \"\n    \"Used primarily for testing libFuzzer itself.\")\nFUZZER_FLAG_STRING(exit_on_item, \"Exit if an item with a given sha1 sum\"\n    \" was added to the corpus. \"\n    \"Used primarily for testing libFuzzer itself.\")\n\nFUZZER_DEPRECATED_FLAG(exit_on_first)\nFUZZER_DEPRECATED_FLAG(save_minimized_corpus)\nFUZZER_DEPRECATED_FLAG(sync_command)\nFUZZER_DEPRECATED_FLAG(sync_timeout)\nFUZZER_DEPRECATED_FLAG(test_single_input)\nFUZZER_DEPRECATED_FLAG(drill)\nFUZZER_DEPRECATED_FLAG(truncate_units)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerIO.cpp",
    "content": "//===- FuzzerIO.cpp - IO utils. -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// IO functions.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerIO.h\"\n#include \"FuzzerDefs.h\"\n#include \"FuzzerExtFunctions.h\"\n#include <algorithm>\n#include <cstdarg>\n#include <fstream>\n#include <iterator>\n#include <sys/stat.h>\n#include <sys/types.h>\n\nnamespace fuzzer {\n\nstatic FILE *OutputFile = stderr;\n\nlong GetEpoch(const std::string &Path) {\n  struct stat St;\n  if (stat(Path.c_str(), &St))\n    return 0;  // Can't stat, be conservative.\n  return St.st_mtime;\n}\n\nUnit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {\n  std::ifstream T(Path);\n  if (ExitOnError && !T) {\n    Printf(\"No such directory: %s; exiting\\n\", Path.c_str());\n    exit(1);\n  }\n\n  T.seekg(0, T.end);\n  size_t FileLen = T.tellg();\n  if (MaxSize)\n    FileLen = std::min(FileLen, MaxSize);\n\n  T.seekg(0, T.beg);\n  Unit Res(FileLen);\n  T.read(reinterpret_cast<char *>(Res.data()), FileLen);\n  return Res;\n}\n\nstd::string FileToString(const std::string &Path) {\n  std::ifstream T(Path);\n  return std::string((std::istreambuf_iterator<char>(T)),\n                     std::istreambuf_iterator<char>());\n}\n\nvoid CopyFileToErr(const std::string &Path) {\n  Printf(\"%s\", FileToString(Path).c_str());\n}\n\nvoid WriteToFile(const Unit &U, const std::string &Path) {\n  // Use raw C interface because this function may be called from a sig handler.\n  FILE *Out = fopen(Path.c_str(), \"w\");\n  if (!Out) return;\n  fwrite(U.data(), sizeof(U[0]), U.size(), Out);\n  fclose(Out);\n}\n\nvoid ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,\n                            long *Epoch, size_t MaxSize, bool ExitOnError) {\n  long E = Epoch ? *Epoch : 0;\n  std::vector<std::string> Files;\n  ListFilesInDirRecursive(Path, Epoch, &Files, /*TopDir*/true);\n  size_t NumLoaded = 0;\n  for (size_t i = 0; i < Files.size(); i++) {\n    auto &X = Files[i];\n    if (Epoch && GetEpoch(X) < E) continue;\n    NumLoaded++;\n    if ((NumLoaded & (NumLoaded - 1)) == 0 && NumLoaded >= 1024)\n      Printf(\"Loaded %zd/%zd files from %s\\n\", NumLoaded, Files.size(), Path);\n    auto S = FileToVector(X, MaxSize, ExitOnError);\n    if (!S.empty())\n      V->push_back(S);\n  }\n}\n\nstd::string DirPlusFile(const std::string &DirPath,\n                        const std::string &FileName) {\n  return DirPath + GetSeparator() + FileName;\n}\n\nvoid DupAndCloseStderr() {\n  int OutputFd = DuplicateFile(2);\n  if (OutputFd > 0) {\n    FILE *NewOutputFile = OpenFile(OutputFd, \"w\");\n    if (NewOutputFile) {\n      OutputFile = NewOutputFile;\n      if (EF->__sanitizer_set_report_fd)\n        EF->__sanitizer_set_report_fd(reinterpret_cast<void *>(OutputFd));\n      CloseFile(2);\n    }\n  }\n}\n\nvoid CloseStdout() {\n  CloseFile(1);\n}\n\nvoid Printf(const char *Fmt, ...) {\n  va_list ap;\n  va_start(ap, Fmt);\n  vfprintf(OutputFile, Fmt, ap);\n  va_end(ap);\n  fflush(OutputFile);\n}\n\n}  // namespace fuzzer\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerIO.h",
    "content": "//===- FuzzerIO.h - Internal header for IO utils ----------------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// IO interface.\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_IO_H\n#define LLVM_FUZZER_IO_H\n\n#include \"FuzzerDefs.h\"\n\nnamespace fuzzer {\n\nlong GetEpoch(const std::string &Path);\n\nUnit FileToVector(const std::string &Path, size_t MaxSize = 0,\n                  bool ExitOnError = true);\n\nstd::string FileToString(const std::string &Path);\n\nvoid CopyFileToErr(const std::string &Path);\n\nvoid WriteToFile(const Unit &U, const std::string &Path);\n\nvoid ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,\n                            long *Epoch, size_t MaxSize, bool ExitOnError);\n\n// Returns \"Dir/FileName\" or equivalent for the current OS.\nstd::string DirPlusFile(const std::string &DirPath,\n                        const std::string &FileName);\n\n// Returns the name of the dir, similar to the 'dirname' utility.\nstd::string DirName(const std::string &FileName);\n\nvoid DupAndCloseStderr();\n\nvoid CloseStdout();\n\nvoid Printf(const char *Fmt, ...);\n\n// Platform specific functions:\nbool IsFile(const std::string &Path);\n\nvoid ListFilesInDirRecursive(const std::string &Dir, long *Epoch,\n                             std::vector<std::string> *V, bool TopDir);\n\nchar GetSeparator();\n\nFILE* OpenFile(int Fd, const char *Mode);\n\nint CloseFile(int Fd);\n\nint DuplicateFile(int Fd);\n\nvoid RemoveFile(const std::string &Path);\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_IO_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerIOPosix.cpp",
    "content": "//===- FuzzerIOPosix.cpp - IO utils for Posix. ----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// IO functions implementation using Posix API.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_POSIX\n\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerIO.h\"\n#include <cstdarg>\n#include <cstdio>\n#include <dirent.h>\n#include <fstream>\n#include <iterator>\n#include <libgen.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nnamespace fuzzer {\n\nbool IsFile(const std::string &Path) {\n  struct stat St;\n  if (stat(Path.c_str(), &St))\n    return false;\n  return S_ISREG(St.st_mode);\n}\n\nvoid ListFilesInDirRecursive(const std::string &Dir, long *Epoch,\n                             std::vector<std::string> *V, bool TopDir) {\n  auto E = GetEpoch(Dir);\n  if (Epoch)\n    if (E && *Epoch >= E) return;\n\n  DIR *D = opendir(Dir.c_str());\n  if (!D) {\n    Printf(\"No such directory: %s; exiting\\n\", Dir.c_str());\n    exit(1);\n  }\n  while (auto E = readdir(D)) {\n    std::string Path = DirPlusFile(Dir, E->d_name);\n    if (E->d_type == DT_REG || E->d_type == DT_LNK)\n      V->push_back(Path);\n    else if (E->d_type == DT_DIR && *E->d_name != '.')\n      ListFilesInDirRecursive(Path, Epoch, V, false);\n  }\n  closedir(D);\n  if (Epoch && TopDir)\n    *Epoch = E;\n}\n\nchar GetSeparator() {\n  return '/';\n}\n\nFILE* OpenFile(int Fd, const char* Mode) {\n  return fdopen(Fd, Mode);\n}\n\nint CloseFile(int fd) {\n  return close(fd);\n}\n\nint DuplicateFile(int Fd) {\n  return dup(Fd);\n}\n\nvoid RemoveFile(const std::string &Path) {\n  unlink(Path.c_str());\n}\n\nstd::string DirName(const std::string &FileName) {\n  char *Tmp = new char[FileName.size() + 1];\n  memcpy(Tmp, FileName.c_str(), FileName.size() + 1);\n  std::string Res = dirname(Tmp);\n  delete [] Tmp;\n  return Res;\n}\n\n}  // namespace fuzzer\n\n#endif // LIBFUZZER_POSIX\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerIOWindows.cpp",
    "content": "//===- FuzzerIOWindows.cpp - IO utils for Windows. ------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// IO functions implementation for Windows.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_WINDOWS\n\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerIO.h\"\n#include <cstdarg>\n#include <cstdio>\n#include <fstream>\n#include <io.h>\n#include <iterator>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <windows.h>\n\nnamespace fuzzer {\n\nstatic bool IsFile(const std::string &Path, const DWORD &FileAttributes) {\n\n  if (FileAttributes & FILE_ATTRIBUTE_NORMAL)\n    return true;\n\n  if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)\n    return false;\n\n  HANDLE FileHandle(\n      CreateFileA(Path.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,\n                  FILE_FLAG_BACKUP_SEMANTICS, 0));\n\n  if (FileHandle == INVALID_HANDLE_VALUE) {\n    Printf(\"CreateFileA() failed for \\\"%s\\\" (Error code: %lu).\\n\", Path.c_str(),\n        GetLastError());\n    return false;\n  }\n\n  DWORD FileType = GetFileType(FileHandle);\n\n  if (FileType == FILE_TYPE_UNKNOWN) {\n    Printf(\"GetFileType() failed for \\\"%s\\\" (Error code: %lu).\\n\", Path.c_str(),\n        GetLastError());\n    CloseHandle(FileHandle);\n    return false;\n  }\n\n  if (FileType != FILE_TYPE_DISK) {\n    CloseHandle(FileHandle);\n    return false;\n  }\n\n  CloseHandle(FileHandle);\n  return true;\n}\n\nbool IsFile(const std::string &Path) {\n  DWORD Att = GetFileAttributesA(Path.c_str());\n\n  if (Att == INVALID_FILE_ATTRIBUTES) {\n    Printf(\"GetFileAttributesA() failed for \\\"%s\\\" (Error code: %lu).\\n\",\n        Path.c_str(), GetLastError());\n    return false;\n  }\n\n  return IsFile(Path, Att);\n}\n\nvoid ListFilesInDirRecursive(const std::string &Dir, long *Epoch,\n                             std::vector<std::string> *V, bool TopDir) {\n  auto E = GetEpoch(Dir);\n  if (Epoch)\n    if (E && *Epoch >= E) return;\n\n  std::string Path(Dir);\n  assert(!Path.empty());\n  if (Path.back() != '\\\\')\n      Path.push_back('\\\\');\n  Path.push_back('*');\n\n  // Get the first directory entry.\n  WIN32_FIND_DATAA FindInfo;\n  HANDLE FindHandle(FindFirstFileA(Path.c_str(), &FindInfo));\n  if (FindHandle == INVALID_HANDLE_VALUE)\n  {\n    Printf(\"No file found in: %s.\\n\", Dir.c_str());\n    return;\n  }\n\n  do {\n    std::string FileName = DirPlusFile(Dir, FindInfo.cFileName);\n\n    if (FindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {\n      size_t FilenameLen = strlen(FindInfo.cFileName);\n      if ((FilenameLen == 1 && FindInfo.cFileName[0] == '.') ||\n          (FilenameLen == 2 && FindInfo.cFileName[0] == '.' &&\n                               FindInfo.cFileName[1] == '.'))\n        continue;\n\n      ListFilesInDirRecursive(FileName, Epoch, V, false);\n    }\n    else if (IsFile(FileName, FindInfo.dwFileAttributes))\n      V->push_back(FileName);\n  } while (FindNextFileA(FindHandle, &FindInfo));\n\n  DWORD LastError = GetLastError();\n  if (LastError != ERROR_NO_MORE_FILES)\n    Printf(\"FindNextFileA failed (Error code: %lu).\\n\", LastError);\n\n  FindClose(FindHandle);\n\n  if (Epoch && TopDir)\n    *Epoch = E;\n}\n\nchar GetSeparator() {\n  return '\\\\';\n}\n\nFILE* OpenFile(int Fd, const char* Mode) {\n  return _fdopen(Fd, Mode);\n}\n\nint CloseFile(int Fd) {\n  return _close(Fd);\n}\n\nint DuplicateFile(int Fd) {\n  return _dup(Fd);\n}\n\nvoid RemoveFile(const std::string &Path) {\n  _unlink(Path.c_str());\n}\n\nstatic bool IsSeparator(char C) {\n  return C == '\\\\' || C == '/';\n}\n\n// Parse disk designators, like \"C:\\\". If Relative == true, also accepts: \"C:\".\n// Returns number of characters considered if successful.\nstatic size_t ParseDrive(const std::string &FileName, const size_t Offset,\n                         bool Relative = true) {\n  if (Offset + 1 >= FileName.size() || FileName[Offset + 1] != ':')\n    return 0;\n  if (Offset + 2 >= FileName.size() || !IsSeparator(FileName[Offset + 2])) {\n    if (!Relative) // Accept relative path?\n      return 0;\n    else\n      return 2;\n  }\n  return 3;\n}\n\n// Parse a file name, like: SomeFile.txt\n// Returns number of characters considered if successful.\nstatic size_t ParseFileName(const std::string &FileName, const size_t Offset) {\n  size_t Pos = Offset;\n  const size_t End = FileName.size();\n  for(; Pos < End && !IsSeparator(FileName[Pos]); ++Pos)\n    ;\n  return Pos - Offset;\n}\n\n// Parse a directory ending in separator, like: SomeDir\\\n// Returns number of characters considered if successful.\nstatic size_t ParseDir(const std::string &FileName, const size_t Offset) {\n  size_t Pos = Offset;\n  const size_t End = FileName.size();\n  if (Pos >= End || IsSeparator(FileName[Pos]))\n    return 0;\n  for(; Pos < End && !IsSeparator(FileName[Pos]); ++Pos)\n    ;\n  if (Pos >= End)\n    return 0;\n  ++Pos; // Include separator.\n  return Pos - Offset;\n}\n\n// Parse a servername and share, like: SomeServer\\SomeShare\\\n// Returns number of characters considered if successful.\nstatic size_t ParseServerAndShare(const std::string &FileName,\n                                  const size_t Offset) {\n  size_t Pos = Offset, Res;\n  if (!(Res = ParseDir(FileName, Pos)))\n    return 0;\n  Pos += Res;\n  if (!(Res = ParseDir(FileName, Pos)))\n    return 0;\n  Pos += Res;\n  return Pos - Offset;\n}\n\n// Parse the given Ref string from the position Offset, to exactly match the given\n// string Patt.\n// Returns number of characters considered if successful.\nstatic size_t ParseCustomString(const std::string &Ref, size_t Offset,\n                                const char *Patt) {\n  size_t Len = strlen(Patt);\n  if (Offset + Len > Ref.size())\n    return 0;\n  return Ref.compare(Offset, Len, Patt) == 0 ? Len : 0;\n}\n\n// Parse a location, like:\n// \\\\?\\UNC\\Server\\Share\\  \\\\?\\C:\\  \\\\Server\\Share\\  \\  C:\\  C:\n// Returns number of characters considered if successful.\nstatic size_t ParseLocation(const std::string &FileName) {\n  size_t Pos = 0, Res;\n\n  if ((Res = ParseCustomString(FileName, Pos, R\"(\\\\?\\)\"))) {\n    Pos += Res;\n    if ((Res = ParseCustomString(FileName, Pos, R\"(UNC\\)\"))) {\n      Pos += Res;\n      if ((Res = ParseServerAndShare(FileName, Pos)))\n        return Pos + Res;\n      return 0;\n    }\n    if ((Res = ParseDrive(FileName, Pos, false)))\n      return Pos + Res;\n    return 0;\n  }\n\n  if (Pos < FileName.size() && IsSeparator(FileName[Pos])) {\n    ++Pos;\n    if (Pos < FileName.size() && IsSeparator(FileName[Pos])) {\n      ++Pos;\n      if ((Res = ParseServerAndShare(FileName, Pos)))\n        return Pos + Res;\n      return 0;\n    }\n    return Pos;\n  }\n\n  if ((Res = ParseDrive(FileName, Pos)))\n    return Pos + Res;\n\n  return Pos;\n}\n\nstd::string DirName(const std::string &FileName) {\n  size_t LocationLen = ParseLocation(FileName);\n  size_t DirLen = 0, Res;\n  while ((Res = ParseDir(FileName, LocationLen + DirLen)))\n    DirLen += Res;\n  size_t FileLen = ParseFileName(FileName, LocationLen + DirLen);\n\n  if (LocationLen + DirLen + FileLen != FileName.size()) {\n    Printf(\"DirName() failed for \\\"%s\\\", invalid path.\\n\", FileName.c_str());\n    exit(1);\n  }\n\n  if (DirLen) {\n    --DirLen; // Remove trailing separator.\n    if (!FileLen) { // Path ended in separator.\n      assert(DirLen);\n      // Remove file name from Dir.\n      while (DirLen && !IsSeparator(FileName[LocationLen + DirLen - 1]))\n        --DirLen;\n      if (DirLen) // Remove trailing separator.\n        --DirLen;\n    }\n  }\n\n  if (!LocationLen) { // Relative path.\n    if (!DirLen)\n      return \".\";\n    return std::string(\".\\\\\").append(FileName, 0, DirLen);\n  }\n\n  return FileName.substr(0, LocationLen + DirLen);\n}\n\n}  // namespace fuzzer\n\n#endif // LIBFUZZER_WINDOWS\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerInterface.h",
    "content": "//===- FuzzerInterface.h - Interface header for the Fuzzer ------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Define the interface between libFuzzer and the library being tested.\n//===----------------------------------------------------------------------===//\n\n// NOTE: the libFuzzer interface is thin and in the majority of cases\n// you should not include this file into your target. In 95% of cases\n// all you need is to define the following function in your file:\n// extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);\n\n// WARNING: keep the interface in C.\n\n#ifndef LLVM_FUZZER_INTERFACE_H\n#define LLVM_FUZZER_INTERFACE_H\n\n#include <stddef.h>\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  // __cplusplus\n\n// Mandatory user-provided target function.\n// Executes the code under test with [Data, Data+Size) as the input.\n// libFuzzer will invoke this function *many* times with different inputs.\n// Must return 0.\nint LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);\n\n// Optional user-provided initialization function.\n// If provided, this function will be called by libFuzzer once at startup.\n// It may read and modify argc/argv.\n// Must return 0.\nint LLVMFuzzerInitialize(int *argc, char ***argv);\n\n// Optional user-provided custom mutator.\n// Mutates raw data in [Data, Data+Size) inplace.\n// Returns the new size, which is not greater than MaxSize.\n// Given the same Seed produces the same mutation.\nsize_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize,\n                               unsigned int Seed);\n\n// Optional user-provided custom cross-over function.\n// Combines pieces of Data1 & Data2 together into Out.\n// Returns the new size, which is not greater than MaxOutSize.\n// Should produce the same mutation given the same Seed.\nsize_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,\n                                 const uint8_t *Data2, size_t Size2,\n                                 uint8_t *Out, size_t MaxOutSize,\n                                 unsigned int Seed);\n\n// Experimental, may go away in future.\n// libFuzzer-provided function to be used inside LLVMFuzzerTestOneInput.\n// Mutates raw data in [Data, Data+Size) inplace.\n// Returns the new size, which is not greater than MaxSize.\nsize_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif  // __cplusplus\n\n#endif  // LLVM_FUZZER_INTERFACE_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerInternal.h",
    "content": "//===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Define the main class fuzzer::Fuzzer and most functions.\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_INTERNAL_H\n#define LLVM_FUZZER_INTERNAL_H\n\n#include \"FuzzerDefs.h\"\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerInterface.h\"\n#include \"FuzzerOptions.h\"\n#include \"FuzzerSHA1.h\"\n#include \"FuzzerValueBitMap.h\"\n#include <algorithm>\n#include <atomic>\n#include <chrono>\n#include <climits>\n#include <cstdlib>\n#include <string.h>\n\nnamespace fuzzer {\n\nusing namespace std::chrono;\n\nclass Fuzzer {\npublic:\n\n  // Aggregates all available coverage measurements.\n  struct Coverage {\n    Coverage() { Reset(); }\n\n    void Reset() {\n      BlockCoverage = 0;\n      CallerCalleeCoverage = 0;\n      CounterBitmapBits = 0;\n      CounterBitmap.clear();\n      VPMap.Reset();\n    }\n\n    size_t BlockCoverage;\n    size_t CallerCalleeCoverage;\n    // Precalculated number of bits in CounterBitmap.\n    size_t CounterBitmapBits;\n    std::vector<uint8_t> CounterBitmap;\n    ValueBitMap VPMap;\n  };\n\n  Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,\n         FuzzingOptions Options);\n  ~Fuzzer();\n  void Loop();\n  void MinimizeCrashLoop(const Unit &U);\n  void ShuffleAndMinimize(UnitVector *V);\n  void InitializeTraceState();\n  void RereadOutputCorpus(size_t MaxSize);\n\n  size_t secondsSinceProcessStartUp() {\n    return duration_cast<seconds>(system_clock::now() - ProcessStartTime)\n        .count();\n  }\n\n  bool TimedOut() {\n    return Options.MaxTotalTimeSec > 0 &&\n           secondsSinceProcessStartUp() >\n               static_cast<size_t>(Options.MaxTotalTimeSec);\n  }\n\n  size_t execPerSec() {\n    size_t Seconds = secondsSinceProcessStartUp();\n    return Seconds ? TotalNumberOfRuns / Seconds : 0;\n  }\n\n  size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }\n\n  static void StaticAlarmCallback();\n  static void StaticCrashSignalCallback();\n  static void StaticInterruptCallback();\n\n  void ExecuteCallback(const uint8_t *Data, size_t Size);\n  size_t RunOne(const uint8_t *Data, size_t Size);\n\n  // Merge Corpora[1:] into Corpora[0].\n  void Merge(const std::vector<std::string> &Corpora);\n  void CrashResistantMerge(const std::vector<std::string> &Args,\n                           const std::vector<std::string> &Corpora);\n  void CrashResistantMergeInternalStep(const std::string &ControlFilePath);\n  // Returns a subset of 'Extra' that adds coverage to 'Initial'.\n  UnitVector FindExtraUnits(const UnitVector &Initial, const UnitVector &Extra);\n  MutationDispatcher &GetMD() { return MD; }\n  void PrintFinalStats();\n  void SetMaxInputLen(size_t MaxInputLen);\n  void SetMaxMutationLen(size_t MaxMutationLen);\n  void RssLimitCallback();\n\n  // Public for tests.\n  void ResetCoverage();\n\n  bool InFuzzingThread() const { return IsMyThread; }\n  size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;\n  void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,\n                               bool DuringInitialCorpusExecution);\n\n  void HandleMalloc(size_t Size);\n\nprivate:\n  void AlarmCallback();\n  void CrashCallback();\n  void InterruptCallback();\n  void MutateAndTestOne();\n  void ReportNewCoverage(InputInfo *II, const Unit &U);\n  size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }\n  void WriteToOutputCorpus(const Unit &U);\n  void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);\n  void PrintStats(const char *Where, const char *End = \"\\n\", size_t Units = 0);\n  void PrintStatusForNewUnit(const Unit &U);\n  void ShuffleCorpus(UnitVector *V);\n  void AddToCorpus(const Unit &U);\n  void CheckExitOnSrcPosOrItem();\n\n  // Trace-based fuzzing: we run a unit with some kind of tracing\n  // enabled and record potentially useful mutations. Then\n  // We apply these mutations one by one to the unit and run it again.\n\n  // Start tracing; forget all previously proposed mutations.\n  void StartTraceRecording();\n  // Stop tracing.\n  void StopTraceRecording();\n\n  void SetDeathCallback();\n  static void StaticDeathCallback();\n  void DumpCurrentUnit(const char *Prefix);\n  void DeathCallback();\n\n  void ResetEdgeCoverage();\n  void ResetCounters();\n  void PrepareCounters(Fuzzer::Coverage *C);\n  bool RecordMaxCoverage(Fuzzer::Coverage *C);\n\n  void AllocateCurrentUnitData();\n  uint8_t *CurrentUnitData = nullptr;\n  std::atomic<size_t> CurrentUnitSize;\n  uint8_t BaseSha1[kSHA1NumBytes];  // Checksum of the base unit.\n  bool RunningCB = false;\n\n  size_t TotalNumberOfRuns = 0;\n  size_t NumberOfNewUnitsAdded = 0;\n\n  bool HasMoreMallocsThanFrees = false;\n  size_t NumberOfLeakDetectionAttempts = 0;\n\n  UserCallback CB;\n  InputCorpus &Corpus;\n  MutationDispatcher &MD;\n  FuzzingOptions Options;\n\n  system_clock::time_point ProcessStartTime = system_clock::now();\n  system_clock::time_point UnitStartTime, UnitStopTime;\n  long TimeOfLongestUnitInSeconds = 0;\n  long EpochOfLastReadOfOutputCorpus = 0;\n\n  // Maximum recorded coverage.\n  Coverage MaxCoverage;\n\n  size_t MaxInputLen = 0;\n  size_t MaxMutationLen = 0;\n\n  // Need to know our own thread.\n  static thread_local bool IsMyThread;\n\n  bool InMergeMode = false;\n};\n\n}; // namespace fuzzer\n\n#endif // LLVM_FUZZER_INTERNAL_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerLoop.cpp",
    "content": "//===- FuzzerLoop.cpp - Fuzzer's main loop --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Fuzzer's main loop.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerCorpus.h\"\n#include \"FuzzerInternal.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerMutate.h\"\n#include \"FuzzerRandom.h\"\n#include \"FuzzerTracePC.h\"\n#include <algorithm>\n#include <cstring>\n#include <memory>\n#include <set>\n\n#if defined(__has_include)\n#if __has_include(<sanitizer / coverage_interface.h>)\n#include <sanitizer/coverage_interface.h>\n#endif\n#if __has_include(<sanitizer / lsan_interface.h>)\n#include <sanitizer/lsan_interface.h>\n#endif\n#endif\n\n#define NO_SANITIZE_MEMORY\n#if defined(__has_feature)\n#if __has_feature(memory_sanitizer)\n#undef NO_SANITIZE_MEMORY\n#define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))\n#endif\n#endif\n\nnamespace fuzzer {\nstatic const size_t kMaxUnitSizeToPrint = 256;\n\nthread_local bool Fuzzer::IsMyThread;\n\nstatic void MissingExternalApiFunction(const char *FnName) {\n  Printf(\"ERROR: %s is not defined. Exiting.\\n\"\n         \"Did you use -fsanitize-coverage=... to build your code?\\n\",\n         FnName);\n  exit(1);\n}\n\n#define CHECK_EXTERNAL_FUNCTION(fn)                                            \\\n  do {                                                                         \\\n    if (!(EF->fn))                                                             \\\n      MissingExternalApiFunction(#fn);                                         \\\n  } while (false)\n\n// Only one Fuzzer per process.\nstatic Fuzzer *F;\n\nvoid Fuzzer::ResetEdgeCoverage() {\n  CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage);\n  EF->__sanitizer_reset_coverage();\n}\n\nvoid Fuzzer::ResetCounters() {\n  if (Options.UseCounters)\n    EF->__sanitizer_update_counter_bitset_and_clear_counters(0);\n}\n\nvoid Fuzzer::PrepareCounters(Fuzzer::Coverage *C) {\n  if (Options.UseCounters) {\n    size_t NumCounters = EF->__sanitizer_get_number_of_counters();\n    C->CounterBitmap.resize(NumCounters);\n  }\n}\n\n// Records data to a maximum coverage tracker. Returns true if additional\n// coverage was discovered.\nbool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) {\n  bool Res = false;\n\n  uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();\n  if (NewBlockCoverage > C->BlockCoverage) {\n    Res = true;\n    C->BlockCoverage = NewBlockCoverage;\n  }\n\n  if (Options.UseIndirCalls &&\n      EF->__sanitizer_get_total_unique_caller_callee_pairs) {\n    uint64_t NewCallerCalleeCoverage =\n        EF->__sanitizer_get_total_unique_caller_callee_pairs();\n    if (NewCallerCalleeCoverage > C->CallerCalleeCoverage) {\n      Res = true;\n      C->CallerCalleeCoverage = NewCallerCalleeCoverage;\n    }\n  }\n\n  if (Options.UseCounters) {\n    uint64_t CounterDelta =\n        EF->__sanitizer_update_counter_bitset_and_clear_counters(\n            C->CounterBitmap.data());\n    if (CounterDelta > 0) {\n      Res = true;\n      C->CounterBitmapBits += CounterDelta;\n    }\n  }\n\n  return Res;\n}\n\n// Leak detection is expensive, so we first check if there were more mallocs\n// than frees (using the sanitizer malloc hooks) and only then try to call lsan.\nstruct MallocFreeTracer {\n  void Start(int TraceLevel) {\n    this->TraceLevel = TraceLevel;\n    if (TraceLevel)\n      Printf(\"MallocFreeTracer: START\\n\");\n    Mallocs = 0;\n    Frees = 0;\n  }\n  // Returns true if there were more mallocs than frees.\n  bool Stop() {\n    if (TraceLevel)\n      Printf(\"MallocFreeTracer: STOP %zd %zd (%s)\\n\", Mallocs.load(),\n             Frees.load(), Mallocs == Frees ? \"same\" : \"DIFFERENT\");\n    bool Result = Mallocs > Frees;\n    Mallocs = 0;\n    Frees = 0;\n    TraceLevel = 0;\n    return Result;\n  }\n  std::atomic<size_t> Mallocs;\n  std::atomic<size_t> Frees;\n  int TraceLevel = 0;\n};\n\nstatic MallocFreeTracer AllocTracer;\n\nATTRIBUTE_NO_SANITIZE_MEMORY\nvoid MallocHook(const volatile void *ptr, size_t size) {\n  size_t N = AllocTracer.Mallocs++;\n  F->HandleMalloc(size);\n  if (int TraceLevel = AllocTracer.TraceLevel) {\n    Printf(\"MALLOC[%zd] %p %zd\\n\", N, ptr, size);\n    if (TraceLevel >= 2 && EF)\n      EF->__sanitizer_print_stack_trace();\n  }\n}\n\nATTRIBUTE_NO_SANITIZE_MEMORY\nvoid FreeHook(const volatile void *ptr) {\n  size_t N = AllocTracer.Frees++;\n  if (int TraceLevel = AllocTracer.TraceLevel) {\n    Printf(\"FREE[%zd]   %p\\n\", N, ptr);\n    if (TraceLevel >= 2 && EF)\n      EF->__sanitizer_print_stack_trace();\n  }\n}\n\n// Crash on a single malloc that exceeds the rss limit.\nvoid Fuzzer::HandleMalloc(size_t Size) {\n  if (!Options.RssLimitMb || (Size >> 20) < (size_t)Options.RssLimitMb)\n    return;\n  Printf(\"==%d== ERROR: libFuzzer: out-of-memory (malloc(%zd))\\n\", GetPid(),\n         Size);\n  Printf(\"   To change the out-of-memory limit use -rss_limit_mb=<N>\\n\\n\");\n  if (EF->__sanitizer_print_stack_trace)\n    EF->__sanitizer_print_stack_trace();\n  DumpCurrentUnit(\"oom-\");\n  Printf(\"SUMMARY: libFuzzer: out-of-memory\\n\");\n  PrintFinalStats();\n  _Exit(Options.ErrorExitCode); // Stop right now.\n}\n\nFuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,\n               FuzzingOptions Options)\n    : CB(CB), Corpus(Corpus), MD(MD), Options(Options) {\n  SetDeathCallback();\n  InitializeTraceState();\n  assert(!F);\n  F = this;\n  TPC.ResetMaps();\n  ResetCoverage();\n  IsMyThread = true;\n  if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks)\n    EF->__sanitizer_install_malloc_and_free_hooks(MallocHook, FreeHook);\n  TPC.SetUseCounters(Options.UseCounters);\n  TPC.SetUseValueProfile(Options.UseValueProfile);\n  TPC.SetPrintNewPCs(Options.PrintNewCovPcs);\n\n  if (Options.Verbosity)\n    TPC.PrintModuleInfo();\n  if (!Options.OutputCorpus.empty() && Options.ReloadIntervalSec)\n    EpochOfLastReadOfOutputCorpus = GetEpoch(Options.OutputCorpus);\n  MaxInputLen = MaxMutationLen = Options.MaxLen;\n  AllocateCurrentUnitData();\n  CurrentUnitSize = 0;\n  memset(BaseSha1, 0, sizeof(BaseSha1));\n}\n\nFuzzer::~Fuzzer() { }\n\nvoid Fuzzer::AllocateCurrentUnitData() {\n  if (CurrentUnitData || MaxInputLen == 0) return;\n  CurrentUnitData = new uint8_t[MaxInputLen];\n}\n\nvoid Fuzzer::SetDeathCallback() {\n  CHECK_EXTERNAL_FUNCTION(__sanitizer_set_death_callback);\n  EF->__sanitizer_set_death_callback(StaticDeathCallback);\n}\n\nvoid Fuzzer::StaticDeathCallback() {\n  assert(F);\n  F->DeathCallback();\n}\n\nstatic void WarnOnUnsuccessfullMerge(bool DoWarn) {\n  if (!DoWarn) return;\n  Printf(\n   \"***\\n\"\n   \"***\\n\"\n   \"***\\n\"\n   \"*** NOTE: merge did not succeed due to a failure on one of the inputs.\\n\"\n   \"*** You will need to filter out crashes from the corpus, e.g. like this:\\n\"\n   \"***   for f in WITH_CRASHES/*; do ./fuzzer $f && cp $f NO_CRASHES; done\\n\"\n   \"*** Future versions may have crash-resistant merge, stay tuned.\\n\"\n   \"***\\n\"\n   \"***\\n\"\n   \"***\\n\");\n}\n\nvoid Fuzzer::DumpCurrentUnit(const char *Prefix) {\n  WarnOnUnsuccessfullMerge(InMergeMode);\n  if (!CurrentUnitData) return;  // Happens when running individual inputs.\n  MD.PrintMutationSequence();\n  Printf(\"; base unit: %s\\n\", Sha1ToString(BaseSha1).c_str());\n  size_t UnitSize = CurrentUnitSize;\n  if (UnitSize <= kMaxUnitSizeToPrint) {\n    PrintHexArray(CurrentUnitData, UnitSize, \"\\n\");\n    PrintASCII(CurrentUnitData, UnitSize, \"\\n\");\n  }\n  WriteUnitToFileWithPrefix({CurrentUnitData, CurrentUnitData + UnitSize},\n                            Prefix);\n}\n\nNO_SANITIZE_MEMORY\nvoid Fuzzer::DeathCallback() {\n  DumpCurrentUnit(\"crash-\");\n  PrintFinalStats();\n}\n\nvoid Fuzzer::StaticAlarmCallback() {\n  assert(F);\n  F->AlarmCallback();\n}\n\nvoid Fuzzer::StaticCrashSignalCallback() {\n  assert(F);\n  F->CrashCallback();\n}\n\nvoid Fuzzer::StaticInterruptCallback() {\n  assert(F);\n  F->InterruptCallback();\n}\n\nvoid Fuzzer::CrashCallback() {\n  Printf(\"==%lu== ERROR: libFuzzer: deadly signal\\n\", GetPid());\n  if (EF->__sanitizer_print_stack_trace)\n    EF->__sanitizer_print_stack_trace();\n  Printf(\"NOTE: libFuzzer has rudimentary signal handlers.\\n\"\n         \"      Combine libFuzzer with AddressSanitizer or similar for better \"\n         \"crash reports.\\n\");\n  Printf(\"SUMMARY: libFuzzer: deadly signal\\n\");\n  DumpCurrentUnit(\"crash-\");\n  PrintFinalStats();\n  exit(Options.ErrorExitCode);\n}\n\nvoid Fuzzer::InterruptCallback() {\n  Printf(\"==%lu== libFuzzer: run interrupted; exiting\\n\", GetPid());\n  PrintFinalStats();\n  _Exit(0);  // Stop right now, don't perform any at-exit actions.\n}\n\nNO_SANITIZE_MEMORY\nvoid Fuzzer::AlarmCallback() {\n  assert(Options.UnitTimeoutSec > 0);\n  if (!InFuzzingThread()) return;\n  if (!RunningCB)\n    return; // We have not started running units yet.\n  size_t Seconds =\n      duration_cast<seconds>(system_clock::now() - UnitStartTime).count();\n  if (Seconds == 0)\n    return;\n  if (Options.Verbosity >= 2)\n    Printf(\"AlarmCallback %zd\\n\", Seconds);\n  if (Seconds >= (size_t)Options.UnitTimeoutSec) {\n    Printf(\"ALARM: working on the last Unit for %zd seconds\\n\", Seconds);\n    Printf(\"       and the timeout value is %d (use -timeout=N to change)\\n\",\n           Options.UnitTimeoutSec);\n    DumpCurrentUnit(\"timeout-\");\n    Printf(\"==%lu== ERROR: libFuzzer: timeout after %d seconds\\n\", GetPid(),\n           Seconds);\n    if (EF->__sanitizer_print_stack_trace)\n      EF->__sanitizer_print_stack_trace();\n    Printf(\"SUMMARY: libFuzzer: timeout\\n\");\n    PrintFinalStats();\n    _Exit(Options.TimeoutExitCode); // Stop right now.\n  }\n}\n\nvoid Fuzzer::RssLimitCallback() {\n  Printf(\n      \"==%lu== ERROR: libFuzzer: out-of-memory (used: %zdMb; limit: %zdMb)\\n\",\n      GetPid(), GetPeakRSSMb(), Options.RssLimitMb);\n  Printf(\"   To change the out-of-memory limit use -rss_limit_mb=<N>\\n\\n\");\n  if (EF->__sanitizer_print_memory_profile)\n    EF->__sanitizer_print_memory_profile(95);\n  DumpCurrentUnit(\"oom-\");\n  Printf(\"SUMMARY: libFuzzer: out-of-memory\\n\");\n  PrintFinalStats();\n  _Exit(Options.ErrorExitCode); // Stop right now.\n}\n\nvoid Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {\n  size_t ExecPerSec = execPerSec();\n  if (Options.OutputCSV) {\n    static bool csvHeaderPrinted = false;\n    if (!csvHeaderPrinted) {\n      csvHeaderPrinted = true;\n      Printf(\"runs,block_cov,bits,cc_cov,corpus,execs_per_sec,tbms,reason\\n\");\n    }\n    Printf(\"%zd,%zd,%zd,%zd,%zd,%zd,%s\\n\", TotalNumberOfRuns,\n           MaxCoverage.BlockCoverage, MaxCoverage.CounterBitmapBits,\n           MaxCoverage.CallerCalleeCoverage, Corpus.size(), ExecPerSec, Where);\n  }\n\n  if (!Options.Verbosity)\n    return;\n  Printf(\"#%zd\\t%s\", TotalNumberOfRuns, Where);\n  if (MaxCoverage.BlockCoverage)\n    Printf(\" cov: %zd\", MaxCoverage.BlockCoverage);\n  if (size_t N = MaxCoverage.VPMap.GetNumBitsSinceLastMerge())\n    Printf(\" vp: %zd\", N);\n  if (size_t N = TPC.GetTotalPCCoverage())\n    Printf(\" cov: %zd\", N);\n  if (auto TB = MaxCoverage.CounterBitmapBits)\n    Printf(\" bits: %zd\", TB);\n  if (size_t N = Corpus.NumFeatures())\n    Printf( \" ft: %zd\", N);\n  if (MaxCoverage.CallerCalleeCoverage)\n    Printf(\" indir: %zd\", MaxCoverage.CallerCalleeCoverage);\n  if (!Corpus.empty()) {\n    Printf(\" corp: %zd\", Corpus.NumActiveUnits());\n    if (size_t N = Corpus.SizeInBytes()) {\n      if (N < (1<<14))\n        Printf(\"/%zdb\", N);\n      else if (N < (1 << 24))\n        Printf(\"/%zdKb\", N >> 10);\n      else\n        Printf(\"/%zdMb\", N >> 20);\n    }\n  }\n  if (Units)\n    Printf(\" units: %zd\", Units);\n\n  Printf(\" exec/s: %zd\", ExecPerSec);\n  Printf(\" rss: %zdMb\", GetPeakRSSMb());\n  Printf(\"%s\", End);\n}\n\nvoid Fuzzer::PrintFinalStats() {\n  if (Options.PrintCoverage)\n    TPC.PrintCoverage();\n  if (Options.DumpCoverage)\n    TPC.DumpCoverage();\n  if (Options.PrintCorpusStats)\n    Corpus.PrintStats();\n  if (!Options.PrintFinalStats) return;\n  size_t ExecPerSec = execPerSec();\n  Printf(\"stat::number_of_executed_units: %zd\\n\", TotalNumberOfRuns);\n  Printf(\"stat::average_exec_per_sec:     %zd\\n\", ExecPerSec);\n  Printf(\"stat::new_units_added:          %zd\\n\", NumberOfNewUnitsAdded);\n  Printf(\"stat::slowest_unit_time_sec:    %zd\\n\", TimeOfLongestUnitInSeconds);\n  Printf(\"stat::peak_rss_mb:              %zd\\n\", GetPeakRSSMb());\n}\n\nvoid Fuzzer::SetMaxInputLen(size_t MaxInputLen) {\n  assert(this->MaxInputLen == 0); // Can only reset MaxInputLen from 0 to non-0.\n  assert(MaxInputLen);\n  this->MaxInputLen = MaxInputLen;\n  this->MaxMutationLen = MaxInputLen;\n  AllocateCurrentUnitData();\n  Printf(\"INFO: -max_len is not provided, using %zd\\n\", MaxInputLen);\n}\n\nvoid Fuzzer::SetMaxMutationLen(size_t MaxMutationLen) {\n  assert(MaxMutationLen && MaxMutationLen <= MaxInputLen);\n  this->MaxMutationLen = MaxMutationLen;\n}\n\nvoid Fuzzer::CheckExitOnSrcPosOrItem() {\n  if (!Options.ExitOnSrcPos.empty()) {\n    static auto *PCsSet = new std::set<uintptr_t>;\n    for (size_t i = 1, N = TPC.GetNumPCs(); i < N; i++) {\n      uintptr_t PC = TPC.GetPC(i);\n      if (!PC) continue;\n      if (!PCsSet->insert(PC).second) continue;\n      std::string Descr = DescribePC(\"%L\", PC);\n      if (Descr.find(Options.ExitOnSrcPos) != std::string::npos) {\n        Printf(\"INFO: found line matching '%s', exiting.\\n\",\n               Options.ExitOnSrcPos.c_str());\n        _Exit(0);\n      }\n    }\n  }\n  if (!Options.ExitOnItem.empty()) {\n    if (Corpus.HasUnit(Options.ExitOnItem)) {\n      Printf(\"INFO: found item with checksum '%s', exiting.\\n\",\n             Options.ExitOnItem.c_str());\n      _Exit(0);\n    }\n  }\n}\n\nvoid Fuzzer::RereadOutputCorpus(size_t MaxSize) {\n  if (Options.OutputCorpus.empty() || !Options.ReloadIntervalSec) return;\n  std::vector<Unit> AdditionalCorpus;\n  ReadDirToVectorOfUnits(Options.OutputCorpus.c_str(), &AdditionalCorpus,\n                         &EpochOfLastReadOfOutputCorpus, MaxSize,\n                         /*ExitOnError*/ false);\n  if (Options.Verbosity >= 2)\n    Printf(\"Reload: read %zd new units.\\n\", AdditionalCorpus.size());\n  bool Reloaded = false;\n  for (auto &U : AdditionalCorpus) {\n    if (U.size() > MaxSize)\n      U.resize(MaxSize);\n    if (!Corpus.HasUnit(U)) {\n      if (size_t NumFeatures = RunOne(U)) {\n        CheckExitOnSrcPosOrItem();\n        Corpus.AddToCorpus(U, NumFeatures);\n        Reloaded = true;\n      }\n    }\n  }\n  if (Reloaded)\n    PrintStats(\"RELOAD\");\n}\n\nvoid Fuzzer::ShuffleCorpus(UnitVector *V) {\n  std::random_shuffle(V->begin(), V->end(), MD.GetRand());\n  if (Options.PreferSmall)\n    std::stable_sort(V->begin(), V->end(), [](const Unit &A, const Unit &B) {\n      return A.size() < B.size();\n    });\n}\n\nvoid Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) {\n  Printf(\"#0\\tREAD units: %zd\\n\", InitialCorpus->size());\n  if (Options.ShuffleAtStartUp)\n    ShuffleCorpus(InitialCorpus);\n\n  // Test the callback with empty input and never try it again.\n  uint8_t dummy;\n  ExecuteCallback(&dummy, 0);\n\n  for (const auto &U : *InitialCorpus) {\n    if (size_t NumFeatures = RunOne(U)) {\n      CheckExitOnSrcPosOrItem();\n      Corpus.AddToCorpus(U, NumFeatures);\n      if (Options.Verbosity >= 2)\n        Printf(\"NEW0: %zd L %zd\\n\", MaxCoverage.BlockCoverage, U.size());\n    }\n    TryDetectingAMemoryLeak(U.data(), U.size(),\n                            /*DuringInitialCorpusExecution*/ true);\n  }\n  PrintStats(\"INITED\");\n  if (Corpus.empty()) {\n    Printf(\"ERROR: no interesting inputs were found. \"\n           \"Is the code instrumented for coverage? Exiting.\\n\");\n    exit(1);\n  }\n}\n\nsize_t Fuzzer::RunOne(const uint8_t *Data, size_t Size) {\n  if (!Size) return 0;\n  TotalNumberOfRuns++;\n\n  ExecuteCallback(Data, Size);\n\n  size_t Res = 0;\n  if (size_t NumFeatures = TPC.CollectFeatures([&](size_t Feature) -> bool {\n        return Corpus.AddFeature(Feature, Size, Options.Shrink);\n      }))\n    Res = NumFeatures;\n\n  if (!TPC.UsingTracePcGuard()) {\n    if (TPC.UpdateValueProfileMap(&MaxCoverage.VPMap))\n      Res = 1;\n    if (!Res && RecordMaxCoverage(&MaxCoverage))\n      Res = 1;\n  }\n\n  auto TimeOfUnit =\n      duration_cast<seconds>(UnitStopTime - UnitStartTime).count();\n  if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&\n      secondsSinceProcessStartUp() >= 2)\n    PrintStats(\"pulse \");\n  if (TimeOfUnit > TimeOfLongestUnitInSeconds * 1.1 &&\n      TimeOfUnit >= Options.ReportSlowUnits) {\n    TimeOfLongestUnitInSeconds = TimeOfUnit;\n    Printf(\"Slowest unit: %zd s:\\n\", TimeOfLongestUnitInSeconds);\n    WriteUnitToFileWithPrefix({Data, Data + Size}, \"slow-unit-\");\n  }\n  return Res;\n}\n\nsize_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {\n  assert(InFuzzingThread());\n  *Data = CurrentUnitData;\n  return CurrentUnitSize;\n}\n\nvoid Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {\n  assert(InFuzzingThread());\n  // We copy the contents of Unit into a separate heap buffer\n  // so that we reliably find buffer overflows in it.\n  uint8_t *DataCopy = new uint8_t[Size];\n  memcpy(DataCopy, Data, Size);\n  if (CurrentUnitData && CurrentUnitData != Data)\n    memcpy(CurrentUnitData, Data, Size);\n  CurrentUnitSize = Size;\n  AllocTracer.Start(Options.TraceMalloc);\n  UnitStartTime = system_clock::now();\n  ResetCounters();  // Reset coverage right before the callback.\n  TPC.ResetMaps();\n  RunningCB = true;\n  int Res = CB(DataCopy, Size);\n  RunningCB = false;\n  UnitStopTime = system_clock::now();\n  (void)Res;\n  assert(Res == 0);\n  HasMoreMallocsThanFrees = AllocTracer.Stop();\n  CurrentUnitSize = 0;\n  delete[] DataCopy;\n}\n\nvoid Fuzzer::WriteToOutputCorpus(const Unit &U) {\n  if (Options.OnlyASCII)\n    assert(IsASCII(U));\n  if (Options.OutputCorpus.empty())\n    return;\n  std::string Path = DirPlusFile(Options.OutputCorpus, Hash(U));\n  WriteToFile(U, Path);\n  if (Options.Verbosity >= 2)\n    Printf(\"Written to %s\\n\", Path.c_str());\n}\n\nvoid Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {\n  if (!Options.SaveArtifacts)\n    return;\n  std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);\n  if (!Options.ExactArtifactPath.empty())\n    Path = Options.ExactArtifactPath; // Overrides ArtifactPrefix.\n  WriteToFile(U, Path);\n  Printf(\"artifact_prefix='%s'; Test unit written to %s\\n\",\n         Options.ArtifactPrefix.c_str(), Path.c_str());\n  if (U.size() <= kMaxUnitSizeToPrint)\n    Printf(\"Base64: %s\\n\", Base64(U).c_str());\n}\n\nvoid Fuzzer::PrintStatusForNewUnit(const Unit &U) {\n  if (!Options.PrintNEW)\n    return;\n  PrintStats(\"NEW   \", \"\");\n  if (Options.Verbosity) {\n    Printf(\" L: %zd \", U.size());\n    MD.PrintMutationSequence();\n    Printf(\"\\n\");\n  }\n}\n\nvoid Fuzzer::ReportNewCoverage(InputInfo *II, const Unit &U) {\n  II->NumSuccessfullMutations++;\n  MD.RecordSuccessfulMutationSequence();\n  PrintStatusForNewUnit(U);\n  WriteToOutputCorpus(U);\n  NumberOfNewUnitsAdded++;\n  TPC.PrintNewPCs();\n}\n\n// Finds minimal number of units in 'Extra' that add coverage to 'Initial'.\n// We do it by actually executing the units, sometimes more than once,\n// because we may be using different coverage-like signals and the only\n// common thing between them is that we can say \"this unit found new stuff\".\nUnitVector Fuzzer::FindExtraUnits(const UnitVector &Initial,\n                                  const UnitVector &Extra) {\n  UnitVector Res = Extra;\n  UnitVector Tmp;\n  size_t OldSize = Res.size();\n  for (int Iter = 0; Iter < 10; Iter++) {\n    ShuffleCorpus(&Res);\n    TPC.ResetMaps();\n    Corpus.ResetFeatureSet();\n    ResetCoverage();\n\n    for (auto &U : Initial) {\n      TPC.ResetMaps();\n      RunOne(U);\n    }\n\n    Tmp.clear();\n    for (auto &U : Res) {\n      TPC.ResetMaps();\n      if (RunOne(U))\n        Tmp.push_back(U);\n    }\n\n    char Stat[7] = \"MIN   \";\n    Stat[3] = '0' + Iter;\n    PrintStats(Stat, \"\\n\", Tmp.size());\n\n    size_t NewSize = Tmp.size();\n    assert(NewSize <= OldSize);\n    Res.swap(Tmp);\n\n    if (NewSize + 5 >= OldSize)\n      break;\n    OldSize = NewSize;\n  }\n  return Res;\n}\n\nvoid Fuzzer::Merge(const std::vector<std::string> &Corpora) {\n  if (Corpora.size() <= 1) {\n    Printf(\"Merge requires two or more corpus dirs\\n\");\n    return;\n  }\n  InMergeMode = true;\n  std::vector<std::string> ExtraCorpora(Corpora.begin() + 1, Corpora.end());\n\n  assert(MaxInputLen > 0);\n  UnitVector Initial, Extra;\n  ReadDirToVectorOfUnits(Corpora[0].c_str(), &Initial, nullptr, MaxInputLen,\n                         true);\n  for (auto &C : ExtraCorpora)\n    ReadDirToVectorOfUnits(C.c_str(), &Extra, nullptr, MaxInputLen, true);\n\n  if (!Initial.empty()) {\n    Printf(\"=== Minimizing the initial corpus of %zd units\\n\", Initial.size());\n    Initial = FindExtraUnits({}, Initial);\n  }\n\n  Printf(\"=== Merging extra %zd units\\n\", Extra.size());\n  auto Res = FindExtraUnits(Initial, Extra);\n\n  for (auto &U: Res)\n    WriteToOutputCorpus(U);\n\n  Printf(\"=== Merge: written %zd units\\n\", Res.size());\n}\n\n// Tries detecting a memory leak on the particular input that we have just\n// executed before calling this function.\nvoid Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,\n                                     bool DuringInitialCorpusExecution) {\n  if (!HasMoreMallocsThanFrees) return;  // mallocs==frees, a leak is unlikely.\n  if (!Options.DetectLeaks) return;\n  if (!&(EF->__lsan_enable) || !&(EF->__lsan_disable) ||\n      !(EF->__lsan_do_recoverable_leak_check))\n    return;  // No lsan.\n  // Run the target once again, but with lsan disabled so that if there is\n  // a real leak we do not report it twice.\n  EF->__lsan_disable();\n  ExecuteCallback(Data, Size);\n  EF->__lsan_enable();\n  if (!HasMoreMallocsThanFrees) return;  // a leak is unlikely.\n  if (NumberOfLeakDetectionAttempts++ > 1000) {\n    Options.DetectLeaks = false;\n    Printf(\"INFO: libFuzzer disabled leak detection after every mutation.\\n\"\n           \"      Most likely the target function accumulates allocated\\n\"\n           \"      memory in a global state w/o actually leaking it.\\n\"\n           \"      You may try running this binary with -trace_malloc=[12]\"\n           \"      to get a trace of mallocs and frees.\\n\"\n           \"      If LeakSanitizer is enabled in this process it will still\\n\"\n           \"      run on the process shutdown.\\n\");\n    return;\n  }\n  // Now perform the actual lsan pass. This is expensive and we must ensure\n  // we don't call it too often.\n  if (EF->__lsan_do_recoverable_leak_check()) { // Leak is found, report it.\n    if (DuringInitialCorpusExecution)\n      Printf(\"\\nINFO: a leak has been found in the initial corpus.\\n\\n\");\n    Printf(\"INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.\\n\\n\");\n    CurrentUnitSize = Size;\n    DumpCurrentUnit(\"leak-\");\n    PrintFinalStats();\n    _Exit(Options.ErrorExitCode);  // not exit() to disable lsan further on.\n  }\n}\n\nvoid Fuzzer::MutateAndTestOne() {\n  MD.StartMutationSequence();\n\n  auto &II = Corpus.ChooseUnitToMutate(MD.GetRand());\n  const auto &U = II.U;\n  memcpy(BaseSha1, II.Sha1, sizeof(BaseSha1));\n  assert(CurrentUnitData);\n  size_t Size = U.size();\n  assert(Size <= MaxInputLen && \"Oversized Unit\");\n  memcpy(CurrentUnitData, U.data(), Size);\n\n  assert(MaxMutationLen > 0);\n\n  for (int i = 0; i < Options.MutateDepth; i++) {\n    if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)\n      break;\n    size_t NewSize = 0;\n    NewSize = MD.Mutate(CurrentUnitData, Size, MaxMutationLen);\n    assert(NewSize > 0 && \"Mutator returned empty unit\");\n    assert(NewSize <= MaxMutationLen && \"Mutator return overisized unit\");\n    Size = NewSize;\n    if (i == 0)\n      StartTraceRecording();\n    II.NumExecutedMutations++;\n    if (size_t NumFeatures = RunOne(CurrentUnitData, Size)) {\n      Corpus.AddToCorpus({CurrentUnitData, CurrentUnitData + Size}, NumFeatures,\n                         /*MayDeleteFile=*/true);\n      ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size});\n      CheckExitOnSrcPosOrItem();\n    }\n    StopTraceRecording();\n    TryDetectingAMemoryLeak(CurrentUnitData, Size,\n                            /*DuringInitialCorpusExecution*/ false);\n  }\n}\n\nvoid Fuzzer::ResetCoverage() {\n  ResetEdgeCoverage();\n  MaxCoverage.Reset();\n  PrepareCounters(&MaxCoverage);\n}\n\nvoid Fuzzer::Loop() {\n  system_clock::time_point LastCorpusReload = system_clock::now();\n  if (Options.DoCrossOver)\n    MD.SetCorpus(&Corpus);\n  while (true) {\n    auto Now = system_clock::now();\n    if (duration_cast<seconds>(Now - LastCorpusReload).count() >=\n        Options.ReloadIntervalSec) {\n      RereadOutputCorpus(MaxInputLen);\n      LastCorpusReload = system_clock::now();\n    }\n    if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)\n      break;\n    if (TimedOut()) break;\n    // Perform several mutations and runs.\n    MutateAndTestOne();\n  }\n\n  PrintStats(\"DONE  \", \"\\n\");\n  MD.PrintRecommendedDictionary();\n}\n\nvoid Fuzzer::MinimizeCrashLoop(const Unit &U) {\n  if (U.size() <= 2) return;\n  while (!TimedOut() && TotalNumberOfRuns < Options.MaxNumberOfRuns) {\n    MD.StartMutationSequence();\n    memcpy(CurrentUnitData, U.data(), U.size());\n    for (int i = 0; i < Options.MutateDepth; i++) {\n      size_t NewSize = MD.Mutate(CurrentUnitData, U.size(), MaxMutationLen);\n      assert(NewSize > 0 && NewSize <= MaxMutationLen);\n      RunOne(CurrentUnitData, NewSize);\n      TryDetectingAMemoryLeak(CurrentUnitData, NewSize,\n                              /*DuringInitialCorpusExecution*/ false);\n    }\n  }\n}\n\n} // namespace fuzzer\n\nextern \"C\" {\n\nsize_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {\n  assert(fuzzer::F);\n  return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);\n}\n}  // extern \"C\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerMain.cpp",
    "content": "//===- FuzzerMain.cpp - main() function and flags -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// main() and flags.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerDefs.h\"\n\nextern \"C\" {\n// This function should be defined by the user.\nint LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);\n}  // extern \"C\"\n\nint main(int argc, char **argv) {\n  return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerMerge.cpp",
    "content": "//===- FuzzerMerge.cpp - merging corpora ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Merging corpora.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerInternal.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerMerge.h\"\n#include \"FuzzerTracePC.h\"\n#include \"FuzzerUtil.h\"\n\n#include <fstream>\n#include <iterator>\n#include <sstream>\n\nnamespace fuzzer {\n\nbool Merger::Parse(const std::string &Str, bool ParseCoverage) {\n  std::istringstream SS(Str);\n  return Parse(SS, ParseCoverage);\n}\n\nvoid Merger::ParseOrExit(std::istream &IS, bool ParseCoverage) {\n  if (!Parse(IS, ParseCoverage)) {\n    Printf(\"MERGE: failed to parse the control file (unexpected error)\\n\");\n    exit(1);\n  }\n}\n\n// The control file example:\n//\n// 3 # The number of inputs\n// 1 # The number of inputs in the first corpus, <= the previous number\n// file0\n// file1\n// file2  # One file name per line.\n// STARTED 0 123  # FileID, file size\n// DONE 0 1 4 6 8  # FileID COV1 COV2 ...\n// STARTED 1 456  # If DONE is missing, the input crashed while processing.\n// STARTED 2 567\n// DONE 2 8 9\nbool Merger::Parse(std::istream &IS, bool ParseCoverage) {\n  LastFailure.clear();\n  std::string Line;\n\n  // Parse NumFiles.\n  if (!std::getline(IS, Line, '\\n')) return false;\n  std::istringstream L1(Line);\n  size_t NumFiles = 0;\n  L1 >> NumFiles;\n  if (NumFiles == 0 || NumFiles > 10000000) return false;\n\n  // Parse NumFilesInFirstCorpus.\n  if (!std::getline(IS, Line, '\\n')) return false;\n  std::istringstream L2(Line);\n  NumFilesInFirstCorpus = NumFiles + 1;\n  L2 >> NumFilesInFirstCorpus;\n  if (NumFilesInFirstCorpus > NumFiles) return false;\n\n  // Parse file names.\n  Files.resize(NumFiles);\n  for (size_t i = 0; i < NumFiles; i++)\n    if (!std::getline(IS, Files[i].Name, '\\n'))\n      return false;\n\n  // Parse STARTED and DONE lines.\n  size_t ExpectedStartMarker = 0;\n  const size_t kInvalidStartMarker = -1;\n  size_t LastSeenStartMarker = kInvalidStartMarker;\n  while (std::getline(IS, Line, '\\n')) {\n    std::istringstream ISS1(Line);\n    std::string Marker;\n    size_t N;\n    ISS1 >> Marker;\n    ISS1 >> N;\n    if (Marker == \"STARTED\") {\n      // STARTED FILE_ID FILE_SIZE\n      if (ExpectedStartMarker != N)\n        return false;\n      ISS1 >> Files[ExpectedStartMarker].Size;\n      LastSeenStartMarker = ExpectedStartMarker;\n      assert(ExpectedStartMarker < Files.size());\n      ExpectedStartMarker++;\n    } else if (Marker == \"DONE\") {\n      // DONE FILE_SIZE COV1 COV2 COV3 ...\n      size_t CurrentFileIdx = N;\n      if (CurrentFileIdx != LastSeenStartMarker)\n        return false;\n      LastSeenStartMarker = kInvalidStartMarker;\n      if (ParseCoverage) {\n        auto &V = Files[CurrentFileIdx].Features;\n        V.clear();\n        while (ISS1 >> std::hex >> N)\n          V.push_back(N);\n        std::sort(V.begin(), V.end());\n      }\n    } else {\n      return false;\n    }\n  }\n  if (LastSeenStartMarker != kInvalidStartMarker)\n    LastFailure = Files[LastSeenStartMarker].Name;\n\n  FirstNotProcessedFile = ExpectedStartMarker;\n  return true;\n}\n\n// Decides which files need to be merged (add thost to NewFiles).\n// Returns the number of new features added.\nsize_t Merger::Merge(std::vector<std::string> *NewFiles) {\n  NewFiles->clear();\n  assert(NumFilesInFirstCorpus <= Files.size());\n  std::set<uint32_t> AllFeatures;\n\n  // What features are in the initial corpus?\n  for (size_t i = 0; i < NumFilesInFirstCorpus; i++) {\n    auto &Cur = Files[i].Features;\n    AllFeatures.insert(Cur.begin(), Cur.end());\n  }\n  size_t InitialNumFeatures = AllFeatures.size();\n\n  // Remove all features that we already know from all other inputs.\n  for (size_t i = NumFilesInFirstCorpus; i < Files.size(); i++) {\n    auto &Cur = Files[i].Features;\n    std::vector<uint32_t> Tmp;\n    std::set_difference(Cur.begin(), Cur.end(), AllFeatures.begin(),\n                        AllFeatures.end(), std::inserter(Tmp, Tmp.begin()));\n    Cur.swap(Tmp);\n  }\n\n  // Sort. Give preference to\n  //   * smaller files\n  //   * files with more features.\n  std::sort(Files.begin() + NumFilesInFirstCorpus, Files.end(),\n            [&](const MergeFileInfo &a, const MergeFileInfo &b) -> bool {\n              if (a.Size != b.Size)\n                return a.Size < b.Size;\n              return a.Features.size() > b.Features.size();\n            });\n\n  // One greedy pass: add the file's features to AllFeatures.\n  // If new features were added, add this file to NewFiles.\n  for (size_t i = NumFilesInFirstCorpus; i < Files.size(); i++) {\n    auto &Cur = Files[i].Features;\n    // Printf(\"%s -> sz %zd ft %zd\\n\", Files[i].Name.c_str(),\n    //       Files[i].Size, Cur.size());\n    size_t OldSize = AllFeatures.size();\n    AllFeatures.insert(Cur.begin(), Cur.end());\n    if (AllFeatures.size() > OldSize)\n      NewFiles->push_back(Files[i].Name);\n  }\n  return AllFeatures.size() - InitialNumFeatures;\n}\n\n// Inner process. May crash if the target crashes.\nvoid Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) {\n  Printf(\"MERGE-INNER: using the control file '%s'\\n\", CFPath.c_str());\n  Merger M;\n  std::ifstream IF(CFPath);\n  M.ParseOrExit(IF, false);\n  IF.close();\n  if (!M.LastFailure.empty())\n    Printf(\"MERGE-INNER: '%s' caused a failure at the previous merge step\\n\",\n           M.LastFailure.c_str());\n\n  Printf(\"MERGE-INNER: %zd total files;\"\n         \" %zd processed earlier; will process %zd files now\\n\",\n         M.Files.size(), M.FirstNotProcessedFile,\n         M.Files.size() - M.FirstNotProcessedFile);\n\n  std::ofstream OF(CFPath, std::ofstream::out | std::ofstream::app);\n  for (size_t i = M.FirstNotProcessedFile; i < M.Files.size(); i++) {\n    auto U = FileToVector(M.Files[i].Name);\n    if (U.size() > MaxInputLen) {\n      U.resize(MaxInputLen);\n      U.shrink_to_fit();\n    }\n    std::ostringstream StartedLine;\n    // Write the pre-run marker.\n    OF << \"STARTED \" << std::dec << i << \" \" << U.size() << \"\\n\";\n    OF.flush();  // Flush is important since ExecuteCommand may crash.\n    // Run.\n    TPC.ResetMaps();\n    ExecuteCallback(U.data(), U.size());\n    // Collect coverage.\n    std::set<size_t> Features;\n    TPC.CollectFeatures([&](size_t Feature) -> bool {\n      Features.insert(Feature);\n      return true;\n    });\n    // Show stats.\n    TotalNumberOfRuns++;\n    if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)))\n      PrintStats(\"pulse \");\n    // Write the post-run marker and the coverage.\n    OF << \"DONE \" << i;\n    for (size_t F : Features)\n      OF << \" \" << std::hex << F;\n    OF << \"\\n\";\n  }\n}\n\n// Outer process. Does not call the target code and thus sohuld not fail.\nvoid Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args,\n                                 const std::vector<std::string> &Corpora) {\n  if (Corpora.size() <= 1) {\n    Printf(\"Merge requires two or more corpus dirs\\n\");\n    return;\n  }\n  std::vector<std::string> AllFiles;\n  ListFilesInDirRecursive(Corpora[0], nullptr, &AllFiles, /*TopDir*/true);\n  size_t NumFilesInFirstCorpus = AllFiles.size();\n  for (size_t i = 1; i < Corpora.size(); i++)\n    ListFilesInDirRecursive(Corpora[i], nullptr, &AllFiles, /*TopDir*/true);\n  Printf(\"MERGE-OUTER: %zd files, %zd in the initial corpus\\n\",\n         AllFiles.size(), NumFilesInFirstCorpus);\n  std::string CFPath =\n      \"libFuzzerTemp.\" + std::to_string(GetPid()) + \".txt\";\n  // Write the control file.\n  RemoveFile(CFPath);\n  std::ofstream ControlFile(CFPath);\n  ControlFile << AllFiles.size() << \"\\n\";\n  ControlFile << NumFilesInFirstCorpus << \"\\n\";\n  for (auto &Path: AllFiles)\n    ControlFile << Path << \"\\n\";\n  ControlFile.close();\n\n  // Execute the inner process untill it passes.\n  // Every inner process should execute at least one input.\n  std::string BaseCmd = CloneArgsWithoutX(Args, \"keep-all-flags\");\n  for (size_t i = 1; i <= AllFiles.size(); i++) {\n    Printf(\"MERGE-OUTER: attempt %zd\\n\", i);\n    auto ExitCode =\n        ExecuteCommand(BaseCmd + \" -merge_control_file=\" + CFPath);\n    if (!ExitCode) {\n      Printf(\"MERGE-OUTER: succesfull in %zd attempt(s)\\n\", i);\n      break;\n    }\n  }\n  // Read the control file and do the merge.\n  Merger M;\n  std::ifstream IF(CFPath);\n  M.ParseOrExit(IF, true);\n  IF.close();\n  std::vector<std::string> NewFiles;\n  size_t NumNewFeatures = M.Merge(&NewFiles);\n  Printf(\"MERGE-OUTER: %zd new files with %zd new features added\\n\",\n         NewFiles.size(), NumNewFeatures);\n  for (auto &F: NewFiles)\n    WriteToOutputCorpus(FileToVector(F));\n  // We are done, delete the control file.\n  RemoveFile(CFPath);\n}\n\n} // namespace fuzzer\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerMerge.h",
    "content": "//===- FuzzerMerge.h - merging corpa ----------------------------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Merging Corpora.\n//\n// The task:\n//   Take the existing corpus (possibly empty) and merge new inputs into\n//   it so that only inputs with new coverage ('features') are added.\n//   The process should tolerate the crashes, OOMs, leaks, etc.\n//\n// Algorithm:\n//   The outter process collects the set of files and writes their names\n//   into a temporary \"control\" file, then repeatedly launches the inner\n//   process until all inputs are processed.\n//   The outer process does not actually execute the target code.\n//\n//   The inner process reads the control file and sees a) list of all the inputs\n//   and b) the last processed input. Then it starts processing the inputs one\n//   by one. Before processing every input it writes one line to control file:\n//   STARTED INPUT_ID INPUT_SIZE\n//   After processing an input it write another line:\n//   DONE INPUT_ID Feature1 Feature2 Feature3 ...\n//   If a crash happens while processing an input the last line in the control\n//   file will be \"STARTED INPUT_ID\" and so the next process will know\n//   where to resume.\n//\n//   Once all inputs are processed by the innner process(es) the outer process\n//   reads the control files and does the merge based entirely on the contents\n//   of control file.\n//   It uses a single pass greedy algorithm choosing first the smallest inputs\n//   within the same size the inputs that have more new features.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_MERGE_H\n#define LLVM_FUZZER_MERGE_H\n\n#include \"FuzzerDefs.h\"\n\n#include <istream>\n#include <set>\n\nnamespace fuzzer {\n\nstruct MergeFileInfo {\n  std::string Name;\n  size_t Size = 0;\n  std::vector<uint32_t> Features;\n};\n\nstruct Merger {\n  std::vector<MergeFileInfo> Files;\n  size_t NumFilesInFirstCorpus = 0;\n  size_t FirstNotProcessedFile = 0;\n  std::string LastFailure;\n\n  bool Parse(std::istream &IS, bool ParseCoverage);\n  bool Parse(const std::string &Str, bool ParseCoverage);\n  void ParseOrExit(std::istream &IS, bool ParseCoverage);\n  size_t Merge(std::vector<std::string> *NewFiles);\n};\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_MERGE_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerMutate.cpp",
    "content": "//===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Mutate a test input.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerCorpus.h\"\n#include \"FuzzerDefs.h\"\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerMutate.h\"\n#include \"FuzzerOptions.h\"\n\nnamespace fuzzer {\n\nconst size_t Dictionary::kMaxDictSize;\n\nstatic void PrintASCII(const Word &W, const char *PrintAfter) {\n  PrintASCII(W.data(), W.size(), PrintAfter);\n}\n\nMutationDispatcher::MutationDispatcher(Random &Rand,\n                                       const FuzzingOptions &Options)\n    : Rand(Rand), Options(Options) {\n  DefaultMutators.insert(\n      DefaultMutators.begin(),\n      {\n          {&MutationDispatcher::Mutate_EraseBytes, \"EraseBytes\"},\n          {&MutationDispatcher::Mutate_InsertByte, \"InsertByte\"},\n          {&MutationDispatcher::Mutate_InsertRepeatedBytes,\n           \"InsertRepeatedBytes\"},\n          {&MutationDispatcher::Mutate_ChangeByte, \"ChangeByte\"},\n          {&MutationDispatcher::Mutate_ChangeBit, \"ChangeBit\"},\n          {&MutationDispatcher::Mutate_ShuffleBytes, \"ShuffleBytes\"},\n          {&MutationDispatcher::Mutate_ChangeASCIIInteger, \"ChangeASCIIInt\"},\n          {&MutationDispatcher::Mutate_ChangeBinaryInteger, \"ChangeBinInt\"},\n          {&MutationDispatcher::Mutate_CopyPart, \"CopyPart\"},\n          {&MutationDispatcher::Mutate_CrossOver, \"CrossOver\"},\n          {&MutationDispatcher::Mutate_AddWordFromManualDictionary,\n           \"ManualDict\"},\n          {&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,\n           \"TempAutoDict\"},\n          {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,\n           \"PersAutoDict\"},\n      });\n  if(Options.UseCmp)\n    DefaultMutators.push_back(\n        {&MutationDispatcher::Mutate_AddWordFromTORC, \"CMP\"});\n\n  if (EF->LLVMFuzzerCustomMutator)\n    Mutators.push_back({&MutationDispatcher::Mutate_Custom, \"Custom\"});\n  else\n    Mutators = DefaultMutators;\n\n  if (EF->LLVMFuzzerCustomCrossOver)\n    Mutators.push_back(\n        {&MutationDispatcher::Mutate_CustomCrossOver, \"CustomCrossOver\"});\n}\n\nstatic char RandCh(Random &Rand) {\n  if (Rand.RandBool()) return Rand(256);\n  const char *Special = \"!*'();:@&=+$,/?%#[]012Az-`~.\\xff\\x00\";\n  return Special[Rand(sizeof(Special) - 1)];\n}\n\nsize_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,\n                                         size_t MaxSize) {\n  return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());\n}\n\nsize_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,\n                                                  size_t MaxSize) {\n  if (!Corpus || Corpus->size() < 2 || Size == 0)\n    return 0;\n  size_t Idx = Rand(Corpus->size());\n  const Unit &Other = (*Corpus)[Idx];\n  if (Other.empty())\n    return 0;\n  MutateInPlaceHere.resize(MaxSize);\n  auto &U = MutateInPlaceHere;\n  size_t NewSize = EF->LLVMFuzzerCustomCrossOver(\n      Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand());\n  if (!NewSize)\n    return 0;\n  assert(NewSize <= MaxSize && \"CustomCrossOver returned overisized unit\");\n  memcpy(Data, U.data(), NewSize);\n  return NewSize;\n}\n\nsize_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,\n                                               size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  assert(Size);\n  size_t ShuffleAmount =\n      Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.\n  size_t ShuffleStart = Rand(Size - ShuffleAmount);\n  assert(ShuffleStart + ShuffleAmount <= Size);\n  std::random_shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount,\n                      Rand);\n  return Size;\n}\n\nsize_t MutationDispatcher::Mutate_EraseBytes(uint8_t *Data, size_t Size,\n                                             size_t MaxSize) {\n  assert(Size);\n  if (Size == 1) return 0;\n  size_t N = Rand(Size / 2) + 1;\n  assert(N < Size);\n  size_t Idx = Rand(Size - N + 1);\n  // Erase Data[Idx:Idx+N].\n  memmove(Data + Idx, Data + Idx + N, Size - Idx - N);\n  // Printf(\"Erase: %zd %zd => %zd; Idx %zd\\n\", N, Size, Size - N, Idx);\n  return Size - N;\n}\n\nsize_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,\n                                             size_t MaxSize) {\n  if (Size >= MaxSize) return 0;\n  size_t Idx = Rand(Size + 1);\n  // Insert new value at Data[Idx].\n  memmove(Data + Idx + 1, Data + Idx, Size - Idx);\n  Data[Idx] = RandCh(Rand);\n  return Size + 1;\n}\n\nsize_t MutationDispatcher::Mutate_InsertRepeatedBytes(uint8_t *Data,\n                                                      size_t Size,\n                                                      size_t MaxSize) {\n  const size_t kMinBytesToInsert = 3;\n  if (Size + kMinBytesToInsert >= MaxSize) return 0;\n  size_t MaxBytesToInsert = std::min(MaxSize - Size, (size_t)128);\n  size_t N = Rand(MaxBytesToInsert - kMinBytesToInsert + 1) + kMinBytesToInsert;\n  assert(Size + N <= MaxSize && N);\n  size_t Idx = Rand(Size + 1);\n  // Insert new values at Data[Idx].\n  memmove(Data + Idx + N, Data + Idx, Size - Idx);\n  // Give preference to 0x00 and 0xff.\n  uint8_t Byte = Rand.RandBool() ? Rand(256) : (Rand.RandBool() ? 0 : 255);\n  for (size_t i = 0; i < N; i++)\n    Data[Idx + i] = Byte;\n  return Size + N;\n}\n\nsize_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,\n                                             size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  size_t Idx = Rand(Size);\n  Data[Idx] = RandCh(Rand);\n  return Size;\n}\n\nsize_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,\n                                            size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  size_t Idx = Rand(Size);\n  Data[Idx] ^= 1 << Rand(8);\n  return Size;\n}\n\nsize_t MutationDispatcher::Mutate_AddWordFromManualDictionary(uint8_t *Data,\n                                                              size_t Size,\n                                                              size_t MaxSize) {\n  return AddWordFromDictionary(ManualDictionary, Data, Size, MaxSize);\n}\n\nsize_t MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary(\n    uint8_t *Data, size_t Size, size_t MaxSize) {\n  return AddWordFromDictionary(TempAutoDictionary, Data, Size, MaxSize);\n}\n\nsize_t MutationDispatcher::ApplyDictionaryEntry(uint8_t *Data, size_t Size,\n                                                size_t MaxSize,\n                                                DictionaryEntry &DE) {\n  const Word &W = DE.GetW();\n  bool UsePositionHint = DE.HasPositionHint() &&\n                         DE.GetPositionHint() + W.size() < Size &&\n                         Rand.RandBool();\n  if (Rand.RandBool()) {  // Insert W.\n    if (Size + W.size() > MaxSize) return 0;\n    size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size + 1);\n    memmove(Data + Idx + W.size(), Data + Idx, Size - Idx);\n    memcpy(Data + Idx, W.data(), W.size());\n    Size += W.size();\n  } else {  // Overwrite some bytes with W.\n    if (W.size() > Size) return 0;\n    size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size - W.size());\n    memcpy(Data + Idx, W.data(), W.size());\n  }\n  return Size;\n}\n\n// Somewhere in the past we have observed a comparison instructions\n// with arguments Arg1 Arg2. This function tries to guess a dictionary\n// entry that will satisfy that comparison.\n// It first tries to find one of the arguments (possibly swapped) in the\n// input and if it succeeds it creates a DE with a position hint.\n// Otherwise it creates a DE with one of the arguments w/o a position hint.\ntemplate <class T>\nDictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(\n    T Arg1, T Arg2, const uint8_t *Data, size_t Size) {\n  ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;\n  bool HandleFirst = Rand.RandBool();\n  T ExistingBytes, DesiredBytes;\n  Word W;\n  const uint8_t *End = Data + Size;\n  for (int Arg = 0; Arg < 2; Arg++) {\n    ExistingBytes = HandleFirst ? Arg1 : Arg2;\n    DesiredBytes = HandleFirst ? Arg2 : Arg1;\n    DesiredBytes += Rand(-1, 1);\n    if (Rand.RandBool()) ExistingBytes = Bswap(ExistingBytes);\n    if (Rand.RandBool()) DesiredBytes = Bswap(DesiredBytes);\n    HandleFirst = !HandleFirst;\n    W.Set(reinterpret_cast<uint8_t*>(&DesiredBytes), sizeof(T));\n    const size_t kMaxNumPositions = 8;\n    size_t Positions[kMaxNumPositions];\n    size_t NumPositions = 0;\n    for (const uint8_t *Cur = Data;\n         Cur < End && NumPositions < kMaxNumPositions; Cur++) {\n      Cur = (uint8_t *)SearchMemory(Cur, End - Cur, &ExistingBytes, sizeof(T));\n      if (!Cur) break;\n      Positions[NumPositions++] = Cur - Data;\n    }\n    if (!NumPositions) break;\n    return DictionaryEntry(W, Positions[Rand(NumPositions)]);\n  }\n  DictionaryEntry DE(W);\n  return DE;\n}\n\nsize_t MutationDispatcher::Mutate_AddWordFromTORC(\n    uint8_t *Data, size_t Size, size_t MaxSize) {\n  Word W;\n  DictionaryEntry DE;\n  if (Rand.RandBool()) {\n    auto X = TPC.TORC8.Get(Rand.Rand());\n    DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);\n  } else {\n    auto X = TPC.TORC4.Get(Rand.Rand());\n    if ((X.A >> 16) == 0 && (X.B >> 16) == 0 && Rand.RandBool())\n      DE = MakeDictionaryEntryFromCMP((uint16_t)X.A, (uint16_t)X.B, Data,\n                                      Size);\n    else\n      DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);\n  }\n  Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);\n  if (!Size) return 0;\n  DictionaryEntry &DERef =\n      CmpDictionaryEntriesDeque[CmpDictionaryEntriesDequeIdx++ %\n                                kCmpDictionaryEntriesDequeSize];\n  DERef = DE;\n  CurrentDictionaryEntrySequence.push_back(&DERef);\n  return Size;\n}\n\nsize_t MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary(\n    uint8_t *Data, size_t Size, size_t MaxSize) {\n  return AddWordFromDictionary(PersistentAutoDictionary, Data, Size, MaxSize);\n}\n\nsize_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,\n                                                 size_t Size, size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  if (D.empty()) return 0;\n  DictionaryEntry &DE = D[Rand(D.size())];\n  Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);\n  if (!Size) return 0;\n  DE.IncUseCount();\n  CurrentDictionaryEntrySequence.push_back(&DE);\n  return Size;\n}\n\n// Overwrites part of To[0,ToSize) with a part of From[0,FromSize).\n// Returns ToSize.\nsize_t MutationDispatcher::CopyPartOf(const uint8_t *From, size_t FromSize,\n                                      uint8_t *To, size_t ToSize) {\n  // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).\n  size_t ToBeg = Rand(ToSize);\n  size_t CopySize = Rand(ToSize - ToBeg) + 1;\n  assert(ToBeg + CopySize <= ToSize);\n  CopySize = std::min(CopySize, FromSize);\n  size_t FromBeg = Rand(FromSize - CopySize + 1);\n  assert(FromBeg + CopySize <= FromSize);\n  memmove(To + ToBeg, From + FromBeg, CopySize);\n  return ToSize;\n}\n\n// Inserts part of From[0,ToSize) into To.\n// Returns new size of To on success or 0 on failure.\nsize_t MutationDispatcher::InsertPartOf(const uint8_t *From, size_t FromSize,\n                                        uint8_t *To, size_t ToSize,\n                                        size_t MaxToSize) {\n  if (ToSize >= MaxToSize) return 0;\n  size_t AvailableSpace = MaxToSize - ToSize;\n  size_t MaxCopySize = std::min(AvailableSpace, FromSize);\n  size_t CopySize = Rand(MaxCopySize) + 1;\n  size_t FromBeg = Rand(FromSize - CopySize + 1);\n  assert(FromBeg + CopySize <= FromSize);\n  size_t ToInsertPos = Rand(ToSize + 1);\n  assert(ToInsertPos + CopySize <= MaxToSize);\n  size_t TailSize = ToSize - ToInsertPos;\n  if (To == From) {\n    MutateInPlaceHere.resize(MaxToSize);\n    memcpy(MutateInPlaceHere.data(), From + FromBeg, CopySize);\n    memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);\n    memmove(To + ToInsertPos, MutateInPlaceHere.data(), CopySize);\n  } else {\n    memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);\n    memmove(To + ToInsertPos, From + FromBeg, CopySize);\n  }\n  return ToSize + CopySize;\n}\n\nsize_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data, size_t Size,\n                                           size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  if (Rand.RandBool())\n    return CopyPartOf(Data, Size, Data, Size);\n  else\n    return InsertPartOf(Data, Size, Data, Size, MaxSize);\n}\n\nsize_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,\n                                                     size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  size_t B = Rand(Size);\n  while (B < Size && !isdigit(Data[B])) B++;\n  if (B == Size) return 0;\n  size_t E = B;\n  while (E < Size && isdigit(Data[E])) E++;\n  assert(B < E);\n  // now we have digits in [B, E).\n  // strtol and friends don't accept non-zero-teminated data, parse it manually.\n  uint64_t Val = Data[B] - '0';\n  for (size_t i = B + 1; i < E; i++)\n    Val = Val * 10 + Data[i] - '0';\n\n  // Mutate the integer value.\n  switch(Rand(5)) {\n    case 0: Val++; break;\n    case 1: Val--; break;\n    case 2: Val /= 2; break;\n    case 3: Val *= 2; break;\n    case 4: Val = Rand(Val * Val); break;\n    default: assert(0);\n  }\n  // Just replace the bytes with the new ones, don't bother moving bytes.\n  for (size_t i = B; i < E; i++) {\n    size_t Idx = E + B - i - 1;\n    assert(Idx >= B && Idx < E);\n    Data[Idx] = (Val % 10) + '0';\n    Val /= 10;\n  }\n  return Size;\n}\n\ntemplate<class T>\nsize_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) {\n  if (Size < sizeof(T)) return 0;\n  size_t Off = Rand(Size - sizeof(T) + 1);\n  assert(Off + sizeof(T) <= Size);\n  T Val;\n  if (Off < 64 && !Rand(4)) {\n    Val = Size;\n    if (Rand.RandBool())\n      Val = Bswap(Val);\n  } else {\n    memcpy(&Val, Data + Off, sizeof(Val));\n    T Add = Rand(21);\n    Add -= 10;\n    if (Rand.RandBool())\n      Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes.\n    else\n      Val = Val + Add;               // Add assuming current endiannes.\n    if (Add == 0 || Rand.RandBool()) // Maybe negate.\n      Val = -Val;\n  }\n  memcpy(Data + Off, &Val, sizeof(Val));\n  return Size;\n}\n\nsize_t MutationDispatcher::Mutate_ChangeBinaryInteger(uint8_t *Data,\n                                                      size_t Size,\n                                                      size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  switch (Rand(4)) {\n    case 3: return ChangeBinaryInteger<uint64_t>(Data, Size, Rand);\n    case 2: return ChangeBinaryInteger<uint32_t>(Data, Size, Rand);\n    case 1: return ChangeBinaryInteger<uint16_t>(Data, Size, Rand);\n    case 0: return ChangeBinaryInteger<uint8_t>(Data, Size, Rand);\n    default: assert(0);\n  }\n  return 0;\n}\n\nsize_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,\n                                            size_t MaxSize) {\n  if (Size > MaxSize) return 0;\n  if (!Corpus || Corpus->size() < 2 || Size == 0) return 0;\n  size_t Idx = Rand(Corpus->size());\n  const Unit &O = (*Corpus)[Idx];\n  if (O.empty()) return 0;\n  MutateInPlaceHere.resize(MaxSize);\n  auto &U = MutateInPlaceHere;\n  size_t NewSize = 0;\n  switch(Rand(3)) {\n    case 0:\n      NewSize = CrossOver(Data, Size, O.data(), O.size(), U.data(), U.size());\n      break;\n    case 1:\n      NewSize = InsertPartOf(O.data(), O.size(), U.data(), U.size(), MaxSize);\n      if (NewSize)\n        break;\n      // LLVM_FALLTHROUGH;\n    case 2:\n      NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size());\n      break;\n    default: assert(0);\n  }\n  assert(NewSize > 0 && \"CrossOver returned empty unit\");\n  assert(NewSize <= MaxSize && \"CrossOver returned overisized unit\");\n  memcpy(Data, U.data(), NewSize);\n  return NewSize;\n}\n\nvoid MutationDispatcher::StartMutationSequence() {\n  CurrentMutatorSequence.clear();\n  CurrentDictionaryEntrySequence.clear();\n}\n\n// Copy successful dictionary entries to PersistentAutoDictionary.\nvoid MutationDispatcher::RecordSuccessfulMutationSequence() {\n  for (auto DE : CurrentDictionaryEntrySequence) {\n    // PersistentAutoDictionary.AddWithSuccessCountOne(DE);\n    DE->IncSuccessCount();\n    // Linear search is fine here as this happens seldom.\n    if (!PersistentAutoDictionary.ContainsWord(DE->GetW()))\n      PersistentAutoDictionary.push_back({DE->GetW(), 1});\n  }\n}\n\nvoid MutationDispatcher::PrintRecommendedDictionary() {\n  std::vector<DictionaryEntry> V;\n  for (auto &DE : PersistentAutoDictionary)\n    if (!ManualDictionary.ContainsWord(DE.GetW()))\n      V.push_back(DE);\n  if (V.empty()) return;\n  Printf(\"###### Recommended dictionary. ######\\n\");\n  for (auto &DE: V) {\n    Printf(\"\\\"\");\n    PrintASCII(DE.GetW(), \"\\\"\");\n    Printf(\" # Uses: %zd\\n\", DE.GetUseCount());\n  }\n  Printf(\"###### End of recommended dictionary. ######\\n\");\n}\n\nvoid MutationDispatcher::PrintMutationSequence() {\n  Printf(\"MS: %zd \", CurrentMutatorSequence.size());\n  for (auto M : CurrentMutatorSequence)\n    Printf(\"%s-\", M.Name);\n  if (!CurrentDictionaryEntrySequence.empty()) {\n    Printf(\" DE: \");\n    for (auto DE : CurrentDictionaryEntrySequence) {\n      Printf(\"\\\"\");\n      PrintASCII(DE->GetW(), \"\\\"-\");\n    }\n  }\n}\n\nsize_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {\n  return MutateImpl(Data, Size, MaxSize, Mutators);\n}\n\nsize_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,\n                                         size_t MaxSize) {\n  return MutateImpl(Data, Size, MaxSize, DefaultMutators);\n}\n\n// Mutates Data in place, returns new size.\nsize_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,\n                                      size_t MaxSize,\n                                      const std::vector<Mutator> &Mutators) {\n  assert(MaxSize > 0);\n  if (Size == 0) {\n    for (size_t i = 0; i < MaxSize; i++)\n      Data[i] = RandCh(Rand);\n    if (Options.OnlyASCII)\n      ToASCII(Data, MaxSize);\n    return MaxSize;\n  }\n  assert(Size > 0);\n  // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),\n  // in which case they will return 0.\n  // Try several times before returning un-mutated data.\n  for (int Iter = 0; Iter < 100; Iter++) {\n    auto M = Mutators[Rand(Mutators.size())];\n    size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);\n    if (NewSize && NewSize <= MaxSize) {\n      if (Options.OnlyASCII)\n        ToASCII(Data, NewSize);\n      CurrentMutatorSequence.push_back(M);\n      return NewSize;\n    }\n  }\n  return std::min(Size, MaxSize);\n}\n\nvoid MutationDispatcher::AddWordToManualDictionary(const Word &W) {\n  ManualDictionary.push_back(\n      {W, std::numeric_limits<size_t>::max()});\n}\n\nvoid MutationDispatcher::AddWordToAutoDictionary(DictionaryEntry DE) {\n  static const size_t kMaxAutoDictSize = 1 << 14;\n  if (TempAutoDictionary.size() >= kMaxAutoDictSize) return;\n  TempAutoDictionary.push_back(DE);\n}\n\nvoid MutationDispatcher::ClearAutoDictionary() {\n  TempAutoDictionary.clear();\n}\n\n}  // namespace fuzzer\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerMutate.h",
    "content": "//===- FuzzerMutate.h - Internal header for the Fuzzer ----------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// fuzzer::MutationDispatcher\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_MUTATE_H\n#define LLVM_FUZZER_MUTATE_H\n\n#include \"FuzzerDefs.h\"\n#include \"FuzzerDictionary.h\"\n#include \"FuzzerRandom.h\"\n\nnamespace fuzzer {\n\nclass MutationDispatcher {\npublic:\n  MutationDispatcher(Random &Rand, const FuzzingOptions &Options);\n  ~MutationDispatcher() {}\n  /// Indicate that we are about to start a new sequence of mutations.\n  void StartMutationSequence();\n  /// Print the current sequence of mutations.\n  void PrintMutationSequence();\n  /// Indicate that the current sequence of mutations was successfull.\n  void RecordSuccessfulMutationSequence();\n  /// Mutates data by invoking user-provided mutator.\n  size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by invoking user-provided crossover.\n  size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by shuffling bytes.\n  size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by erasing bytes.\n  size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by inserting a byte.\n  size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by inserting several repeated bytes.\n  size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by chanding one byte.\n  size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by chanding one bit.\n  size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Mutates data by copying/inserting a part of data into a different place.\n  size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize);\n\n  /// Mutates data by adding a word from the manual dictionary.\n  size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,\n                                            size_t MaxSize);\n\n  /// Mutates data by adding a word from the temporary automatic dictionary.\n  size_t Mutate_AddWordFromTemporaryAutoDictionary(uint8_t *Data, size_t Size,\n                                                   size_t MaxSize);\n\n  /// Mutates data by adding a word from the TORC.\n  size_t Mutate_AddWordFromTORC(uint8_t *Data, size_t Size, size_t MaxSize);\n\n  /// Mutates data by adding a word from the persistent automatic dictionary.\n  size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,\n                                                    size_t MaxSize);\n\n  /// Tries to find an ASCII integer in Data, changes it to another ASCII int.\n  size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.\n  size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);\n\n  /// CrossOver Data with some other element of the corpus.\n  size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);\n\n  /// Applies one of the configured mutations.\n  /// Returns the new size of data which could be up to MaxSize.\n  size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);\n  /// Applies one of the default mutations. Provided as a service\n  /// to mutation authors.\n  size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);\n\n  /// Creates a cross-over of two pieces of Data, returns its size.\n  size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,\n                   size_t Size2, uint8_t *Out, size_t MaxOutSize);\n\n  void AddWordToManualDictionary(const Word &W);\n\n  void AddWordToAutoDictionary(DictionaryEntry DE);\n  void ClearAutoDictionary();\n  void PrintRecommendedDictionary();\n\n  void SetCorpus(const InputCorpus *Corpus) { this->Corpus = Corpus; }\n\n  Random &GetRand() { return Rand; }\n\nprivate:\n\n  struct Mutator {\n    size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);\n    const char *Name;\n  };\n\n  size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,\n                               size_t MaxSize);\n  size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,\n                    const std::vector<Mutator> &Mutators);\n\n  size_t InsertPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,\n                      size_t ToSize, size_t MaxToSize);\n  size_t CopyPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,\n                    size_t ToSize);\n  size_t ApplyDictionaryEntry(uint8_t *Data, size_t Size, size_t MaxSize,\n                              DictionaryEntry &DE);\n\n  template <class T>\n  DictionaryEntry MakeDictionaryEntryFromCMP(T Arg1, T Arg2,\n                                             const uint8_t *Data, size_t Size);\n\n  Random &Rand;\n  const FuzzingOptions &Options;\n\n  // Dictionary provided by the user via -dict=DICT_FILE.\n  Dictionary ManualDictionary;\n  // Temporary dictionary modified by the fuzzer itself,\n  // recreated periodically.\n  Dictionary TempAutoDictionary;\n  // Persistent dictionary modified by the fuzzer, consists of\n  // entries that led to successfull discoveries in the past mutations.\n  Dictionary PersistentAutoDictionary;\n\n  std::vector<Mutator> CurrentMutatorSequence;\n  std::vector<DictionaryEntry *> CurrentDictionaryEntrySequence;\n\n  static const size_t kCmpDictionaryEntriesDequeSize = 16;\n  DictionaryEntry CmpDictionaryEntriesDeque[kCmpDictionaryEntriesDequeSize];\n  size_t CmpDictionaryEntriesDequeIdx = 0;\n\n  const InputCorpus *Corpus = nullptr;\n  std::vector<uint8_t> MutateInPlaceHere;\n\n  std::vector<Mutator> Mutators;\n  std::vector<Mutator> DefaultMutators;\n};\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_MUTATE_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerOptions.h",
    "content": "//===- FuzzerOptions.h - Internal header for the Fuzzer ---------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// fuzzer::FuzzingOptions\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_OPTIONS_H\n#define LLVM_FUZZER_OPTIONS_H\n\n#include \"FuzzerDefs.h\"\n\nnamespace fuzzer {\n\nstruct FuzzingOptions {\n  int Verbosity = 1;\n  size_t MaxLen = 0;\n  int UnitTimeoutSec = 300;\n  int TimeoutExitCode = 77;\n  int ErrorExitCode = 77;\n  int MaxTotalTimeSec = 0;\n  int RssLimitMb = 0;\n  bool DoCrossOver = true;\n  int MutateDepth = 5;\n  bool UseCounters = false;\n  bool UseIndirCalls = true;\n  bool UseMemcmp = true;\n  bool UseMemmem = true;\n  bool UseCmp = false;\n  bool UseValueProfile = false;\n  bool Shrink = false;\n  int ReloadIntervalSec = 1;\n  bool ShuffleAtStartUp = true;\n  bool PreferSmall = true;\n  size_t MaxNumberOfRuns = -1L;\n  int ReportSlowUnits = 10;\n  bool OnlyASCII = false;\n  std::string OutputCorpus;\n  std::string ArtifactPrefix = \"./\";\n  std::string ExactArtifactPath;\n  std::string ExitOnSrcPos;\n  std::string ExitOnItem;\n  bool SaveArtifacts = true;\n  bool PrintNEW = true; // Print a status line when new units are found;\n  bool OutputCSV = false;\n  bool PrintNewCovPcs = false;\n  bool PrintFinalStats = false;\n  bool PrintCorpusStats = false;\n  bool PrintCoverage = false;\n  bool DumpCoverage = false;\n  bool DetectLeaks = true;\n  int  TraceMalloc = 0;\n  bool HandleAbrt = false;\n  bool HandleBus = false;\n  bool HandleFpe = false;\n  bool HandleIll = false;\n  bool HandleInt = false;\n  bool HandleSegv = false;\n  bool HandleTerm = false;\n};\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_OPTIONS_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerRandom.h",
    "content": "//===- FuzzerRandom.h - Internal header for the Fuzzer ----------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// fuzzer::Random\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_RANDOM_H\n#define LLVM_FUZZER_RANDOM_H\n\n#include <random>\n\nnamespace fuzzer {\nclass Random {\n public:\n  Random(unsigned int seed) : R(seed) {}\n  size_t Rand() { return R(); }\n  size_t RandBool() { return Rand() % 2; }\n  size_t operator()(size_t n) { return n ? Rand() % n : 0; }\n  intptr_t operator()(intptr_t From, intptr_t To) {\n    assert(From < To);\n    intptr_t RangeSize = To - From + 1;\n    return operator()(RangeSize) + From;\n  }\n  std::mt19937 &Get_mt19937() { return R; }\n private:\n  std::mt19937 R;\n};\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_RANDOM_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerSHA1.cpp",
    "content": "//===- FuzzerSHA1.h - Private copy of the SHA1 implementation ---*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// This code is taken from public domain\n// (http://oauth.googlecode.com/svn/code/c/liboauth/src/sha1.c)\n// and modified by adding anonymous namespace, adding an interface\n// function fuzzer::ComputeSHA1() and removing unnecessary code.\n//\n// lib/Fuzzer can not use SHA1 implementation from openssl because\n// openssl may not be available and because we may be fuzzing openssl itself.\n// For the same reason we do not want to depend on SHA1 from LLVM tree.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerSHA1.h\"\n#include \"FuzzerDefs.h\"\n\n/* This code is public-domain - it is based on libcrypt\n * placed in the public domain by Wei Dai and other contributors.\n */\n\n#include <iomanip>\n#include <sstream>\n#include <stdint.h>\n#include <string.h>\n\nnamespace {  // Added for LibFuzzer\n\n#ifdef __BIG_ENDIAN__\n# define SHA_BIG_ENDIAN\n#elif defined __LITTLE_ENDIAN__\n/* override */\n#elif defined __BYTE_ORDER\n# if __BYTE_ORDER__ ==  __ORDER_BIG_ENDIAN__\n# define SHA_BIG_ENDIAN\n# endif\n#else // ! defined __LITTLE_ENDIAN__\n# include <endian.h> // machine/endian.h\n# if __BYTE_ORDER__ ==  __ORDER_BIG_ENDIAN__\n#  define SHA_BIG_ENDIAN\n# endif\n#endif\n\n\n/* header */\n\n#define HASH_LENGTH 20\n#define BLOCK_LENGTH 64\n\ntypedef struct sha1nfo {\n\tuint32_t buffer[BLOCK_LENGTH/4];\n\tuint32_t state[HASH_LENGTH/4];\n\tuint32_t byteCount;\n\tuint8_t bufferOffset;\n\tuint8_t keyBuffer[BLOCK_LENGTH];\n\tuint8_t innerHash[HASH_LENGTH];\n} sha1nfo;\n\n/* public API - prototypes - TODO: doxygen*/\n\n/**\n */\nvoid sha1_init(sha1nfo *s);\n/**\n */\nvoid sha1_writebyte(sha1nfo *s, uint8_t data);\n/**\n */\nvoid sha1_write(sha1nfo *s, const char *data, size_t len);\n/**\n */\nuint8_t* sha1_result(sha1nfo *s);\n\n\n/* code */\n#define SHA1_K0  0x5a827999\n#define SHA1_K20 0x6ed9eba1\n#define SHA1_K40 0x8f1bbcdc\n#define SHA1_K60 0xca62c1d6\n\nvoid sha1_init(sha1nfo *s) {\n\ts->state[0] = 0x67452301;\n\ts->state[1] = 0xefcdab89;\n\ts->state[2] = 0x98badcfe;\n\ts->state[3] = 0x10325476;\n\ts->state[4] = 0xc3d2e1f0;\n\ts->byteCount = 0;\n\ts->bufferOffset = 0;\n}\n\nuint32_t sha1_rol32(uint32_t number, uint8_t bits) {\n\treturn ((number << bits) | (number >> (32-bits)));\n}\n\nvoid sha1_hashBlock(sha1nfo *s) {\n\tuint8_t i;\n\tuint32_t a,b,c,d,e,t;\n\n\ta=s->state[0];\n\tb=s->state[1];\n\tc=s->state[2];\n\td=s->state[3];\n\te=s->state[4];\n\tfor (i=0; i<80; i++) {\n\t\tif (i>=16) {\n\t\t\tt = s->buffer[(i+13)&15] ^ s->buffer[(i+8)&15] ^ s->buffer[(i+2)&15] ^ s->buffer[i&15];\n\t\t\ts->buffer[i&15] = sha1_rol32(t,1);\n\t\t}\n\t\tif (i<20) {\n\t\t\tt = (d ^ (b & (c ^ d))) + SHA1_K0;\n\t\t} else if (i<40) {\n\t\t\tt = (b ^ c ^ d) + SHA1_K20;\n\t\t} else if (i<60) {\n\t\t\tt = ((b & c) | (d & (b | c))) + SHA1_K40;\n\t\t} else {\n\t\t\tt = (b ^ c ^ d) + SHA1_K60;\n\t\t}\n\t\tt+=sha1_rol32(a,5) + e + s->buffer[i&15];\n\t\te=d;\n\t\td=c;\n\t\tc=sha1_rol32(b,30);\n\t\tb=a;\n\t\ta=t;\n\t}\n\ts->state[0] += a;\n\ts->state[1] += b;\n\ts->state[2] += c;\n\ts->state[3] += d;\n\ts->state[4] += e;\n}\n\nvoid sha1_addUncounted(sha1nfo *s, uint8_t data) {\n\tuint8_t * const b = (uint8_t*) s->buffer;\n#ifdef SHA_BIG_ENDIAN\n\tb[s->bufferOffset] = data;\n#else\n\tb[s->bufferOffset ^ 3] = data;\n#endif\n\ts->bufferOffset++;\n\tif (s->bufferOffset == BLOCK_LENGTH) {\n\t\tsha1_hashBlock(s);\n\t\ts->bufferOffset = 0;\n\t}\n}\n\nvoid sha1_writebyte(sha1nfo *s, uint8_t data) {\n\t++s->byteCount;\n\tsha1_addUncounted(s, data);\n}\n\nvoid sha1_write(sha1nfo *s, const char *data, size_t len) {\n\tfor (;len--;) sha1_writebyte(s, (uint8_t) *data++);\n}\n\nvoid sha1_pad(sha1nfo *s) {\n\t// Implement SHA-1 padding (fips180-2 §5.1.1)\n\n\t// Pad with 0x80 followed by 0x00 until the end of the block\n\tsha1_addUncounted(s, 0x80);\n\twhile (s->bufferOffset != 56) sha1_addUncounted(s, 0x00);\n\n\t// Append length in the last 8 bytes\n\tsha1_addUncounted(s, 0); // We're only using 32 bit lengths\n\tsha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths\n\tsha1_addUncounted(s, 0); // So zero pad the top bits\n\tsha1_addUncounted(s, s->byteCount >> 29); // Shifting to multiply by 8\n\tsha1_addUncounted(s, s->byteCount >> 21); // as SHA-1 supports bitstreams as well as\n\tsha1_addUncounted(s, s->byteCount >> 13); // byte.\n\tsha1_addUncounted(s, s->byteCount >> 5);\n\tsha1_addUncounted(s, s->byteCount << 3);\n}\n\nuint8_t* sha1_result(sha1nfo *s) {\n\t// Pad to complete the last block\n\tsha1_pad(s);\n\n#ifndef SHA_BIG_ENDIAN\n\t// Swap byte order back\n\tint i;\n\tfor (i=0; i<5; i++) {\n\t\ts->state[i]=\n\t\t\t  (((s->state[i])<<24)& 0xff000000)\n\t\t\t| (((s->state[i])<<8) & 0x00ff0000)\n\t\t\t| (((s->state[i])>>8) & 0x0000ff00)\n\t\t\t| (((s->state[i])>>24)& 0x000000ff);\n\t}\n#endif\n\n\t// Return pointer to hash (20 characters)\n\treturn (uint8_t*) s->state;\n}\n\n}  // namespace; Added for LibFuzzer\n\nnamespace fuzzer {\n\n// The rest is added for LibFuzzer\nvoid ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out) {\n  sha1nfo s;\n  sha1_init(&s);\n  sha1_write(&s, (const char*)Data, Len);\n  memcpy(Out, sha1_result(&s), HASH_LENGTH);\n}\n\nstd::string Sha1ToString(const uint8_t Sha1[kSHA1NumBytes]) {\n  std::stringstream SS;\n  for (int i = 0; i < kSHA1NumBytes; i++)\n    SS << std::hex << std::setfill('0') << std::setw(2) << (unsigned)Sha1[i];\n  return SS.str();\n}\n\nstd::string Hash(const Unit &U) {\n  uint8_t Hash[kSHA1NumBytes];\n  ComputeSHA1(U.data(), U.size(), Hash);\n  return Sha1ToString(Hash);\n}\n\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerSHA1.h",
    "content": "//===- FuzzerSHA1.h - Internal header for the SHA1 utils --------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// SHA1 utils.\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_SHA1_H\n#define LLVM_FUZZER_SHA1_H\n\n#include \"FuzzerDefs.h\"\n#include <cstddef>\n#include <stdint.h>\n\nnamespace fuzzer {\n\n// Private copy of SHA1 implementation.\nstatic const int kSHA1NumBytes = 20;\n\n// Computes SHA1 hash of 'Len' bytes in 'Data', writes kSHA1NumBytes to 'Out'.\nvoid ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out);\n\nstd::string Sha1ToString(const uint8_t Sha1[kSHA1NumBytes]);\n\nstd::string Hash(const Unit &U);\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_SHA1_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerTracePC.cpp",
    "content": "//===- FuzzerTracePC.cpp - PC tracing--------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Trace PCs.\n// This module implements __sanitizer_cov_trace_pc_guard[_init],\n// the callback required for -fsanitize-coverage=trace-pc-guard instrumentation.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerCorpus.h\"\n#include \"FuzzerDefs.h\"\n#include \"FuzzerDictionary.h\"\n#include \"FuzzerExtFunctions.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerTracePC.h\"\n#include \"FuzzerValueBitMap.h\"\n#include <map>\n#include <sanitizer/coverage_interface.h>\n#include <set>\n#include <sstream>\n\nnamespace fuzzer {\n\nTracePC TPC;\n\nvoid TracePC::HandleTrace(uint32_t *Guard, uintptr_t PC) {\n  uint32_t Idx = *Guard;\n  if (!Idx) return;\n  PCs[Idx % kNumPCs] = PC;\n  Counters[Idx % kNumCounters]++;\n}\n\nsize_t TracePC::GetTotalPCCoverage() {\n  size_t Res = 0;\n  for (size_t i = 1; i < GetNumPCs(); i++)\n    if (PCs[i])\n      Res++;\n  return Res;\n}\n\nvoid TracePC::HandleInit(uint32_t *Start, uint32_t *Stop) {\n  if (Start == Stop || *Start) return;\n  assert(NumModules < sizeof(Modules) / sizeof(Modules[0]));\n  for (uint32_t *P = Start; P < Stop; P++)\n    *P = ++NumGuards;\n  Modules[NumModules].Start = Start;\n  Modules[NumModules].Stop = Stop;\n  NumModules++;\n}\n\nvoid TracePC::PrintModuleInfo() {\n  Printf(\"INFO: Loaded %zd modules (%zd guards): \", NumModules, NumGuards);\n  for (size_t i = 0; i < NumModules; i++)\n    Printf(\"[%p, %p), \", Modules[i].Start, Modules[i].Stop);\n  Printf(\"\\n\");\n}\n\nvoid TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {\n  const uintptr_t kBits = 12;\n  const uintptr_t kMask = (1 << kBits) - 1;\n  uintptr_t Idx = (Caller & kMask) | ((Callee & kMask) << kBits);\n  HandleValueProfile(Idx);\n}\n\nstatic bool IsInterestingCoverageFile(std::string &File) {\n  if (File.find(\"compiler-rt/lib/\") != std::string::npos)\n    return false; // sanitizer internal.\n  if (File.find(\"/usr/lib/\") != std::string::npos)\n    return false;\n  if (File.find(\"/usr/include/\") != std::string::npos)\n    return false;\n  if (File == \"<null>\")\n    return false;\n  return true;\n}\n\nvoid TracePC::PrintNewPCs() {\n  if (DoPrintNewPCs) {\n    if (!PrintedPCs)\n      PrintedPCs = new std::set<uintptr_t>;\n    for (size_t i = 1; i < GetNumPCs(); i++)\n      if (PCs[i] && PrintedPCs->insert(PCs[i]).second)\n        PrintPC(\"\\tNEW_PC: %p %F %L\\n\", \"\\tNEW_PC: %p\\n\", PCs[i]);\n  }\n}\n\nvoid TracePC::PrintCoverage() {\n  if (!EF->__sanitizer_symbolize_pc ||\n      !EF->__sanitizer_get_module_and_offset_for_pc) {\n    Printf(\"INFO: __sanitizer_symbolize_pc or \"\n           \"__sanitizer_get_module_and_offset_for_pc is not available,\"\n           \" not printing coverage\\n\");\n    return;\n  }\n  std::map<std::string, std::vector<uintptr_t>> CoveredPCsPerModule;\n  std::map<std::string, uintptr_t> ModuleOffsets;\n  std::set<std::string> CoveredDirs, CoveredFiles, CoveredFunctions,\n      CoveredLines;\n  Printf(\"COVERAGE:\\n\");\n  for (size_t i = 1; i < GetNumPCs(); i++) {\n    if (!PCs[i]) continue;\n    std::string FileStr = DescribePC(\"%s\", PCs[i]);\n    if (!IsInterestingCoverageFile(FileStr)) continue;\n    std::string FixedPCStr = DescribePC(\"%p\", PCs[i]);\n    std::string FunctionStr = DescribePC(\"%F\", PCs[i]);\n    std::string LineStr = DescribePC(\"%l\", PCs[i]);\n    char ModulePathRaw[4096] = \"\";  // What's PATH_MAX in portable C++?\n    void *OffsetRaw = nullptr;\n    if (!EF->__sanitizer_get_module_and_offset_for_pc(\n            reinterpret_cast<void *>(PCs[i]), ModulePathRaw,\n            sizeof(ModulePathRaw), &OffsetRaw))\n      continue;\n    std::string Module = ModulePathRaw;\n    uintptr_t FixedPC = std::stol(FixedPCStr, 0, 16);\n    uintptr_t PcOffset = reinterpret_cast<uintptr_t>(OffsetRaw);\n    ModuleOffsets[Module] = FixedPC - PcOffset;\n    CoveredPCsPerModule[Module].push_back(PcOffset);\n    CoveredFunctions.insert(FunctionStr);\n    CoveredFiles.insert(FileStr);\n    CoveredDirs.insert(DirName(FileStr));\n    if (!CoveredLines.insert(FileStr + \":\" + LineStr).second)\n      continue;\n    Printf(\"COVERED: %s %s:%s\\n\", FunctionStr.c_str(),\n           FileStr.c_str(), LineStr.c_str());\n  }\n\n  std::string CoveredDirsStr;\n  for (auto &Dir : CoveredDirs) {\n    if (!CoveredDirsStr.empty())\n      CoveredDirsStr += \",\";\n    CoveredDirsStr += Dir;\n  }\n  Printf(\"COVERED_DIRS: %s\\n\", CoveredDirsStr.c_str());\n\n  for (auto &M : CoveredPCsPerModule) {\n    std::set<std::string> UncoveredFiles, UncoveredFunctions;\n    std::map<std::string, std::set<int> > UncoveredLines;  // Func+File => lines\n    auto &ModuleName = M.first;\n    auto &CoveredOffsets = M.second;\n    uintptr_t ModuleOffset = ModuleOffsets[ModuleName];\n    std::sort(CoveredOffsets.begin(), CoveredOffsets.end());\n    Printf(\"MODULE_WITH_COVERAGE: %s\\n\", ModuleName.c_str());\n    // sancov does not yet fully support DSOs.\n    // std::string Cmd = \"sancov -print-coverage-pcs \" + ModuleName;\n    std::string Cmd = \"objdump -d \" + ModuleName +\n        \" | grep 'call.*__sanitizer_cov_trace_pc_guard' | awk -F: '{print $1}'\";\n    std::string SanCovOutput;\n    if (!ExecuteCommandAndReadOutput(Cmd, &SanCovOutput)) {\n      Printf(\"INFO: Command failed: %s\\n\", Cmd.c_str());\n      continue;\n    }\n    std::istringstream ISS(SanCovOutput);\n    std::string S;\n    while (std::getline(ISS, S, '\\n')) {\n      uintptr_t PcOffset = std::stol(S, 0, 16);\n      if (!std::binary_search(CoveredOffsets.begin(), CoveredOffsets.end(),\n                              PcOffset)) {\n        uintptr_t PC = ModuleOffset + PcOffset;\n        auto FileStr = DescribePC(\"%s\", PC);\n        if (!IsInterestingCoverageFile(FileStr)) continue;\n        if (CoveredFiles.count(FileStr) == 0) {\n          UncoveredFiles.insert(FileStr);\n          continue;\n        }\n        auto FunctionStr = DescribePC(\"%F\", PC);\n        if (CoveredFunctions.count(FunctionStr) == 0) {\n          UncoveredFunctions.insert(FunctionStr);\n          continue;\n        }\n        std::string LineStr = DescribePC(\"%l\", PC);\n        uintptr_t Line = std::stoi(LineStr);\n        std::string FileLineStr = FileStr + \":\" + LineStr;\n        if (CoveredLines.count(FileLineStr) == 0)\n          UncoveredLines[FunctionStr + \" \" + FileStr].insert(Line);\n      }\n    }\n    for (auto &FileLine: UncoveredLines)\n      for (int Line : FileLine.second)\n        Printf(\"UNCOVERED_LINE: %s:%d\\n\", FileLine.first.c_str(), Line);\n    for (auto &Func : UncoveredFunctions)\n      Printf(\"UNCOVERED_FUNC: %s\\n\", Func.c_str());\n    for (auto &File : UncoveredFiles)\n      Printf(\"UNCOVERED_FILE: %s\\n\", File.c_str());\n  }\n}\n\nvoid TracePC::DumpCoverage() {\n  __sanitizer_dump_coverage(PCs, GetNumPCs());\n}\n\n// Value profile.\n// We keep track of various values that affect control flow.\n// These values are inserted into a bit-set-based hash map.\n// Every new bit in the map is treated as a new coverage.\n//\n// For memcmp/strcmp/etc the interesting value is the length of the common\n// prefix of the parameters.\n// For cmp instructions the interesting value is a XOR of the parameters.\n// The interesting value is mixed up with the PC and is then added to the map.\n\nATTRIBUTE_NO_SANITIZE_MEMORY\nvoid TracePC::AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,\n                              size_t n) {\n  if (!n) return;\n  size_t Len = std::min(n, (size_t)32);\n  const uint8_t *A1 = reinterpret_cast<const uint8_t *>(s1);\n  const uint8_t *A2 = reinterpret_cast<const uint8_t *>(s2);\n  size_t I = 0;\n  for (; I < Len; I++)\n    if (A1[I] != A2[I])\n      break;\n  size_t PC = reinterpret_cast<size_t>(caller_pc);\n  size_t Idx = I;\n  // if (I < Len)\n  //  Idx += __builtin_popcountl((A1[I] ^ A2[I])) - 1;\n  TPC.HandleValueProfile((PC & 4095) | (Idx << 12));\n}\n\nATTRIBUTE_NO_SANITIZE_MEMORY\nvoid TracePC::AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,\n                              size_t n) {\n  if (!n) return;\n  size_t Len = std::min(n, (size_t)32);\n  const uint8_t *A1 = reinterpret_cast<const uint8_t *>(s1);\n  const uint8_t *A2 = reinterpret_cast<const uint8_t *>(s2);\n  size_t I = 0;\n  for (; I < Len; I++)\n    if (A1[I] != A2[I] || A1[I] == 0)\n      break;\n  size_t PC = reinterpret_cast<size_t>(caller_pc);\n  size_t Idx = I;\n  // if (I < Len && A1[I])\n  //  Idx += __builtin_popcountl((A1[I] ^ A2[I])) - 1;\n  TPC.HandleValueProfile((PC & 4095) | (Idx << 12));\n}\n\ntemplate <class T>\nATTRIBUTE_TARGET_POPCNT\n#ifdef __clang__  // g++ can't handle this __attribute__ here :(\n__attribute__((always_inline))\n#endif  // __clang__\nvoid TracePC::HandleCmp(void *PC, T Arg1, T Arg2) {\n  uintptr_t PCuint = reinterpret_cast<uintptr_t>(PC);\n  uint64_t ArgXor = Arg1 ^ Arg2;\n  uint64_t ArgDistance = __builtin_popcountl(ArgXor) + 1; // [1,65]\n  uintptr_t Idx = ((PCuint & 4095) + 1) * ArgDistance;\n  if (sizeof(T) == 4)\n      TORC4.Insert(ArgXor, Arg1, Arg2);\n  else if (sizeof(T) == 8)\n      TORC8.Insert(ArgXor, Arg1, Arg2);\n  HandleValueProfile(Idx);\n}\n\n} // namespace fuzzer\n\nextern \"C\" {\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {\n  uintptr_t PC = (uintptr_t)__builtin_return_address(0);\n  fuzzer::TPC.HandleTrace(Guard, PC);\n}\n\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_pc_guard_init(uint32_t *Start, uint32_t *Stop) {\n  fuzzer::TPC.HandleInit(Start, Stop);\n}\n\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_pc_indir(uintptr_t Callee) {\n  uintptr_t PC = (uintptr_t)__builtin_return_address(0);\n  fuzzer::TPC.HandleCallerCallee(PC, Callee);\n}\n\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {\n  fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2);\n}\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {\n  fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2);\n}\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {\n  fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2);\n}\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {\n  fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2);\n}\n\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) {\n  // Updates the value profile based on the relative position of Val and Cases.\n  // We want to handle one random case at every call (handling all is slow).\n  // Since none of the arguments contain any random bits we use a thread-local\n  // counter to choose the random case to handle.\n  static thread_local size_t Counter;\n  Counter++;\n  uint64_t N = Cases[0];\n  uint64_t *Vals = Cases + 2;\n  char *PC = (char*)__builtin_return_address(0);\n  // We need a random number < N using Counter as a seed. But w/o DIV.\n  // * find a power of two >= N\n  // * mask Counter with this power of two.\n  // * maybe subtract N.\n  size_t Nlog = sizeof(long) * 8 - __builtin_clzl((long)N);\n  size_t PowerOfTwoGeN = 1U << Nlog;\n  assert(PowerOfTwoGeN >= N);\n  size_t Idx = Counter & (PowerOfTwoGeN - 1);\n  if (Idx >= N)\n    Idx -= N;\n  assert(Idx < N);\n  uint64_t TwoIn32 = 1ULL << 32;\n  if ((Val | Vals[Idx]) < TwoIn32)\n    fuzzer::TPC.HandleCmp(PC + Idx, static_cast<uint32_t>(Val),\n                          static_cast<uint32_t>(Vals[Idx]));\n  else\n    fuzzer::TPC.HandleCmp(PC + Idx, Val, Vals[Idx]);\n}\n\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_div4(uint32_t Val) {\n  fuzzer::TPC.HandleCmp(__builtin_return_address(0), Val, (uint32_t)0);\n}\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_div8(uint64_t Val) {\n  fuzzer::TPC.HandleCmp(__builtin_return_address(0), Val, (uint64_t)0);\n}\n__attribute__((visibility(\"default\")))\nvoid __sanitizer_cov_trace_gep(uintptr_t Idx) {\n  fuzzer::TPC.HandleCmp(__builtin_return_address(0), Idx, (uintptr_t)0);\n}\n\n}  // extern \"C\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerTracePC.h",
    "content": "//===- FuzzerTracePC.h - Internal header for the Fuzzer ---------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// fuzzer::TracePC\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_TRACE_PC\n#define LLVM_FUZZER_TRACE_PC\n\n#include \"FuzzerDefs.h\"\n#include \"FuzzerValueBitMap.h\"\n#include <set>\n\nnamespace fuzzer {\n\n// TableOfRecentCompares (TORC) remembers the most recently performed\n// comparisons of type T.\n// We record the arguments of CMP instructions in this table unconditionally\n// because it seems cheaper this way than to compute some expensive\n// conditions inside __sanitizer_cov_trace_cmp*.\n// After the unit has been executed we may decide to use the contents of\n// this table to populate a Dictionary.\ntemplate<class T, size_t kSizeT>\nstruct TableOfRecentCompares {\n  static const size_t kSize = kSizeT;\n  struct Pair {\n    T A, B;\n  };\n  void Insert(size_t Idx, T Arg1, T Arg2) {\n    Idx = Idx % kSize;\n    Table[Idx].A = Arg1;\n    Table[Idx].B = Arg2;\n  }\n\n  Pair Get(size_t I) { return Table[I % kSize]; }\n\n  Pair Table[kSize];\n};\n\nclass TracePC {\n public:\n  static const size_t kFeatureSetSize = ValueBitMap::kNumberOfItems;\n\n  void HandleTrace(uint32_t *guard, uintptr_t PC);\n  void HandleInit(uint32_t *start, uint32_t *stop);\n  void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);\n  void HandleValueProfile(size_t Value) { ValueProfileMap.AddValue(Value); }\n  template <class T> void HandleCmp(void *PC, T Arg1, T Arg2);\n  size_t GetTotalPCCoverage();\n  void SetUseCounters(bool UC) { UseCounters = UC; }\n  void SetUseValueProfile(bool VP) { UseValueProfile = VP; }\n  void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }\n  template <class Callback> size_t CollectFeatures(Callback CB);\n  bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {\n    return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap);\n  }\n\n  void ResetMaps() {\n    ValueProfileMap.Reset();\n    memset(Counters, 0, sizeof(Counters));\n  }\n\n  void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize);\n  void PrintFeatureSet();\n\n  void PrintModuleInfo();\n\n  void PrintCoverage();\n  void DumpCoverage();\n\n  void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,\n                         size_t n);\n  void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,\n                         size_t n);\n\n  bool UsingTracePcGuard() const {return NumModules; }\n\n  static const size_t kTORCSize = 1 << 5;\n  TableOfRecentCompares<uint32_t, kTORCSize> TORC4;\n  TableOfRecentCompares<uint64_t, kTORCSize> TORC8;\n\n  void PrintNewPCs();\n  size_t GetNumPCs() const { return Min(kNumPCs, NumGuards + 1); }\n  uintptr_t GetPC(size_t Idx) {\n    assert(Idx < GetNumPCs());\n    return PCs[Idx];\n  }\n\nprivate:\n  bool UseCounters = false;\n  bool UseValueProfile = false;\n  bool DoPrintNewPCs = false;\n\n  struct Module {\n    uint32_t *Start, *Stop;\n  };\n\n  Module Modules[4096];\n  size_t NumModules;  // linker-initialized.\n  size_t NumGuards;  // linker-initialized.\n\n  static const size_t kNumCounters = 1 << 14;\n  alignas(8) uint8_t Counters[kNumCounters];\n\n  static const size_t kNumPCs = 1 << 24;\n  uintptr_t PCs[kNumPCs];\n\n  std::set<uintptr_t> *PrintedPCs;\n\n  ValueBitMap ValueProfileMap;\n};\n\ntemplate <class Callback>\nsize_t TracePC::CollectFeatures(Callback CB) {\n  if (!UsingTracePcGuard()) return 0;\n  size_t Res = 0;\n  const size_t Step = 8;\n  assert(reinterpret_cast<uintptr_t>(Counters) % Step == 0);\n  size_t N = Min(kNumCounters, NumGuards + 1);\n  N = (N + Step - 1) & ~(Step - 1);  // Round up.\n  for (size_t Idx = 0; Idx < N; Idx += Step) {\n    uint64_t Bundle = *reinterpret_cast<uint64_t*>(&Counters[Idx]);\n    if (!Bundle) continue;\n    for (size_t i = Idx; i < Idx + Step; i++) {\n      uint8_t Counter = (Bundle >> ((i - Idx) * 8)) & 0xff;\n      if (!Counter) continue;\n      Counters[i] = 0;\n      unsigned Bit = 0;\n      /**/ if (Counter >= 128) Bit = 7;\n      else if (Counter >= 32) Bit = 6;\n      else if (Counter >= 16) Bit = 5;\n      else if (Counter >= 8) Bit = 4;\n      else if (Counter >= 4) Bit = 3;\n      else if (Counter >= 3) Bit = 2;\n      else if (Counter >= 2) Bit = 1;\n      size_t Feature = (i * 8 + Bit);\n      if (CB(Feature))\n        Res++;\n    }\n  }\n  if (UseValueProfile)\n    ValueProfileMap.ForEach([&](size_t Idx) {\n      if (CB(NumGuards * 8 + Idx))\n        Res++;\n    });\n  return Res;\n}\n\nextern TracePC TPC;\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_TRACE_PC\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerTraceState.cpp",
    "content": "//===- FuzzerTraceState.cpp - Trace-based fuzzer mutator ------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Data tracing.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerDictionary.h\"\n#include \"FuzzerInternal.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerMutate.h\"\n#include \"FuzzerRandom.h\"\n#include \"FuzzerTracePC.h\"\n#include <algorithm>\n#include <cstring>\n#include <map>\n#include <set>\n#include <thread>\n\nnamespace fuzzer {\n\n// For now, very simple: put Size bytes of Data at position Pos.\nstruct TraceBasedMutation {\n  uint32_t Pos;\n  Word W;\n};\n\n// Declared as static globals for faster checks inside the hooks.\nstatic bool RecordingMemcmp = false;\nstatic bool RecordingMemmem = false;\nstatic bool DoingMyOwnMemmem = false;\n\nScopedDoingMyOwnMemmem::ScopedDoingMyOwnMemmem() { DoingMyOwnMemmem = true; }\nScopedDoingMyOwnMemmem::~ScopedDoingMyOwnMemmem() { DoingMyOwnMemmem = false; }\n\nclass TraceState {\npublic:\n  TraceState(MutationDispatcher &MD, const FuzzingOptions &Options,\n             const Fuzzer *F)\n      : MD(MD), Options(Options), F(F) {}\n\n  void TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,\n                           const uint8_t *Data2);\n\n  void TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits, uint64_t Val,\n                           size_t NumCases, uint64_t *Cases);\n  int TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,\n                          size_t DataSize);\n  int TryToAddDesiredData(const uint8_t *PresentData,\n                          const uint8_t *DesiredData, size_t DataSize);\n\n  void StartTraceRecording() {\n    if (!Options.UseMemcmp)\n      return;\n    RecordingMemcmp = Options.UseMemcmp;\n    RecordingMemmem = Options.UseMemmem;\n    NumMutations = 0;\n    InterestingWords.clear();\n    MD.ClearAutoDictionary();\n  }\n\n  void StopTraceRecording() {\n    if (!RecordingMemcmp)\n      return;\n    RecordingMemcmp = false;\n    for (size_t i = 0; i < NumMutations; i++) {\n      auto &M = Mutations[i];\n      if (Options.Verbosity >= 2) {\n        AutoDictUnitCounts[M.W]++;\n        AutoDictAdds++;\n        if ((AutoDictAdds & (AutoDictAdds - 1)) == 0) {\n          typedef std::pair<size_t, Word> CU;\n          std::vector<CU> CountedUnits;\n          for (auto &I : AutoDictUnitCounts)\n            CountedUnits.push_back(std::make_pair(I.second, I.first));\n          std::sort(CountedUnits.begin(), CountedUnits.end(),\n                    [](const CU &a, const CU &b) { return a.first > b.first; });\n          Printf(\"AutoDict:\\n\");\n          for (auto &I : CountedUnits) {\n            Printf(\"   %zd \", I.first);\n            PrintASCII(I.second.data(), I.second.size());\n            Printf(\"\\n\");\n          }\n        }\n      }\n      MD.AddWordToAutoDictionary({M.W, M.Pos});\n    }\n    for (auto &W : InterestingWords)\n      MD.AddWordToAutoDictionary({W});\n  }\n\n  void AddMutation(uint32_t Pos, uint32_t Size, const uint8_t *Data) {\n    if (NumMutations >= kMaxMutations) return;\n    auto &M = Mutations[NumMutations++];\n    M.Pos = Pos;\n    M.W.Set(Data, Size);\n  }\n\n  void AddMutation(uint32_t Pos, uint32_t Size, uint64_t Data) {\n    assert(Size <= sizeof(Data));\n    AddMutation(Pos, Size, reinterpret_cast<uint8_t*>(&Data));\n  }\n\n  void AddInterestingWord(const uint8_t *Data, size_t Size) {\n    if (!RecordingMemmem || !F->InFuzzingThread()) return;\n    if (Size <= 1) return;\n    Size = std::min(Size, Word::GetMaxSize());\n    Word W(Data, Size);\n    InterestingWords.insert(W);\n  }\n\n private:\n  bool IsTwoByteData(uint64_t Data) {\n    int64_t Signed = static_cast<int64_t>(Data);\n    Signed >>= 16;\n    return Signed == 0 || Signed == -1L;\n  }\n\n  // We don't want to create too many trace-based mutations as it is both\n  // expensive and useless. So after some number of mutations is collected,\n  // start rejecting some of them. The more there are mutations the more we\n  // reject.\n  bool WantToHandleOneMoreMutation() {\n    const size_t FirstN = 64;\n    // Gladly handle first N mutations.\n    if (NumMutations <= FirstN) return true;\n    size_t Diff = NumMutations - FirstN;\n    size_t DiffLog = sizeof(long) * 8 - __builtin_clzl((long)Diff);\n    assert(DiffLog > 0 && DiffLog < 64);\n    bool WantThisOne = MD.GetRand()(1 << DiffLog) == 0;  // 1 out of DiffLog.\n    return WantThisOne;\n  }\n\n  static const size_t kMaxMutations = 1 << 16;\n  size_t NumMutations;\n  TraceBasedMutation Mutations[kMaxMutations];\n  // TODO: std::set is too inefficient, need to have a custom DS here.\n  std::set<Word> InterestingWords;\n  MutationDispatcher &MD;\n  const FuzzingOptions Options;\n  const Fuzzer *F;\n  std::map<Word, size_t> AutoDictUnitCounts;\n  size_t AutoDictAdds = 0;\n};\n\nint TraceState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,\n                                    size_t DataSize) {\n  if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;\n  ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;\n  const uint8_t *UnitData;\n  auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);\n  int Res = 0;\n  const uint8_t *Beg = UnitData;\n  const uint8_t *End = Beg + UnitSize;\n  for (const uint8_t *Cur = Beg; Cur < End; Cur++) {\n    Cur = (uint8_t *)SearchMemory(Cur, End - Cur, &PresentData, DataSize);\n    if (!Cur)\n      break;\n    size_t Pos = Cur - Beg;\n    assert(Pos < UnitSize);\n    AddMutation(Pos, DataSize, DesiredData);\n    AddMutation(Pos, DataSize, DesiredData + 1);\n    AddMutation(Pos, DataSize, DesiredData - 1);\n    Res++;\n  }\n  return Res;\n}\n\nint TraceState::TryToAddDesiredData(const uint8_t *PresentData,\n                                    const uint8_t *DesiredData,\n                                    size_t DataSize) {\n  if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;\n  ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;\n  const uint8_t *UnitData;\n  auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);\n  int Res = 0;\n  const uint8_t *Beg = UnitData;\n  const uint8_t *End = Beg + UnitSize;\n  for (const uint8_t *Cur = Beg; Cur < End; Cur++) {\n    Cur = (uint8_t *)SearchMemory(Cur, End - Cur, PresentData, DataSize);\n    if (!Cur)\n      break;\n    size_t Pos = Cur - Beg;\n    assert(Pos < UnitSize);\n    AddMutation(Pos, DataSize, DesiredData);\n    Res++;\n  }\n  return Res;\n}\n\nvoid TraceState::TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,\n                                     const uint8_t *Data2) {\n  if (!RecordingMemcmp || !F->InFuzzingThread()) return;\n  CmpSize = std::min(CmpSize, Word::GetMaxSize());\n  int Added2 = TryToAddDesiredData(Data1, Data2, CmpSize);\n  int Added1 = TryToAddDesiredData(Data2, Data1, CmpSize);\n  if ((Added1 || Added2) && Options.Verbosity >= 3) {\n    Printf(\"MemCmp Added %d%d: \", Added1, Added2);\n    if (Added1) PrintASCII(Data1, CmpSize);\n    if (Added2) PrintASCII(Data2, CmpSize);\n    Printf(\"\\n\");\n  }\n}\n\nvoid TraceState::TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits,\n                                     uint64_t Val, size_t NumCases,\n                                     uint64_t *Cases) {\n  if (F->InFuzzingThread()) return;\n  size_t ValSize = ValSizeInBits / 8;\n  bool TryShort = IsTwoByteData(Val);\n  for (size_t i = 0; i < NumCases; i++)\n    TryShort &= IsTwoByteData(Cases[i]);\n\n  if (Options.Verbosity >= 3)\n    Printf(\"TraceSwitch: %p %zd # %zd; TryShort %d\\n\", PC, Val, NumCases,\n           TryShort);\n\n  for (size_t i = 0; i < NumCases; i++) {\n    TryToAddDesiredData(Val, Cases[i], ValSize);\n    if (TryShort)\n      TryToAddDesiredData(Val, Cases[i], 2);\n  }\n}\n\nstatic TraceState *TS;\n\nvoid Fuzzer::StartTraceRecording() {\n  if (!TS) return;\n  TS->StartTraceRecording();\n}\n\nvoid Fuzzer::StopTraceRecording() {\n  if (!TS) return;\n  TS->StopTraceRecording();\n}\n\nvoid Fuzzer::InitializeTraceState() {\n  if (!Options.UseMemcmp) return;\n  TS = new TraceState(MD, Options, this);\n}\n\nstatic size_t InternalStrnlen(const char *S, size_t MaxLen) {\n  size_t Len = 0;\n  for (; Len < MaxLen && S[Len]; Len++) {}\n  return Len;\n}\n\n}  // namespace fuzzer\n\nusing fuzzer::TS;\nusing fuzzer::RecordingMemcmp;\n\nextern \"C\" {\n\n// We may need to avoid defining weak hooks to stay compatible with older clang.\n#ifndef LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS\n# define LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS 1\n#endif\n\n#if LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS\nvoid __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,\n                                  const void *s2, size_t n, int result) {\n  fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, n);\n  if (!RecordingMemcmp) return;\n  if (result == 0) return;  // No reason to mutate.\n  if (n <= 1) return;  // Not interesting.\n  TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),\n                          reinterpret_cast<const uint8_t *>(s2));\n}\n\nvoid __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,\n                                   const char *s2, size_t n, int result) {\n  fuzzer::TPC.AddValueForStrcmp(caller_pc, s1, s2, n);\n  if (!RecordingMemcmp) return;\n  if (result == 0) return;  // No reason to mutate.\n  size_t Len1 = fuzzer::InternalStrnlen(s1, n);\n  size_t Len2 = fuzzer::InternalStrnlen(s2, n);\n  n = std::min(n, Len1);\n  n = std::min(n, Len2);\n  if (n <= 1) return;  // Not interesting.\n  TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),\n                          reinterpret_cast<const uint8_t *>(s2));\n}\n\nvoid __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,\n                                   const char *s2, int result) {\n  fuzzer::TPC.AddValueForStrcmp(caller_pc, s1, s2, 64);\n  if (!RecordingMemcmp) return;\n  if (result == 0) return;  // No reason to mutate.\n  size_t Len1 = strlen(s1);\n  size_t Len2 = strlen(s2);\n  size_t N = std::min(Len1, Len2);\n  if (N <= 1) return;  // Not interesting.\n  TS->TraceMemcmpCallback(N, reinterpret_cast<const uint8_t *>(s1),\n                          reinterpret_cast<const uint8_t *>(s2));\n}\n\nvoid __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,\n                                       const char *s2, size_t n, int result) {\n  return __sanitizer_weak_hook_strncmp(called_pc, s1, s2, n, result);\n}\nvoid __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,\n                                      const char *s2, int result) {\n  return __sanitizer_weak_hook_strcmp(called_pc, s1, s2, result);\n}\nvoid __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,\n                                  const char *s2, char *result) {\n  TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));\n}\nvoid __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,\n                                      const char *s2, char *result) {\n  TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));\n}\nvoid __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,\n                                  const void *s2, size_t len2, void *result) {\n  if (fuzzer::DoingMyOwnMemmem) return;\n  TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), len2);\n}\n\n#endif  // LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS\n}  // extern \"C\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerUtil.cpp",
    "content": "//===- FuzzerUtil.cpp - Misc utils ----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Misc utils.\n//===----------------------------------------------------------------------===//\n\n#include \"FuzzerUtil.h\"\n#include \"FuzzerIO.h\"\n#include \"FuzzerInternal.h\"\n#include <cassert>\n#include <chrono>\n#include <cstring>\n#include <errno.h>\n#include <signal.h>\n#include <sstream>\n#include <stdio.h>\n#include <sys/types.h>\n#include <thread>\n\nnamespace fuzzer {\n\nvoid PrintHexArray(const uint8_t *Data, size_t Size,\n                   const char *PrintAfter) {\n  for (size_t i = 0; i < Size; i++)\n    Printf(\"0x%x,\", (unsigned)Data[i]);\n  Printf(\"%s\", PrintAfter);\n}\n\nvoid Print(const Unit &v, const char *PrintAfter) {\n  PrintHexArray(v.data(), v.size(), PrintAfter);\n}\n\nvoid PrintASCIIByte(uint8_t Byte) {\n  if (Byte == '\\\\')\n    Printf(\"\\\\\\\\\");\n  else if (Byte == '\"')\n    Printf(\"\\\\\\\"\");\n  else if (Byte >= 32 && Byte < 127)\n    Printf(\"%c\", Byte);\n  else\n    Printf(\"\\\\x%02x\", Byte);\n}\n\nvoid PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter) {\n  for (size_t i = 0; i < Size; i++)\n    PrintASCIIByte(Data[i]);\n  Printf(\"%s\", PrintAfter);\n}\n\nvoid PrintASCII(const Unit &U, const char *PrintAfter) {\n  PrintASCII(U.data(), U.size(), PrintAfter);\n}\n\nbool ToASCII(uint8_t *Data, size_t Size) {\n  bool Changed = false;\n  for (size_t i = 0; i < Size; i++) {\n    uint8_t &X = Data[i];\n    auto NewX = X;\n    NewX &= 127;\n    if (!isspace(NewX) && !isprint(NewX))\n      NewX = ' ';\n    Changed |= NewX != X;\n    X = NewX;\n  }\n  return Changed;\n}\n\nbool IsASCII(const Unit &U) { return IsASCII(U.data(), U.size()); }\n\nbool IsASCII(const uint8_t *Data, size_t Size) {\n  for (size_t i = 0; i < Size; i++)\n    if (!(isprint(Data[i]) || isspace(Data[i]))) return false;\n  return true;\n}\n\nbool ParseOneDictionaryEntry(const std::string &Str, Unit *U) {\n  U->clear();\n  if (Str.empty()) return false;\n  size_t L = 0, R = Str.size() - 1;  // We are parsing the range [L,R].\n  // Skip spaces from both sides.\n  while (L < R && isspace(Str[L])) L++;\n  while (R > L && isspace(Str[R])) R--;\n  if (R - L < 2) return false;\n  // Check the closing \"\n  if (Str[R] != '\"') return false;\n  R--;\n  // Find the opening \"\n  while (L < R && Str[L] != '\"') L++;\n  if (L >= R) return false;\n  assert(Str[L] == '\\\"');\n  L++;\n  assert(L <= R);\n  for (size_t Pos = L; Pos <= R; Pos++) {\n    uint8_t V = (uint8_t)Str[Pos];\n    if (!isprint(V) && !isspace(V)) return false;\n    if (V =='\\\\') {\n      // Handle '\\\\'\n      if (Pos + 1 <= R && (Str[Pos + 1] == '\\\\' || Str[Pos + 1] == '\"')) {\n        U->push_back(Str[Pos + 1]);\n        Pos++;\n        continue;\n      }\n      // Handle '\\xAB'\n      if (Pos + 3 <= R && Str[Pos + 1] == 'x'\n           && isxdigit(Str[Pos + 2]) && isxdigit(Str[Pos + 3])) {\n        char Hex[] = \"0xAA\";\n        Hex[2] = Str[Pos + 2];\n        Hex[3] = Str[Pos + 3];\n        U->push_back(strtol(Hex, nullptr, 16));\n        Pos += 3;\n        continue;\n      }\n      return false;  // Invalid escape.\n    } else {\n      // Any other character.\n      U->push_back(V);\n    }\n  }\n  return true;\n}\n\nbool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units) {\n  if (Text.empty()) {\n    Printf(\"ParseDictionaryFile: file does not exist or is empty\\n\");\n    return false;\n  }\n  std::istringstream ISS(Text);\n  Units->clear();\n  Unit U;\n  int LineNo = 0;\n  std::string S;\n  while (std::getline(ISS, S, '\\n')) {\n    LineNo++;\n    size_t Pos = 0;\n    while (Pos < S.size() && isspace(S[Pos])) Pos++;  // Skip spaces.\n    if (Pos == S.size()) continue;  // Empty line.\n    if (S[Pos] == '#') continue;  // Comment line.\n    if (ParseOneDictionaryEntry(S, &U)) {\n      Units->push_back(U);\n    } else {\n      Printf(\"ParseDictionaryFile: error in line %d\\n\\t\\t%s\\n\", LineNo,\n             S.c_str());\n      return false;\n    }\n  }\n  return true;\n}\n\nstd::string Base64(const Unit &U) {\n  static const char Table[] = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n                              \"abcdefghijklmnopqrstuvwxyz\"\n                              \"0123456789+/\";\n  std::string Res;\n  size_t i;\n  for (i = 0; i + 2 < U.size(); i += 3) {\n    uint32_t x = (U[i] << 16) + (U[i + 1] << 8) + U[i + 2];\n    Res += Table[(x >> 18) & 63];\n    Res += Table[(x >> 12) & 63];\n    Res += Table[(x >> 6) & 63];\n    Res += Table[x & 63];\n  }\n  if (i + 1 == U.size()) {\n    uint32_t x = (U[i] << 16);\n    Res += Table[(x >> 18) & 63];\n    Res += Table[(x >> 12) & 63];\n    Res += \"==\";\n  } else if (i + 2 == U.size()) {\n    uint32_t x = (U[i] << 16) + (U[i + 1] << 8);\n    Res += Table[(x >> 18) & 63];\n    Res += Table[(x >> 12) & 63];\n    Res += Table[(x >> 6) & 63];\n    Res += \"=\";\n  }\n  return Res;\n}\n\nstd::string DescribePC(const char *SymbolizedFMT, uintptr_t PC) {\n  if (!EF->__sanitizer_symbolize_pc) return \"<can not symbolize>\";\n  char PcDescr[1024];\n  EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PC),\n                               SymbolizedFMT, PcDescr, sizeof(PcDescr));\n  PcDescr[sizeof(PcDescr) - 1] = 0;  // Just in case.\n  return PcDescr;\n}\n\nvoid PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC) {\n  if (EF->__sanitizer_symbolize_pc)\n    Printf(\"%s\", DescribePC(SymbolizedFMT, PC).c_str());\n  else\n    Printf(FallbackFMT, PC);\n}\n\nunsigned NumberOfCpuCores() {\n  unsigned N = std::thread::hardware_concurrency();\n  if (!N) {\n    Printf(\"WARNING: std::thread::hardware_concurrency not well defined for \"\n           \"your platform. Assuming CPU count of 1.\\n\");\n    N = 1;\n  }\n  return N;\n}\n\nbool ExecuteCommandAndReadOutput(const std::string &Command, std::string *Out) {\n  FILE *Pipe = OpenProcessPipe(Command.c_str(), \"r\");\n  if (!Pipe) return false;\n  char Buff[1024];\n  size_t N;\n  while ((N = fread(Buff, 1, sizeof(Buff), Pipe)) > 0)\n    Out->append(Buff, N);\n  return true;\n}\n\n}  // namespace fuzzer\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerUtil.h",
    "content": "//===- FuzzerUtil.h - Internal header for the Fuzzer Utils ------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Util functions.\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_UTIL_H\n#define LLVM_FUZZER_UTIL_H\n\n#include \"FuzzerDefs.h\"\n\nnamespace fuzzer {\n\nvoid PrintHexArray(const Unit &U, const char *PrintAfter = \"\");\n\nvoid PrintHexArray(const uint8_t *Data, size_t Size,\n                   const char *PrintAfter = \"\");\n\nvoid PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter = \"\");\n\nvoid PrintASCII(const Unit &U, const char *PrintAfter = \"\");\n\n// Changes U to contain only ASCII (isprint+isspace) characters.\n// Returns true iff U has been changed.\nbool ToASCII(uint8_t *Data, size_t Size);\n\nbool IsASCII(const Unit &U);\n\nbool IsASCII(const uint8_t *Data, size_t Size);\n\nstd::string Base64(const Unit &U);\n\nvoid PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC);\n\nstd::string DescribePC(const char *SymbolizedFMT, uintptr_t PC);\n\nunsigned NumberOfCpuCores();\n\nbool ExecuteCommandAndReadOutput(const std::string &Command, std::string *Out);\n\n// Platform specific functions.\nvoid SetSignalHandler(const FuzzingOptions& Options);\n\nvoid SleepSeconds(int Seconds);\n\nunsigned long GetPid();\n\nsize_t GetPeakRSSMb();\n\nint ExecuteCommand(const std::string &Command);\n\nFILE *OpenProcessPipe(const char *Command, const char *Mode);\n\nconst void *SearchMemory(const void *haystack, size_t haystacklen,\n                         const void *needle, size_t needlelen);\n\nstd::string CloneArgsWithoutX(const std::vector<std::string> &Args,\n                              const char *X1, const char *X2);\n\ninline std::string CloneArgsWithoutX(const std::vector<std::string> &Args,\n                                     const char *X) {\n  return CloneArgsWithoutX(Args, X, X);\n}\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_UTIL_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerUtilDarwin.cpp",
    "content": "//===- FuzzerUtilDarwin.cpp - Misc utils ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Misc utils for Darwin.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_APPLE\n\n#include \"FuzzerIO.h\"\n#include <mutex>\n#include <signal.h>\n#include <spawn.h>\n#include <sys/wait.h>\n\n// There is no header for this on macOS so declare here\nextern \"C\" char **environ;\n\nnamespace fuzzer {\n\nstatic std::mutex SignalMutex;\n// Global variables used to keep track of how signal handling should be\n// restored. They should **not** be accessed without holding `SignalMutex`.\nstatic int ActiveThreadCount = 0;\nstatic struct sigaction OldSigIntAction;\nstatic struct sigaction OldSigQuitAction;\nstatic sigset_t OldBlockedSignalsSet;\n\n// This is a reimplementation of Libc's `system()`. On Darwin the Libc\n// implementation contains a mutex which prevents it from being used\n// concurrently. This implementation **can** be used concurrently. It sets the\n// signal handlers when the first thread enters and restores them when the last\n// thread finishes execution of the function and ensures this is not racey by\n// using a mutex.\nint ExecuteCommand(const std::string &Command) {\n  posix_spawnattr_t SpawnAttributes;\n  if (posix_spawnattr_init(&SpawnAttributes))\n    return -1;\n  // Block and ignore signals of the current process when the first thread\n  // enters.\n  {\n    std::lock_guard<std::mutex> Lock(SignalMutex);\n    if (ActiveThreadCount == 0) {\n      static struct sigaction IgnoreSignalAction;\n      sigset_t BlockedSignalsSet;\n      memset(&IgnoreSignalAction, 0, sizeof(IgnoreSignalAction));\n      IgnoreSignalAction.sa_handler = SIG_IGN;\n\n      if (sigaction(SIGINT, &IgnoreSignalAction, &OldSigIntAction) == -1) {\n        Printf(\"Failed to ignore SIGINT\\n\");\n        (void)posix_spawnattr_destroy(&SpawnAttributes);\n        return -1;\n      }\n      if (sigaction(SIGQUIT, &IgnoreSignalAction, &OldSigQuitAction) == -1) {\n        Printf(\"Failed to ignore SIGQUIT\\n\");\n        // Try our best to restore the signal handlers.\n        (void)sigaction(SIGINT, &OldSigIntAction, NULL);\n        (void)posix_spawnattr_destroy(&SpawnAttributes);\n        return -1;\n      }\n\n      (void)sigemptyset(&BlockedSignalsSet);\n      (void)sigaddset(&BlockedSignalsSet, SIGCHLD);\n      if (sigprocmask(SIG_BLOCK, &BlockedSignalsSet, &OldBlockedSignalsSet) ==\n          -1) {\n        Printf(\"Failed to block SIGCHLD\\n\");\n        // Try our best to restore the signal handlers.\n        (void)sigaction(SIGQUIT, &OldSigQuitAction, NULL);\n        (void)sigaction(SIGINT, &OldSigIntAction, NULL);\n        (void)posix_spawnattr_destroy(&SpawnAttributes);\n        return -1;\n      }\n    }\n    ++ActiveThreadCount;\n  }\n\n  // NOTE: Do not introduce any new `return` statements past this\n  // point. It is important that `ActiveThreadCount` always be decremented\n  // when leaving this function.\n\n  // Make sure the child process uses the default handlers for the\n  // following signals rather than inheriting what the parent has.\n  sigset_t DefaultSigSet;\n  (void)sigemptyset(&DefaultSigSet);\n  (void)sigaddset(&DefaultSigSet, SIGQUIT);\n  (void)sigaddset(&DefaultSigSet, SIGINT);\n  (void)posix_spawnattr_setsigdefault(&SpawnAttributes, &DefaultSigSet);\n  // Make sure the child process doesn't block SIGCHLD\n  (void)posix_spawnattr_setsigmask(&SpawnAttributes, &OldBlockedSignalsSet);\n  short SpawnFlags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;\n  (void)posix_spawnattr_setflags(&SpawnAttributes, SpawnFlags);\n\n  pid_t Pid;\n  char **Environ = environ; // Read from global\n  const char *CommandCStr = Command.c_str();\n  const char *Argv[] = {\"sh\", \"-c\", CommandCStr, NULL};\n  int ErrorCode = 0, ProcessStatus = 0;\n  // FIXME: We probably shouldn't hardcode the shell path.\n  ErrorCode = posix_spawn(&Pid, \"/bin/sh\", NULL, &SpawnAttributes,\n                          (char *const *)Argv, Environ);\n  (void)posix_spawnattr_destroy(&SpawnAttributes);\n  if (!ErrorCode) {\n    pid_t SavedPid = Pid;\n    do {\n      // Repeat until call completes uninterrupted.\n      Pid = waitpid(SavedPid, &ProcessStatus, /*options=*/0);\n    } while (Pid == -1 && errno == EINTR);\n    if (Pid == -1) {\n      // Fail for some other reason.\n      ProcessStatus = -1;\n    }\n  } else if (ErrorCode == ENOMEM || ErrorCode == EAGAIN) {\n    // Fork failure.\n    ProcessStatus = -1;\n  } else {\n    // Shell execution failure.\n    ProcessStatus = W_EXITCODE(127, 0);\n  }\n\n  // Restore the signal handlers of the current process when the last thread\n  // using this function finishes.\n  {\n    std::lock_guard<std::mutex> Lock(SignalMutex);\n    --ActiveThreadCount;\n    if (ActiveThreadCount == 0) {\n      bool FailedRestore = false;\n      if (sigaction(SIGINT, &OldSigIntAction, NULL) == -1) {\n        Printf(\"Failed to restore SIGINT handling\\n\");\n        FailedRestore = true;\n      }\n      if (sigaction(SIGQUIT, &OldSigQuitAction, NULL) == -1) {\n        Printf(\"Failed to restore SIGQUIT handling\\n\");\n        FailedRestore = true;\n      }\n      if (sigprocmask(SIG_BLOCK, &OldBlockedSignalsSet, NULL) == -1) {\n        Printf(\"Failed to unblock SIGCHLD\\n\");\n        FailedRestore = true;\n      }\n      if (FailedRestore)\n        ProcessStatus = -1;\n    }\n  }\n  return ProcessStatus;\n}\n\n} // namespace fuzzer\n\n#endif // LIBFUZZER_APPLE\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerUtilLinux.cpp",
    "content": "//===- FuzzerUtilLinux.cpp - Misc utils for Linux. ------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Misc utils for Linux.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_LINUX\n\n#include <stdlib.h>\n\nnamespace fuzzer {\n\nint ExecuteCommand(const std::string &Command) {\n  return system(Command.c_str());\n}\n\n} // namespace fuzzer\n\n#endif // LIBFUZZER_LINUX\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerUtilPosix.cpp",
    "content": "//===- FuzzerUtilPosix.cpp - Misc utils for Posix. ------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Misc utils implementation using Posix API.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_POSIX\n#include \"FuzzerIO.h\"\n#include \"FuzzerInternal.h\"\n#include <cassert>\n#include <chrono>\n#include <cstring>\n#include <errno.h>\n#include <iomanip>\n#include <signal.h>\n#include <sstream>\n#include <stdio.h>\n#include <sys/resource.h>\n#include <sys/syscall.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <thread>\n#include <unistd.h>\n\nnamespace fuzzer {\n\nstatic void AlarmHandler(int, siginfo_t *, void *) {\n  Fuzzer::StaticAlarmCallback();\n}\n\nstatic void CrashHandler(int, siginfo_t *, void *) {\n  Fuzzer::StaticCrashSignalCallback();\n}\n\nstatic void InterruptHandler(int, siginfo_t *, void *) {\n  Fuzzer::StaticInterruptCallback();\n}\n\nstatic void SetSigaction(int signum,\n                         void (*callback)(int, siginfo_t *, void *)) {\n  struct sigaction sigact;\n  memset(&sigact, 0, sizeof(sigact));\n  sigact.sa_sigaction = callback;\n  if (sigaction(signum, &sigact, 0)) {\n    Printf(\"libFuzzer: sigaction failed with %d\\n\", errno);\n    exit(1);\n  }\n}\n\nvoid SetTimer(int Seconds) {\n  struct itimerval T {\n    {Seconds, 0}, { Seconds, 0 }\n  };\n  if (setitimer(ITIMER_REAL, &T, nullptr)) {\n    Printf(\"libFuzzer: setitimer failed with %d\\n\", errno);\n    exit(1);\n  }\n  SetSigaction(SIGALRM, AlarmHandler);\n}\n\nvoid SetSignalHandler(const FuzzingOptions& Options) {\n  if (Options.UnitTimeoutSec > 0)\n    SetTimer(Options.UnitTimeoutSec / 2 + 1);\n  if (Options.HandleInt)\n    SetSigaction(SIGINT, InterruptHandler);\n  if (Options.HandleTerm)\n    SetSigaction(SIGTERM, InterruptHandler);\n  if (Options.HandleSegv)\n    SetSigaction(SIGSEGV, CrashHandler);\n  if (Options.HandleBus)\n    SetSigaction(SIGBUS, CrashHandler);\n  if (Options.HandleAbrt)\n    SetSigaction(SIGABRT, CrashHandler);\n  if (Options.HandleIll)\n    SetSigaction(SIGILL, CrashHandler);\n  if (Options.HandleFpe)\n    SetSigaction(SIGFPE, CrashHandler);\n}\n\nvoid SleepSeconds(int Seconds) {\n  sleep(Seconds); // Use C API to avoid coverage from instrumented libc++.\n}\n\nunsigned long GetPid() { return (unsigned long)getpid(); }\n\nsize_t GetPeakRSSMb() {\n  struct rusage usage;\n  if (getrusage(RUSAGE_SELF, &usage))\n    return 0;\n  if (LIBFUZZER_LINUX) {\n    // ru_maxrss is in KiB\n    return usage.ru_maxrss >> 10;\n  } else if (LIBFUZZER_APPLE) {\n    // ru_maxrss is in bytes\n    return usage.ru_maxrss >> 20;\n  }\n  assert(0 && \"GetPeakRSSMb() is not implemented for your platform\");\n  return 0;\n}\n\nFILE *OpenProcessPipe(const char *Command, const char *Mode) {\n  return popen(Command, Mode);\n}\n\nconst void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,\n                         size_t PattLen) {\n  return memmem(Data, DataLen, Patt, PattLen);\n}\n\n}  // namespace fuzzer\n\n#endif // LIBFUZZER_POSIX\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerUtilWindows.cpp",
    "content": "//===- FuzzerUtilWindows.cpp - Misc utils for Windows. --------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Misc utils implementation for Windows.\n//===----------------------------------------------------------------------===//\n#include \"FuzzerDefs.h\"\n#if LIBFUZZER_WINDOWS\n#include \"FuzzerIO.h\"\n#include \"FuzzerInternal.h\"\n#include <cassert>\n#include <chrono>\n#include <cstring>\n#include <errno.h>\n#include <iomanip>\n#include <signal.h>\n#include <sstream>\n#include <stdio.h>\n#include <sys/types.h>\n#include <windows.h>\n#include <Psapi.h>\n\nnamespace fuzzer {\n\nstatic const FuzzingOptions* HandlerOpt = nullptr;\n\nLONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {\n  switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {\n    case EXCEPTION_ACCESS_VIOLATION:\n    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:\n    case EXCEPTION_STACK_OVERFLOW:\n      if (HandlerOpt->HandleSegv)\n        Fuzzer::StaticCrashSignalCallback();\n      break;\n    case EXCEPTION_DATATYPE_MISALIGNMENT:\n    case EXCEPTION_IN_PAGE_ERROR:\n      if (HandlerOpt->HandleBus)\n        Fuzzer::StaticCrashSignalCallback();\n      break;\n    case EXCEPTION_ILLEGAL_INSTRUCTION:\n    case EXCEPTION_PRIV_INSTRUCTION:\n      if (HandlerOpt->HandleIll)\n        Fuzzer::StaticCrashSignalCallback();\n      break;\n    case EXCEPTION_FLT_DENORMAL_OPERAND:\n    case EXCEPTION_FLT_DIVIDE_BY_ZERO:\n    case EXCEPTION_FLT_INEXACT_RESULT:\n    case EXCEPTION_FLT_INVALID_OPERATION:\n    case EXCEPTION_FLT_OVERFLOW:\n    case EXCEPTION_FLT_STACK_CHECK:\n    case EXCEPTION_FLT_UNDERFLOW:\n    case EXCEPTION_INT_DIVIDE_BY_ZERO:\n    case EXCEPTION_INT_OVERFLOW:\n      if (HandlerOpt->HandleFpe)\n        Fuzzer::StaticCrashSignalCallback();\n      break;\n  }\n  return EXCEPTION_CONTINUE_SEARCH;\n}\n\nBOOL WINAPI CtrlHandler(DWORD dwCtrlType) {\n  switch (dwCtrlType) {\n    case CTRL_C_EVENT:\n      if (HandlerOpt->HandleInt)\n        Fuzzer::StaticInterruptCallback();\n      return TRUE;\n    case CTRL_BREAK_EVENT:\n      if (HandlerOpt->HandleTerm)\n        Fuzzer::StaticInterruptCallback();\n      return TRUE;\n  }\n  return FALSE;\n}\n\nvoid CALLBACK AlarmHandler(PVOID, BOOLEAN) {\n  Fuzzer::StaticAlarmCallback();\n}\n\nclass TimerQ {\n  HANDLE TimerQueue;\n public:\n  TimerQ() : TimerQueue(NULL) {};\n  ~TimerQ() {\n    if (TimerQueue)\n      DeleteTimerQueueEx(TimerQueue, NULL);\n  };\n  void SetTimer(int Seconds) {\n    if (!TimerQueue) {\n      TimerQueue = CreateTimerQueue();\n      if (!TimerQueue) {\n        Printf(\"libFuzzer: CreateTimerQueue failed.\\n\");\n        exit(1);\n      }\n    }\n    HANDLE Timer;\n    if (!CreateTimerQueueTimer(&Timer, TimerQueue, AlarmHandler, NULL,\n        Seconds*1000, Seconds*1000, 0)) {\n      Printf(\"libFuzzer: CreateTimerQueueTimer failed.\\n\");\n      exit(1);\n    }\n  };\n};\n\nstatic TimerQ Timer;\n\nstatic void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); }\n\nvoid SetSignalHandler(const FuzzingOptions& Options) {\n  HandlerOpt = &Options;\n\n  if (Options.UnitTimeoutSec > 0)\n    Timer.SetTimer(Options.UnitTimeoutSec / 2 + 1);\n\n  if (Options.HandleInt || Options.HandleTerm)\n    if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) {\n      DWORD LastError = GetLastError();\n      Printf(\"libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\\n\",\n        LastError);\n      exit(1);\n    }\n\n  if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||\n      Options.HandleFpe)\n    if (!AddVectoredExceptionHandler(1, ExceptionHandler)) {\n      Printf(\"libFuzzer: AddVectoredExceptionHandler failed.\\n\");\n      exit(1);\n    }\n\n  if (Options.HandleAbrt)\n    if (SIG_ERR == signal(SIGABRT, CrashHandler)) {\n      Printf(\"libFuzzer: signal failed with %d\\n\", errno);\n      exit(1);\n    }\n}\n\nvoid SleepSeconds(int Seconds) { Sleep(Seconds * 1000); }\n\nunsigned long GetPid() { return GetCurrentProcessId(); }\n\nsize_t GetPeakRSSMb() {\n  PROCESS_MEMORY_COUNTERS info;\n  if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)))\n    return 0;\n  return info.PeakWorkingSetSize >> 20;\n}\n\nFILE *OpenProcessPipe(const char *Command, const char *Mode) {\n  return _popen(Command, Mode);\n}\n\nint ExecuteCommand(const std::string &Command) {\n  return system(Command.c_str());\n}\n\nconst void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,\n                         size_t PattLen) {\n  // TODO: make this implementation more efficient.\n  const char *Cdata = (const char *)Data;\n  const char *Cpatt = (const char *)Patt;\n\n  if (!Data || !Patt || DataLen == 0 || PattLen == 0 || DataLen < PattLen)\n    return NULL;\n\n  if (PattLen == 1)\n    return memchr(Data, *Cpatt, DataLen);\n\n  const char *End = Cdata + DataLen - PattLen + 1;\n\n  for (const char *It = Cdata; It < End; ++It)\n    if (It[0] == Cpatt[0] && memcmp(It, Cpatt, PattLen) == 0)\n      return It;\n\n  return NULL;\n}\n\n} // namespace fuzzer\n\n#endif // LIBFUZZER_WINDOWS\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/FuzzerValueBitMap.h",
    "content": "//===- FuzzerValueBitMap.h - INTERNAL - Bit map -----------------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// ValueBitMap.\n//===----------------------------------------------------------------------===//\n\n#ifndef LLVM_FUZZER_VALUE_BIT_MAP_H\n#define LLVM_FUZZER_VALUE_BIT_MAP_H\n\n#include \"FuzzerDefs.h\"\n\nnamespace fuzzer {\n\n// A bit map containing kMapSizeInWords bits.\nstruct ValueBitMap {\n  static const size_t kMapSizeInBits = 65371;        // Prime.\n  static const size_t kMapSizeInBitsAligned = 65536; // 2^16\n  static const size_t kBitsInWord = (sizeof(uintptr_t) * 8);\n  static const size_t kMapSizeInWords = kMapSizeInBitsAligned / kBitsInWord;\n public:\n  static const size_t kNumberOfItems = kMapSizeInBits;\n  // Clears all bits.\n  void Reset() { memset(Map, 0, sizeof(Map)); }\n\n  // Computes a hash function of Value and sets the corresponding bit.\n  // Returns true if the bit was changed from 0 to 1.\n  inline bool AddValue(uintptr_t Value) {\n    uintptr_t Idx = Value < kMapSizeInBits ? Value : Value % kMapSizeInBits;\n    uintptr_t WordIdx = Idx / kBitsInWord;\n    uintptr_t BitIdx = Idx % kBitsInWord;\n    uintptr_t Old = Map[WordIdx];\n    uintptr_t New = Old | (1UL << BitIdx);\n    Map[WordIdx] = New;\n    return New != Old;\n  }\n\n  inline bool Get(uintptr_t Idx) {\n    assert(Idx < kMapSizeInBits);\n    uintptr_t WordIdx = Idx / kBitsInWord;\n    uintptr_t BitIdx = Idx % kBitsInWord;\n    return Map[WordIdx] & (1UL << BitIdx);\n  }\n\n  size_t GetNumBitsSinceLastMerge() const { return NumBits; }\n\n  // Merges 'Other' into 'this', clears 'Other', updates NumBits,\n  // returns true if new bits were added.\n  ATTRIBUTE_TARGET_POPCNT\n  bool MergeFrom(ValueBitMap &Other) {\n    uintptr_t Res = 0;\n    size_t OldNumBits = NumBits;\n    for (size_t i = 0; i < kMapSizeInWords; i++) {\n      auto O = Other.Map[i];\n      auto M = Map[i];\n      if (O) {\n        Map[i] = (M |= O);\n        Other.Map[i] = 0;\n      }\n      if (M)\n        Res += __builtin_popcountl(M);\n    }\n    NumBits = Res;\n    return OldNumBits < NumBits;\n  }\n\n  template <class Callback>\n  void ForEach(Callback CB) {\n    for (size_t i = 0; i < kMapSizeInWords; i++)\n      if (uintptr_t M = Map[i])\n        for (size_t j = 0; j < sizeof(M) * 8; j++)\n          if (M & ((uintptr_t)1 << j))\n            CB(i * sizeof(M) * 8 + j);\n  }\n\n private:\n  size_t NumBits = 0;\n  uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512)));\n};\n\n}  // namespace fuzzer\n\n#endif  // LLVM_FUZZER_VALUE_BIT_MAP_H\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/README.txt",
    "content": "Move to http://llvm.org/docs/LibFuzzer.html\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/afl/afl_driver.cpp",
    "content": "//===- afl_driver.cpp - a glue between AFL and libFuzzer --------*- C++ -* ===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//===----------------------------------------------------------------------===//\n\n/* This file allows to fuzz libFuzzer-style target functions\n (LLVMFuzzerTestOneInput) with AFL using AFL's persistent (in-process) mode.\n\nUsage:\n################################################################################\ncat << EOF > test_fuzzer.cc\n#include <stdint.h>\n#include <stddef.h>\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {\n  if (size > 0 && data[0] == 'H')\n    if (size > 1 && data[1] == 'I')\n       if (size > 2 && data[2] == '!')\n       __builtin_trap();\n  return 0;\n}\nEOF\n# Build your target with -fsanitize-coverage=trace-pc using fresh clang.\nclang -g -fsanitize-coverage=trace-pc test_fuzzer.cc -c\n# Build afl-llvm-rt.o.c from the AFL distribution.\nclang -c -w $AFL_HOME/llvm_mode/afl-llvm-rt.o.c\n# Build this file, link it with afl-llvm-rt.o.o and the target code.\nclang++ afl_driver.cpp test_fuzzer.o afl-llvm-rt.o.o\n# Run AFL:\nrm -rf IN OUT; mkdir IN OUT; echo z > IN/z;\n$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out\n################################################################################\nEnvironment Variables:\nThere are a few environment variables that can be set to use features that\nafl-fuzz doesn't have.\n\nAFL_DRIVER_STDERR_DUPLICATE_FILENAME: Setting this *appends* stderr to the file\nspecified. If the file does not exist, it is created. This is useful for getting\nstack traces (when using ASAN for example) or original error messages on hard to\nreproduce bugs.\n\nAFL_DRIVER_EXTRA_STATS_FILENAME: Setting this causes afl_driver to write extra\nstatistics to the file specified. Currently these are peak_rss_mb\n(the peak amount of virtual memory used in MB) and slowest_unit_time_secs. If\nthe file does not exist it is created. If the file does exist then\nafl_driver assumes it was restarted by afl-fuzz and will try to read old\nstatistics from the file. If that fails then the process will quit.\n\n*/\n#include <assert.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <errno.h>\n#include <signal.h>\n#include <sys/resource.h>\n#include <sys/time.h>\n// Platform detection. Copied from FuzzerInternal.h\n#ifdef __linux__\n#define LIBFUZZER_LINUX 1\n#define LIBFUZZER_APPLE 0\n#elif __APPLE__\n#define LIBFUZZER_LINUX 0\n#define LIBFUZZER_APPLE 1\n#else\n#error \"Support for your platform has not been implemented\"\n#endif\n\n// Used to avoid repeating error checking boilerplate. If cond is false, a\n// fatal error has occured in the program. In this event print error_message\n// to stderr and abort(). Otherwise do nothing. Note that setting\n// AFL_DRIVER_STDERR_DUPLICATE_FILENAME may cause error_message to be appended\n// to the file as well, if the error occurs after the duplication is performed.\n#define CHECK_ERROR(cond, error_message)                                       \\\n  if (!(cond)) {                                                               \\\n    fprintf(stderr, (error_message));                                          \\\n    abort();                                                                   \\\n  }\n\n// libFuzzer interface is thin, so we don't include any libFuzzer headers.\nextern \"C\" {\nint LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);\n__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);\n}\n\n// Notify AFL about persistent mode.\nstatic volatile char AFL_PERSISTENT[] = \"##SIG_AFL_PERSISTENT##\";\nextern \"C\" int __afl_persistent_loop(unsigned int);\nstatic volatile char suppress_warning2 = AFL_PERSISTENT[0];\n\n// Notify AFL about deferred forkserver.\nstatic volatile char AFL_DEFER_FORKSVR[] = \"##SIG_AFL_DEFER_FORKSRV##\";\nextern \"C\" void  __afl_manual_init();\nstatic volatile char suppress_warning1 = AFL_DEFER_FORKSVR[0];\n\n// Input buffer.\nstatic const size_t kMaxAflInputSize = 1 << 20;\nstatic uint8_t AflInputBuf[kMaxAflInputSize];\n\n// Variables we need for writing to the extra stats file.\nstatic FILE *extra_stats_file = NULL;\nstatic uint32_t previous_peak_rss = 0;\nstatic time_t slowest_unit_time_secs = 0;\nstatic const int kNumExtraStats = 2;\nstatic const char *kExtraStatsFormatString = \"peak_rss_mb            : %u\\n\"\n                                             \"slowest_unit_time_sec  : %u\\n\";\n\n// Copied from FuzzerUtil.cpp.\nsize_t GetPeakRSSMb() {\n  struct rusage usage;\n  if (getrusage(RUSAGE_SELF, &usage))\n    return 0;\n  if (LIBFUZZER_LINUX) {\n    // ru_maxrss is in KiB\n    return usage.ru_maxrss >> 10;\n  } else if (LIBFUZZER_APPLE) {\n    // ru_maxrss is in bytes\n    return usage.ru_maxrss >> 20;\n  }\n  assert(0 && \"GetPeakRSSMb() is not implemented for your platform\");\n  return 0;\n}\n\n// Based on SetSigaction in FuzzerUtil.cpp\nstatic void SetSigaction(int signum,\n                         void (*callback)(int, siginfo_t *, void *)) {\n  struct sigaction sigact;\n  memset(&sigact, 0, sizeof(sigact));\n  sigact.sa_sigaction = callback;\n  if (sigaction(signum, &sigact, 0)) {\n    fprintf(stderr, \"libFuzzer: sigaction failed with %d\\n\", errno);\n    exit(1);\n  }\n}\n\n// Write extra stats to the file specified by the user. If none is specified\n// this function will never be called.\nstatic void write_extra_stats() {\n  uint32_t peak_rss = GetPeakRSSMb();\n\n  if (peak_rss < previous_peak_rss)\n    peak_rss = previous_peak_rss;\n\n  int chars_printed = fprintf(extra_stats_file, kExtraStatsFormatString,\n                              peak_rss, slowest_unit_time_secs);\n\n  CHECK_ERROR(chars_printed != 0, \"Failed to write extra_stats_file\");\n\n  CHECK_ERROR(fclose(extra_stats_file) == 0,\n              \"Failed to close extra_stats_file\");\n}\n\n// Call write_extra_stats before we exit.\nstatic void crash_handler(int, siginfo_t *, void *) {\n  // Make sure we don't try calling write_extra_stats again if we crashed while\n  // trying to call it.\n  static bool first_crash = true;\n  CHECK_ERROR(first_crash,\n              \"Crashed in crash signal handler. This is a bug in the fuzzer.\");\n\n  first_crash = false;\n  write_extra_stats();\n}\n\n// If the user has specified an extra_stats_file through the environment\n// variable AFL_DRIVER_EXTRA_STATS_FILENAME, then perform necessary set up\n// to write stats to it on exit. If no file is specified, do nothing. Otherwise\n// install signal and exit handlers to write to the file when the process exits.\n// Then if the file doesn't exist create it and set extra stats to 0. But if it\n// does exist then read the initial values of the extra stats from the file\n// and check that the file is writable.\nstatic void maybe_initialize_extra_stats() {\n  // If AFL_DRIVER_EXTRA_STATS_FILENAME isn't set then we have nothing to do.\n  char *extra_stats_filename = getenv(\"AFL_DRIVER_EXTRA_STATS_FILENAME\");\n  if (!extra_stats_filename)\n    return;\n\n  // Open the file and find the previous peak_rss_mb value.\n  // This is necessary because the fuzzing process is restarted after N\n  // iterations are completed. So we may need to get this value from a previous\n  // process to be accurate.\n  extra_stats_file = fopen(extra_stats_filename, \"r\");\n\n  // If extra_stats_file already exists: read old stats from it.\n  if (extra_stats_file) {\n    int matches = fscanf(extra_stats_file, kExtraStatsFormatString,\n                         &previous_peak_rss, &slowest_unit_time_secs);\n\n    // Make sure we have read a real extra stats file and that we have used it\n    // to set slowest_unit_time_secs and previous_peak_rss.\n    CHECK_ERROR(matches == kNumExtraStats, \"Extra stats file is corrupt\");\n\n    CHECK_ERROR(fclose(extra_stats_file) == 0, \"Failed to close file\");\n\n    // Now open the file for writing.\n    extra_stats_file = fopen(extra_stats_filename, \"w\");\n    CHECK_ERROR(extra_stats_file,\n                \"Failed to open extra stats file for writing\");\n  } else {\n    // Looks like this is the first time in a fuzzing job this is being called.\n    extra_stats_file = fopen(extra_stats_filename, \"w+\");\n    CHECK_ERROR(extra_stats_file, \"failed to create extra stats file\");\n  }\n\n  // Make sure that crash_handler gets called on any kind of fatal error.\n  int crash_signals[] = {SIGSEGV, SIGBUS, SIGABRT, SIGILL, SIGFPE,  SIGINT,\n                         SIGTERM};\n\n  const size_t num_signals = sizeof(crash_signals) / sizeof(crash_signals[0]);\n\n  for (size_t idx = 0; idx < num_signals; idx++)\n    SetSigaction(crash_signals[idx], crash_handler);\n\n  // Make sure it gets called on other kinds of exits.\n  atexit(write_extra_stats);\n}\n\n// If the user asks us to duplicate stderr, then do it.\nstatic void maybe_duplicate_stderr() {\n  char* stderr_duplicate_filename =\n      getenv(\"AFL_DRIVER_STDERR_DUPLICATE_FILENAME\");\n\n  if (!stderr_duplicate_filename)\n    return;\n\n  FILE* stderr_duplicate_stream =\n      freopen(stderr_duplicate_filename, \"a+\", stderr);\n\n  if (!stderr_duplicate_stream) {\n    fprintf(\n        stderr,\n        \"Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME\");\n    abort();\n  }\n}\n\nint main(int argc, char **argv) {\n  fprintf(stderr, \"======================= INFO =========================\\n\"\n                  \"This binary is built for AFL-fuzz.\\n\"\n                  \"To run the target function on a single input execute this:\\n\"\n                  \"  %s < INPUT_FILE\\n\"\n                  \"To run the fuzzing execute this:\\n\"\n                  \"  afl-fuzz [afl-flags] %s [N] \"\n                  \"-- run N fuzzing iterations before \"\n                  \"re-spawning the process (default: 1000)\\n\"\n                  \"======================================================\\n\",\n          argv[0], argv[0]);\n  if (LLVMFuzzerInitialize)\n    LLVMFuzzerInitialize(&argc, &argv);\n  // Do any other expensive one-time initialization here.\n\n  maybe_duplicate_stderr();\n  maybe_initialize_extra_stats();\n\n  __afl_manual_init();\n\n  int N = 1000;\n  if (argc >= 2)\n    N = atoi(argv[1]);\n  assert(N > 0);\n  time_t unit_time_secs;\n  int num_runs = 0;\n  while (__afl_persistent_loop(N)) {\n    ssize_t n_read = read(0, AflInputBuf, kMaxAflInputSize);\n    if (n_read > 0) {\n      // Copy AflInputBuf into a separate buffer to let asan find buffer\n      // overflows. Don't use unique_ptr/etc to avoid extra dependencies.\n      uint8_t *copy = new uint8_t[n_read];\n      memcpy(copy, AflInputBuf, n_read);\n\n      struct timeval unit_start_time;\n      CHECK_ERROR(gettimeofday(&unit_start_time, NULL) == 0,\n                  \"Calling gettimeofday failed\");\n\n      num_runs++;\n      LLVMFuzzerTestOneInput(copy, n_read);\n\n      struct timeval unit_stop_time;\n      CHECK_ERROR(gettimeofday(&unit_stop_time, NULL) == 0,\n                  \"Calling gettimeofday failed\");\n\n      // Update slowest_unit_time_secs if we see a new max.\n      unit_time_secs = unit_stop_time.tv_sec - unit_start_time.tv_sec;\n      if (slowest_unit_time_secs < unit_time_secs)\n        slowest_unit_time_secs = unit_time_secs;\n\n      delete[] copy;\n    }\n  }\n  fprintf(stderr, \"%s: successfully executed %d input(s)\\n\", argv[0], num_runs);\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/build.sh",
    "content": "#!/bin/bash\nLIBFUZZER_SRC_DIR=$(dirname $0)\nfor f in $LIBFUZZER_SRC_DIR/*.cpp; do\n  clang -g -O2 -fno-omit-frame-pointer -std=c++11 $f -c &\ndone\nwait\nrm -f libFuzzer.a\nar ru libFuzzer.a Fuzzer*.o\nrm -f Fuzzer*.o\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/cxx.dict",
    "content": "\"++\"\n\"--\"\n\"<<\"\n\">>\"\n\"+=\"\n\"-=\"\n\"*=\"\n\"/=\"\n\">>=\"\n\"<<=\"\n\"&=\"\n\"|=\"\n\"^=\"\n\"%=\"\n\"!=\"\n\"&&\"\n\"||\"\n\"==\"\n\">=\"\n\"<=\"\n\"->\"\n\"alignas\"\n\"alignof\"\n\"and\"\n\"and_eq\"\n\"asm\"\n\"auto\"\n\"bitand\"\n\"bitor\"\n\"bool\"\n\"break\"\n\"case\"\n\"catch\"\n\"char\"\n\"char16_t\"\n\"char32_t\"\n\"class\"\n\"compl\"\n\"concept\"\n\"const\"\n\"constexpr\"\n\"const_cast\"\n\"continue\"\n\"decltype\"\n\"default\"\n\"delete\"\n\"do\"\n\"double\"\n\"dynamic_cast\"\n\"else\"\n\"enum\"\n\"explicit\"\n\"export\"\n\"extern\"\n\"false\"\n\"float\"\n\"for\"\n\"friend\"\n\"goto\"\n\"if\"\n\"inline\"\n\"int\"\n\"long\"\n\"mutable\"\n\"namespace\"\n\"new\"\n\"noexcept\"\n\"not\"\n\"not_eq\"\n\"nullptr\"\n\"operator\"\n\"or\"\n\"or_eq\"\n\"private\"\n\"protected\"\n\"public\"\n\"register\"\n\"reinterpret_cast\"\n\"requires\"\n\"return\"\n\"short\"\n\"signed\"\n\"sizeof\"\n\"static\"\n\"static_assert\"\n\"static_cast\"\n\"struct\"\n\"switch\"\n\"template\"\n\"this\"\n\"thread_local\"\n\"throw\"\n\"true\"\n\"try\"\n\"typedef\"\n\"typeid\"\n\"typename\"\n\"union\"\n\"unsigned\"\n\"using\"\n\"virtual\"\n\"void\"\n\"volatile\"\n\"wchar_t\"\n\"while\"\n\"xor\"\n\"xor_eq\"\n\"if\"\n\"elif\"\n\"else\"\n\"endif\"\n\"defined\"\n\"ifdef\"\n\"ifndef\"\n\"define\"\n\"undef\"\n\"include\"\n\"line\"\n\"error\"\n\"pragma\"\n\"override\"\n\"final\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/standalone/StandaloneFuzzTargetMain.c",
    "content": "/*===- StandaloneFuzzTargetMain.c - standalone main() for fuzz targets. ---===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// This main() function can be linked to a fuzz target (i.e. a library\n// that exports LLVMFuzzerTestOneInput() and possibly LLVMFuzzerInitialize())\n// instead of libFuzzer. This main() function will not perform any fuzzing\n// but will simply feed all input files one by one to the fuzz target.\n//\n// Use this file to provide reproducers for bugs when linking against libFuzzer\n// or other fuzzing engine is undesirable.\n//===----------------------------------------------------------------------===*/\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n\nextern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);\n__attribute__((weak)) extern int LLVMFuzzerInitialize(int *argc, char ***argv);\nint main(int argc, char **argv) {\n  fprintf(stderr, \"StandaloneFuzzTargetMain: running %d inputs\\n\", argc - 1);\n  if (LLVMFuzzerInitialize)\n    LLVMFuzzerInitialize(&argc, &argv);\n  for (int i = 1; i < argc; i++) {\n    fprintf(stderr, \"Running: %s\\n\", argv[i]);\n    FILE *f = fopen(argv[i], \"r\");\n    assert(f);\n    fseek(f, 0, SEEK_END);\n    size_t len = ftell(f);\n    fseek(f, 0, SEEK_SET);\n    unsigned char *buf = (unsigned char*)malloc(len);\n    size_t n_read = fread(buf, 1, len, f);\n    assert(n_read == len);\n    LLVMFuzzerTestOneInput(buf, len);\n    free(buf);\n    fprintf(stderr, \"Done:    %s: (%zd bytes)\\n\", argv[i], n_read);\n  }\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/AFLDriverTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Contains dummy functions used to avoid dependency on AFL.\n#include <stdint.h>\n#include <stdlib.h>\n\nextern \"C\" void __afl_manual_init() {}\n\nextern \"C\" int __afl_persistent_loop(unsigned int) {\n  return 0;\n}\n\n// This declaration exists to prevent the Darwin linker\n// from complaining about this being a missing weak symbol.\nextern \"C\" int LLVMFuzzerInitialize(int *argc, char ***argv) {\n  return 0;\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/AbsNegAndConstant64Test.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// abs(x) < 0 and y == Const puzzle, 64-bit variant.\n#include <cstring>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstdio>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 16) return 0;\n  int64_t x;\n  uint64_t y;\n  memcpy(&x, Data, sizeof(x));\n  memcpy(&y, Data + sizeof(x), sizeof(y));\n  if (labs(x) < 0 && y == 0xbaddcafedeadbeefUL) {\n    printf(\"BINGO; Found the target, exiting; x = 0x%lx y 0x%lx\\n\", x, y);\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/AbsNegAndConstantTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// abs(x) < 0 and y == Const puzzle.\n#include <cstring>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstdio>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 8) return 0;\n  int x;\n  unsigned y;\n  memcpy(&x, Data, sizeof(x));\n  memcpy(&y, Data + sizeof(x), sizeof(y));\n  if (abs(x) < 0 && y == 0xbaddcafe) {\n    printf(\"BINGO; Found the target, exiting; x = 0x%x y 0x%x\\n\", x, y);\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/AccumulateAllocationsTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test with a more mallocs than frees, but no leak.\n#include <cstdint>\n#include <cstddef>\n\nconst int kAllocatedPointersSize = 10000;\nint NumAllocatedPointers = 0;\nint *AllocatedPointers[kAllocatedPointersSize];\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (NumAllocatedPointers < kAllocatedPointersSize)\n    AllocatedPointers[NumAllocatedPointers++] = new int;\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/BufferOverflowOnInput.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the string \"Hi!\".\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile bool SeedLargeBuffer;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  assert(Data);\n  if (Size >= 4)\n    SeedLargeBuffer = true;\n  if (Size == 3 && SeedLargeBuffer && Data[3]) {\n    std::cout << \"Woops, reading Data[3] w/o crashing\\n\";\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/CMakeLists.txt",
    "content": "# Build all these tests with -O0, otherwise optimizations may merge some\n# basic blocks and we'll fail to discover the targets.\n# We change the flags for every build type because we might be doing\n# a multi-configuration build (e.g. Xcode) where CMAKE_BUILD_TYPE doesn't\n# mean anything.\nset(variables_to_filter\n  CMAKE_CXX_FLAGS_RELEASE\n  CMAKE_CXX_FLAGS_DEBUG\n  CMAKE_CXX_FLAGS_RELWITHDEBINFO\n  CMAKE_CXX_FLAGS_MINSIZEREL\n  LIBFUZZER_FLAGS_BASE\n  )\nforeach (VARNAME ${variables_to_filter})\n  string(REPLACE \" \" \";\" BUILD_FLAGS_AS_LIST \"${${VARNAME}}\")\n  set(new_flags \"\")\n  foreach (flag ${BUILD_FLAGS_AS_LIST})\n    # NOTE: Use of XX here is to avoid a CMake warning due to CMP0054\n    if (NOT (\"XX${flag}\" MATCHES \"XX-O[0123s]\"))\n      set(new_flags \"${new_flags} ${flag}\")\n    else()\n      set(new_flags \"${new_flags} -O0\")\n    endif()\n  endforeach()\n  set(${VARNAME} \"${new_flags}\")\nendforeach()\n\n# Enable the coverage instrumentation (it is disabled for the Fuzzer lib).\nset(CMAKE_CXX_FLAGS \"${LIBFUZZER_FLAGS_BASE} -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp,trace-div,trace-gep -g\")\n\n# add_libfuzzer_test(<name>\n#   SOURCES source0.cpp [source1.cpp ...]\n#   )\n#\n#   Declares a LibFuzzer test executable with target name LLVMFuzzer-<name>.\n#\n#   One or more source files to be compiled into the binary must be declared\n#   after the SOURCES keyword.\nfunction(add_libfuzzer_test name)\n  set(multi_arg_options \"SOURCES\")\n  cmake_parse_arguments(\n    \"add_libfuzzer_test\" \"\" \"\" \"${multi_arg_options}\" ${ARGN})\n  if (\"${add_libfuzzer_test_SOURCES}\" STREQUAL \"\")\n    message(FATAL_ERROR \"Source files must be specified\")\n  endif()\n  add_executable(LLVMFuzzer-${name}\n    ${add_libfuzzer_test_SOURCES}\n    )\n  target_link_libraries(LLVMFuzzer-${name} LLVMFuzzer)\n  # Place binary where llvm-lit expects to find it\n  set_target_properties(LLVMFuzzer-${name}\n    PROPERTIES RUNTIME_OUTPUT_DIRECTORY\n    \"${CMAKE_BINARY_DIR}/lib/Fuzzer/test\"\n    )\n  set(TestBinaries ${TestBinaries} LLVMFuzzer-${name} PARENT_SCOPE)\nendfunction()\n\n# Variable to keep track of all test targets\nset(TestBinaries)\n\n###############################################################################\n# Basic tests\n###############################################################################\n\nset(Tests\n  AbsNegAndConstantTest\n  AbsNegAndConstant64Test\n  AccumulateAllocationsTest\n  BufferOverflowOnInput\n  CallerCalleeTest\n  CounterTest\n  CustomCrossOverTest\n  CustomMutatorTest\n  DivTest\n  EmptyTest\n  FourIndependentBranchesTest\n  FullCoverageSetTest\n  InitializeTest\n  MemcmpTest\n  LeakTest\n  LeakTimeoutTest\n  LoadTest\n  NullDerefTest\n  NullDerefOnEmptyTest\n  NthRunCrashTest\n  OneHugeAllocTest\n  OutOfMemoryTest\n  OutOfMemorySingleLargeMallocTest\n  RepeatedMemcmp\n  RepeatedBytesTest\n  SimpleCmpTest\n  SimpleDictionaryTest\n  SimpleHashTest\n  SimpleTest\n  SimpleThreadedTest\n  SingleMemcmpTest\n  SingleStrcmpTest\n  SingleStrncmpTest\n  SpamyTest\n  ShrinkControlFlowTest\n  ShrinkValueProfileTest\n  StrcmpTest\n  StrncmpOOBTest\n  StrncmpTest\n  StrstrTest\n  SwapCmpTest\n  SwitchTest\n  Switch2Test\n  ThreadedLeakTest\n  ThreadedTest\n  TimeoutTest\n  TimeoutEmptyTest\n  TraceMallocTest\n  )\n\nif(APPLE)\n  # LeakSanitizer is not supported on OSX right now\n  set(HAS_LSAN 0)\n  message(WARNING \"LeakSanitizer is not supported on Apple platforms.\"\n    \" Building and running LibFuzzer LeakSanitizer tests is disabled.\"\n    )\nelse()\n  set(HAS_LSAN 1)\nendif()\n\nforeach(Test ${Tests})\n  add_libfuzzer_test(${Test} SOURCES ${Test}.cpp)\nendforeach()\n\n\n###############################################################################\n# Unit tests\n###############################################################################\n\nadd_executable(LLVMFuzzer-Unittest\n  FuzzerUnittest.cpp\n  )\n\nadd_executable(LLVMFuzzer-StandaloneInitializeTest\n  InitializeTest.cpp\n  ../standalone/StandaloneFuzzTargetMain.c\n  )\n\ntarget_link_libraries(LLVMFuzzer-Unittest\n  gtest\n  gtest_main\n  LLVMFuzzerNoMain\n  )\n\ntarget_include_directories(LLVMFuzzer-Unittest PRIVATE\n  \"${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include\"\n  )\n\nset(TestBinaries ${TestBinaries} LLVMFuzzer-Unittest)\nset_target_properties(LLVMFuzzer-Unittest\n  PROPERTIES RUNTIME_OUTPUT_DIRECTORY\n  \"${CMAKE_CURRENT_BINARY_DIR}\"\n)\n\nset(TestBinaries ${TestBinaries} LLVMFuzzer-StandaloneInitializeTest)\nset_target_properties(LLVMFuzzer-StandaloneInitializeTest\n  PROPERTIES RUNTIME_OUTPUT_DIRECTORY\n  \"${CMAKE_CURRENT_BINARY_DIR}\"\n)\n\n###############################################################################\n# Additional tests\n###############################################################################\n\ninclude_directories(..)\n\n# add_subdirectory(uninstrumented)\nadd_subdirectory(no-coverage)\nadd_subdirectory(ubsan)\n\nadd_library(LLVMFuzzer-DSO1 SHARED DSO1.cpp)\nadd_library(LLVMFuzzer-DSO2 SHARED DSO2.cpp)\n\nadd_executable(LLVMFuzzer-DSOTest\n  DSOTestMain.cpp\n  DSOTestExtra.cpp)\n\ntarget_link_libraries(LLVMFuzzer-DSOTest\n  LLVMFuzzer-DSO1\n  LLVMFuzzer-DSO2\n  LLVMFuzzer\n  )\n\nset_target_properties(LLVMFuzzer-DSOTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY\n  \"${CMAKE_BINARY_DIR}/lib/Fuzzer/test\")\nset_target_properties(LLVMFuzzer-DSO1 PROPERTIES LIBRARY_OUTPUT_DIRECTORY\n  \"${CMAKE_BINARY_DIR}/lib/Fuzzer/lib\")\nset_target_properties(LLVMFuzzer-DSO2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY\n  \"${CMAKE_BINARY_DIR}/lib/Fuzzer/lib\")\n\nset(TestBinaries ${TestBinaries} LLVMFuzzer-DSOTest)\n\n###############################################################################\n# Configure lit to run the tests\n#\n# Note this is done after declaring all tests so we can inform lit if any tests\n# need to be disabled.\n###############################################################################\n\nconfigure_lit_site_cfg(\n  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in\n  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg\n  )\n\nconfigure_lit_site_cfg(\n  ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.in\n  ${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg\n  )\n\nadd_lit_testsuite(check-fuzzer \"Running Fuzzer tests\"\n    ${CMAKE_CURRENT_BINARY_DIR}\n    DEPENDS ${TestBinaries} FileCheck not\n    )\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/CallerCalleeTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer.\n// Try to find the target using the indirect caller-callee pairs.\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstring>\n#include <iostream>\n\ntypedef void (*F)();\nstatic F t[256];\n\nvoid f34() {\n  std::cerr << \"BINGO\\n\";\n  exit(1);\n}\nvoid f23() { t[(unsigned)'d'] = f34;}\nvoid f12() { t[(unsigned)'c'] = f23;}\nvoid f01() { t[(unsigned)'b'] = f12;}\nvoid f00() {}\n\nstatic F t0[256] = {\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,\n};\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 4) return 0;\n  // Spoof the counters.\n  for (int i = 0; i < 200; i++) {\n    f23();\n    f12();\n    f01();\n  }\n  memcpy(t, t0, sizeof(t));\n  t[(unsigned)'a'] = f01;\n  t[Data[0]]();\n  t[Data[1]]();\n  t[Data[2]]();\n  t[Data[3]]();\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/CounterTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test for a fuzzer: must find the case where a particular basic block is\n// executed many times.\n#include <iostream>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  int Num = 0;\n  for (size_t i = 0; i < Size; i++)\n    if (Data[i] == 'A' + i)\n      Num++;\n  if (Num >= 4) {\n    std::cerr <<  \"BINGO!\\n\";\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/CustomCrossOverTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a cutom mutator.\n#include <assert.h>\n#include <cstddef>\n#include <cstdint>\n#include <cstdlib>\n#include <iostream>\n#include <random>\n#include <string.h>\n\n#include \"FuzzerInterface.h\"\n\nstatic const char *Separator = \"-_^_-\";\nstatic const char *Target = \"012-_^_-abc\";\n\nstatic volatile int sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  assert(Data);\n  std::string Str(reinterpret_cast<const char *>(Data), Size);\n\n  // Ensure that two different elements exist in the corpus.\n  if (Size && Data[0] == '0') sink++;\n  if (Size && Data[0] == 'a') sink--;\n\n  if (Str.find(Target) != std::string::npos) {\n    std::cout << \"BINGO; Found the target, exiting\\n\";\n    exit(1);\n  }\n  return 0;\n}\n\nextern \"C\" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,\n                                            const uint8_t *Data2, size_t Size2,\n                                            uint8_t *Out, size_t MaxOutSize,\n                                            unsigned int Seed) {\n  static bool Printed;\n  static size_t SeparatorLen = strlen(Separator);\n\n  if (!Printed) {\n    std::cerr << \"In LLVMFuzzerCustomCrossover\\n\";\n    Printed = true;\n  }\n\n  std::mt19937 R(Seed);\n\n  size_t Offset1 = 0;\n  size_t Len1 = R() % (Size1 - Offset1);\n  size_t Offset2 = 0;\n  size_t Len2 = R() % (Size2 - Offset2);\n  size_t Size = Len1 + Len2 + SeparatorLen;\n\n  if (Size > MaxOutSize)\n    return 0;\n\n  memcpy(Out, Data1 + Offset1, Len1);\n  memcpy(Out + Len1, Separator, SeparatorLen);\n  memcpy(Out + Len1 + SeparatorLen, Data2 + Offset2, Len2);\n\n  return Len1 + Len2 + SeparatorLen;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/CustomMutatorTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a cutom mutator.\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\n#include \"FuzzerInterface.h\"\n\nstatic volatile int Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  assert(Data);\n  if (Size > 0 && Data[0] == 'H') {\n    Sink = 1;\n    if (Size > 1 && Data[1] == 'i') {\n      Sink = 2;\n      if (Size > 2 && Data[2] == '!') {\n        std::cout << \"BINGO; Found the target, exiting\\n\";\n        exit(1);\n      }\n    }\n  }\n  return 0;\n}\n\nextern \"C\" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,\n                                          size_t MaxSize, unsigned int Seed) {\n  static bool Printed;\n  if (!Printed) {\n    std::cerr << \"In LLVMFuzzerCustomMutator\\n\";\n    Printed = true;\n  }\n  return LLVMFuzzerMutate(Data, Size, MaxSize);\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/DSO1.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Source code for a simple DSO.\n\nint DSO1(int a) {\n  if (a < 123456)\n    return 0;\n  return 1;\n}\n\nvoid Uncovered1() { }\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/DSO2.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Source code for a simple DSO.\n\nint DSO2(int a) {\n  if (a < 3598235)\n    return 0;\n  return 1;\n}\n\nvoid Uncovered2() {}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/DSOTestExtra.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Source code for a simple DSO.\n\nint DSOTestExtra(int a) {\n  if (a < 452345)\n    return 0;\n  return 1;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/DSOTestMain.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Source code for a simple DSO.\n\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <cstdio>\nextern int DSO1(int a);\nextern int DSO2(int a);\nextern int DSOTestExtra(int a);\n\nstatic volatile int *nil = 0;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  int x, y, z;\n  if (Size < sizeof(int) * 3) {\n    x = y = z = 0;\n  } else {\n    memcpy(&x, Data + 0 * sizeof(int), sizeof(int));\n    memcpy(&y, Data + 1 * sizeof(int), sizeof(int));\n    memcpy(&z, Data + 2 * sizeof(int), sizeof(int));\n  }\n  int sum = DSO1(x) + DSO2(y) + (z ? DSOTestExtra(z) : 0);\n  if (sum == 3) {\n    fprintf(stderr, \"BINGO %d %d %d\\n\", x, y, z);\n    *nil = 0;\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/DivTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer: find the interesting argument for div.\n#include <assert.h>\n#include <cstdint>\n#include <cstring>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile int Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 4) return 0;\n  int a;\n  memcpy(&a, Data, 4);\n  Sink = 12345678 / (987654 - a);\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/EmptyTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n// A fuzzer with empty target function.\n\n#include <cstdint>\n#include <cstdlib>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/FourIndependentBranchesTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the string \"FUZZ\".\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  int bits = 0;\n  if (Size > 0 && Data[0] == 'F') bits |= 1;\n  if (Size > 1 && Data[1] == 'U') bits |= 2;\n  if (Size > 2 && Data[2] == 'Z') bits |= 4;\n  if (Size > 3 && Data[3] == 'Z') bits |= 8;\n  if (bits == 15) {\n    std::cerr <<  \"BINGO!\\n\";\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/FullCoverageSetTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the string \"FUZZER\".\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  int bits = 0;\n  if (Size > 0 && Data[0] == 'F') bits |= 1;\n  if (Size > 1 && Data[1] == 'U') bits |= 2;\n  if (Size > 2 && Data[2] == 'Z') bits |= 4;\n  if (Size > 3 && Data[3] == 'Z') bits |= 8;\n  if (Size > 4 && Data[4] == 'E') bits |= 16;\n  if (Size > 5 && Data[5] == 'R') bits |= 32;\n  if (bits == 63) {\n    std::cerr <<  \"BINGO!\\n\";\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/FuzzerUnittest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Avoid ODR violations (LibFuzzer is built without ASan and this test is built\n// with ASan) involving C++ standard library types when using libcxx.\n#define _LIBCPP_HAS_NO_ASAN\n\n#include \"FuzzerCorpus.h\"\n#include \"FuzzerInternal.h\"\n#include \"FuzzerDictionary.h\"\n#include \"FuzzerMerge.h\"\n#include \"FuzzerMutate.h\"\n#include \"FuzzerRandom.h\"\n#include \"gtest/gtest.h\"\n#include <memory>\n#include <set>\n\nusing namespace fuzzer;\n\n// For now, have LLVMFuzzerTestOneInput just to make it link.\n// Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  abort();\n}\n\nTEST(Fuzzer, CrossOver) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  Unit A({0, 1, 2}), B({5, 6, 7});\n  Unit C;\n  Unit Expected[] = {\n       { 0 },\n       { 0, 1 },\n       { 0, 5 },\n       { 0, 1, 2 },\n       { 0, 1, 5 },\n       { 0, 5, 1 },\n       { 0, 5, 6 },\n       { 0, 1, 2, 5 },\n       { 0, 1, 5, 2 },\n       { 0, 1, 5, 6 },\n       { 0, 5, 1, 2 },\n       { 0, 5, 1, 6 },\n       { 0, 5, 6, 1 },\n       { 0, 5, 6, 7 },\n       { 0, 1, 2, 5, 6 },\n       { 0, 1, 5, 2, 6 },\n       { 0, 1, 5, 6, 2 },\n       { 0, 1, 5, 6, 7 },\n       { 0, 5, 1, 2, 6 },\n       { 0, 5, 1, 6, 2 },\n       { 0, 5, 1, 6, 7 },\n       { 0, 5, 6, 1, 2 },\n       { 0, 5, 6, 1, 7 },\n       { 0, 5, 6, 7, 1 },\n       { 0, 1, 2, 5, 6, 7 },\n       { 0, 1, 5, 2, 6, 7 },\n       { 0, 1, 5, 6, 2, 7 },\n       { 0, 1, 5, 6, 7, 2 },\n       { 0, 5, 1, 2, 6, 7 },\n       { 0, 5, 1, 6, 2, 7 },\n       { 0, 5, 1, 6, 7, 2 },\n       { 0, 5, 6, 1, 2, 7 },\n       { 0, 5, 6, 1, 7, 2 },\n       { 0, 5, 6, 7, 1, 2 }\n  };\n  for (size_t Len = 1; Len < 8; Len++) {\n    std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;\n    for (int Iter = 0; Iter < 3000; Iter++) {\n      C.resize(Len);\n      size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(),\n                                    C.data(), C.size());\n      C.resize(NewSize);\n      FoundUnits.insert(C);\n    }\n    for (const Unit &U : Expected)\n      if (U.size() <= Len)\n        ExpectedUnitsWitThisLength.insert(U);\n    EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);\n  }\n}\n\nTEST(Fuzzer, Hash) {\n  uint8_t A[] = {'a', 'b', 'c'};\n  fuzzer::Unit U(A, A + sizeof(A));\n  EXPECT_EQ(\"a9993e364706816aba3e25717850c26c9cd0d89d\", fuzzer::Hash(U));\n  U.push_back('d');\n  EXPECT_EQ(\"81fe8bfe87576c3ecb22426f8e57847382917acf\", fuzzer::Hash(U));\n}\n\ntypedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,\n                                              size_t MaxSize);\n\nvoid TestEraseBytes(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};\n  uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};\n  uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};\n  uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};\n  uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};\n\n  uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};\n  uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};\n\n  uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};\n  uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};\n\n\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  int FoundMask = 0;\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n    size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));\n    if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;\n    if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;\n    if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;\n    if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;\n    if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;\n    if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;\n    if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;\n    if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;\n\n    if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;\n    if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;\n    if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;\n\n    if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;\n    if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;\n    if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;\n  }\n  EXPECT_EQ(FoundMask, (1 << 14) - 1);\n}\n\nTEST(FuzzerMutate, EraseBytes1) {\n  TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);\n}\nTEST(FuzzerMutate, EraseBytes2) {\n  TestEraseBytes(&MutationDispatcher::Mutate, 2000);\n}\n\nvoid TestInsertByte(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  int FoundMask = 0;\n  uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};\n  uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};\n  uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};\n  uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};\n  uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};\n  uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};\n  uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};\n  uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};\n    size_t NewSize = (MD.*M)(T, 7, 8);\n    if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;\n    if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;\n    if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;\n    if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;\n    if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;\n    if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;\n    if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;\n    if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;\n  }\n  EXPECT_EQ(FoundMask, 255);\n}\n\nTEST(FuzzerMutate, InsertByte1) {\n  TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);\n}\nTEST(FuzzerMutate, InsertByte2) {\n  TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);\n}\n\nvoid TestInsertRepeatedBytes(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  int FoundMask = 0;\n  uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};\n  uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};\n  uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};\n  uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};\n  uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};\n\n  uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};\n  uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};\n  uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};\n  uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};\n  uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};\n\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};\n    size_t NewSize = (MD.*M)(T, 4, 8);\n    if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;\n    if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;\n    if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;\n    if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;\n    if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;\n\n    if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;\n    if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;\n    if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;\n    if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;\n    if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;\n\n  }\n  EXPECT_EQ(FoundMask, (1 << 10) - 1);\n}\n\nTEST(FuzzerMutate, InsertRepeatedBytes1) {\n  TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);\n}\nTEST(FuzzerMutate, InsertRepeatedBytes2) {\n  TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);\n}\n\nvoid TestChangeByte(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  int FoundMask = 0;\n  uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};\n  uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};\n  uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};\n  uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n    size_t NewSize = (MD.*M)(T, 8, 9);\n    if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;\n    if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;\n    if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;\n    if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;\n    if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;\n    if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;\n    if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;\n    if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;\n  }\n  EXPECT_EQ(FoundMask, 255);\n}\n\nTEST(FuzzerMutate, ChangeByte1) {\n  TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);\n}\nTEST(FuzzerMutate, ChangeByte2) {\n  TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);\n}\n\nvoid TestChangeBit(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  int FoundMask = 0;\n  uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};\n  uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};\n  uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};\n  uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n    size_t NewSize = (MD.*M)(T, 8, 9);\n    if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;\n    if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;\n    if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;\n    if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;\n    if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;\n    if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;\n    if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;\n    if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;\n  }\n  EXPECT_EQ(FoundMask, 255);\n}\n\nTEST(FuzzerMutate, ChangeBit1) {\n  TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);\n}\nTEST(FuzzerMutate, ChangeBit2) {\n  TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);\n}\n\nvoid TestShuffleBytes(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  int FoundMask = 0;\n  uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};\n  uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};\n  uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};\n  uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};\n  uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};\n    size_t NewSize = (MD.*M)(T, 7, 7);\n    if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;\n    if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;\n    if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;\n    if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;\n    if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;\n  }\n  EXPECT_EQ(FoundMask, 31);\n}\n\nTEST(FuzzerMutate, ShuffleBytes1) {\n  TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 16);\n}\nTEST(FuzzerMutate, ShuffleBytes2) {\n  TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);\n}\n\nvoid TestCopyPart(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  int FoundMask = 0;\n  uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};\n  uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};\n  uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};\n  uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};\n  uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};\n\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};\n    size_t NewSize = (MD.*M)(T, 7, 7);\n    if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;\n    if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;\n    if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;\n    if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;\n    if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;\n  }\n\n  uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};\n  uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};\n  uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};\n  uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};\n  uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};\n\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n    size_t NewSize = (MD.*M)(T, 5, 8);\n    if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;\n    if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;\n    if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;\n    if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;\n    if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;\n  }\n\n  EXPECT_EQ(FoundMask, 1023);\n}\n\nTEST(FuzzerMutate, CopyPart1) {\n  TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);\n}\nTEST(FuzzerMutate, CopyPart2) {\n  TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);\n}\n\nvoid TestAddWordFromDictionary(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};\n  uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};\n  MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1)));\n  MD.AddWordToManualDictionary(Word(Word2, sizeof(Word2)));\n  int FoundMask = 0;\n  uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};\n  uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};\n  uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};\n  uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};\n  uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};\n  uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};\n  uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};\n  uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[7] = {0x00, 0x11, 0x22};\n    size_t NewSize = (MD.*M)(T, 3, 7);\n    if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;\n    if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;\n    if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;\n    if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;\n    if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;\n    if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;\n    if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;\n    if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;\n  }\n  EXPECT_EQ(FoundMask, 255);\n}\n\nTEST(FuzzerMutate, AddWordFromDictionary1) {\n  TestAddWordFromDictionary(\n      &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);\n}\n\nTEST(FuzzerMutate, AddWordFromDictionary2) {\n  TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);\n}\n\nvoid TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n  uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};\n  size_t PosHint = 7777;\n  MD.AddWordToAutoDictionary({Word(W, sizeof(W)), PosHint});\n  int FoundMask = 0;\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[10000];\n    memset(T, 0, sizeof(T));\n    size_t NewSize = (MD.*M)(T, 9000, 10000);\n    if (NewSize >= PosHint + sizeof(W) &&\n        !memcmp(W, T + PosHint, sizeof(W)))\n      FoundMask = 1;\n  }\n  EXPECT_EQ(FoundMask, 1);\n}\n\nTEST(FuzzerMutate, AddWordFromDictionaryWithHint1) {\n  TestAddWordFromDictionaryWithHint(\n      &MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary, 1 << 5);\n}\n\nTEST(FuzzerMutate, AddWordFromDictionaryWithHint2) {\n  TestAddWordFromDictionaryWithHint(&MutationDispatcher::Mutate, 1 << 10);\n}\n\nvoid TestChangeASCIIInteger(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n\n  uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};\n  uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};\n  uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};\n  uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};\n  int FoundMask = 0;\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};\n    size_t NewSize = (MD.*M)(T, 8, 8);\n    /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;\n    else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;\n    else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;\n    else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;\n    else if (NewSize == 8)                       FoundMask |= 1 << 4;\n  }\n  EXPECT_EQ(FoundMask, 31);\n}\n\nTEST(FuzzerMutate, ChangeASCIIInteger1) {\n  TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,\n                         1 << 15);\n}\n\nTEST(FuzzerMutate, ChangeASCIIInteger2) {\n  TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);\n}\n\nvoid TestChangeBinaryInteger(Mutator M, int NumIter) {\n  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());\n  fuzzer::EF = t.get();\n  Random Rand(0);\n  MutationDispatcher MD(Rand, {});\n\n  uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};\n  uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};\n  uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};\n  uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};\n  uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size\n  uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)\n\n  int FoundMask = 0;\n  for (int i = 0; i < NumIter; i++) {\n    uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};\n    size_t NewSize = (MD.*M)(T, 8, 8);\n    /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;\n    else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;\n    else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;\n    else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;\n    else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;\n    else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;\n    else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;\n    else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;\n  }\n  EXPECT_EQ(FoundMask, 255);\n}\n\nTEST(FuzzerMutate, ChangeBinaryInteger1) {\n  TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,\n                         1 << 12);\n}\n\nTEST(FuzzerMutate, ChangeBinaryInteger2) {\n  TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);\n}\n\n\nTEST(FuzzerDictionary, ParseOneDictionaryEntry) {\n  Unit U;\n  EXPECT_FALSE(ParseOneDictionaryEntry(\"\", &U));\n  EXPECT_FALSE(ParseOneDictionaryEntry(\" \", &U));\n  EXPECT_FALSE(ParseOneDictionaryEntry(\"\\t  \", &U));\n  EXPECT_FALSE(ParseOneDictionaryEntry(\"  \\\" \", &U));\n  EXPECT_FALSE(ParseOneDictionaryEntry(\"  zz\\\" \", &U));\n  EXPECT_FALSE(ParseOneDictionaryEntry(\"  \\\"zz \", &U));\n  EXPECT_FALSE(ParseOneDictionaryEntry(\"  \\\"\\\" \", &U));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"\\\"a\\\"\", &U));\n  EXPECT_EQ(U, Unit({'a'}));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"\\\"abc\\\"\", &U));\n  EXPECT_EQ(U, Unit({'a', 'b', 'c'}));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"abc=\\\"abc\\\"\", &U));\n  EXPECT_EQ(U, Unit({'a', 'b', 'c'}));\n  EXPECT_FALSE(ParseOneDictionaryEntry(\"\\\"\\\\\\\"\", &U));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"\\\"\\\\\\\\\\\"\", &U));\n  EXPECT_EQ(U, Unit({'\\\\'}));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"\\\"\\\\xAB\\\"\", &U));\n  EXPECT_EQ(U, Unit({0xAB}));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"\\\"\\\\xABz\\\\xDE\\\"\", &U));\n  EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"\\\"#\\\"\", &U));\n  EXPECT_EQ(U, Unit({'#'}));\n  EXPECT_TRUE(ParseOneDictionaryEntry(\"\\\"\\\\\\\"\\\"\", &U));\n  EXPECT_EQ(U, Unit({'\"'}));\n}\n\nTEST(FuzzerDictionary, ParseDictionaryFile) {\n  std::vector<Unit> Units;\n  EXPECT_FALSE(ParseDictionaryFile(\"zzz\\n\", &Units));\n  EXPECT_FALSE(ParseDictionaryFile(\"\", &Units));\n  EXPECT_TRUE(ParseDictionaryFile(\"\\n\", &Units));\n  EXPECT_EQ(Units.size(), 0U);\n  EXPECT_TRUE(ParseDictionaryFile(\"#zzzz a b c d\\n\", &Units));\n  EXPECT_EQ(Units.size(), 0U);\n  EXPECT_TRUE(ParseDictionaryFile(\" #zzzz\\n\", &Units));\n  EXPECT_EQ(Units.size(), 0U);\n  EXPECT_TRUE(ParseDictionaryFile(\"  #zzzz\\n\", &Units));\n  EXPECT_EQ(Units.size(), 0U);\n  EXPECT_TRUE(ParseDictionaryFile(\"  #zzzz\\naaa=\\\"aa\\\"\", &Units));\n  EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));\n  EXPECT_TRUE(\n      ParseDictionaryFile(\"  #zzzz\\naaa=\\\"aa\\\"\\n\\nabc=\\\"abc\\\"\", &Units));\n  EXPECT_EQ(Units,\n            std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));\n}\n\nTEST(FuzzerUtil, Base64) {\n  EXPECT_EQ(\"\", Base64({}));\n  EXPECT_EQ(\"YQ==\", Base64({'a'}));\n  EXPECT_EQ(\"eA==\", Base64({'x'}));\n  EXPECT_EQ(\"YWI=\", Base64({'a', 'b'}));\n  EXPECT_EQ(\"eHk=\", Base64({'x', 'y'}));\n  EXPECT_EQ(\"YWJj\", Base64({'a', 'b', 'c'}));\n  EXPECT_EQ(\"eHl6\", Base64({'x', 'y', 'z'}));\n  EXPECT_EQ(\"YWJjeA==\", Base64({'a', 'b', 'c', 'x'}));\n  EXPECT_EQ(\"YWJjeHk=\", Base64({'a', 'b', 'c', 'x', 'y'}));\n  EXPECT_EQ(\"YWJjeHl6\", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));\n}\n\nTEST(Corpus, Distribution) {\n  Random Rand(0);\n  InputCorpus C(\"\");\n  size_t N = 10;\n  size_t TriesPerUnit = 1<<16;\n  for (size_t i = 0; i < N; i++)\n    C.AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 0);\n\n  std::vector<size_t> Hist(N);\n  for (size_t i = 0; i < N * TriesPerUnit; i++) {\n    Hist[C.ChooseUnitIdxToMutate(Rand)]++;\n  }\n  for (size_t i = 0; i < N; i++) {\n    // A weak sanity check that every unit gets invoked.\n    EXPECT_GT(Hist[i], TriesPerUnit / N / 3);\n  }\n}\n\nTEST(Merge, Bad) {\n  const char *kInvalidInputs[] = {\n    \"\",\n    \"x\",\n    \"3\\nx\",\n    \"2\\n3\",\n    \"2\\n2\",\n    \"2\\n2\\nA\\n\",\n    \"2\\n2\\nA\\nB\\nC\\n\",\n    \"0\\n0\\n\",\n    \"1\\n1\\nA\\nDONE 0\",\n    \"1\\n1\\nA\\nSTARTED 1\",\n  };\n  Merger M;\n  for (auto S : kInvalidInputs) {\n    // fprintf(stderr, \"TESTING:\\n%s\\n\", S);\n    EXPECT_FALSE(M.Parse(S, false));\n  }\n}\n\nvoid EQ(const std::vector<uint32_t> &A, const std::vector<uint32_t> &B) {\n  EXPECT_EQ(A, B);\n}\n\nvoid EQ(const std::vector<std::string> &A, const std::vector<std::string> &B) {\n  std::set<std::string> a(A.begin(), A.end());\n  std::set<std::string> b(B.begin(), B.end());\n  EXPECT_EQ(a, b);\n}\n\nstatic void Merge(const std::string &Input,\n                  const std::vector<std::string> Result,\n                  size_t NumNewFeatures) {\n  Merger M;\n  std::vector<std::string> NewFiles;\n  EXPECT_TRUE(M.Parse(Input, true));\n  EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));\n  EQ(NewFiles, Result);\n}\n\nTEST(Merge, Good) {\n  Merger M;\n\n  EXPECT_TRUE(M.Parse(\"1\\n0\\nAA\\n\", false));\n  EXPECT_EQ(M.Files.size(), 1U);\n  EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);\n  EXPECT_EQ(M.Files[0].Name, \"AA\");\n  EXPECT_TRUE(M.LastFailure.empty());\n  EXPECT_EQ(M.FirstNotProcessedFile, 0U);\n\n  EXPECT_TRUE(M.Parse(\"2\\n1\\nAA\\nBB\\nSTARTED 0 42\\n\", false));\n  EXPECT_EQ(M.Files.size(), 2U);\n  EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);\n  EXPECT_EQ(M.Files[0].Name, \"AA\");\n  EXPECT_EQ(M.Files[1].Name, \"BB\");\n  EXPECT_EQ(M.LastFailure, \"AA\");\n  EXPECT_EQ(M.FirstNotProcessedFile, 1U);\n\n  EXPECT_TRUE(M.Parse(\"3\\n1\\nAA\\nBB\\nC\\n\"\n                        \"STARTED 0 1000\\n\"\n                        \"DONE 0 1 2 3\\n\"\n                        \"STARTED 1 1001\\n\"\n                        \"DONE 1 4 5 6 \\n\"\n                        \"STARTED 2 1002\\n\"\n                        \"\", true));\n  EXPECT_EQ(M.Files.size(), 3U);\n  EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);\n  EXPECT_EQ(M.Files[0].Name, \"AA\");\n  EXPECT_EQ(M.Files[0].Size, 1000U);\n  EXPECT_EQ(M.Files[1].Name, \"BB\");\n  EXPECT_EQ(M.Files[1].Size, 1001U);\n  EXPECT_EQ(M.Files[2].Name, \"C\");\n  EXPECT_EQ(M.Files[2].Size, 1002U);\n  EXPECT_EQ(M.LastFailure, \"C\");\n  EXPECT_EQ(M.FirstNotProcessedFile, 3U);\n  EQ(M.Files[0].Features, {1, 2, 3});\n  EQ(M.Files[1].Features, {4, 5, 6});\n\n\n  std::vector<std::string> NewFiles;\n\n  EXPECT_TRUE(M.Parse(\"3\\n2\\nAA\\nBB\\nC\\n\"\n                        \"STARTED 0 1000\\nDONE 0 1 2 3\\n\"\n                        \"STARTED 1 1001\\nDONE 1 4 5 6 \\n\"\n                        \"STARTED 2 1002\\nDONE 2 6 1 3 \\n\"\n                        \"\", true));\n  EXPECT_EQ(M.Files.size(), 3U);\n  EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);\n  EXPECT_TRUE(M.LastFailure.empty());\n  EXPECT_EQ(M.FirstNotProcessedFile, 3U);\n  EQ(M.Files[0].Features, {1, 2, 3});\n  EQ(M.Files[1].Features, {4, 5, 6});\n  EQ(M.Files[2].Features, {1, 3, 6});\n  EXPECT_EQ(0U, M.Merge(&NewFiles));\n  EQ(NewFiles, {});\n\n  EXPECT_TRUE(M.Parse(\"3\\n1\\nA\\nB\\nC\\n\"\n                        \"STARTED 0 1000\\nDONE 0 1 2 3\\n\"\n                        \"STARTED 1 1001\\nDONE 1 4 5 6 \\n\"\n                        \"STARTED 2 1002\\nDONE 2 6 1 3\\n\"\n                        \"\", true));\n  EQ(M.Files[0].Features, {1, 2, 3});\n  EQ(M.Files[1].Features, {4, 5, 6});\n  EQ(M.Files[2].Features, {1, 3, 6});\n  EXPECT_EQ(3U, M.Merge(&NewFiles));\n  EQ(NewFiles, {\"B\"});\n}\n\nTEST(Merge, Merge) {\n\n  Merge(\"3\\n1\\nA\\nB\\nC\\n\"\n        \"STARTED 0 1000\\nDONE 0 1 2 3\\n\"\n        \"STARTED 1 1001\\nDONE 1 4 5 6 \\n\"\n        \"STARTED 2 1002\\nDONE 2 6 1 3 \\n\",\n        {\"B\"}, 3);\n\n  Merge(\"3\\n0\\nA\\nB\\nC\\n\"\n        \"STARTED 0 2000\\nDONE 0 1 2 3\\n\"\n        \"STARTED 1 1001\\nDONE 1 4 5 6 \\n\"\n        \"STARTED 2 1002\\nDONE 2 6 1 3 \\n\",\n        {\"A\", \"B\", \"C\"}, 6);\n\n  Merge(\"4\\n0\\nA\\nB\\nC\\nD\\n\"\n        \"STARTED 0 2000\\nDONE 0 1 2 3\\n\"\n        \"STARTED 1 1101\\nDONE 1 4 5 6 \\n\"\n        \"STARTED 2 1102\\nDONE 2 6 1 3 100 \\n\"\n        \"STARTED 3 1000\\nDONE 3 1  \\n\",\n        {\"A\", \"B\", \"C\", \"D\"}, 7);\n\n  Merge(\"4\\n1\\nA\\nB\\nC\\nD\\n\"\n        \"STARTED 0 2000\\nDONE 0 4 5 6 7 8\\n\"\n        \"STARTED 1 1100\\nDONE 1 1 2 3 \\n\"\n        \"STARTED 2 1100\\nDONE 2 2 3 \\n\"\n        \"STARTED 3 1000\\nDONE 3 1  \\n\",\n        {\"B\", \"D\"}, 3);\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/InitializeTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Make sure LLVMFuzzerInitialize is called.\n#include <assert.h>\n#include <stddef.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nstatic char *argv0;\n\nextern \"C\" int LLVMFuzzerInitialize(int *argc, char ***argv) {\n  assert(*argc > 0);\n  argv0 = **argv;\n  fprintf(stderr, \"LLVMFuzzerInitialize: %s\\n\", argv0);\n  return 0;\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size == strlen(argv0) &&\n      !strncmp(reinterpret_cast<const char *>(Data), argv0, Size)) {\n    fprintf(stderr, \"BINGO %s\\n\", argv0);\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/LeakTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test with a leak.\n#include <cstdint>\n#include <cstddef>\n\nstatic volatile void *Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size > 0 && *Data == 'H') {\n    Sink = new int;\n    Sink = nullptr;\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/LeakTimeoutTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test with a leak.\n#include <cstdint>\n#include <cstddef>\n\nstatic volatile int *Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (!Size) return 0;\n  Sink = new int;\n  Sink = new int;\n  while (Sink) *Sink = 0;  // Infinite loop.\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/LoadTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer: find interesting value of array index.\n#include <assert.h>\n#include <cstdint>\n#include <cstring>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile int Sink;\nconst int kArraySize = 1234567;\nint array[kArraySize];\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 8) return 0;\n  size_t a = 0;\n  memcpy(&a, Data, 8);\n  Sink = array[a % (kArraySize + 1)];\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/MemcmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find a particular string.\n#include <cstring>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  // TODO: check other sizes.\n  if (Size >= 8 && memcmp(Data, \"01234567\", 8) == 0) {\n    if (Size >= 12 && memcmp(Data + 8, \"ABCD\", 4) == 0) {\n      if (Size >= 14 && memcmp(Data + 12, \"XY\", 2) == 0) {\n        if (Size >= 17 && memcmp(Data + 14, \"KLM\", 3) == 0) {\n          if (Size >= 27 && memcmp(Data + 17, \"ABCDE-GHIJ\", 10) == 0){\n            fprintf(stderr, \"BINGO %zd\\n\", Size);\n            for (size_t i = 0; i < Size; i++) {\n              uint8_t C = Data[i];\n              if (C >= 32 && C < 127)\n                fprintf(stderr, \"%c\", C);\n            }\n            fprintf(stderr, \"\\n\");\n            exit(1);\n          }\n        }\n      }\n    }\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/NthRunCrashTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Crash on the N-th execution.\n#include <cstdint>\n#include <cstddef>\n#include <iostream>\n\nstatic int Counter;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Counter++ == 1000) {\n    std::cout << \"BINGO; Found the target, exiting\\n\";\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/NullDerefOnEmptyTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the empty string.\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile int *Null = 0;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size == 0) {\n    std::cout << \"Found the target, dereferencing NULL\\n\";\n    *Null = 1;\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/NullDerefTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the string \"Hi!\".\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile int Sink;\nstatic volatile int *Null = 0;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size > 0 && Data[0] == 'H') {\n    Sink = 1;\n    if (Size > 1 && Data[1] == 'i') {\n      Sink = 2;\n      if (Size > 2 && Data[2] == '!') {\n        std::cout << \"Found the target, dereferencing NULL\\n\";\n        *Null = 1;\n      }\n    }\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/OneHugeAllocTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Tests OOM handling when there is a single large allocation.\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstring>\n#include <iostream>\n\nstatic volatile char *SinkPtr;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size > 0 && Data[0] == 'H') {\n    if (Size > 1 && Data[1] == 'i') {\n      if (Size > 2 && Data[2] == '!') {\n        size_t kSize = (size_t)1 << 31;\n        char *p = new char[kSize];\n        memset(p, 0, kSize);\n        SinkPtr = p;\n        delete [] p;\n      }\n    }\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Tests OOM handling.\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstring>\n#include <iostream>\n\nstatic volatile char *SinkPtr;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size > 0 && Data[0] == 'H') {\n    if (Size > 1 && Data[1] == 'i') {\n      if (Size > 2 && Data[2] == '!') {\n          size_t kSize = 0xff000000U;\n          char *p = new char[kSize];\n          SinkPtr = p;\n          delete [] p;\n      }\n    }\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/OutOfMemoryTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Tests OOM handling.\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstring>\n#include <iostream>\n#include <thread>\n\nstatic volatile char *SinkPtr;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size > 0 && Data[0] == 'H') {\n    if (Size > 1 && Data[1] == 'i') {\n      if (Size > 2 && Data[2] == '!') {\n        while (true) {\n          size_t kSize = 1 << 28;\n          char *p = new char[kSize];\n          memset(p, 0, kSize);\n          SinkPtr = p;\n          std::this_thread::sleep_for(std::chrono::seconds(1));\n        }\n      }\n    }\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/RepeatedBytesTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find repeated bytes.\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  assert(Data);\n  // Looking for AAAAAAAAAAAAAAAAAAAAAA or some such.\n  size_t CurA = 0, MaxA = 0;\n  for (size_t i = 0; i < Size; i++) {\n    // Make sure there are no conditionals in the loop so that\n    // coverage can't help the fuzzer.\n    int EQ = Data[i] == 'A';\n    CurA = EQ * (CurA + 1);\n    int GT = CurA > MaxA;\n    MaxA = GT * CurA + (!GT) * MaxA;\n  }\n  if (MaxA >= 20) {\n    std::cout << \"BINGO; Found the target (Max: \" << MaxA << \"), exiting\\n\";\n    exit(0);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/RepeatedMemcmp.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n\n#include <cstring>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  int Matches = 0;\n  for (size_t i = 0; i + 2 < Size; i += 3) {\n    const char *Pat = i % 2 ? \"foo\" : \"bar\";\n    if (!memcmp(Data + i, Pat, 3))\n      Matches++;\n  }\n  if (Matches > 20) {\n    fprintf(stderr, \"BINGO!\\n\");\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/ShrinkControlFlowTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test that we can find the minimal item in the corpus (3 bytes: \"FUZ\").\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstring>\n#include <cstdio>\n\nstatic volatile int Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  int8_t Ids[256];\n  memset(Ids, -1, sizeof(Ids));\n  for (size_t i = 0; i < Size; i++)\n    if (Ids[Data[i]] == -1)\n      Ids[Data[i]] = i;\n  int F = Ids[(unsigned char)'F'];\n  int U = Ids[(unsigned char)'U'];\n  int Z = Ids[(unsigned char)'Z'];\n  if (F >= 0 && U > F && Z > U) {\n    Sink++;\n    //fprintf(stderr, \"IDS: %d %d %d\\n\", F, U, Z);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/ShrinkValueProfileTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test that we can find the minimal item in the corpus (3 bytes: \"FUZ\").\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstring>\n#include <cstdio>\n\nstatic volatile uint32_t Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < sizeof(uint32_t)) return 0;\n  uint32_t X, Y;\n  size_t Offset = Size < 8 ? 0 : Size / 2;\n  memcpy(&X, Data + Offset, sizeof(uint32_t));\n  memcpy(&Y, \"FUZZ\", sizeof(uint32_t));\n  Sink = X == Y;\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SignedIntOverflowTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test for signed-integer-overflow.\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n#include <climits>\n\nstatic volatile int Sink;\nstatic int Large = INT_MAX;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  assert(Data);\n  if (Size > 0 && Data[0] == 'H') {\n    Sink = 1;\n    if (Size > 1 && Data[1] == 'i') {\n      Sink = 2;\n      if (Size > 2 && Data[2] == '!') {\n        Large++;  // int overflow.\n      }\n    }\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SimpleCmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find several narrow ranges.\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <cstdio>\n\nextern int AllLines[];\n\nbool PrintOnce(int Line) {\n  if (!AllLines[Line])\n    fprintf(stderr, \"Seen line %d\\n\", Line);\n  AllLines[Line] = 1;\n  return true;\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size != 22) return 0;\n  uint64_t x = 0;\n  int64_t  y = 0;\n  int32_t z = 0;\n  uint16_t a = 0;\n  memcpy(&x, Data, 8);  // 8\n  memcpy(&y, Data + 8, 8);  // 16\n  memcpy(&z, Data + 16, sizeof(z));  // 20\n  memcpy(&a, Data + 20, sizeof(a));  // 22\n\n  if (x > 1234567890 && PrintOnce(__LINE__) &&\n      x < 1234567895 && PrintOnce(__LINE__) &&\n      a == 0x4242 && PrintOnce(__LINE__) &&\n      y >= 987654321 && PrintOnce(__LINE__) &&\n      y <= 987654325 && PrintOnce(__LINE__) &&\n      z < -10000 && PrintOnce(__LINE__) &&\n      z >= -10005 && PrintOnce(__LINE__) &&\n      z != -10003 && PrintOnce(__LINE__) &&\n      true) {\n    fprintf(stderr, \"BINGO; Found the target: size %zd (%zd, %zd, %d, %d), exiting.\\n\",\n            Size, x, y, z, a);\n    exit(1);\n  }\n  return 0;\n}\n\nint AllLines[__LINE__ + 1];  // Must be the last line.\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SimpleDictionaryTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer.\n// The fuzzer must find a string based on dictionary words:\n//   \"Elvis\"\n//   \"Presley\"\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <cstring>\n#include <iostream>\n\nstatic volatile int Zero = 0;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  const char *Expected = \"ElvisPresley\";\n  if (Size < strlen(Expected)) return 0;\n  size_t Match = 0;\n  for (size_t i = 0; Expected[i]; i++)\n    if (Expected[i] + Zero == Data[i])\n      Match++;\n  if (Match == strlen(Expected)) {\n    std::cout << \"BINGO; Found the target, exiting\\n\";\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SimpleHashTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// This test computes a checksum of the data (all but the last 4 bytes),\n// and then compares the last 4 bytes with the computed value.\n// A fuzzer with cmp traces is expected to defeat this check.\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <cstdio>\n\n// A modified jenkins_one_at_a_time_hash initialized by non-zero,\n// so that simple_hash(0) != 0. See also\n// https://en.wikipedia.org/wiki/Jenkins_hash_function\nstatic uint32_t simple_hash(const uint8_t *Data, size_t Size) {\n  uint32_t Hash = 0x12039854;\n  for (uint32_t i = 0; i < Size; i++) {\n    Hash += Data[i];\n    Hash += (Hash << 10);\n    Hash ^= (Hash >> 6);\n  }\n  Hash += (Hash << 3);\n  Hash ^= (Hash >> 11);\n  Hash += (Hash << 15);\n  return Hash;\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 14)\n    return 0;\n\n  uint32_t Hash = simple_hash(&Data[0], Size - 4);\n  uint32_t Want = reinterpret_cast<const uint32_t *>(&Data[Size - 4])[0];\n  if (Hash != Want)\n    return 0;\n  fprintf(stderr, \"BINGO; simple_hash defeated: %x == %x\\n\", (unsigned int)Hash,\n          (unsigned int)Want);\n  exit(1);\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SimpleTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the string \"Hi!\".\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile int Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  assert(Data);\n  if (Size > 0 && Data[0] == 'H') {\n    Sink = 1;\n    if (Size > 1 && Data[1] == 'i') {\n      Sink = 2;\n      if (Size > 2 && Data[2] == '!') {\n        std::cout << \"BINGO; Found the target, exiting\\n\";\n        exit(0);\n      }\n    }\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SimpleThreadedTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Threaded test for a fuzzer. The fuzzer should find \"H\"\n#include <assert.h>\n#include <cstdint>\n#include <cstddef>\n#include <cstring>\n#include <iostream>\n#include <thread>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  auto C = [&] {\n    if (Size >= 2 && Data[0] == 'H') {\n        std::cout << \"BINGO; Found the target, exiting\\n\";\n        abort();\n    }\n  };\n  std::thread T[] = {std::thread(C), std::thread(C), std::thread(C),\n                     std::thread(C), std::thread(C), std::thread(C)};\n  for (auto &X : T)\n    X.join();\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SingleMemcmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find a particular string.\n#include <cstring>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  char *S = (char*)Data;\n  if (Size >= 6 && !memcmp(S, \"qwerty\", 6)) {\n    fprintf(stderr, \"BINGO\\n\");\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SingleStrcmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find a particular string.\n#include <cstring>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  char *S = (char*)Data;\n  if (Size >= 7 && !strcmp(S, \"qwerty\")) {\n    fprintf(stderr, \"BINGO\\n\");\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SingleStrncmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find a particular string.\n#include <cstring>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  char *S = (char*)Data;\n  if (Size >= 6 && !strncmp(S, \"qwerty\", 6)) {\n    fprintf(stderr, \"BINGO\\n\");\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SpamyTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// The test spams to stderr and stdout.\n#include <assert.h>\n#include <cstdint>\n#include <cstdio>\n#include <cstddef>\n#include <iostream>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  assert(Data);\n  printf(\"PRINTF_STDOUT\\n\");\n  fflush(stdout);\n  fprintf(stderr, \"PRINTF_STDERR\\n\");\n  std::cout << \"STREAM_COUT\\n\";\n  std::cout.flush();\n  std::cerr << \"STREAM_CERR\\n\";\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/StrcmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Break through a series of strcmp.\n#include <cstring>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <cassert>\n\nbool Eq(const uint8_t *Data, size_t Size, const char *Str) {\n  char Buff[1024];\n  size_t Len = strlen(Str);\n  if (Size < Len) return false;\n  if (Len >= sizeof(Buff)) return false;\n  memcpy(Buff, (char*)Data, Len);\n  Buff[Len] = 0;\n  int res = strcmp(Buff, Str);\n  return res == 0;\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Eq(Data, Size, \"ABC\") &&\n      Size >= 3 && Eq(Data + 3, Size - 3, \"QWER\") &&\n      Size >= 7 && Eq(Data + 7, Size - 7, \"ZXCVN\") &&\n      Size >= 14 && Data[13] == 42\n    ) {\n    fprintf(stderr, \"BINGO\\n\");\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/StrncmpOOBTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test that libFuzzer itself does not read out of bounds.\n#include <assert.h>\n#include <cstdint>\n#include <cstring>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile int Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 5) return 0;\n  const char *Ch = reinterpret_cast<const char *>(Data);\n  if (Ch[Size - 3] == 'a')\n    Sink = strncmp(Ch + Size - 3, \"abcdefg\", 6);\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/StrncmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find a particular string.\n#include <cstring>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n\nstatic volatile int sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  // TODO: check other sizes.\n  char *S = (char*)Data;\n  if (Size >= 8 && strncmp(S, \"123\", 8))\n    sink = 1;\n  if (Size >= 8 && strncmp(S, \"01234567\", 8) == 0) {\n    if (Size >= 12 && strncmp(S + 8, \"ABCD\", 4) == 0) {\n      if (Size >= 14 && strncmp(S + 12, \"XY\", 2) == 0) {\n        if (Size >= 17 && strncmp(S + 14, \"KLM\", 3) == 0) {\n          fprintf(stderr, \"BINGO\\n\");\n          exit(1);\n        }\n      }\n    }\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/StrstrTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Test strstr and strcasestr hooks.\n#include <string>\n#include <string.h>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n\n// Windows does not have strcasestr and memmem, so we are not testing them.\n#ifdef _WIN32\n#define strcasestr strstr\n#define memmem(a, b, c, d) true\n#endif\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 4) return 0;\n  std::string s(reinterpret_cast<const char*>(Data), Size);\n  if (strstr(s.c_str(), \"FUZZ\") &&\n      strcasestr(s.c_str(), \"aBcD\") &&\n      memmem(s.data(), s.size(), \"kuku\", 4)\n      ) {\n    fprintf(stderr, \"BINGO\\n\");\n    exit(1);\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SwapCmpTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// The fuzzer must find several constants with swapped bytes.\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <cstdio>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 14) return 0;\n  uint64_t x = 0;\n  uint32_t y = 0;\n  uint16_t z = 0;\n  memcpy(&x, Data, sizeof(x));\n  memcpy(&y, Data + Size / 2, sizeof(y));\n  memcpy(&z, Data + Size - sizeof(z), sizeof(z));\n\n  x = __builtin_bswap64(x);\n  y = __builtin_bswap32(y);\n  z = __builtin_bswap16(z);\n\n  if (x == 0x46555A5A5A5A5546ULL &&\n      z == 0x4F4B &&\n      y == 0x66757A7A &&\n      true\n      ) {\n    if (Data[Size - 3] == 'z') {\n      fprintf(stderr, \"BINGO; Found the target\\n\");\n      exit(1);\n    }\n  }\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/Switch2Test.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the interesting switch value.\n#include <cstdint>\n#include <cstdlib>\n#include <cstdio>\n#include <cstring>\n#include <cstddef>\n\nint Switch(int a) {\n  switch(a) {\n    case 100001: return 1;\n    case 100002: return 2;\n    case 100003: return 4;\n  }\n  return 0;\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  const int N = 3;\n  if (Size < N * sizeof(int)) return 0;\n  int Res = 0;\n  for (int i = 0; i < N; i++) {\n    int X;\n    memcpy(&X, Data + i * sizeof(int), sizeof(int));\n    Res += Switch(X);\n  }\n  if (Res == 5 || Res == 3 || Res == 6 || Res == 7) {\n    fprintf(stderr, \"BINGO; Found the target, exiting; Res=%d\\n\", Res);\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/SwitchTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the interesting switch value.\n#include <cstdint>\n#include <cstdlib>\n#include <cstdio>\n#include <cstring>\n#include <cstddef>\n\nstatic volatile int Sink;\n\ntemplate<class T>\nbool Switch(const uint8_t *Data, size_t Size) {\n  T X;\n  if (Size < sizeof(X)) return false;\n  memcpy(&X, Data, sizeof(X));\n  switch (X) {\n    case 1: Sink = __LINE__; break;\n    case 101: Sink = __LINE__; break;\n    case 1001: Sink = __LINE__; break;\n    case 10001: Sink = __LINE__; break;\n//    case 100001: Sink = __LINE__; break;\n//    case 1000001: Sink = __LINE__; break;\n    case 10000001: Sink = __LINE__; break;\n    case 100000001: return true;\n  }\n  return false;\n}\n\nbool ShortSwitch(const uint8_t *Data, size_t Size) {\n  short X;\n  if (Size < sizeof(short)) return false;\n  memcpy(&X, Data, sizeof(short));\n  switch(X) {\n    case 42: Sink = __LINE__; break;\n    case 402: Sink = __LINE__; break;\n    case 4002: Sink = __LINE__; break;\n    case 5002: Sink = __LINE__; break;\n    case 7002: Sink = __LINE__; break;\n    case 9002: Sink = __LINE__; break;\n    case 14002: Sink = __LINE__; break;\n    case 21402: return true;\n  }\n  return false;\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size >= 4  && Switch<int>(Data, Size) &&\n      Size >= 12 && Switch<uint64_t>(Data + 4, Size - 4) &&\n      Size >= 14 && ShortSwitch(Data + 12, 2)\n    ) {\n    fprintf(stderr, \"BINGO; Found the target, exiting\\n\");\n    exit(1);\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/ThreadedLeakTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// The fuzzer should find a leak in a non-main thread.\n#include <cstdint>\n#include <cstddef>\n#include <thread>\n\nstatic volatile int *Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size == 0) return 0;\n  if (Data[0] != 'F') return 0;\n  std::thread T([&] { Sink = new int; });\n  T.join();\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/ThreadedTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Threaded test for a fuzzer. The fuzzer should not crash.\n#include <assert.h>\n#include <cstdint>\n#include <cstddef>\n#include <cstring>\n#include <thread>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size < 8) return 0;\n  assert(Data);\n  auto C = [&] {\n    size_t Res = 0;\n    for (size_t i = 0; i < Size / 2; i++)\n      Res += memcmp(Data, Data + Size / 2, 4);\n    return Res;\n  };\n  std::thread T[] = {std::thread(C), std::thread(C), std::thread(C),\n                     std::thread(C), std::thread(C), std::thread(C)};\n  for (auto &X : T)\n    X.join();\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/TimeoutEmptyTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the empty string.\n#include <cstdint>\n#include <cstddef>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  static volatile int Zero = 0;\n  if (!Size)\n    while(!Zero)\n      ;\n  return 0;\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/TimeoutTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Simple test for a fuzzer. The fuzzer must find the string \"Hi!\".\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nstatic volatile int Sink;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (Size > 0 && Data[0] == 'H') {\n    Sink = 1;\n    if (Size > 1 && Data[1] == 'i') {\n      Sink = 2;\n      if (Size > 2 && Data[2] == '!') {\n        Sink = 2;\n        while (Sink)\n          ;\n      }\n    }\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/TraceMallocTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// Tests -trace_malloc\n#include <assert.h>\n#include <cstdint>\n#include <cstdlib>\n#include <cstddef>\n#include <iostream>\n\nint *Ptr;\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  if (!Size) return 0;\n  if (*Data == 1) {\n    delete Ptr;\n    Ptr = nullptr;\n  } else if (*Data == 2) {\n    delete Ptr;\n    Ptr = new int;\n  } else if (*Data == 3) {\n    if (!Ptr)\n      Ptr = new int;\n  }\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/UninstrumentedTest.cpp",
    "content": "// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n\n// This test should not be instrumented.\n#include <cstdint>\n#include <cstddef>\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/afl-driver-extra-stats.test",
    "content": "; Test that not specifying an extra stats file isn't broken.\nRUN: unset AFL_DRIVER_EXTRA_STATS_FILENAME\nRUN: AFLDriverTest\n\n; Test that specifying an invalid extra stats file causes a crash.\nRUN: ASAN_OPTIONS= AFL_DRIVER_EXTRA_STATS_FILENAME=%T not --crash AFLDriverTest\n\n; Test that specifying a corrupted stats file causes a crash.\necho \"peak_rss_mb :0\" > %t\nASAN_OPTIONS= AFL_DRIVER_EXTRA_STATS_FILENAME=%t not --crash AFLDriverTest\n\n; Test that specifying a valid nonexistent stats file works.\nRUN: rm -f %t\nRUN: AFL_DRIVER_EXTRA_STATS_FILENAME=%t AFLDriverTest\nRUN: [[ $(grep \"peak_rss_mb\\|slowest_unit_time_sec\" %t | wc -l) -eq 2 ]]\n\n; Test that specifying a valid preexisting stats file works.\nRUN: printf \"peak_rss_mb : 0\\nslowest_unit_time_sec: 0\\n\" > %t\nRUN: AFL_DRIVER_EXTRA_STATS_FILENAME=%t AFLDriverTest\n; Check that both lines were printed.\nRUN: [[ $(grep \"peak_rss_mb\\|slowest_unit_time_sec\" %t | wc -l) -eq 2 ]]\n\n; Test that peak_rss_mb and slowest_unit_time_in_secs are only updated when necessary.\n; Check that both lines have 9999 since there's no way we have exceeded that\n; amount of time or virtual memory.\nRUN: printf \"peak_rss_mb : 9999\\nslowest_unit_time_sec: 9999\\n\" > %t\nRUN: AFL_DRIVER_EXTRA_STATS_FILENAME=%t AFLDriverTest\nRUN: [[ $(grep \"9999\" %t | wc -l) -eq 2 ]]\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/afl-driver-stderr.test",
    "content": "; Test that not specifying a stderr file isn't broken.\nRUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME\nRUN: AFLDriverTest\n\n; Test that specifying an invalid file causes a crash.\nRUN: ASAN_OPTIONS= AFL_DRIVER_STDERR_DUPLICATE_FILENAME=\"%T\" not --crash AFLDriverTest\n\n; Test that a file is created when specified as the duplicate stderr.\nRUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME=%t AFLDriverTest\nRUN: stat %t\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/caller-callee.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-CallerCalleeTest          -use_value_profile=1 -cross_over=0 -max_len=6 -seed=1 -runs=10000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/coverage.test",
    "content": "CHECK: COVERAGE:\nCHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13\nCHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14\nCHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16\nCHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:19\nCHECK: COVERED_DIRS: {{.*}}lib/Fuzzer/test\nRUN: not LLVMFuzzer-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s\n\nRUN: LLVMFuzzer-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO\nDSO: COVERAGE:\nDSO-DAG: COVERED:{{.*}}DSO1{{.*}}DSO1.cpp\nDSO-DAG: COVERED:{{.*}}DSO2{{.*}}DSO2.cpp\nDSO-DAG: COVERED:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain\nDSO-DAG: UNCOVERED_LINE:{{.*}}DSO1{{.*}}DSO1.cpp\nDSO-DAG: UNCOVERED_LINE:{{.*}}DSO2{{.*}}DSO2.cpp\nDSO-DAG: UNCOVERED_FUNC: in Uncovered1\nDSO-DAG: UNCOVERED_FUNC: in Uncovered2\nDSO-DAG: UNCOVERED_LINE: in LLVMFuzzerTestOneInput\nDSO-DAG: UNCOVERED_FILE:{{.*}}DSOTestExtra.cpp\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/dict1.txt",
    "content": "# Dictionary for SimpleDictionaryTest\n\na=\"Elvis\"\nb=\"Presley\"\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/dump_coverage.test",
    "content": "RUN: DIR=%t_workdir\nRUN: BUILD_DIR=$(pwd)\nRUN: rm -rf $DIR && mkdir -p $DIR && cd $DIR\nRUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s\nRUN: $BUILD_DIR/LLVMFuzzer-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO\nRUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV\nRUN: rm -rf $DIR\n\n\nCHECK: SanitizerCoverage: ./LLVMFuzzer-NullDerefTest.{{.*}}.sancov {{.*}} PCs written\n\nDSO: SanitizerCoverage: ./LLVMFuzzer-DSOTest.{{.*}}.sancov {{.*}} PCs written\nDSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO1.{{.*}}.sancov {{.*}} PCs written\nDSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO2.{{.*}}.sancov {{.*}} PCs written\n\nNOCOV-NOT: SanitizerCoverage: {{.*}} PCs written\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-customcrossover.test",
    "content": "RUN: rm -rf %t/CustomCrossover\nRUN: mkdir -p %t/CustomCrossover\nRUN: echo \"0123456789\" > %t/CustomCrossover/digits\nRUN: echo \"abcdefghij\" > %t/CustomCrossover/chars\nRUN: not LLVMFuzzer-CustomCrossOverTest -seed=1 -use_memcmp=0 -runs=100000 %t/CustomCrossover 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomCrossover\nRUN: rm -rf %t/CustomCrossover\n\nLLVMFuzzerCustomCrossover: In LLVMFuzzerCustomCrossover\nLLVMFuzzerCustomCrossover: BINGO\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-custommutator.test",
    "content": "RUN: not LLVMFuzzer-CustomMutatorTest 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomMutator\nLLVMFuzzerCustomMutator: In LLVMFuzzerCustomMutator\nLLVMFuzzerCustomMutator: BINGO\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-dict.test",
    "content": "CHECK: BINGO\nDone1000000: Done 1000000 runs in\n\nRUN: not LLVMFuzzer-SimpleDictionaryTest -dict=%S/dict1.txt -seed=1 -runs=1000003  2>&1 | FileCheck %s\nRUN:     LLVMFuzzer-SimpleDictionaryTest                    -seed=1 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-dirs.test",
    "content": "RUN: rm -rf %t/SUB1\nRUN: mkdir -p %t/SUB1/SUB2/SUB3\nRUN: echo a > %t/SUB1/a\nRUN: echo b > %t/SUB1/SUB2/b\nRUN: echo c > %t/SUB1/SUB2/SUB3/c\nRUN: LLVMFuzzer-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=SUBDIRS\nSUBDIRS: READ   units: 3\nRUN: echo zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz > %t/SUB1/long\nRUN: LLVMFuzzer-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=LONG\nLONG: INFO: -max_len is not provided, using 94\nRUN: rm -rf %t/SUB1\n\nRUN: not LLVMFuzzer-SimpleTest NONEXISTENT_DIR 2>&1 | FileCheck %s --check-prefix=NONEXISTENT_DIR\nNONEXISTENT_DIR: No such directory: NONEXISTENT_DIR; exiting\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-fdmask.test",
    "content": "RUN: LLVMFuzzer-SpamyTest -runs=1                  2>&1 | FileCheck %s --check-prefix=FD_MASK_0\nRUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=0 2>&1 | FileCheck %s --check-prefix=FD_MASK_0\nRUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_1\nRUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=2 2>&1 | FileCheck %s --check-prefix=FD_MASK_2\nRUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=FD_MASK_3\n\nFD_MASK_0: PRINTF_STDOUT\nFD_MASK_0: PRINTF_STDERR\nFD_MASK_0: STREAM_COUT\nFD_MASK_0: STREAM_CERR\nFD_MASK_0: INITED\n\nFD_MASK_1-NOT: PRINTF_STDOUT\nFD_MASK_1: PRINTF_STDERR\nFD_MASK_1-NOT: STREAM_COUT\nFD_MASK_1: STREAM_CERR\nFD_MASK_1: INITED\n\nFD_MASK_2: PRINTF_STDOUT\nFD_MASK_2-NOT: PRINTF_STDERR\nFD_MASK_2: STREAM_COUT\nFD_MASK_2-NOTE: STREAM_CERR\nFD_MASK_2: INITED\n\nFD_MASK_3-NOT: PRINTF_STDOUT\nFD_MASK_3-NOT: PRINTF_STDERR\nFD_MASK_3-NOT: STREAM_COUT\nFD_MASK_3-NOT: STREAM_CERR\nFD_MASK_3: INITED\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-finalstats.test",
    "content": "RUN: LLVMFuzzer-SimpleTest -seed=1 -runs=77 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS\nFINAL_STATS: stat::number_of_executed_units: 77\nFINAL_STATS: stat::average_exec_per_sec:     0\nFINAL_STATS: stat::new_units_added:\nFINAL_STATS: stat::slowest_unit_time_sec:    0\nFINAL_STATS: stat::peak_rss_mb:\n\nRUN: LLVMFuzzer-SimpleTest %S/dict1.txt -runs=33 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS1\nFINAL_STATS1: stat::number_of_executed_units: 33\nFINAL_STATS1: stat::peak_rss_mb:\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-flags.test",
    "content": "RUN: LLVMFuzzer-SimpleTest -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR\nFOO_BAR: WARNING: unrecognized flag '-foo_bar=1'; use -help=1 to list all flags\nFOO_BAR: BINGO\n\nRUN: LLVMFuzzer-SimpleTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH\nDASH_DASH: WARNING: did you mean '-max_len=100' (single dash)?\nDASH_DASH: INFO: A corpus is not provided, starting from an empty corpus\n\nRUN: LLVMFuzzer-SimpleTest -help=1 2>&1 | FileCheck %s --check-prefix=NO_INTERNAL\nNO_INTERNAL-NOT: internal flag\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-jobs.test",
    "content": "RUN: rm -rf %tmp\nRUN: mkdir %tmp && cd %tmp\n# Create a shared corpus directory\nRUN: rm -rf FuzzerJobsTestCORPUS\nRUN: mkdir FuzzerJobsTestCORPUS\nRUN: rm -f fuzz-{0,1}.log\n# Start fuzzer and in parallel check that the output files\n# that should be created exist.\nRUN: LLVMFuzzer-EmptyTest -max_total_time=4 -jobs=2 -workers=2 FuzzerJobsTestCORPUS > %t-fuzzer-jobs-test.log 2>&1 & export FUZZER_PID=$!\n# Wait a short while to give time for the child processes\n# to start fuzzing\nRUN: sleep 2\n# If the instances are running in parallel they should have created their log\n# files by now.\nRUN: ls fuzz-0.log\nRUN: ls fuzz-1.log\n# Wait for libfuzzer to finish.\n# This probably isn't portable but we need a way to block until\n# the fuzzer is done otherwise we might remove the files while\n# they are being used.\nRUN: while kill -0 ${FUZZER_PID}; do : ; done\nRUN: rm -f fuzz-{0,1}.log\nRUN: rm -rf FuzzerJobsTestCORPUS\nRUN: FileCheck -input-file=%t-fuzzer-jobs-test.log %s\nRUN: rm %t-fuzzer-jobs-test.log\nRUN: cd ../\n\nCHECK-DAG: Job 0 exited with exit code 0\nCHECK-DAG: Job 1 exited with exit code 0\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-leak.test",
    "content": "REQUIRES: lsan\nRUN: not LLVMFuzzer-LeakTest -runs=100000 -detect_leaks=1 2>&1 | FileCheck %s --check-prefix=LEAK_DURING\nLEAK_DURING: ERROR: LeakSanitizer: detected memory leaks\nLEAK_DURING: Direct leak of 4 byte(s) in 1 object(s) allocated from:\nLEAK_DURING: INFO: to ignore leaks on libFuzzer side use -detect_leaks=0\nLEAK_DURING: Test unit written to ./leak-\nLEAK_DURING-NOT: DONE\nLEAK_DURING-NOT: Done\n\nRUN: not LLVMFuzzer-LeakTest -runs=0 -detect_leaks=1 %S 2>&1 | FileCheck %s --check-prefix=LEAK_IN_CORPUS\nLEAK_IN_CORPUS: ERROR: LeakSanitizer: detected memory leaks\nLEAK_IN_CORPUS: INFO: a leak has been found in the initial corpus.\n\nRUN: not LLVMFuzzer-LeakTest -runs=100000000 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=MULTI_RUN_LEAK\nMULTI_RUN_LEAK-NOT: pulse\nMULTI_RUN_LEAK: LeakSanitizer: detected memory leaks\n\nRUN: not LLVMFuzzer-LeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER\nRUN: not LLVMFuzzer-LeakTest -runs=100000                 2>&1 | FileCheck %s --check-prefix=LEAK_DURING\nRUN: not LLVMFuzzer-ThreadedLeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER\nRUN: not LLVMFuzzer-ThreadedLeakTest -runs=100000                 2>&1 | FileCheck %s --check-prefix=LEAK_DURING\nLEAK_AFTER: Done 100000 runs in\nLEAK_AFTER: ERROR: LeakSanitizer: detected memory leaks\n\nRUN: not LLVMFuzzer-LeakTest -runs=100000 -max_len=1 2>&1 | FileCheck %s --check-prefix=MAX_LEN_1\nMAX_LEN_1: Test unit written to ./leak-7cf184f4c67ad58283ecb19349720b0cae756829\n\nRUN: not LLVMFuzzer-LeakTimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=LEAK_TIMEOUT\nLEAK_TIMEOUT: ERROR: libFuzzer: timeout after\nLEAK_TIMEOUT-NOT: LeakSanitizer\n\nRUN: LLVMFuzzer-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS\nACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation\n\nRUN: LLVMFuzzer-LeakTest -error_exitcode=0\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-oom-with-profile.test",
    "content": "REQUIRES: linux\nRUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s\nCHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)\nCHECK: Live Heap Allocations\nCHECK: Test unit written to ./oom-\nSUMMARY: libFuzzer: out-of-memory\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-oom.test",
    "content": "RUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s\nCHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)\nCHECK: Test unit written to ./oom-\nSUMMARY: libFuzzer: out-of-memory\n\nRUN: not LLVMFuzzer-OutOfMemorySingleLargeMallocTest 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC\nSINGLE_LARGE_MALLOC: libFuzzer: out-of-memory (malloc(42{{.*}}))\nSINGLE_LARGE_MALLOC: in LLVMFuzzerTestOneInput\n\n# Check that -rss_limit_mb=0 means no limit.\nRUN: LLVMFuzzer-AccumulateAllocationsTest -runs=1000 -rss_limit_mb=0\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-printcovpcs.test",
    "content": "RUN: LLVMFuzzer-SimpleTest -print_pcs=1 -seed=1 2>&1 | FileCheck %s --check-prefix=PCS\nPCS-NOT: NEW_PC\nPCS:INITED\nPCS:NEW_PC: {{0x[a-f0-9]+}}\nPCS:NEW_PC: {{0x[a-f0-9]+}}\nPCS:NEW\nPCS:BINGO\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-runs.test",
    "content": "RUN: mkdir -p %t\nRUN: echo abcd > %t/NthRunCrashTest.in\nRUN: LLVMFuzzer-NthRunCrashTest %t/NthRunCrashTest.in\nRUN: LLVMFuzzer-NthRunCrashTest %t/NthRunCrashTest.in -runs=10\nRUN: not LLVMFuzzer-NthRunCrashTest %t/NthRunCrashTest.in -runs=10000 2>&1 | FileCheck %s\nRUN: rm %t/NthRunCrashTest.in\nCHECK: BINGO\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-seed.test",
    "content": "RUN: LLVMFuzzer-SimpleCmpTest -seed=-1 -runs=0 2>&1 | FileCheck %s --check-prefix=CHECK_SEED_MINUS_ONE\nCHECK_SEED_MINUS_ONE: Seed: 4294967295\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-segv.test",
    "content": "RUN: ASAN_OPTIONS=handle_segv=0 not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER\nLIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal\nLIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal\nLIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash-\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-singleinputs.test",
    "content": "RUN: not LLVMFuzzer-NullDerefTest %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInput\nSingleInput-NOT: Test unit written to ./crash-\n\nRUN: rm -rf  %tmp/SINGLE_INPUTS\nRUN: mkdir -p  %tmp/SINGLE_INPUTS\nRUN: echo aaa > %tmp/SINGLE_INPUTS/aaa\nRUN: echo bbb > %tmp/SINGLE_INPUTS/bbb\nRUN: LLVMFuzzer-SimpleTest            %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS\nRUN: LLVMFuzzer-SimpleTest -max_len=2 %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS\nRUN: rm -rf  %tmp/SINGLE_INPUTS\nSINGLE_INPUTS: LLVMFuzzer-SimpleTest: Running 2 inputs 1 time(s) each.\nSINGLE_INPUTS: aaa in\nSINGLE_INPUTS: bbb in\nSINGLE_INPUTS: NOTE: fuzzing was not performed, you have only\nSINGLE_INPUTS: executed the target code on a fixed set of inputs.\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-threaded.test",
    "content": "CHECK: Done 1000 runs in\n\nRUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000  2>&1 | FileCheck %s\nRUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000  2>&1 | FileCheck %s\nRUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000  2>&1 | FileCheck %s\nRUN: LLVMFuzzer-ThreadedTest -use_traces=1 -runs=1000  2>&1 | FileCheck %s\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-timeout.test",
    "content": "RUN: not LLVMFuzzer-TimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutTest\nTimeoutTest: ALARM: working on the last Unit for\nTimeoutTest: Test unit written to ./timeout-\nTimeoutTest: == ERROR: libFuzzer: timeout after\nTimeoutTest: #0\nTimeoutTest: #1\nTimeoutTest: #2\nTimeoutTest: SUMMARY: libFuzzer: timeout\n\nRUN: not LLVMFuzzer-TimeoutTest -timeout=1 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInputTimeoutTest\nSingleInputTimeoutTest: ALARM: working on the last Unit for {{[1-3]}} seconds\nSingleInputTimeoutTest-NOT: Test unit written to ./timeout-\n\nRUN: LLVMFuzzer-TimeoutTest -timeout=1 -timeout_exitcode=0\n\nRUN: not LLVMFuzzer-TimeoutEmptyTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutEmptyTest\nTimeoutEmptyTest: ALARM: working on the last Unit for\nTimeoutEmptyTest: == ERROR: libFuzzer: timeout after\nTimeoutEmptyTest: SUMMARY: libFuzzer: timeout\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-traces-hooks.test",
    "content": "// FIXME: Support sanitizer hooks for memcmp and strcmp need\n// to be implemented in the sanitizer runtime for platforms other\n// than linux\nREQUIRES: linux\nCHECK: BINGO\nDone1000000: Done 1000000 runs in\n\nRUN: not LLVMFuzzer-MemcmpTest               -seed=4294967295 -runs=100000   2>&1 | FileCheck %s\nRUN:     LLVMFuzzer-MemcmpTest -use_memcmp=0 -seed=4294967295 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000\n\nRUN: not LLVMFuzzer-StrncmpTest               -seed=2 -runs=100000   2>&1 | FileCheck %s\nRUN:     LLVMFuzzer-StrncmpTest -use_memcmp=0 -seed=3 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000\n\nRUN: not LLVMFuzzer-StrcmpTest               -seed=4 -runs=200000   2>&1 | FileCheck %s\nRUN:     LLVMFuzzer-StrcmpTest -use_memcmp=0 -seed=5 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000\n\nRUN: not LLVMFuzzer-StrstrTest               -seed=6 -runs=200000   2>&1 | FileCheck %s\nRUN:     LLVMFuzzer-StrstrTest -use_memmem=0 -seed=7 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000\n\nRUN: LLVMFuzzer-RepeatedMemcmp -seed=10 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT\nRECOMMENDED_DICT:###### Recommended dictionary. ######\nRECOMMENDED_DICT-DAG: \"foo\"\nRECOMMENDED_DICT-DAG: \"bar\"\nRECOMMENDED_DICT:###### End of recommended dictionary. ######\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer-ubsan.test",
    "content": "RUN: not LLVMFuzzer-SignedIntOverflowTest-Ubsan 2>&1 | FileCheck %s\nCHECK: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'\nCHECK: Test unit written to ./crash-\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/fuzzer.test",
    "content": "CHECK: BINGO\nDone1000000: Done 1000000 runs in\n\nRUN: LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s\n\n# only_ascii mode. Will perform some minimal self-validation.\nRUN: LLVMFuzzer-SimpleTest -only_ascii=1 2>&1\n\nRUN: LLVMFuzzer-SimpleCmpTest -max_total_time=1 -use_cmp=0 2>&1 | FileCheck %s --check-prefix=MaxTotalTime\nMaxTotalTime: Done {{.*}} runs in {{.}} second(s)\n\nRUN: not LLVMFuzzer-NullDerefTest                  2>&1 | FileCheck %s --check-prefix=NullDerefTest\nRUN: not LLVMFuzzer-NullDerefTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=NullDerefTest\nNullDerefTest: ERROR: AddressSanitizer: SEGV on unknown address\nNullDerefTest: Test unit written to ./crash-\nRUN: not LLVMFuzzer-NullDerefTest  -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix\nNullDerefTestPrefix: Test unit written to ZZZcrash-\nRUN: not LLVMFuzzer-NullDerefTest  -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=NullDerefTestExactPath\nNullDerefTestExactPath: Test unit written to FOOBAR\n\nRUN: not LLVMFuzzer-NullDerefOnEmptyTest -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=NULL_DEREF_ON_EMPTY\nNULL_DEREF_ON_EMPTY: stat::number_of_executed_units:\n\n#not LLVMFuzzer-FullCoverageSetTest -timeout=15 -seed=1 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s\n\nRUN: not LLVMFuzzer-CounterTest  -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS\n\nCOUNTERS: INITED {{.*}} {{bits:|ft:}}\nCOUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}\nCOUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}\nCOUNTERS: BINGO\n\n# Don't run UninstrumentedTest for now since we build libFuzzer itself with asan.\nDISABLED: not LLVMFuzzer-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED\nUNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting.\n\nRUN: not LLVMFuzzer-UninstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE\nNO_COVERAGE: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting\n\nRUN: not LLVMFuzzer-BufferOverflowOnInput 2>&1 | FileCheck %s --check-prefix=OOB\nOOB: AddressSanitizer: heap-buffer-overflow\nOOB: is located 0 bytes to the right of 3-byte region\n\nRUN: not LLVMFuzzer-InitializeTest -use_value_profile=1 2>&1 | FileCheck %s\n\nRUN: not LLVMFuzzer-DSOTest 2>&1 | FileCheck %s --check-prefix=DSO\nDSO: INFO: Loaded 3 modules\nDSO: BINGO\n\nRUN: LLVMFuzzer-SimpleTest  -exit_on_src_pos=SimpleTest.cpp:17                 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS\nRUN: LLVMFuzzer-ShrinkControlFlowTest  -exit_on_src_pos=ShrinkControlFlowTest.cpp:23 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS\nEXIT_ON_SRC_POS: INFO: found line matching '{{.*}}', exiting.\n\nRUN: ASAN_OPTIONS=strict_string_checks=1 not LLVMFuzzer-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP\nSTRNCMP: AddressSanitizer: heap-buffer-overflow\nSTRNCMP-NOT: __sanitizer_weak_hook_strncmp\nSTRNCMP: in LLVMFuzzerTestOneInput\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/hi.txt",
    "content": "Hi!"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/lit.cfg",
    "content": "import lit.formats\nimport sys\n\nconfig.name = \"LLVMFuzzer\"\nconfig.test_format = lit.formats.ShTest(True)\nconfig.suffixes = ['.test']\nconfig.test_source_root = os.path.dirname(__file__)\n\n# Tweak PATH to include llvm tools dir and current exec dir.\nllvm_tools_dir = getattr(config, 'llvm_tools_dir', None)\nif (not llvm_tools_dir) or (not os.path.exists(llvm_tools_dir)):\n  lit_config.fatal(\"Invalid llvm_tools_dir config attribute: %r\" % llvm_tools_dir)\npath = os.path.pathsep.join((llvm_tools_dir, config.test_exec_root,\n                             config.environment['PATH']))\nconfig.environment['PATH'] = path\n\nif config.has_lsan:\n  lit_config.note('lsan feature available')\n  config.available_features.add('lsan')\nelse:\n  lit_config.note('lsan feature unavailable')\n\nif sys.platform.startswith('linux'):\n  # Note the value of ``sys.platform`` is not consistent\n  # between python 2 and 3, hence the use of ``.startswith()``.\n  lit_config.note('linux feature available')\n  config.available_features.add('linux')\nelse:\n  lit_config.note('linux feature unavailable')\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/lit.site.cfg.in",
    "content": "config.test_exec_root = \"@CMAKE_CURRENT_BINARY_DIR@\"\nconfig.llvm_tools_dir = \"@LLVM_TOOLS_DIR@\"\nconfig.has_lsan = True if @HAS_LSAN@ == 1 else False\nlit_config.load_config(config, \"@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg\")\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/merge.test",
    "content": "CHECK: BINGO\n\nRUN: rm -rf  %tmp/T1 %tmp/T2\nRUN: mkdir -p %tmp/T1 %tmp/T2\nRUN: echo F..... > %tmp/T1/1\nRUN: echo .U.... > %tmp/T1/2\nRUN: echo ..Z... > %tmp/T1/3\n\n# T1 has 3 elements, T2 is empty.\nRUN: LLVMFuzzer-FullCoverageSetTest         -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1\nCHECK1: MERGE-OUTER: 3 files, 3 in the initial corpus\nCHECK1: MERGE-OUTER: 0 new files with 0 new features added\n\nRUN: echo ...Z.. > %tmp/T2/1\nRUN: echo ....E. > %tmp/T2/2\nRUN: echo .....R > %tmp/T2/3\nRUN: echo F..... > %tmp/T2/a\nRUN: echo .U.... > %tmp/T2/b\nRUN: echo ..Z... > %tmp/T2/c\n\n# T1 has 3 elements, T2 has 6 elements, only 3 are new.\nRUN: LLVMFuzzer-FullCoverageSetTest         -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2\nCHECK2: MERGE-OUTER: 9 files, 3 in the initial corpus\nCHECK2: MERGE-OUTER: 3 new files with 3 new features added\n\n# Now, T1 has 6 units and T2 has no new interesting units.\nRUN: LLVMFuzzer-FullCoverageSetTest         -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3\nCHECK3: MERGE-OUTER: 12 files, 6 in the initial corpus\nCHECK3: MERGE-OUTER: 0 new files with 0 new features added\n\n# Check that we respect max_len during the merge and don't crash.\nRUN: rm %tmp/T1/??*\nRUN: echo looooooooong > %tmp/T2/looooooooong\nRUN: LLVMFuzzer-FullCoverageSetTest         -merge=1 %tmp/T1 %tmp/T2 -max_len=6 2>&1 | FileCheck %s --check-prefix=MAX_LEN\nMAX_LEN: MERGE-OUTER: 3 new files\n\n# Check that merge tolerates failures.\nRUN: rm %tmp/T1/??*\nRUN: echo 'FUZZER' > %tmp/T2/FUZZER\nRUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=MERGE_WITH_CRASH\nMERGE_WITH_CRASH: MERGE-OUTER: succesfull in 2 attempt(s)\nMERGE_WITH_CRASH: MERGE-OUTER: 3 new files\n\n# Check that we actually limit the size with max_len\nRUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2  -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5\nMERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/minimize_crash.test",
    "content": "RUN: echo 'Hi!rv349f34t3gg' > not_minimal_crash\nRUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s\nCHECK: CRASH_MIN: failed to minimize beyond minimized-from-{{.*}} (3 bytes), exiting\nRUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT\nCHECK_EXACT: CRASH_MIN: failed to minimize beyond exact_minimized_path (3 bytes), exiting\nRUN: rm not_minimal_crash minimized-from-* exact_minimized_path\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/no-coverage/CMakeLists.txt",
    "content": "# These tests are not instrumented with coverage,\n# but have coverage rt in the binary.\n\nset(CMAKE_CXX_FLAGS\n  \"${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard\")\n\nset(NoCoverageTests\n  UninstrumentedTest\n  )\n\nforeach(Test ${NoCoverageTests})\n  add_libfuzzer_test(${Test}-NoCoverage SOURCES ../${Test}.cpp)\nendforeach()\n\n\n###############################################################################\n# AFL Driver test\n###############################################################################\n\nadd_executable(AFLDriverTest\n  ../AFLDriverTest.cpp ../../afl/afl_driver.cpp)\n\nset_target_properties(AFLDriverTest\n    PROPERTIES RUNTIME_OUTPUT_DIRECTORY\n    \"${CMAKE_BINARY_DIR}/lib/Fuzzer/test\"\n    )\n\n# Propagate value into parent directory\nset(TestBinaries ${TestBinaries} AFLDriverTest PARENT_SCOPE)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/repeated-bytes.test",
    "content": "CHECK: BINGO\nRUN: LLVMFuzzer-RepeatedBytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/shrink.test",
    "content": "RUN: LLVMFuzzer-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000  -shrink=1 2>&1 | FileCheck %s --check-prefix=SHRINK1\nRUN: LLVMFuzzer-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=0 2>&1 | FileCheck %s --check-prefix=SHRINK0\nRUN: LLVMFuzzer-ShrinkValueProfileTest -seed=1 -exit_on_item=aea2e3923af219a8956f626558ef32f30a914ebc -runs=100000 -shrink=1 -use_value_profile=1 2>&1 | FileCheck %s --check-prefix=SHRINK1_VP\n\nSHRINK0: Done 1000000 runs in\nSHRINK1: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60', exiting.\nSHRINK1_VP: INFO: found item with checksum 'aea2e3923af219a8956f626558ef32f30a914ebc', exiting\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/simple-cmp.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SimpleCmpTest -seed=1 -runs=100000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/standalone.test",
    "content": "RUN: LLVMFuzzer-StandaloneInitializeTest %S/hi.txt %S/dict1.txt 2>&1 | FileCheck %s\nCHECK: StandaloneFuzzTargetMain: running 2 inputs\nCHECK: Done:    {{.*}}hi.txt: (3 bytes)\nCHECK: Done:    {{.*}}dict1.txt: (61 bytes)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/swap-cmp.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SwapCmpTest -seed=1 -runs=10000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/trace-malloc.test",
    "content": "RUN: LLVMFuzzer-TraceMallocTest -seed=1 -trace_malloc=1 -runs=10000 2>&1 | FileCheck %s\nCHECK-DAG: MallocFreeTracer: STOP 0 0 (same)\nCHECK-DAG: MallocFreeTracer: STOP 0 1 (DIFFERENT)\nCHECK-DAG: MallocFreeTracer: STOP 1 0 (DIFFERENT)\nCHECK-DAG: MallocFreeTracer: STOP 1 1 (same)\n\nRUN: LLVMFuzzer-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2\nTRACE2-DAG: FREE[0]\nTRACE2-DAG: MALLOC[0]\nTRACE2-DAG: in LLVMFuzzerTestOneInput\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/ubsan/CMakeLists.txt",
    "content": "# These tests are instrumented with ubsan in non-recovery mode.\n\nset(CMAKE_CXX_FLAGS\n  \"${LIBFUZZER_FLAGS_BASE} -fsanitize=undefined -fno-sanitize-recover=all\")\n\nset(UbsanTests\n  SignedIntOverflowTest\n  )\n\nforeach(Test ${UbsanTests})\n  add_libfuzzer_test(${Test}-Ubsan SOURCES ../${Test}.cpp)\nendforeach()\n\n# Propagate value into parent directory\nset(TestBinaries ${TestBinaries} PARENT_SCOPE)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/ulimit.test",
    "content": "RUN: ulimit -s 1000\nRUN: LLVMFuzzer-SimpleTest\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/uninstrumented/CMakeLists.txt",
    "content": "# These tests are not instrumented with coverage and don't\n# have coverage rt in the binary.\n\nset(CMAKE_CXX_FLAGS\n  \"${LIBFUZZER_FLAGS_BASE} -fno-sanitize=all -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard\")\n\nset(UninstrumentedTests\n  UninstrumentedTest\n  )\n\nforeach(Test ${UninstrumentedTests})\n  add_libfuzzer_test(${Test}-Uninstrumented SOURCES ../${Test}.cpp)\nendforeach()\n\n# Propagate value into parent directory\nset(TestBinaries ${TestBinaries} PARENT_SCOPE)\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/unit/lit.cfg",
    "content": "import lit.formats\n\nconfig.name = \"LLVMFuzzer-Unittest\"\nprint config.test_exec_root\nconfig.test_format = lit.formats.GoogleTest(\".\", \"Unittest\")\nconfig.suffixes = []\nconfig.test_source_root = config.test_exec_root\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/unit/lit.site.cfg.in",
    "content": "config.test_exec_root = \"@CMAKE_CURRENT_BINARY_DIR@\"\nlit_config.load_config(config, \"@CMAKE_CURRENT_SOURCE_DIR@/unit/lit.cfg\")\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-cmp.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SimpleCmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-cmp2.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SimpleHashTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-cmp3.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-AbsNegAndConstantTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-cmp4.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-AbsNegAndConstant64Test -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-div.test",
    "content": "CHECK: AddressSanitizer: FPE\nRUN: not LLVMFuzzer-DivTest -seed=1 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-load.test",
    "content": "CHECK: AddressSanitizer: global-buffer-overflow\nRUN: not LLVMFuzzer-LoadTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-mem.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SingleMemcmpTest -seed=1  -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-set.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-FourIndependentBranchesTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-strcmp.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SingleStrcmpTest -seed=1  -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-strncmp.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SingleStrncmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/Fuzzer/test/value-profile-switch.test",
    "content": "CHECK: BINGO\nRUN: not LLVMFuzzer-SwitchTest  -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s\nRUN: not LLVMFuzzer-Switch2Test -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/doctest/LICENSE.txt",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016-2021 Viktor Kirilov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/doctest/doctest.h",
    "content": "// ====================================================================== lgtm [cpp/missing-header-guard]\n// == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! ==\n// ======================================================================\n//\n// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD\n//\n// Copyright (c) 2016-2021 Viktor Kirilov\n//\n// Distributed under the MIT Software License\n// See accompanying file LICENSE.txt or copy at\n// https://opensource.org/licenses/MIT\n//\n// The documentation can be found at the library's page:\n// https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md\n//\n// =================================================================================================\n// =================================================================================================\n// =================================================================================================\n//\n// The library is heavily influenced by Catch - https://github.com/catchorg/Catch2\n// which uses the Boost Software License - Version 1.0\n// see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt\n//\n// The concept of subcases (sections in Catch) and expression decomposition are from there.\n// Some parts of the code are taken directly:\n// - stringification - the detection of \"ostream& operator<<(ostream&, const T&)\" and StringMaker<>\n// - the Approx() helper class for floating point comparison\n// - colors in the console\n// - breaking into a debugger\n// - signal / SEH handling\n// - timer\n// - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste)\n//\n// The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest\n// which uses the Boost Software License - Version 1.0\n// see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt\n//\n// =================================================================================================\n// =================================================================================================\n// =================================================================================================\n\n#ifndef DOCTEST_LIBRARY_INCLUDED\n#define DOCTEST_LIBRARY_INCLUDED\n\n// =================================================================================================\n// == VERSION ======================================================================================\n// =================================================================================================\n\n#define DOCTEST_VERSION_MAJOR 2\n#define DOCTEST_VERSION_MINOR 4\n#define DOCTEST_VERSION_PATCH 6\n#define DOCTEST_VERSION_STR \"2.4.6\"\n\n#define DOCTEST_VERSION                                                                            \\\n    (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)\n\n// =================================================================================================\n// == COMPILER VERSION =============================================================================\n// =================================================================================================\n\n// ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect\n\n#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH))\n\n// GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl...\n#if defined(_MSC_VER) && defined(_MSC_FULL_VER)\n#if _MSC_VER == _MSC_FULL_VER / 10000\n#define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)\n#else // MSVC\n#define DOCTEST_MSVC                                                                               \\\n    DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)\n#endif // MSVC\n#endif // MSVC\n#if defined(__clang__) && defined(__clang_minor__)\n#define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__)\n#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) &&              \\\n        !defined(__INTEL_COMPILER)\n#define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)\n#endif // GCC\n\n#ifndef DOCTEST_MSVC\n#define DOCTEST_MSVC 0\n#endif // DOCTEST_MSVC\n#ifndef DOCTEST_CLANG\n#define DOCTEST_CLANG 0\n#endif // DOCTEST_CLANG\n#ifndef DOCTEST_GCC\n#define DOCTEST_GCC 0\n#endif // DOCTEST_GCC\n\n// =================================================================================================\n// == COMPILER WARNINGS HELPERS ====================================================================\n// =================================================================================================\n\n#if DOCTEST_CLANG\n#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)\n#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma(\"clang diagnostic push\")\n#define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w)\n#define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma(\"clang diagnostic pop\")\n#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)                                                \\\n    DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w)\n#else // DOCTEST_CLANG\n#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH\n#define DOCTEST_CLANG_SUPPRESS_WARNING(w)\n#define DOCTEST_CLANG_SUPPRESS_WARNING_POP\n#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)\n#endif // DOCTEST_CLANG\n\n#if DOCTEST_GCC\n#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)\n#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma(\"GCC diagnostic push\")\n#define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w)\n#define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma(\"GCC diagnostic pop\")\n#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)                                                  \\\n    DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w)\n#else // DOCTEST_GCC\n#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH\n#define DOCTEST_GCC_SUPPRESS_WARNING(w)\n#define DOCTEST_GCC_SUPPRESS_WARNING_POP\n#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)\n#endif // DOCTEST_GCC\n\n#if DOCTEST_MSVC\n#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push))\n#define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w))\n#define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop))\n#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)                                                 \\\n    DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w)\n#else // DOCTEST_MSVC\n#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH\n#define DOCTEST_MSVC_SUPPRESS_WARNING(w)\n#define DOCTEST_MSVC_SUPPRESS_WARNING_POP\n#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)\n#endif // DOCTEST_MSVC\n\n// =================================================================================================\n// == COMPILER WARNINGS ============================================================================\n// =================================================================================================\n\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wunknown-pragmas\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wnon-virtual-dtor\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wweak-vtables\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wpadded\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wdeprecated\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wmissing-prototypes\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wunused-local-typedef\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wc++98-compat\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wc++98-compat-pedantic\")\n\nDOCTEST_GCC_SUPPRESS_WARNING_PUSH\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wunknown-pragmas\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wpragmas\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Weffc++\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wstrict-overflow\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wstrict-aliasing\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wctor-dtor-privacy\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wmissing-declarations\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wnon-virtual-dtor\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wunused-local-typedefs\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wuseless-cast\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wnoexcept\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wsign-promo\")\n\nDOCTEST_MSVC_SUPPRESS_WARNING_PUSH\nDOCTEST_MSVC_SUPPRESS_WARNING(4616) // invalid compiler warning\nDOCTEST_MSVC_SUPPRESS_WARNING(4619) // invalid compiler warning\nDOCTEST_MSVC_SUPPRESS_WARNING(4996) // The compiler encountered a deprecated declaration\nDOCTEST_MSVC_SUPPRESS_WARNING(4706) // assignment within conditional expression\nDOCTEST_MSVC_SUPPRESS_WARNING(4512) // 'class' : assignment operator could not be generated\nDOCTEST_MSVC_SUPPRESS_WARNING(4127) // conditional expression is constant\nDOCTEST_MSVC_SUPPRESS_WARNING(4820) // padding\nDOCTEST_MSVC_SUPPRESS_WARNING(4625) // copy constructor was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment operator was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(4640) // construction of local static object is not thread-safe\n// static analysis\nDOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Declare it 'noexcept'\nDOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable\nDOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ...\nDOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtr...\nDOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'\n\n// 4548 - expression before comma has no effect; expected expression with side - effect\n// 4265 - class has virtual functions, but destructor is not virtual\n// 4986 - exception specification does not match previous declaration\n// 4350 - behavior change: 'member1' called instead of 'member2'\n// 4668 - 'x' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'\n// 4365 - conversion from 'int' to 'unsigned long', signed/unsigned mismatch\n// 4774 - format string expected in argument 'x' is not a string literal\n// 4820 - padding in structs\n\n// only 4 should be disabled globally:\n// - 4514 # unreferenced inline function has been removed\n// - 4571 # SEH related\n// - 4710 # function not inlined\n// - 4711 # function 'x' selected for automatic inline expansion\n\n#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN                                 \\\n    DOCTEST_MSVC_SUPPRESS_WARNING_PUSH                                                             \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4548)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4265)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4986)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4350)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4668)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4365)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4774)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4820)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4625)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4626)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(5027)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(5026)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(4623)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(5039)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(5045)                                                            \\\n    DOCTEST_MSVC_SUPPRESS_WARNING(5105)\n\n#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP\n\n// =================================================================================================\n// == FEATURE DETECTION ============================================================================\n// =================================================================================================\n\n// general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support\n// MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx\n// GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html\n// MSVC version table:\n// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering\n// MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019)\n// MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017)\n// MSVC++ 14.0      _MSC_VER == 1900 (Visual Studio 2015)\n// MSVC++ 12.0      _MSC_VER == 1800 (Visual Studio 2013)\n// MSVC++ 11.0      _MSC_VER == 1700 (Visual Studio 2012)\n// MSVC++ 10.0      _MSC_VER == 1600 (Visual Studio 2010)\n// MSVC++ 9.0       _MSC_VER == 1500 (Visual Studio 2008)\n// MSVC++ 8.0       _MSC_VER == 1400 (Visual Studio 2005)\n\n#if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH)\n#define DOCTEST_CONFIG_WINDOWS_SEH\n#endif // MSVC\n#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH)\n#undef DOCTEST_CONFIG_WINDOWS_SEH\n#endif // DOCTEST_CONFIG_NO_WINDOWS_SEH\n\n#if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) &&             \\\n        !defined(__EMSCRIPTEN__)\n#define DOCTEST_CONFIG_POSIX_SIGNALS\n#endif // _WIN32\n#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS)\n#undef DOCTEST_CONFIG_POSIX_SIGNALS\n#endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS\n\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND)\n#define DOCTEST_CONFIG_NO_EXCEPTIONS\n#endif // no exceptions\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n\n#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n#define DOCTEST_CONFIG_NO_EXCEPTIONS\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS\n\n#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS)\n#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS\n\n#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT)\n#define DOCTEST_CONFIG_IMPLEMENT\n#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN\n\n#if defined(_WIN32) || defined(__CYGWIN__)\n#if DOCTEST_MSVC\n#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport)\n#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport)\n#else // MSVC\n#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport))\n#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport))\n#endif // MSVC\n#else  // _WIN32\n#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility(\"default\")))\n#define DOCTEST_SYMBOL_IMPORT\n#endif // _WIN32\n\n#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL\n#ifdef DOCTEST_CONFIG_IMPLEMENT\n#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT\n#else // DOCTEST_CONFIG_IMPLEMENT\n#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT\n#endif // DOCTEST_CONFIG_IMPLEMENT\n#else  // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL\n#define DOCTEST_INTERFACE\n#endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL\n\n#define DOCTEST_EMPTY\n\n#if DOCTEST_MSVC\n#define DOCTEST_NOINLINE __declspec(noinline)\n#define DOCTEST_UNUSED\n#define DOCTEST_ALIGNMENT(x)\n#elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)\n#define DOCTEST_NOINLINE\n#define DOCTEST_UNUSED\n#define DOCTEST_ALIGNMENT(x)\n#else\n#define DOCTEST_NOINLINE __attribute__((noinline))\n#define DOCTEST_UNUSED __attribute__((unused))\n#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))\n#endif\n\n#ifndef DOCTEST_NORETURN\n#define DOCTEST_NORETURN [[noreturn]]\n#endif // DOCTEST_NORETURN\n\n#ifndef DOCTEST_NOEXCEPT\n#define DOCTEST_NOEXCEPT noexcept\n#endif // DOCTEST_NOEXCEPT\n\n// =================================================================================================\n// == FEATURE DETECTION END ========================================================================\n// =================================================================================================\n\n// internal macros for string concatenation and anonymous variable name generation\n#define DOCTEST_CAT_IMPL(s1, s2) s1##s2\n#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2)\n#ifdef __COUNTER__ // not standard and may be missing for some compilers\n#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__)\n#else // __COUNTER__\n#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__)\n#endif // __COUNTER__\n\n#define DOCTEST_TOSTR(x) #x\n\n#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE\n#define DOCTEST_REF_WRAP(x) x&\n#else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE\n#define DOCTEST_REF_WRAP(x) x\n#endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE\n\n// not using __APPLE__ because... this is how Catch does it\n#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED\n#define DOCTEST_PLATFORM_MAC\n#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)\n#define DOCTEST_PLATFORM_IPHONE\n#elif defined(_WIN32)\n#define DOCTEST_PLATFORM_WINDOWS\n#else // DOCTEST_PLATFORM\n#define DOCTEST_PLATFORM_LINUX\n#endif // DOCTEST_PLATFORM\n\n#define DOCTEST_GLOBAL_NO_WARNINGS(var)                                                            \\\n    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wglobal-constructors\")                              \\\n    DOCTEST_CLANG_SUPPRESS_WARNING(\"-Wunused-variable\")                                            \\\n    static const int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp)\n#define DOCTEST_GLOBAL_NO_WARNINGS_END() DOCTEST_CLANG_SUPPRESS_WARNING_POP\n\n#ifndef DOCTEST_BREAK_INTO_DEBUGGER\n// should probably take a look at https://github.com/scottt/debugbreak\n#ifdef DOCTEST_PLATFORM_LINUX\n#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))\n// Break at the location of the failing check if possible\n#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__(\"int $3\\n\" : :) // NOLINT (hicpp-no-assembler)\n#else\n#include <signal.h>\n#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)\n#endif\n#elif defined(DOCTEST_PLATFORM_MAC)\n#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)\n#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__(\"int $3\\n\" : :) // NOLINT (hicpp-no-assembler)\n#else\n#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__(\"brk #0\"); // NOLINT (hicpp-no-assembler)\n#endif\n#elif DOCTEST_MSVC\n#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()\n#elif defined(__MINGW32__)\nDOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wredundant-decls\")\nextern \"C\" __declspec(dllimport) void __stdcall DebugBreak();\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()\n#else // linux\n#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))\n#endif // linux\n#endif // DOCTEST_BREAK_INTO_DEBUGGER\n\n// this is kept here for backwards compatibility since the config option was changed\n#ifdef DOCTEST_CONFIG_USE_IOSFWD\n#define DOCTEST_CONFIG_USE_STD_HEADERS\n#endif // DOCTEST_CONFIG_USE_IOSFWD\n\n#ifdef DOCTEST_CONFIG_USE_STD_HEADERS\n#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n#include <iosfwd>\n#include <cstddef>\n#include <ostream>\n#else // DOCTEST_CONFIG_USE_STD_HEADERS\n\n#if DOCTEST_CLANG\n// to detect if libc++ is being used with clang (the _LIBCPP_VERSION identifier)\n#include <ciso646>\n#endif // clang\n\n#ifdef _LIBCPP_VERSION\n#define DOCTEST_STD_NAMESPACE_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD\n#define DOCTEST_STD_NAMESPACE_END _LIBCPP_END_NAMESPACE_STD\n#else // _LIBCPP_VERSION\n#define DOCTEST_STD_NAMESPACE_BEGIN namespace std {\n#define DOCTEST_STD_NAMESPACE_END }\n#endif // _LIBCPP_VERSION\n\n// Forward declaring 'X' in namespace std is not permitted by the C++ Standard.\nDOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643)\n\nDOCTEST_STD_NAMESPACE_BEGIN // NOLINT (cert-dcl58-cpp)\ntypedef decltype(nullptr) nullptr_t;\ntemplate <class charT>\nstruct char_traits;\ntemplate <>\nstruct char_traits<char>;\ntemplate <class charT, class traits>\nclass basic_ostream;\ntypedef basic_ostream<char, char_traits<char>> ostream;\ntemplate <class... Types>\nclass tuple;\n#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)\n// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183\ntemplate <class _Ty>\nclass allocator;\ntemplate <class _Elem, class _Traits, class _Alloc>\nclass basic_string;\nusing string = basic_string<char, char_traits<char>, allocator<char>>;\n#endif // VS 2019\nDOCTEST_STD_NAMESPACE_END\n\nDOCTEST_MSVC_SUPPRESS_WARNING_POP\n\n#endif // DOCTEST_CONFIG_USE_STD_HEADERS\n\n#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n#include <type_traits>\n#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n\nnamespace doctest {\n\nDOCTEST_INTERFACE extern bool is_running_in_test;\n\n// A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length\n// of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for:\n// - \"is small\" bit - the highest bit - if \"0\" then it is small - otherwise its \"1\" (128)\n// - if small - capacity left before going on the heap - using the lowest 5 bits\n// - if small - 2 bits are left unused - the second and third highest ones\n// - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator)\n//              and the \"is small\" bit remains \"0\" (\"as well as the capacity left\") so its OK\n// Idea taken from this lecture about the string implementation of facebook/folly - fbstring\n// https://www.youtube.com/watch?v=kPR8h4-qZdk\n// TODO:\n// - optimizations - like not deleting memory unnecessarily in operator= and etc.\n// - resize/reserve/clear\n// - substr\n// - replace\n// - back/front\n// - iterator stuff\n// - find & friends\n// - push_back/pop_back\n// - assign/insert/erase\n// - relational operators as free functions - taking const char* as one of the params\nclass DOCTEST_INTERFACE String\n{\n    static const unsigned len  = 24;      //!OCLINT avoid private static members\n    static const unsigned last = len - 1; //!OCLINT avoid private static members\n\n    struct view // len should be more than sizeof(view) - because of the final byte for flags\n    {\n        char*    ptr;\n        unsigned size;\n        unsigned capacity;\n    };\n\n    union\n    {\n        char buf[len];\n        view data;\n    };\n\n    bool isOnStack() const { return (buf[last] & 128) == 0; }\n    void setOnHeap();\n    void setLast(unsigned in = last);\n\n    void copy(const String& other);\n\npublic:\n    String();\n    ~String();\n\n    // cppcheck-suppress noExplicitConstructor\n    String(const char* in);\n    String(const char* in, unsigned in_size);\n\n    String(const String& other);\n    String& operator=(const String& other);\n\n    String& operator+=(const String& other);\n    String  operator+(const String& other) const;\n\n    String(String&& other);\n    String& operator=(String&& other);\n\n    char  operator[](unsigned i) const;\n    char& operator[](unsigned i);\n\n    // the only functions I'm willing to leave in the interface - available for inlining\n    const char* c_str() const { return const_cast<String*>(this)->c_str(); } // NOLINT\n    char*       c_str() {\n        if(isOnStack())\n            return reinterpret_cast<char*>(buf);\n        return data.ptr;\n    }\n\n    unsigned size() const;\n    unsigned capacity() const;\n\n    int compare(const char* other, bool no_case = false) const;\n    int compare(const String& other, bool no_case = false) const;\n};\n\nDOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs);\nDOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs);\nDOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs);\nDOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs);\nDOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs);\nDOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs);\n\nDOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, const String& in);\n\nnamespace Color {\n    enum Enum\n    {\n        None = 0,\n        White,\n        Red,\n        Green,\n        Blue,\n        Cyan,\n        Yellow,\n        Grey,\n\n        Bright = 0x10,\n\n        BrightRed   = Bright | Red,\n        BrightGreen = Bright | Green,\n        LightGrey   = Bright | Grey,\n        BrightWhite = Bright | White\n    };\n\n    DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, Color::Enum code);\n} // namespace Color\n\nnamespace assertType {\n    enum Enum\n    {\n        // macro traits\n\n        is_warn    = 1,\n        is_check   = 2 * is_warn,\n        is_require = 2 * is_check,\n\n        is_normal      = 2 * is_require,\n        is_throws      = 2 * is_normal,\n        is_throws_as   = 2 * is_throws,\n        is_throws_with = 2 * is_throws_as,\n        is_nothrow     = 2 * is_throws_with,\n\n        is_false = 2 * is_nothrow,\n        is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types\n\n        is_eq = 2 * is_unary,\n        is_ne = 2 * is_eq,\n\n        is_lt = 2 * is_ne,\n        is_gt = 2 * is_lt,\n\n        is_ge = 2 * is_gt,\n        is_le = 2 * is_ge,\n\n        // macro types\n\n        DT_WARN    = is_normal | is_warn,\n        DT_CHECK   = is_normal | is_check,\n        DT_REQUIRE = is_normal | is_require,\n\n        DT_WARN_FALSE    = is_normal | is_false | is_warn,\n        DT_CHECK_FALSE   = is_normal | is_false | is_check,\n        DT_REQUIRE_FALSE = is_normal | is_false | is_require,\n\n        DT_WARN_THROWS    = is_throws | is_warn,\n        DT_CHECK_THROWS   = is_throws | is_check,\n        DT_REQUIRE_THROWS = is_throws | is_require,\n\n        DT_WARN_THROWS_AS    = is_throws_as | is_warn,\n        DT_CHECK_THROWS_AS   = is_throws_as | is_check,\n        DT_REQUIRE_THROWS_AS = is_throws_as | is_require,\n\n        DT_WARN_THROWS_WITH    = is_throws_with | is_warn,\n        DT_CHECK_THROWS_WITH   = is_throws_with | is_check,\n        DT_REQUIRE_THROWS_WITH = is_throws_with | is_require,\n        \n        DT_WARN_THROWS_WITH_AS    = is_throws_with | is_throws_as | is_warn,\n        DT_CHECK_THROWS_WITH_AS   = is_throws_with | is_throws_as | is_check,\n        DT_REQUIRE_THROWS_WITH_AS = is_throws_with | is_throws_as | is_require,\n\n        DT_WARN_NOTHROW    = is_nothrow | is_warn,\n        DT_CHECK_NOTHROW   = is_nothrow | is_check,\n        DT_REQUIRE_NOTHROW = is_nothrow | is_require,\n\n        DT_WARN_EQ    = is_normal | is_eq | is_warn,\n        DT_CHECK_EQ   = is_normal | is_eq | is_check,\n        DT_REQUIRE_EQ = is_normal | is_eq | is_require,\n\n        DT_WARN_NE    = is_normal | is_ne | is_warn,\n        DT_CHECK_NE   = is_normal | is_ne | is_check,\n        DT_REQUIRE_NE = is_normal | is_ne | is_require,\n\n        DT_WARN_GT    = is_normal | is_gt | is_warn,\n        DT_CHECK_GT   = is_normal | is_gt | is_check,\n        DT_REQUIRE_GT = is_normal | is_gt | is_require,\n\n        DT_WARN_LT    = is_normal | is_lt | is_warn,\n        DT_CHECK_LT   = is_normal | is_lt | is_check,\n        DT_REQUIRE_LT = is_normal | is_lt | is_require,\n\n        DT_WARN_GE    = is_normal | is_ge | is_warn,\n        DT_CHECK_GE   = is_normal | is_ge | is_check,\n        DT_REQUIRE_GE = is_normal | is_ge | is_require,\n\n        DT_WARN_LE    = is_normal | is_le | is_warn,\n        DT_CHECK_LE   = is_normal | is_le | is_check,\n        DT_REQUIRE_LE = is_normal | is_le | is_require,\n\n        DT_WARN_UNARY    = is_normal | is_unary | is_warn,\n        DT_CHECK_UNARY   = is_normal | is_unary | is_check,\n        DT_REQUIRE_UNARY = is_normal | is_unary | is_require,\n\n        DT_WARN_UNARY_FALSE    = is_normal | is_false | is_unary | is_warn,\n        DT_CHECK_UNARY_FALSE   = is_normal | is_false | is_unary | is_check,\n        DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require,\n    };\n} // namespace assertType\n\nDOCTEST_INTERFACE const char* assertString(assertType::Enum at);\nDOCTEST_INTERFACE const char* failureString(assertType::Enum at);\nDOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);\n\nstruct DOCTEST_INTERFACE TestCaseData\n{\n    String      m_file;       // the file in which the test was registered (using String - see #350)\n    unsigned    m_line;       // the line where the test was registered\n    const char* m_name;       // name of the test case\n    const char* m_test_suite; // the test suite in which the test was added\n    const char* m_description;\n    bool        m_skip;\n    bool        m_no_breaks;\n    bool        m_no_output;\n    bool        m_may_fail;\n    bool        m_should_fail;\n    int         m_expected_failures;\n    double      m_timeout;\n};\n\nstruct DOCTEST_INTERFACE AssertData\n{\n    // common - for all asserts\n    const TestCaseData* m_test_case;\n    assertType::Enum    m_at;\n    const char*         m_file;\n    int                 m_line;\n    const char*         m_expr;\n    bool                m_failed;\n\n    // exception-related - for all asserts\n    bool   m_threw;\n    String m_exception;\n\n    // for normal asserts\n    String m_decomp;\n\n    // for specific exception-related asserts\n    bool        m_threw_as;\n    const char* m_exception_type;\n    const char* m_exception_string;\n};\n\nstruct DOCTEST_INTERFACE MessageData\n{\n    String           m_string;\n    const char*      m_file;\n    int              m_line;\n    assertType::Enum m_severity;\n};\n\nstruct DOCTEST_INTERFACE SubcaseSignature\n{\n    String      m_name;\n    const char* m_file;\n    int         m_line;\n\n    bool operator<(const SubcaseSignature& other) const;\n};\n\nstruct DOCTEST_INTERFACE IContextScope\n{\n    IContextScope();\n    virtual ~IContextScope();\n    virtual void stringify(std::ostream*) const = 0;\n};\n\nnamespace detail {\n    struct DOCTEST_INTERFACE TestCase;\n} // namespace detail\n\nstruct ContextOptions //!OCLINT too many fields\n{\n    std::ostream* cout;        // stdout stream - std::cout by default\n    std::ostream* cerr;        // stderr stream - std::cerr by default\n    String        binary_name; // the test binary name\n\n    const detail::TestCase* currentTest = nullptr;\n\n    // == parameters from the command line\n    String   out;       // output filename\n    String   order_by;  // how tests should be ordered\n    unsigned rand_seed; // the seed for rand ordering\n\n    unsigned first; // the first (matching) test to be executed\n    unsigned last;  // the last (matching) test to be executed\n\n    int abort_after;           // stop tests after this many failed assertions\n    int subcase_filter_levels; // apply the subcase filters for the first N levels\n\n    bool success;              // include successful assertions in output\n    bool case_sensitive;       // if filtering should be case sensitive\n    bool exit;                 // if the program should be exited after the tests are ran/whatever\n    bool duration;             // print the time duration of each test case\n    bool no_throw;             // to skip exceptions-related assertion macros\n    bool no_exitcode;          // if the framework should return 0 as the exitcode\n    bool no_run;               // to not run the tests at all (can be done with an \"*\" exclude)\n    bool no_version;           // to not print the version of the framework\n    bool no_colors;            // if output to the console should be colorized\n    bool force_colors;         // forces the use of colors even when a tty cannot be detected\n    bool no_breaks;            // to not break into the debugger\n    bool no_skip;              // don't skip test cases which are marked to be skipped\n    bool gnu_file_line;        // if line numbers should be surrounded with :x: and not (x):\n    bool no_path_in_filenames; // if the path to files should be removed from the output\n    bool no_line_numbers;      // if source code line numbers should be omitted from the output\n    bool no_debug_output;      // no output in the debug console when a debugger is attached\n    bool no_skipped_summary;   // don't print \"skipped\" in the summary !!! UNDOCUMENTED !!!\n    bool no_time_in_output;    // omit any time/timestamps from output !!! UNDOCUMENTED !!!\n\n    bool help;             // to print the help\n    bool version;          // to print the version\n    bool count;            // if only the count of matching tests is to be retrieved\n    bool list_test_cases;  // to list all tests matching the filters\n    bool list_test_suites; // to list all suites matching the filters\n    bool list_reporters;   // lists all registered reporters\n};\n\nnamespace detail {\n    template <bool CONDITION, typename TYPE = void>\n    struct enable_if\n    {};\n\n    template <typename TYPE>\n    struct enable_if<true, TYPE>\n    { typedef TYPE type; };\n\n    // clang-format off\n    template<class T> struct remove_reference      { typedef T type; };\n    template<class T> struct remove_reference<T&>  { typedef T type; };\n    template<class T> struct remove_reference<T&&> { typedef T type; };\n\n    template<typename T, typename U = T&&> U declval(int); \n\n    template<typename T> T declval(long); \n\n    template<typename T> auto declval() DOCTEST_NOEXCEPT -> decltype(declval<T>(0)) ;\n\n    template<class T> struct is_lvalue_reference { const static bool value=false; };\n    template<class T> struct is_lvalue_reference<T&> { const static bool value=true; };\n\n    template <class T>\n    inline T&& forward(typename remove_reference<T>::type& t) DOCTEST_NOEXCEPT\n    {\n        return static_cast<T&&>(t);\n    }\n\n    template <class T>\n    inline T&& forward(typename remove_reference<T>::type&& t) DOCTEST_NOEXCEPT\n    {\n        static_assert(!is_lvalue_reference<T>::value,\n                        \"Can not forward an rvalue as an lvalue.\");\n        return static_cast<T&&>(t);\n    }\n\n    template<class T> struct remove_const          { typedef T type; };\n    template<class T> struct remove_const<const T> { typedef T type; };\n#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n    template<class T> struct is_enum : public std::is_enum<T> {};\n    template<class T> struct underlying_type : public std::underlying_type<T> {};\n#else\n    // Use compiler intrinsics\n    template<class T> struct is_enum { constexpr static bool value = __is_enum(T); };\n    template<class T> struct underlying_type { typedef __underlying_type(T) type; };\n#endif\n    // clang-format on\n\n    template <typename T>\n    struct deferred_false\n    // cppcheck-suppress unusedStructMember\n    { static const bool value = false; };\n\n    namespace has_insertion_operator_impl {\n        std::ostream &os();\n        template<class T>\n        DOCTEST_REF_WRAP(T) val();\n\n        template<class, class = void>\n        struct check {\n            static constexpr bool value = false;\n        };\n\n        template<class T>\n        struct check<T, decltype(os() << val<T>(), void())> {\n            static constexpr bool value = true;\n        };\n    } // namespace has_insertion_operator_impl\n\n    template<class T>\n    using has_insertion_operator = has_insertion_operator_impl::check<const T>;\n\n    DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num);\n\n    DOCTEST_INTERFACE std::ostream* getTlsOss(); // returns a thread-local ostringstream\n    DOCTEST_INTERFACE String getTlsOssResult();\n\n    template <bool C>\n    struct StringMakerBase\n    {\n        template <typename T>\n        static String convert(const DOCTEST_REF_WRAP(T)) {\n            return \"{?}\";\n        }\n    };\n\n    template <>\n    struct StringMakerBase<true>\n    {\n        template <typename T>\n        static String convert(const DOCTEST_REF_WRAP(T) in) {\n            *getTlsOss() << in;\n            return getTlsOssResult();\n        }\n    };\n\n    DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size);\n\n    template <typename T>\n    String rawMemoryToString(const DOCTEST_REF_WRAP(T) object) {\n        return rawMemoryToString(&object, sizeof(object));\n    }\n\n    template <typename T>\n    const char* type_to_string() {\n        return \"<>\";\n    }\n} // namespace detail\n\ntemplate <typename T>\nstruct StringMaker : public detail::StringMakerBase<detail::has_insertion_operator<T>::value>\n{};\n\ntemplate <typename T>\nstruct StringMaker<T*>\n{\n    template <typename U>\n    static String convert(U* p) {\n        if(p)\n            return detail::rawMemoryToString(p);\n        return \"NULL\";\n    }\n};\n\ntemplate <typename R, typename C>\nstruct StringMaker<R C::*>\n{\n    static String convert(R C::*p) {\n        if(p)\n            return detail::rawMemoryToString(p);\n        return \"NULL\";\n    }\n};\n\ntemplate <typename T, typename detail::enable_if<!detail::is_enum<T>::value, bool>::type = true>\nString toString(const DOCTEST_REF_WRAP(T) value) {\n    return StringMaker<T>::convert(value);\n}\n\n#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\nDOCTEST_INTERFACE String toString(char* in);\nDOCTEST_INTERFACE String toString(const char* in);\n#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\nDOCTEST_INTERFACE String toString(bool in);\nDOCTEST_INTERFACE String toString(float in);\nDOCTEST_INTERFACE String toString(double in);\nDOCTEST_INTERFACE String toString(double long in);\n\nDOCTEST_INTERFACE String toString(char in);\nDOCTEST_INTERFACE String toString(char signed in);\nDOCTEST_INTERFACE String toString(char unsigned in);\nDOCTEST_INTERFACE String toString(int short in);\nDOCTEST_INTERFACE String toString(int short unsigned in);\nDOCTEST_INTERFACE String toString(int in);\nDOCTEST_INTERFACE String toString(int unsigned in);\nDOCTEST_INTERFACE String toString(int long in);\nDOCTEST_INTERFACE String toString(int long unsigned in);\nDOCTEST_INTERFACE String toString(int long long in);\nDOCTEST_INTERFACE String toString(int long long unsigned in);\nDOCTEST_INTERFACE String toString(std::nullptr_t in);\n\ntemplate <typename T, typename detail::enable_if<detail::is_enum<T>::value, bool>::type = true>\nString toString(const DOCTEST_REF_WRAP(T) value) {\n    typedef typename detail::underlying_type<T>::type UT;\n    return toString(static_cast<UT>(value));\n}\n\n#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)\n// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183\nDOCTEST_INTERFACE String toString(const std::string& in);\n#endif // VS 2019\n\nclass DOCTEST_INTERFACE Approx\n{\npublic:\n    explicit Approx(double value);\n\n    Approx operator()(double value) const;\n\n#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n    template <typename T>\n    explicit Approx(const T& value,\n                    typename detail::enable_if<std::is_constructible<double, T>::value>::type* =\n                            static_cast<T*>(nullptr)) {\n        *this = Approx(static_cast<double>(value));\n    }\n#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n\n    Approx& epsilon(double newEpsilon);\n\n#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n    template <typename T>\n    typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type epsilon(\n            const T& newEpsilon) {\n        m_epsilon = static_cast<double>(newEpsilon);\n        return *this;\n    }\n#endif //  DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n\n    Approx& scale(double newScale);\n\n#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n    template <typename T>\n    typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type scale(\n            const T& newScale) {\n        m_scale = static_cast<double>(newScale);\n        return *this;\n    }\n#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n\n    // clang-format off\n    DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs);\n    DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs);\n    DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs);\n    DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs);\n    DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs);\n    DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs);\n    DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs);\n    DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs);\n    DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs);\n    DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs);\n    DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs);\n    DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs);\n\n    DOCTEST_INTERFACE friend String toString(const Approx& in);\n\n#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n#define DOCTEST_APPROX_PREFIX \\\n    template <typename T> friend typename detail::enable_if<std::is_constructible<double, T>::value, bool>::type\n\n    DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); }\n    DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); }\n    DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); }\n    DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); }\n    DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value || lhs == rhs; }\n    DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) || lhs == rhs; }\n    DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value || lhs == rhs; }\n    DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) || lhs == rhs; }\n    DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value && lhs != rhs; }\n    DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) && lhs != rhs; }\n    DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; }\n    DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; }\n#undef DOCTEST_APPROX_PREFIX\n#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS\n\n    // clang-format on\n\nprivate:\n    double m_epsilon;\n    double m_scale;\n    double m_value;\n};\n\nDOCTEST_INTERFACE String toString(const Approx& in);\n\nDOCTEST_INTERFACE const ContextOptions* getContextOptions();\n\n#if !defined(DOCTEST_CONFIG_DISABLE)\n\nnamespace detail {\n    // clang-format off\n#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n    template<class T>               struct decay_array       { typedef T type; };\n    template<class T, unsigned N>   struct decay_array<T[N]> { typedef T* type; };\n    template<class T>               struct decay_array<T[]>  { typedef T* type; };\n\n    template<class T>   struct not_char_pointer              { enum { value = 1 }; };\n    template<>          struct not_char_pointer<char*>       { enum { value = 0 }; };\n    template<>          struct not_char_pointer<const char*> { enum { value = 0 }; };\n\n    template<class T> struct can_use_op : public not_char_pointer<typename decay_array<T>::type> {};\n#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n    // clang-format on\n\n    struct DOCTEST_INTERFACE TestFailureException\n    {\n    };\n\n    DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at);\n\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n    DOCTEST_NORETURN\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n    DOCTEST_INTERFACE void throwException();\n\n    struct DOCTEST_INTERFACE Subcase\n    {\n        SubcaseSignature m_signature;\n        bool             m_entered = false;\n\n        Subcase(const String& name, const char* file, int line);\n        ~Subcase();\n\n        operator bool() const;\n    };\n\n    template <typename L, typename R>\n    String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,\n                               const DOCTEST_REF_WRAP(R) rhs) {\n        // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\n        return toString(lhs) + op + toString(rhs);\n    }\n\n#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)\nDOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wunused-comparison\")\n#endif\n\n// This will check if there is any way it could find a operator like member or friend and uses it.\n// If not it doesn't find the operator or if the operator at global scope is defined after\n// this template, the template won't be instantiated due to SFINAE. Once the template is not\n// instantiated it can look for global operator using normal conversions.\n#define SFINAE_OP(ret,op) decltype(doctest::detail::declval<L>() op doctest::detail::declval<R>(),static_cast<ret>(0))\n\n#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro)                              \\\n    template <typename R>                                                                          \\\n    DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) {             \\\n\t    bool res = op_macro(doctest::detail::forward<L>(lhs), doctest::detail::forward<R>(rhs));                                                             \\\n        if(m_at & assertType::is_false)                                                            \\\n            res = !res;                                                                            \\\n        if(!res || doctest::getContextOptions()->success)                                          \\\n            return Result(res, stringifyBinaryExpr(lhs, op_str, rhs));                             \\\n        return Result(res);                                                                        \\\n    }\n\n    // more checks could be added - like in Catch:\n    // https://github.com/catchorg/Catch2/pull/1480/files\n    // https://github.com/catchorg/Catch2/pull/1481/files\n#define DOCTEST_FORBIT_EXPRESSION(rt, op)                                                          \\\n    template <typename R>                                                                          \\\n    rt& operator op(const R&) {                                                                    \\\n        static_assert(deferred_false<R>::value,                                                    \\\n                      \"Expression Too Complex Please Rewrite As Binary Comparison!\");              \\\n        return *this;                                                                              \\\n    }\n\n    struct DOCTEST_INTERFACE Result\n    {\n        bool   m_passed;\n        String m_decomp;\n\n        Result(bool passed, const String& decomposition = String());\n\n        // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence\n        DOCTEST_FORBIT_EXPRESSION(Result, &)\n        DOCTEST_FORBIT_EXPRESSION(Result, ^)\n        DOCTEST_FORBIT_EXPRESSION(Result, |)\n        DOCTEST_FORBIT_EXPRESSION(Result, &&)\n        DOCTEST_FORBIT_EXPRESSION(Result, ||)\n        DOCTEST_FORBIT_EXPRESSION(Result, ==)\n        DOCTEST_FORBIT_EXPRESSION(Result, !=)\n        DOCTEST_FORBIT_EXPRESSION(Result, <)\n        DOCTEST_FORBIT_EXPRESSION(Result, >)\n        DOCTEST_FORBIT_EXPRESSION(Result, <=)\n        DOCTEST_FORBIT_EXPRESSION(Result, >=)\n        DOCTEST_FORBIT_EXPRESSION(Result, =)\n        DOCTEST_FORBIT_EXPRESSION(Result, +=)\n        DOCTEST_FORBIT_EXPRESSION(Result, -=)\n        DOCTEST_FORBIT_EXPRESSION(Result, *=)\n        DOCTEST_FORBIT_EXPRESSION(Result, /=)\n        DOCTEST_FORBIT_EXPRESSION(Result, %=)\n        DOCTEST_FORBIT_EXPRESSION(Result, <<=)\n        DOCTEST_FORBIT_EXPRESSION(Result, >>=)\n        DOCTEST_FORBIT_EXPRESSION(Result, &=)\n        DOCTEST_FORBIT_EXPRESSION(Result, ^=)\n        DOCTEST_FORBIT_EXPRESSION(Result, |=)\n    };\n\n#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION\n\n    DOCTEST_CLANG_SUPPRESS_WARNING_PUSH\n    DOCTEST_CLANG_SUPPRESS_WARNING(\"-Wsign-conversion\")\n    DOCTEST_CLANG_SUPPRESS_WARNING(\"-Wsign-compare\")\n    //DOCTEST_CLANG_SUPPRESS_WARNING(\"-Wdouble-promotion\")\n    //DOCTEST_CLANG_SUPPRESS_WARNING(\"-Wconversion\")\n    //DOCTEST_CLANG_SUPPRESS_WARNING(\"-Wfloat-equal\")\n\n    DOCTEST_GCC_SUPPRESS_WARNING_PUSH\n    DOCTEST_GCC_SUPPRESS_WARNING(\"-Wsign-conversion\")\n    DOCTEST_GCC_SUPPRESS_WARNING(\"-Wsign-compare\")\n    //DOCTEST_GCC_SUPPRESS_WARNING(\"-Wdouble-promotion\")\n    //DOCTEST_GCC_SUPPRESS_WARNING(\"-Wconversion\")\n    //DOCTEST_GCC_SUPPRESS_WARNING(\"-Wfloat-equal\")\n\n    DOCTEST_MSVC_SUPPRESS_WARNING_PUSH\n    // https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389\n    DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch\n    DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch\n    DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch\n    //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation\n\n#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION\n\n    // clang-format off\n#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n#define DOCTEST_COMPARISON_RETURN_TYPE bool\n#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type\n    // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\n    inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }\n    inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }\n    inline bool lt(const char* lhs, const char* rhs) { return String(lhs) <  String(rhs); }\n    inline bool gt(const char* lhs, const char* rhs) { return String(lhs) >  String(rhs); }\n    inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); }\n    inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); }\n#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n    // clang-format on\n\n#define DOCTEST_RELATIONAL_OP(name, op)                                                            \\\n    template <typename L, typename R>                                                              \\\n    DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs,                             \\\n                                        const DOCTEST_REF_WRAP(R) rhs) {                           \\\n        return lhs op rhs;                                                                         \\\n    }\n\n    DOCTEST_RELATIONAL_OP(eq, ==)\n    DOCTEST_RELATIONAL_OP(ne, !=)\n    DOCTEST_RELATIONAL_OP(lt, <)\n    DOCTEST_RELATIONAL_OP(gt, >)\n    DOCTEST_RELATIONAL_OP(le, <=)\n    DOCTEST_RELATIONAL_OP(ge, >=)\n\n#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n#define DOCTEST_CMP_EQ(l, r) l == r\n#define DOCTEST_CMP_NE(l, r) l != r\n#define DOCTEST_CMP_GT(l, r) l > r\n#define DOCTEST_CMP_LT(l, r) l < r\n#define DOCTEST_CMP_GE(l, r) l >= r\n#define DOCTEST_CMP_LE(l, r) l <= r\n#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n#define DOCTEST_CMP_EQ(l, r) eq(l, r)\n#define DOCTEST_CMP_NE(l, r) ne(l, r)\n#define DOCTEST_CMP_GT(l, r) gt(l, r)\n#define DOCTEST_CMP_LT(l, r) lt(l, r)\n#define DOCTEST_CMP_GE(l, r) ge(l, r)\n#define DOCTEST_CMP_LE(l, r) le(l, r)\n#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n\n    template <typename L>\n    // cppcheck-suppress copyCtorAndEqOperator\n    struct Expression_lhs\n    {\n        L                lhs;\n        assertType::Enum m_at;\n\n        explicit Expression_lhs(L&& in, assertType::Enum at)\n                : lhs(doctest::detail::forward<L>(in))\n                , m_at(at) {}\n\n        DOCTEST_NOINLINE operator Result() {\n// this is needed only foc MSVC 2015:\n// https://ci.appveyor.com/project/onqtam/doctest/builds/38181202\nDOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool\n            bool res = static_cast<bool>(lhs);\nDOCTEST_MSVC_SUPPRESS_WARNING_POP\n            if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional\n                res = !res;\n\n            if(!res || getContextOptions()->success)\n                return Result(res, toString(lhs));\n            return Result(res);\n        }\n\n\t/* This is required for user-defined conversions from Expression_lhs to L */\n\t//operator L() const { return lhs; }\n\toperator L() const { return lhs; }\n\n        // clang-format off\n        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, \" == \", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional\n        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, \" != \", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional\n        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>,  \" >  \", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional\n        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<,  \" <  \", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional\n        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, \" >= \", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional\n        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, \" <= \", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional\n        // clang-format on\n\n        // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=)\n        // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the\n        // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression...\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<)\n        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>)\n    };\n\n#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION\n\n    DOCTEST_CLANG_SUPPRESS_WARNING_POP\n    DOCTEST_MSVC_SUPPRESS_WARNING_POP\n    DOCTEST_GCC_SUPPRESS_WARNING_POP\n\n#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION\n\n#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n#endif\n\n    struct DOCTEST_INTERFACE ExpressionDecomposer\n    {\n        assertType::Enum m_at;\n\n        ExpressionDecomposer(assertType::Enum at);\n\n        // The right operator for capturing expressions is \"<=\" instead of \"<<\" (based on the operator precedence table)\n        // but then there will be warnings from GCC about \"-Wparentheses\" and since \"_Pragma()\" is problematic this will stay for now...\n        // https://github.com/catchorg/Catch2/issues/870\n        // https://github.com/catchorg/Catch2/issues/565\n        template <typename L>\n\tExpression_lhs<L> operator<<(L &&operand) {\n            return Expression_lhs<L>(doctest::detail::forward<L>(operand), m_at);\n        }\n    };\n\n    struct DOCTEST_INTERFACE TestSuite\n    {\n        const char* m_test_suite;\n        const char* m_description;\n        bool        m_skip;\n        bool        m_no_breaks;\n        bool        m_no_output;\n        bool        m_may_fail;\n        bool        m_should_fail;\n        int         m_expected_failures;\n        double      m_timeout;\n\n        TestSuite& operator*(const char* in);\n\n        template <typename T>\n        TestSuite& operator*(const T& in) {\n            in.fill(*this);\n            return *this;\n        }\n    };\n\n    typedef void (*funcType)();\n\n    struct DOCTEST_INTERFACE TestCase : public TestCaseData\n    {\n        funcType m_test; // a function pointer to the test case\n\n        const char* m_type; // for templated test cases - gets appended to the real name\n        int m_template_id; // an ID used to distinguish between the different versions of a templated test case\n        String m_full_name; // contains the name (only for templated test cases!) + the template type\n\n        TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,\n                 const char* type = \"\", int template_id = -1);\n\n        TestCase(const TestCase& other);\n\n        DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function\n        TestCase& operator=(const TestCase& other);\n        DOCTEST_MSVC_SUPPRESS_WARNING_POP\n\n        TestCase& operator*(const char* in);\n\n        template <typename T>\n        TestCase& operator*(const T& in) {\n            in.fill(*this);\n            return *this;\n        }\n\n        bool operator<(const TestCase& other) const;\n    };\n\n    // forward declarations of functions used by the macros\n    DOCTEST_INTERFACE int  regTest(const TestCase& tc);\n    DOCTEST_INTERFACE int  setTestSuite(const TestSuite& ts);\n    DOCTEST_INTERFACE bool isDebuggerActive();\n\n    template<typename T>\n    int instantiationHelper(const T&) { return 0; }\n\n    namespace binaryAssertComparison {\n        enum Enum\n        {\n            eq = 0,\n            ne,\n            gt,\n            lt,\n            ge,\n            le\n        };\n    } // namespace binaryAssertComparison\n\n    // clang-format off\n    template <int, class L, class R> struct RelationalComparator     { bool operator()(const DOCTEST_REF_WRAP(L),     const DOCTEST_REF_WRAP(R)    ) const { return false;        } };\n\n#define DOCTEST_BINARY_RELATIONAL_OP(n, op) \\\n    template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } };\n    // clang-format on\n\n    DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq)\n    DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne)\n    DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt)\n    DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt)\n    DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge)\n    DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le)\n\n    struct DOCTEST_INTERFACE ResultBuilder : public AssertData\n    {\n        ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,\n                      const char* exception_type = \"\", const char* exception_string = \"\");\n\n        void setResult(const Result& res);\n\n        template <int comparison, typename L, typename R>\n        DOCTEST_NOINLINE void binary_assert(const DOCTEST_REF_WRAP(L) lhs,\n                                            const DOCTEST_REF_WRAP(R) rhs) {\n            m_failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);\n            if(m_failed || getContextOptions()->success)\n                m_decomp = stringifyBinaryExpr(lhs, \", \", rhs);\n        }\n\n        template <typename L>\n        DOCTEST_NOINLINE void unary_assert(const DOCTEST_REF_WRAP(L) val) {\n            m_failed = !val;\n\n            if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional\n                m_failed = !m_failed;\n\n            if(m_failed || getContextOptions()->success)\n                m_decomp = toString(val);\n        }\n\n        void translateException();\n\n        bool log();\n        void react() const;\n    };\n\n    namespace assertAction {\n        enum Enum\n        {\n            nothing     = 0,\n            dbgbreak    = 1,\n            shouldthrow = 2\n        };\n    } // namespace assertAction\n\n    DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData& ad);\n\n    DOCTEST_INTERFACE void decomp_assert(assertType::Enum at, const char* file, int line,\n                                         const char* expr, Result result);\n\n#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp)                                                        \\\n    do {                                                                                           \\\n        if(!is_running_in_test) {                                                                  \\\n            if(failed) {                                                                           \\\n                ResultBuilder rb(at, file, line, expr);                                            \\\n                rb.m_failed = failed;                                                              \\\n                rb.m_decomp = decomp;                                                              \\\n                failed_out_of_a_testing_context(rb);                                               \\\n                if(isDebuggerActive() && !getContextOptions()->no_breaks)                          \\\n                    DOCTEST_BREAK_INTO_DEBUGGER();                                                 \\\n                if(checkIfShouldThrow(at))                                                         \\\n                    throwException();                                                              \\\n            }                                                                                      \\\n            return;                                                                                \\\n        }                                                                                          \\\n    } while(false)\n\n#define DOCTEST_ASSERT_IN_TESTS(decomp)                                                            \\\n    ResultBuilder rb(at, file, line, expr);                                                        \\\n    rb.m_failed = failed;                                                                          \\\n    if(rb.m_failed || getContextOptions()->success)                                                \\\n        rb.m_decomp = decomp;                                                                      \\\n    if(rb.log())                                                                                   \\\n        DOCTEST_BREAK_INTO_DEBUGGER();                                                             \\\n    if(rb.m_failed && checkIfShouldThrow(at))                                                      \\\n    throwException()\n\n    template <int comparison, typename L, typename R>\n    DOCTEST_NOINLINE void binary_assert(assertType::Enum at, const char* file, int line,\n                                        const char* expr, const DOCTEST_REF_WRAP(L) lhs,\n                                        const DOCTEST_REF_WRAP(R) rhs) {\n        bool failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);\n\n        // ###################################################################################\n        // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT\n        // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED\n        // ###################################################################################\n        DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, \", \", rhs));\n        DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, \", \", rhs));\n    }\n\n    template <typename L>\n    DOCTEST_NOINLINE void unary_assert(assertType::Enum at, const char* file, int line,\n                                       const char* expr, const DOCTEST_REF_WRAP(L) val) {\n        bool failed = !val;\n\n        if(at & assertType::is_false) //!OCLINT bitwise operator in conditional\n            failed = !failed;\n\n        // ###################################################################################\n        // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT\n        // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED\n        // ###################################################################################\n        DOCTEST_ASSERT_OUT_OF_TESTS(toString(val));\n        DOCTEST_ASSERT_IN_TESTS(toString(val));\n    }\n\n    struct DOCTEST_INTERFACE IExceptionTranslator\n    {\n        IExceptionTranslator();\n        virtual ~IExceptionTranslator();\n        virtual bool translate(String&) const = 0;\n    };\n\n    template <typename T>\n    class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class\n    {\n    public:\n        explicit ExceptionTranslator(String (*translateFunction)(T))\n                : m_translateFunction(translateFunction) {}\n\n        bool translate(String& res) const override {\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n            try {\n                throw; // lgtm [cpp/rethrow-no-exception]\n                // cppcheck-suppress catchExceptionByValue\n            } catch(T ex) {                    // NOLINT\n                res = m_translateFunction(ex); //!OCLINT parameter reassignment\n                return true;\n            } catch(...) {}         //!OCLINT -  empty catch statement\n#endif                              // DOCTEST_CONFIG_NO_EXCEPTIONS\n            static_cast<void>(res); // to silence -Wunused-parameter\n            return false;\n        }\n\n    private:\n        String (*m_translateFunction)(T);\n    };\n\n    DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et);\n\n    template <bool C>\n    struct StringStreamBase\n    {\n        template <typename T>\n        static void convert(std::ostream* s, const T& in) {\n            *s << toString(in);\n        }\n\n        // always treat char* as a string in this context - no matter\n        // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined\n        static void convert(std::ostream* s, const char* in) { *s << String(in); }\n    };\n\n    template <>\n    struct StringStreamBase<true>\n    {\n        template <typename T>\n        static void convert(std::ostream* s, const T& in) {\n            *s << in;\n        }\n    };\n\n    template <typename T>\n    struct StringStream : public StringStreamBase<has_insertion_operator<T>::value>\n    {};\n\n    template <typename T>\n    void toStream(std::ostream* s, const T& value) {\n        StringStream<T>::convert(s, value);\n    }\n\n#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n    DOCTEST_INTERFACE void toStream(std::ostream* s, char* in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in);\n#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n    DOCTEST_INTERFACE void toStream(std::ostream* s, bool in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, float in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, double in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, double long in);\n\n    DOCTEST_INTERFACE void toStream(std::ostream* s, char in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int short in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int long in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);\n    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);\n\n    // ContextScope base class used to allow implementing methods of ContextScope \n    // that don't depend on the template parameter in doctest.cpp.\n    class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {\n    protected:\n        ContextScopeBase();\n\n        void destroy();\n    };\n\n    template <typename L> class ContextScope : public ContextScopeBase\n    {\n        const L lambda_;\n\n    public:\n        explicit ContextScope(const L &lambda) : lambda_(lambda) {}\n\n        ContextScope(ContextScope &&other) : lambda_(other.lambda_) {}\n\n        void stringify(std::ostream* s) const override { lambda_(s); }\n\n        ~ContextScope() override { destroy(); }\n    };\n\n    struct DOCTEST_INTERFACE MessageBuilder : public MessageData\n    {\n        std::ostream* m_stream;\n\n        MessageBuilder(const char* file, int line, assertType::Enum severity);\n        MessageBuilder() = delete;\n        ~MessageBuilder();\n\n        // the preferred way of chaining parameters for stringification\n        template <typename T>\n        MessageBuilder& operator,(const T& in) {\n            toStream(m_stream, in);\n            return *this;\n        }\n\n        // kept here just for backwards-compatibility - the comma operator should be preferred now\n        template <typename T>\n        MessageBuilder& operator<<(const T& in) { return this->operator,(in); }\n\n        // the `,` operator has the lowest operator precedence - if `<<` is used by the user then\n        // the `,` operator will be called last which is not what we want and thus the `*` operator\n        // is used first (has higher operator precedence compared to `<<`) so that we guarantee that\n        // an operator of the MessageBuilder class is called first before the rest of the parameters\n        template <typename T>\n        MessageBuilder& operator*(const T& in) { return this->operator,(in); }\n\n        bool log();\n        void react();\n    };\n    \n    template <typename L>\n    ContextScope<L> MakeContextScope(const L &lambda) {\n        return ContextScope<L>(lambda);\n    }\n} // namespace detail\n\n#define DOCTEST_DEFINE_DECORATOR(name, type, def)                                                  \\\n    struct name                                                                                    \\\n    {                                                                                              \\\n        type data;                                                                                 \\\n        name(type in = def)                                                                        \\\n                : data(in) {}                                                                      \\\n        void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; }           \\\n        void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; }          \\\n    }\n\nDOCTEST_DEFINE_DECORATOR(test_suite, const char*, \"\");\nDOCTEST_DEFINE_DECORATOR(description, const char*, \"\");\nDOCTEST_DEFINE_DECORATOR(skip, bool, true);\nDOCTEST_DEFINE_DECORATOR(no_breaks, bool, true);\nDOCTEST_DEFINE_DECORATOR(no_output, bool, true);\nDOCTEST_DEFINE_DECORATOR(timeout, double, 0);\nDOCTEST_DEFINE_DECORATOR(may_fail, bool, true);\nDOCTEST_DEFINE_DECORATOR(should_fail, bool, true);\nDOCTEST_DEFINE_DECORATOR(expected_failures, int, 0);\n\ntemplate <typename T>\nint registerExceptionTranslator(String (*translateFunction)(T)) {\n    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wexit-time-destructors\")\n    static detail::ExceptionTranslator<T> exceptionTranslator(translateFunction);\n    DOCTEST_CLANG_SUPPRESS_WARNING_POP\n    detail::registerExceptionTranslatorImpl(&exceptionTranslator);\n    return 0;\n}\n\n} // namespace doctest\n\n// in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro\n// introduces an anonymous namespace in which getCurrentTestSuite gets overridden\nnamespace doctest_detail_test_suite_ns {\nDOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite();\n} // namespace doctest_detail_test_suite_ns\n\nnamespace doctest {\n#else  // DOCTEST_CONFIG_DISABLE\ntemplate <typename T>\nint registerExceptionTranslator(String (*)(T)) {\n    return 0;\n}\n#endif // DOCTEST_CONFIG_DISABLE\n\nnamespace detail {\n    typedef void (*assert_handler)(const AssertData&);\n    struct ContextState;\n} // namespace detail\n\nclass DOCTEST_INTERFACE Context\n{\n    detail::ContextState* p;\n\n    void parseArgs(int argc, const char* const* argv, bool withDefaults = false);\n\npublic:\n    explicit Context(int argc = 0, const char* const* argv = nullptr);\n\n    ~Context();\n\n    void applyCommandLine(int argc, const char* const* argv);\n\n    void addFilter(const char* filter, const char* value);\n    void clearFilters();\n    void setOption(const char* option, int value);\n    void setOption(const char* option, const char* value);\n\n    bool shouldExit();\n\n    void setAsDefaultForAssertsOutOfTestCases();\n\n    void setAssertHandler(detail::assert_handler ah);\n\n    int run();\n};\n\nnamespace TestCaseFailureReason {\n    enum Enum\n    {\n        None                     = 0,\n        AssertFailure            = 1,   // an assertion has failed in the test case\n        Exception                = 2,   // test case threw an exception\n        Crash                    = 4,   // a crash...\n        TooManyFailedAsserts     = 8,   // the abort-after option\n        Timeout                  = 16,  // see the timeout decorator\n        ShouldHaveFailedButDidnt = 32,  // see the should_fail decorator\n        ShouldHaveFailedAndDid   = 64,  // see the should_fail decorator\n        DidntFailExactlyNumTimes = 128, // see the expected_failures decorator\n        FailedExactlyNumTimes    = 256, // see the expected_failures decorator\n        CouldHaveFailedAndDid    = 512  // see the may_fail decorator\n    };\n} // namespace TestCaseFailureReason\n\nstruct DOCTEST_INTERFACE CurrentTestCaseStats\n{\n    int    numAssertsCurrentTest;\n    int    numAssertsFailedCurrentTest;\n    double seconds;\n    int    failure_flags; // use TestCaseFailureReason::Enum\n};\n\nstruct DOCTEST_INTERFACE TestCaseException\n{\n    String error_string;\n    bool   is_crash;\n};\n\nstruct DOCTEST_INTERFACE TestRunStats\n{\n    unsigned numTestCases;\n    unsigned numTestCasesPassingFilters;\n    unsigned numTestSuitesPassingFilters;\n    unsigned numTestCasesFailed;\n    int      numAsserts;\n    int      numAssertsFailed;\n};\n\nstruct QueryData\n{\n    const TestRunStats*  run_stats = nullptr;\n    const TestCaseData** data      = nullptr;\n    unsigned             num_data  = 0;\n};\n\nstruct DOCTEST_INTERFACE IReporter\n{\n    // The constructor has to accept \"const ContextOptions&\" as a single argument\n    // which has most of the options for the run + a pointer to the stdout stream\n    // Reporter(const ContextOptions& in)\n\n    // called when a query should be reported (listing test cases, printing the version, etc.)\n    virtual void report_query(const QueryData&) = 0;\n\n    // called when the whole test run starts\n    virtual void test_run_start() = 0;\n    // called when the whole test run ends (caching a pointer to the input doesn't make sense here)\n    virtual void test_run_end(const TestRunStats&) = 0;\n\n    // called when a test case is started (safe to cache a pointer to the input)\n    virtual void test_case_start(const TestCaseData&) = 0;\n    // called when a test case is reentered because of unfinished subcases (safe to cache a pointer to the input)\n    virtual void test_case_reenter(const TestCaseData&) = 0;\n    // called when a test case has ended\n    virtual void test_case_end(const CurrentTestCaseStats&) = 0;\n\n    // called when an exception is thrown from the test case (or it crashes)\n    virtual void test_case_exception(const TestCaseException&) = 0;\n\n    // called whenever a subcase is entered (don't cache pointers to the input)\n    virtual void subcase_start(const SubcaseSignature&) = 0;\n    // called whenever a subcase is exited (don't cache pointers to the input)\n    virtual void subcase_end() = 0;\n\n    // called for each assert (don't cache pointers to the input)\n    virtual void log_assert(const AssertData&) = 0;\n    // called for each message (don't cache pointers to the input)\n    virtual void log_message(const MessageData&) = 0;\n\n    // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator\n    // or isn't in the execution range (between first and last) (safe to cache a pointer to the input)\n    virtual void test_case_skipped(const TestCaseData&) = 0;\n\n    // doctest will not be managing the lifetimes of reporters given to it but this would still be nice to have\n    virtual ~IReporter();\n\n    // can obtain all currently active contexts and stringify them if one wishes to do so\n    static int                         get_num_active_contexts();\n    static const IContextScope* const* get_active_contexts();\n\n    // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown\n    static int           get_num_stringified_contexts();\n    static const String* get_stringified_contexts();\n};\n\nnamespace detail {\n    typedef IReporter* (*reporterCreatorFunc)(const ContextOptions&);\n\n    DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c, bool isReporter);\n\n    template <typename Reporter>\n    IReporter* reporterCreator(const ContextOptions& o) {\n        return new Reporter(o);\n    }\n} // namespace detail\n\ntemplate <typename Reporter>\nint registerReporter(const char* name, int priority, bool isReporter) {\n    detail::registerReporterImpl(name, priority, detail::reporterCreator<Reporter>, isReporter);\n    return 0;\n}\n} // namespace doctest\n\n// if registering is not disabled\n#if !defined(DOCTEST_CONFIG_DISABLE)\n\n// common code in asserts - for convenience\n#define DOCTEST_ASSERT_LOG_AND_REACT(b)                                                            \\\n    if(b.log())                                                                                    \\\n        DOCTEST_BREAK_INTO_DEBUGGER();                                                             \\\n    b.react()\n\n#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS\n#define DOCTEST_WRAP_IN_TRY(x) x;\n#else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS\n#define DOCTEST_WRAP_IN_TRY(x)                                                                     \\\n    try {                                                                                          \\\n        x;                                                                                         \\\n    } catch(...) { _DOCTEST_RB.translateException(); }\n#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS\n\n#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS\n#define DOCTEST_CAST_TO_VOID(...)                                                                  \\\n    DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wuseless-cast\")                                       \\\n    static_cast<void>(__VA_ARGS__);                                                                \\\n    DOCTEST_GCC_SUPPRESS_WARNING_POP\n#else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS\n#define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__;\n#endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS\n\n// registers the test by initializing a dummy var with a function\n#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators)                                    \\\n    global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) =              \\\n            doctest::detail::regTest(                                                              \\\n                    doctest::detail::TestCase(                                                     \\\n                            f, __FILE__, __LINE__,                                                 \\\n                            doctest_detail_test_suite_ns::getCurrentTestSuite()) *                 \\\n                    decorators);                                                                   \\\n    DOCTEST_GLOBAL_NO_WARNINGS_END()\n\n#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators)                                     \\\n    namespace {                                                                                    \\\n        struct der : public base                                                                   \\\n        {                                                                                          \\\n            void f();                                                                              \\\n        };                                                                                         \\\n        static void func() {                                                                       \\\n            der v;                                                                                 \\\n            v.f();                                                                                 \\\n        }                                                                                          \\\n        DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators)                                 \\\n    }                                                                                              \\\n    inline DOCTEST_NOINLINE void der::f()\n\n#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators)                                        \\\n    static void f();                                                                               \\\n    DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators)                                        \\\n    static void f()\n\n#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators)                        \\\n    static doctest::detail::funcType proxy() { return f; }                                         \\\n    DOCTEST_REGISTER_FUNCTION(inline const, proxy(), decorators)                                   \\\n    static void f()\n\n// for registering tests\n#define DOCTEST_TEST_CASE(decorators)                                                              \\\n    DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators)\n\n// for registering tests in classes - requires C++17 for inline variables!\n#if __cplusplus >= 201703L || (DOCTEST_MSVC >= DOCTEST_COMPILER(19, 12, 0) && _MSVC_LANG >= 201703L)\n#define DOCTEST_TEST_CASE_CLASS(decorators)                                                        \\\n    DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_),          \\\n                                                  DOCTEST_ANONYMOUS(_DOCTEST_ANON_PROXY_),         \\\n                                                  decorators)\n#else // DOCTEST_TEST_CASE_CLASS\n#define DOCTEST_TEST_CASE_CLASS(...)                                                               \\\n    TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER\n#endif // DOCTEST_TEST_CASE_CLASS\n\n// for registering tests with a fixture\n#define DOCTEST_TEST_CASE_FIXTURE(c, decorators)                                                   \\\n    DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), c,                          \\\n                              DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators)\n\n// for converting types to strings without the <typeinfo> header and demangling\n#define DOCTEST_TYPE_TO_STRING_IMPL(...)                                                           \\\n    template <>                                                                                    \\\n    inline const char* type_to_string<__VA_ARGS__>() {                                             \\\n        return \"<\" #__VA_ARGS__ \">\";                                                               \\\n    }\n#define DOCTEST_TYPE_TO_STRING(...)                                                                \\\n    namespace doctest { namespace detail {                                                         \\\n            DOCTEST_TYPE_TO_STRING_IMPL(__VA_ARGS__)                                               \\\n        }                                                                                          \\\n    }                                                                                              \\\n    typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func)                                 \\\n    template <typename T>                                                                          \\\n    static void func();                                                                            \\\n    namespace {                                                                                    \\\n        template <typename Tuple>                                                                  \\\n        struct iter;                                                                               \\\n        template <typename Type, typename... Rest>                                                 \\\n        struct iter<std::tuple<Type, Rest...>>                                                     \\\n        {                                                                                          \\\n            iter(const char* file, unsigned line, int index) {                                     \\\n                doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line,         \\\n                                            doctest_detail_test_suite_ns::getCurrentTestSuite(),   \\\n                                            doctest::detail::type_to_string<Type>(),               \\\n                                            int(line) * 1000 + index)                              \\\n                                         * dec);                                                   \\\n                iter<std::tuple<Rest...>>(file, line, index + 1);                                  \\\n            }                                                                                      \\\n        };                                                                                         \\\n        template <>                                                                                \\\n        struct iter<std::tuple<>>                                                                  \\\n        {                                                                                          \\\n            iter(const char*, unsigned, int) {}                                                    \\\n        };                                                                                         \\\n    }                                                                                              \\\n    template <typename T>                                                                          \\\n    static void func()\n\n#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id)                                              \\\n    DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR),                      \\\n                                           DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_))\n\n#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...)                                 \\\n    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) =                                         \\\n        doctest::detail::instantiationHelper(DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0));\\\n    DOCTEST_GLOBAL_NO_WARNINGS_END()\n\n#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...)                                                 \\\n    DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \\\n    typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...)                                                  \\\n    DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \\\n    typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...)                                         \\\n    DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon);             \\\n    DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>)               \\\n    template <typename T>                                                                          \\\n    static void anon()\n\n#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...)                                                    \\\n    DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__)\n\n// for subcases\n#define DOCTEST_SUBCASE(name)                                                                      \\\n    if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \\\n               doctest::detail::Subcase(name, __FILE__, __LINE__))\n\n// for grouping tests in test suites by using code blocks\n#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name)                                               \\\n    namespace ns_name { namespace doctest_detail_test_suite_ns {                                   \\\n            static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() {            \\\n                DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640)                                      \\\n                DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wexit-time-destructors\")                \\\n                DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wmissing-field-initializers\")             \\\n                static doctest::detail::TestSuite data{};                                          \\\n                static bool                       inited = false;                                  \\\n                DOCTEST_MSVC_SUPPRESS_WARNING_POP                                                  \\\n                DOCTEST_CLANG_SUPPRESS_WARNING_POP                                                 \\\n                DOCTEST_GCC_SUPPRESS_WARNING_POP                                                   \\\n                if(!inited) {                                                                      \\\n                    data* decorators;                                                              \\\n                    inited = true;                                                                 \\\n                }                                                                                  \\\n                return data;                                                                       \\\n            }                                                                                      \\\n        }                                                                                          \\\n    }                                                                                              \\\n    namespace ns_name\n\n#define DOCTEST_TEST_SUITE(decorators)                                                             \\\n    DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUITE_))\n\n// for starting a testsuite block\n#define DOCTEST_TEST_SUITE_BEGIN(decorators)                                                       \\\n    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) =                            \\\n            doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators);              \\\n    DOCTEST_GLOBAL_NO_WARNINGS_END()                                                               \\\n    typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n// for ending a testsuite block\n#define DOCTEST_TEST_SUITE_END                                                                     \\\n    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) =                            \\\n            doctest::detail::setTestSuite(doctest::detail::TestSuite() * \"\");                      \\\n    DOCTEST_GLOBAL_NO_WARNINGS_END()                                                               \\\n    typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n// for registering exception translators\n#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature)                      \\\n    inline doctest::String translatorName(signature);                                              \\\n    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)) =                     \\\n            doctest::registerExceptionTranslator(translatorName);                                  \\\n    DOCTEST_GLOBAL_NO_WARNINGS_END()                                                               \\\n    doctest::String translatorName(signature)\n\n#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)                                           \\\n    DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_),       \\\n                                               signature)\n\n// for registering reporters\n#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)                                        \\\n    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_REPORTER_)) =                       \\\n            doctest::registerReporter<reporter>(name, priority, true);                             \\\n    DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n// for registering listeners\n#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)                                        \\\n    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_REPORTER_)) =                       \\\n            doctest::registerReporter<reporter>(name, priority, false);                            \\\n    DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n// for logging\n#define DOCTEST_INFO(...)                                                                          \\\n    DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_),  \\\n                      __VA_ARGS__)\n\n#define DOCTEST_INFO_IMPL(mb_name, s_name, ...)                                       \\\n    auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(                 \\\n        [&](std::ostream* s_name) {                                                                \\\n        doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \\\n        mb_name.m_stream = s_name;                                                                 \\\n        mb_name * __VA_ARGS__;                                                                     \\\n    })\n\n#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x \" := \", x)\n\n#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...)                                             \\\n    do {                                                                                           \\\n        doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type);                 \\\n        mb * __VA_ARGS__;                                                                          \\\n        DOCTEST_ASSERT_LOG_AND_REACT(mb);                                                          \\\n    } while(false)\n\n// clang-format off\n#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)\n#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)\n#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)\n// clang-format on\n\n#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)\n#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)\n#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)\n\n#define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.\n\n#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS\n\n#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...)                                               \\\n    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Woverloaded-shift-op-parentheses\")                  \\\n    doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__,         \\\n                                               __LINE__, #__VA_ARGS__);                            \\\n    DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.setResult(                                                     \\\n            doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type)                \\\n            << __VA_ARGS__))                                                                       \\\n    DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB)                                                      \\\n    DOCTEST_CLANG_SUPPRESS_WARNING_POP\n\n#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...)                                               \\\n    do {                                                                                           \\\n        DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__);                                      \\\n    } while(false)\n\n#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS\n\n// necessary for <ASSERT>_MESSAGE\n#define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1\n\n#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...)                                               \\\n    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Woverloaded-shift-op-parentheses\")                  \\\n    doctest::detail::decomp_assert(                                                                \\\n            doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__,                    \\\n            doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type)                \\\n                    << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP\n\n#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS\n\n#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__)\n#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__)\n#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__)\n#define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__)\n#define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__)\n#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)\n\n// clang-format off\n#define DOCTEST_WARN_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false)\n#define DOCTEST_CHECK_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false)\n#define DOCTEST_REQUIRE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false)\n#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false)\n#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false)\n#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false)\n// clang-format on\n\n#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...)                                  \\\n    do {                                                                                           \\\n        if(!doctest::getContextOptions()->no_throw) {                                              \\\n            doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \\\n                                                       __LINE__, #expr, #__VA_ARGS__, message);    \\\n            try {                                                                                  \\\n                DOCTEST_CAST_TO_VOID(expr)                                                         \\\n            } catch(const typename doctest::detail::remove_const<                                  \\\n                    typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) {       \\\n                _DOCTEST_RB.translateException();                                                  \\\n                _DOCTEST_RB.m_threw_as = true;                                                     \\\n            } catch(...) { _DOCTEST_RB.translateException(); }                                     \\\n            DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);                                             \\\n        }                                                                                          \\\n    } while(false)\n\n#define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...)                               \\\n    do {                                                                                           \\\n        if(!doctest::getContextOptions()->no_throw) {                                              \\\n            doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \\\n                                                       __LINE__, expr_str, \"\", __VA_ARGS__);       \\\n            try {                                                                                  \\\n                DOCTEST_CAST_TO_VOID(expr)                                                         \\\n            } catch(...) { _DOCTEST_RB.translateException(); }                                     \\\n            DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);                                             \\\n        }                                                                                          \\\n    } while(false)\n\n#define DOCTEST_ASSERT_NOTHROW(assert_type, ...)                                                   \\\n    do {                                                                                           \\\n        doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__,     \\\n                                                   __LINE__, #__VA_ARGS__);                        \\\n        try {                                                                                      \\\n            DOCTEST_CAST_TO_VOID(__VA_ARGS__)                                                      \\\n        } catch(...) { _DOCTEST_RB.translateException(); }                                         \\\n        DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);                                                 \\\n    } while(false)\n\n// clang-format off\n#define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, \"\")\n#define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, \"\")\n#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, \"\")\n\n#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, \"\", __VA_ARGS__)\n#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, \"\", __VA_ARGS__)\n#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, \"\", __VA_ARGS__)\n\n#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__)\n#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__)\n#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__)\n\n#define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__)\n#define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__)\n#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__)\n\n#define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)\n#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)\n#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)\n\n#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } while(false)\n#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } while(false)\n#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } while(false)\n#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false)\n#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false)\n#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false)\n#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false)\n#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false)\n#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false)\n#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false)\n#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false)\n#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false)\n#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } while(false)\n#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } while(false)\n#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)\n// clang-format on\n\n#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS\n\n#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...)                                              \\\n    do {                                                                                           \\\n        doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__,     \\\n                                                   __LINE__, #__VA_ARGS__);                        \\\n        DOCTEST_WRAP_IN_TRY(                                                                       \\\n                _DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>(          \\\n                        __VA_ARGS__))                                                              \\\n        DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);                                                 \\\n    } while(false)\n\n#define DOCTEST_UNARY_ASSERT(assert_type, ...)                                                     \\\n    do {                                                                                           \\\n        doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__,     \\\n                                                   __LINE__, #__VA_ARGS__);                        \\\n        DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(__VA_ARGS__))                                 \\\n        DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);                                                 \\\n    } while(false)\n\n#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS\n\n#define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...)                                        \\\n    doctest::detail::binary_assert<doctest::detail::binaryAssertComparison::comparison>(           \\\n            doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__)\n\n#define DOCTEST_UNARY_ASSERT(assert_type, ...)                                                     \\\n    doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__,            \\\n                                  #__VA_ARGS__, __VA_ARGS__)\n\n#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS\n\n#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__)\n#define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__)\n#define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__)\n#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__)\n#define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__)\n#define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__)\n#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__)\n#define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__)\n#define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__)\n#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__)\n#define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__)\n#define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__)\n#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__)\n#define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__)\n#define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__)\n#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__)\n#define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__)\n#define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__)\n\n#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__)\n#define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__)\n#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__)\n#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__)\n#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__)\n#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__)\n\n#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS\n\n#undef DOCTEST_WARN_THROWS\n#undef DOCTEST_CHECK_THROWS\n#undef DOCTEST_REQUIRE_THROWS\n#undef DOCTEST_WARN_THROWS_AS\n#undef DOCTEST_CHECK_THROWS_AS\n#undef DOCTEST_REQUIRE_THROWS_AS\n#undef DOCTEST_WARN_THROWS_WITH\n#undef DOCTEST_CHECK_THROWS_WITH\n#undef DOCTEST_REQUIRE_THROWS_WITH\n#undef DOCTEST_WARN_THROWS_WITH_AS\n#undef DOCTEST_CHECK_THROWS_WITH_AS\n#undef DOCTEST_REQUIRE_THROWS_WITH_AS\n#undef DOCTEST_WARN_NOTHROW\n#undef DOCTEST_CHECK_NOTHROW\n#undef DOCTEST_REQUIRE_NOTHROW\n\n#undef DOCTEST_WARN_THROWS_MESSAGE\n#undef DOCTEST_CHECK_THROWS_MESSAGE\n#undef DOCTEST_REQUIRE_THROWS_MESSAGE\n#undef DOCTEST_WARN_THROWS_AS_MESSAGE\n#undef DOCTEST_CHECK_THROWS_AS_MESSAGE\n#undef DOCTEST_REQUIRE_THROWS_AS_MESSAGE\n#undef DOCTEST_WARN_THROWS_WITH_MESSAGE\n#undef DOCTEST_CHECK_THROWS_WITH_MESSAGE\n#undef DOCTEST_REQUIRE_THROWS_WITH_MESSAGE\n#undef DOCTEST_WARN_THROWS_WITH_AS_MESSAGE\n#undef DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE\n#undef DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE\n#undef DOCTEST_WARN_NOTHROW_MESSAGE\n#undef DOCTEST_CHECK_NOTHROW_MESSAGE\n#undef DOCTEST_REQUIRE_NOTHROW_MESSAGE\n\n#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS\n\n#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))\n\n#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))\n\n#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS\n\n#undef DOCTEST_REQUIRE\n#undef DOCTEST_REQUIRE_FALSE\n#undef DOCTEST_REQUIRE_MESSAGE\n#undef DOCTEST_REQUIRE_FALSE_MESSAGE\n#undef DOCTEST_REQUIRE_EQ\n#undef DOCTEST_REQUIRE_NE\n#undef DOCTEST_REQUIRE_GT\n#undef DOCTEST_REQUIRE_LT\n#undef DOCTEST_REQUIRE_GE\n#undef DOCTEST_REQUIRE_LE\n#undef DOCTEST_REQUIRE_UNARY\n#undef DOCTEST_REQUIRE_UNARY_FALSE\n\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS\n\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n\n// =================================================================================================\n// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING!                      ==\n// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY!                            ==\n// =================================================================================================\n#else // DOCTEST_CONFIG_DISABLE\n\n#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name)                                           \\\n    namespace {                                                                                    \\\n        template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                           \\\n        struct der : public base                                                                   \\\n        { void f(); };                                                                             \\\n    }                                                                                              \\\n    template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                               \\\n    inline void der<DOCTEST_UNUSED_TEMPLATE_TYPE>::f()\n\n#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name)                                              \\\n    template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                               \\\n    static inline void f()\n\n// for registering tests\n#define DOCTEST_TEST_CASE(name)                                                                    \\\n    DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name)\n\n// for registering tests in classes\n#define DOCTEST_TEST_CASE_CLASS(name)                                                              \\\n    DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name)\n\n// for registering tests with a fixture\n#define DOCTEST_TEST_CASE_FIXTURE(x, name)                                                         \\\n    DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), x,                          \\\n                              DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name)\n\n// for converting types to strings without the <typeinfo> header and demangling\n#define DOCTEST_TYPE_TO_STRING(...) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n#define DOCTEST_TYPE_TO_STRING_IMPL(...)\n\n// for typed tests\n#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...)                                                \\\n    template <typename type>                                                                       \\\n    inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)()\n\n#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id)                                          \\\n    template <typename type>                                                                       \\\n    inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)()\n\n#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...)                                                 \\\n    typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...)                                                  \\\n    typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n// for subcases\n#define DOCTEST_SUBCASE(name)\n\n// for a testsuite block\n#define DOCTEST_TEST_SUITE(name) namespace\n\n// for starting a testsuite block\n#define DOCTEST_TEST_SUITE_BEGIN(name) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n// for ending a testsuite block\n#define DOCTEST_TEST_SUITE_END typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)\n\n#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)                                           \\\n    template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                               \\\n    static inline doctest::String DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)(signature)\n\n#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)\n#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)\n\n#define DOCTEST_INFO(...) (static_cast<void>(0))\n#define DOCTEST_CAPTURE(x) (static_cast<void>(0))\n#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))\n#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))\n#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))\n#define DOCTEST_MESSAGE(...) (static_cast<void>(0))\n#define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))\n#define DOCTEST_FAIL(...) (static_cast<void>(0))\n\n#define DOCTEST_WARN(...) (static_cast<void>(0))\n#define DOCTEST_CHECK(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE(...) (static_cast<void>(0))\n#define DOCTEST_WARN_FALSE(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_FALSE(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_FALSE(...) (static_cast<void>(0))\n\n#define DOCTEST_WARN_MESSAGE(cond, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_MESSAGE(cond, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_MESSAGE(cond, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))\n\n#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))\n\n#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))\n#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))\n\n#define DOCTEST_WARN_EQ(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_EQ(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_EQ(...) (static_cast<void>(0))\n#define DOCTEST_WARN_NE(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_NE(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_NE(...) (static_cast<void>(0))\n#define DOCTEST_WARN_GT(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_GT(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_GT(...) (static_cast<void>(0))\n#define DOCTEST_WARN_LT(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_LT(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_LT(...) (static_cast<void>(0))\n#define DOCTEST_WARN_GE(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_GE(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_GE(...) (static_cast<void>(0))\n#define DOCTEST_WARN_LE(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_LE(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_LE(...) (static_cast<void>(0))\n\n#define DOCTEST_WARN_UNARY(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_UNARY(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_UNARY(...) (static_cast<void>(0))\n#define DOCTEST_WARN_UNARY_FALSE(...) (static_cast<void>(0))\n#define DOCTEST_CHECK_UNARY_FALSE(...) (static_cast<void>(0))\n#define DOCTEST_REQUIRE_UNARY_FALSE(...) (static_cast<void>(0))\n\n#endif // DOCTEST_CONFIG_DISABLE\n\n// clang-format off\n// KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS\n#define DOCTEST_FAST_WARN_EQ             DOCTEST_WARN_EQ\n#define DOCTEST_FAST_CHECK_EQ            DOCTEST_CHECK_EQ\n#define DOCTEST_FAST_REQUIRE_EQ          DOCTEST_REQUIRE_EQ\n#define DOCTEST_FAST_WARN_NE             DOCTEST_WARN_NE\n#define DOCTEST_FAST_CHECK_NE            DOCTEST_CHECK_NE\n#define DOCTEST_FAST_REQUIRE_NE          DOCTEST_REQUIRE_NE\n#define DOCTEST_FAST_WARN_GT             DOCTEST_WARN_GT\n#define DOCTEST_FAST_CHECK_GT            DOCTEST_CHECK_GT\n#define DOCTEST_FAST_REQUIRE_GT          DOCTEST_REQUIRE_GT\n#define DOCTEST_FAST_WARN_LT             DOCTEST_WARN_LT\n#define DOCTEST_FAST_CHECK_LT            DOCTEST_CHECK_LT\n#define DOCTEST_FAST_REQUIRE_LT          DOCTEST_REQUIRE_LT\n#define DOCTEST_FAST_WARN_GE             DOCTEST_WARN_GE\n#define DOCTEST_FAST_CHECK_GE            DOCTEST_CHECK_GE\n#define DOCTEST_FAST_REQUIRE_GE          DOCTEST_REQUIRE_GE\n#define DOCTEST_FAST_WARN_LE             DOCTEST_WARN_LE\n#define DOCTEST_FAST_CHECK_LE            DOCTEST_CHECK_LE\n#define DOCTEST_FAST_REQUIRE_LE          DOCTEST_REQUIRE_LE\n\n#define DOCTEST_FAST_WARN_UNARY          DOCTEST_WARN_UNARY\n#define DOCTEST_FAST_CHECK_UNARY         DOCTEST_CHECK_UNARY\n#define DOCTEST_FAST_REQUIRE_UNARY       DOCTEST_REQUIRE_UNARY\n#define DOCTEST_FAST_WARN_UNARY_FALSE    DOCTEST_WARN_UNARY_FALSE\n#define DOCTEST_FAST_CHECK_UNARY_FALSE   DOCTEST_CHECK_UNARY_FALSE\n#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE\n\n#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)\n// clang-format on\n\n// BDD style macros\n// clang-format off\n#define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(\"  Scenario: \" name)\n#define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(\"  Scenario: \" name)\n#define DOCTEST_SCENARIO_TEMPLATE(name, T, ...)  DOCTEST_TEST_CASE_TEMPLATE(\"  Scenario: \" name, T, __VA_ARGS__)\n#define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(\"  Scenario: \" name, T, id)\n\n#define DOCTEST_GIVEN(name)     DOCTEST_SUBCASE(\"   Given: \" name)\n#define DOCTEST_WHEN(name)      DOCTEST_SUBCASE(\"    When: \" name)\n#define DOCTEST_AND_WHEN(name)  DOCTEST_SUBCASE(\"And when: \" name)\n#define DOCTEST_THEN(name)      DOCTEST_SUBCASE(\"    Then: \" name)\n#define DOCTEST_AND_THEN(name)  DOCTEST_SUBCASE(\"     And: \" name)\n// clang-format on\n\n// == SHORT VERSIONS OF THE MACROS\n#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES)\n\n#define TEST_CASE(name) DOCTEST_TEST_CASE(name)\n#define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name)\n#define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)\n#define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)\n#define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)\n#define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)\n#define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)\n#define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)\n#define SUBCASE(name) DOCTEST_SUBCASE(name)\n#define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators)\n#define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name)\n#define TEST_SUITE_END DOCTEST_TEST_SUITE_END\n#define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)\n#define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)\n#define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)\n#define INFO(...) DOCTEST_INFO(__VA_ARGS__)\n#define CAPTURE(x) DOCTEST_CAPTURE(x)\n#define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)\n#define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)\n#define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)\n#define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__)\n#define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)\n#define FAIL(...) DOCTEST_FAIL(__VA_ARGS__)\n#define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__)\n\n#define WARN(...) DOCTEST_WARN(__VA_ARGS__)\n#define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__)\n#define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__)\n#define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)\n#define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)\n#define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)\n#define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)\n#define CHECK(...) DOCTEST_CHECK(__VA_ARGS__)\n#define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)\n#define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)\n#define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)\n#define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)\n#define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)\n#define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)\n#define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__)\n#define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)\n#define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)\n#define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)\n#define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)\n#define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)\n#define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)\n\n#define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)\n#define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)\n#define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)\n#define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)\n#define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)\n#define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)\n#define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)\n#define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)\n#define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)\n#define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)\n#define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)\n#define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)\n#define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)\n#define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)\n#define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)\n#define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)\n#define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)\n#define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)\n#define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)\n#define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)\n#define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)\n\n#define SCENARIO(name) DOCTEST_SCENARIO(name)\n#define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name)\n#define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)\n#define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)\n#define GIVEN(name) DOCTEST_GIVEN(name)\n#define WHEN(name) DOCTEST_WHEN(name)\n#define AND_WHEN(name) DOCTEST_AND_WHEN(name)\n#define THEN(name) DOCTEST_THEN(name)\n#define AND_THEN(name) DOCTEST_AND_THEN(name)\n\n#define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__)\n#define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__)\n#define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)\n#define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__)\n#define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__)\n#define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)\n#define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__)\n#define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__)\n#define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)\n#define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__)\n#define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__)\n#define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)\n#define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__)\n#define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__)\n#define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)\n#define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__)\n#define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__)\n#define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)\n#define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__)\n#define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)\n#define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)\n#define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)\n#define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)\n#define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)\n\n// KEPT FOR BACKWARDS COMPATIBILITY\n#define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)\n#define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)\n#define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)\n#define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)\n#define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)\n#define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)\n#define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)\n#define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)\n#define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)\n#define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)\n#define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)\n#define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)\n#define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)\n#define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)\n#define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)\n#define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)\n#define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)\n#define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)\n\n#define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)\n#define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)\n#define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)\n#define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)\n#define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)\n#define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)\n\n#define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)\n\n#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES\n\n#if !defined(DOCTEST_CONFIG_DISABLE)\n\n// this is here to clear the 'current test suite' for the current translation unit - at the top\nDOCTEST_TEST_SUITE_END();\n\n// add stringification for primitive/fundamental types\nnamespace doctest { namespace detail {\n    DOCTEST_TYPE_TO_STRING_IMPL(bool)\n    DOCTEST_TYPE_TO_STRING_IMPL(float)\n    DOCTEST_TYPE_TO_STRING_IMPL(double)\n    DOCTEST_TYPE_TO_STRING_IMPL(long double)\n    DOCTEST_TYPE_TO_STRING_IMPL(char)\n    DOCTEST_TYPE_TO_STRING_IMPL(signed char)\n    DOCTEST_TYPE_TO_STRING_IMPL(unsigned char)\n#if !DOCTEST_MSVC || defined(_NATIVE_WCHAR_T_DEFINED)\n    DOCTEST_TYPE_TO_STRING_IMPL(wchar_t)\n#endif // not MSVC or wchar_t support enabled\n    DOCTEST_TYPE_TO_STRING_IMPL(short int)\n    DOCTEST_TYPE_TO_STRING_IMPL(unsigned short int)\n    DOCTEST_TYPE_TO_STRING_IMPL(int)\n    DOCTEST_TYPE_TO_STRING_IMPL(unsigned int)\n    DOCTEST_TYPE_TO_STRING_IMPL(long int)\n    DOCTEST_TYPE_TO_STRING_IMPL(unsigned long int)\n    DOCTEST_TYPE_TO_STRING_IMPL(long long int)\n    DOCTEST_TYPE_TO_STRING_IMPL(unsigned long long int)\n}} // namespace doctest::detail\n\n#endif // DOCTEST_CONFIG_DISABLE\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\nDOCTEST_MSVC_SUPPRESS_WARNING_POP\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n\n#endif // DOCTEST_LIBRARY_INCLUDED\n\n#ifndef DOCTEST_SINGLE_HEADER\n#define DOCTEST_SINGLE_HEADER\n#endif // DOCTEST_SINGLE_HEADER\n\n#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER)\n\n#ifndef DOCTEST_SINGLE_HEADER\n#include \"doctest_fwd.h\"\n#endif // DOCTEST_SINGLE_HEADER\n\nDOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wunused-macros\")\n\n#ifndef DOCTEST_LIBRARY_IMPLEMENTATION\n#define DOCTEST_LIBRARY_IMPLEMENTATION\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\n\nDOCTEST_CLANG_SUPPRESS_WARNING_PUSH\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wunknown-pragmas\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wpadded\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wweak-vtables\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wglobal-constructors\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wexit-time-destructors\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wmissing-prototypes\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wsign-conversion\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wshorten-64-to-32\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wmissing-variable-declarations\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wswitch\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wswitch-enum\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wcovered-switch-default\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wmissing-noreturn\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wunused-local-typedef\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wdisabled-macro-expansion\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wmissing-braces\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wmissing-field-initializers\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wc++98-compat\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wc++98-compat-pedantic\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wunused-member-function\")\nDOCTEST_CLANG_SUPPRESS_WARNING(\"-Wnonportable-system-include-path\")\n\nDOCTEST_GCC_SUPPRESS_WARNING_PUSH\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wunknown-pragmas\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wpragmas\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wconversion\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Weffc++\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wsign-conversion\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wstrict-overflow\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wstrict-aliasing\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wmissing-field-initializers\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wmissing-braces\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wmissing-declarations\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wswitch\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wswitch-enum\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wswitch-default\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wunsafe-loop-optimizations\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wold-style-cast\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wunused-local-typedefs\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wuseless-cast\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wunused-function\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wmultiple-inheritance\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wnoexcept\")\nDOCTEST_GCC_SUPPRESS_WARNING(\"-Wsuggest-attribute\")\n\nDOCTEST_MSVC_SUPPRESS_WARNING_PUSH\nDOCTEST_MSVC_SUPPRESS_WARNING(4616) // invalid compiler warning\nDOCTEST_MSVC_SUPPRESS_WARNING(4619) // invalid compiler warning\nDOCTEST_MSVC_SUPPRESS_WARNING(4996) // The compiler encountered a deprecated declaration\nDOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data\nDOCTEST_MSVC_SUPPRESS_WARNING(4706) // assignment within conditional expression\nDOCTEST_MSVC_SUPPRESS_WARNING(4512) // 'class' : assignment operator could not be generated\nDOCTEST_MSVC_SUPPRESS_WARNING(4127) // conditional expression is constant\nDOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled\nDOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified\nDOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal\nDOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch\nDOCTEST_MSVC_SUPPRESS_WARNING(4820) // padding in structs\nDOCTEST_MSVC_SUPPRESS_WARNING(4640) // construction of local static object is not thread-safe\nDOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C\nDOCTEST_MSVC_SUPPRESS_WARNING(5045) // Spectre mitigation stuff\nDOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment operator was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(4625) // copy constructor was implicitly defined as deleted\nDOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning)\n// static analysis\nDOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Declare it 'noexcept'\nDOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable\nDOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ...\nDOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtor...\nDOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'\n\nDOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN\n\n// required includes - will go only in one translation unit!\n#include <ctime>\n#include <cmath>\n#include <climits>\n// borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/onqtam/doctest/pull/37\n#ifdef __BORLANDC__\n#include <math.h>\n#endif // __BORLANDC__\n#include <new>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <limits>\n#include <utility>\n#include <fstream>\n#include <sstream>\n#include <iostream>\n#include <algorithm>\n#include <iomanip>\n#include <vector>\n#include <atomic>\n#include <mutex>\n#include <set>\n#include <map>\n#include <exception>\n#include <stdexcept>\n#include <csignal>\n#include <cfloat>\n#include <cctype>\n#include <cstdint>\n\n#ifdef DOCTEST_PLATFORM_MAC\n#include <sys/types.h>\n#include <unistd.h>\n#include <sys/sysctl.h>\n#endif // DOCTEST_PLATFORM_MAC\n\n#ifdef DOCTEST_PLATFORM_WINDOWS\n\n// defines for a leaner windows.h\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif // WIN32_LEAN_AND_MEAN\n#ifndef NOMINMAX\n#define NOMINMAX\n#endif // NOMINMAX\n\n// not sure what AfxWin.h is for - here I do what Catch does\n#ifdef __AFXDLL\n#include <AfxWin.h>\n#else\n#include <windows.h>\n#endif\n#include <io.h>\n\n#else // DOCTEST_PLATFORM_WINDOWS\n\n#include <sys/time.h>\n#include <unistd.h>\n\n#endif // DOCTEST_PLATFORM_WINDOWS\n\n// this is a fix for https://github.com/onqtam/doctest/issues/348\n// https://mail.gnome.org/archives/xml/2012-January/msg00000.html\n#if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO)\n#define STDOUT_FILENO fileno(stdout)\n#endif // HAVE_UNISTD_H\n\nDOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END\n\n// counts the number of elements in a C array\n#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))\n\n#ifdef DOCTEST_CONFIG_DISABLE\n#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled\n#else // DOCTEST_CONFIG_DISABLE\n#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled\n#endif // DOCTEST_CONFIG_DISABLE\n\n#ifndef DOCTEST_CONFIG_OPTIONS_PREFIX\n#define DOCTEST_CONFIG_OPTIONS_PREFIX \"dt-\"\n#endif\n\n#ifndef DOCTEST_THREAD_LOCAL\n#define DOCTEST_THREAD_LOCAL thread_local\n#endif\n\n#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES\n#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32\n#endif\n\n#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE\n#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64\n#endif\n\n#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS\n#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX\n#else\n#define DOCTEST_OPTIONS_PREFIX_DISPLAY \"\"\n#endif\n\n#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)\n#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS\n#endif\n\nnamespace doctest {\n\nbool is_running_in_test = false;\n\nnamespace {\n    using namespace detail;\n    // case insensitive strcmp\n    int stricmp(const char* a, const char* b) {\n        for(;; a++, b++) {\n            const int d = tolower(*a) - tolower(*b);\n            if(d != 0 || !*a)\n                return d;\n        }\n    }\n\n    template <typename T>\n    String fpToString(T value, int precision) {\n        std::ostringstream oss;\n        oss << std::setprecision(precision) << std::fixed << value;\n        std::string d = oss.str();\n        size_t      i = d.find_last_not_of('0');\n        if(i != std::string::npos && i != d.size() - 1) {\n            if(d[i] == '.')\n                i++;\n            d = d.substr(0, i + 1);\n        }\n        return d.c_str();\n    }\n\n    struct Endianness\n    {\n        enum Arch\n        {\n            Big,\n            Little\n        };\n\n        static Arch which() {\n            int x = 1;\n            // casting any data pointer to char* is allowed\n            auto ptr = reinterpret_cast<char*>(&x);\n            if(*ptr)\n                return Little;\n            return Big;\n        }\n    };\n} // namespace\n\nnamespace detail {\n    void my_memcpy(void* dest, const void* src, unsigned num) { memcpy(dest, src, num); }\n\n    String rawMemoryToString(const void* object, unsigned size) {\n        // Reverse order for little endian architectures\n        int i = 0, end = static_cast<int>(size), inc = 1;\n        if(Endianness::which() == Endianness::Little) {\n            i   = end - 1;\n            end = inc = -1;\n        }\n\n        unsigned const char* bytes = static_cast<unsigned const char*>(object);\n        std::ostringstream   oss;\n        oss << \"0x\" << std::setfill('0') << std::hex;\n        for(; i != end; i += inc)\n            oss << std::setw(2) << static_cast<unsigned>(bytes[i]);\n        return oss.str().c_str();\n    }\n\n    DOCTEST_THREAD_LOCAL std::ostringstream g_oss; // NOLINT(cert-err58-cpp)\n\n    std::ostream* getTlsOss() {\n        g_oss.clear(); // there shouldn't be anything worth clearing in the flags\n        g_oss.str(\"\"); // the slow way of resetting a string stream\n        //g_oss.seekp(0); // optimal reset - as seen here: https://stackoverflow.com/a/624291/3162383\n        return &g_oss;\n    }\n\n    String getTlsOssResult() {\n        //g_oss << std::ends; // needed - as shown here: https://stackoverflow.com/a/624291/3162383\n        return g_oss.str().c_str();\n    }\n\n#ifndef DOCTEST_CONFIG_DISABLE\n\nnamespace timer_large_integer\n{\n    \n#if defined(DOCTEST_PLATFORM_WINDOWS)\n    typedef ULONGLONG type;\n#else // DOCTEST_PLATFORM_WINDOWS\n    using namespace std;\n    typedef uint64_t type;\n#endif // DOCTEST_PLATFORM_WINDOWS\n}\n\ntypedef timer_large_integer::type ticks_t;\n\n#ifdef DOCTEST_CONFIG_GETCURRENTTICKS\n    ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }\n#elif defined(DOCTEST_PLATFORM_WINDOWS)\n    ticks_t getCurrentTicks() {\n        static LARGE_INTEGER hz = {0}, hzo = {0};\n        if(!hz.QuadPart) {\n            QueryPerformanceFrequency(&hz);\n            QueryPerformanceCounter(&hzo);\n        }\n        LARGE_INTEGER t;\n        QueryPerformanceCounter(&t);\n        return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart;\n    }\n#else  // DOCTEST_PLATFORM_WINDOWS\n    ticks_t getCurrentTicks() {\n        timeval t;\n        gettimeofday(&t, nullptr);\n        return static_cast<ticks_t>(t.tv_sec) * 1000000 + static_cast<ticks_t>(t.tv_usec);\n    }\n#endif // DOCTEST_PLATFORM_WINDOWS\n\n    struct Timer\n    {\n        void         start() { m_ticks = getCurrentTicks(); }\n        unsigned int getElapsedMicroseconds() const {\n            return static_cast<unsigned int>(getCurrentTicks() - m_ticks);\n        }\n        //unsigned int getElapsedMilliseconds() const {\n        //    return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);\n        //}\n        double getElapsedSeconds() const { return static_cast<double>(getCurrentTicks() - m_ticks) / 1000000.0; }\n\n    private:\n        ticks_t m_ticks = 0;\n    };\n\n#ifdef DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS\n    template <typename T>\n    using AtomicOrMultiLaneAtomic = std::atomic<T>;\n#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS\n    // Provides a multilane implementation of an atomic variable that supports add, sub, load,\n    // store. Instead of using a single atomic variable, this splits up into multiple ones,\n    // each sitting on a separate cache line. The goal is to provide a speedup when most\n    // operations are modifying. It achieves this with two properties:\n    //\n    // * Multiple atomics are used, so chance of congestion from the same atomic is reduced.\n    // * Each atomic sits on a separate cache line, so false sharing is reduced.\n    //\n    // The disadvantage is that there is a small overhead due to the use of TLS, and load/store\n    // is slower because all atomics have to be accessed.\n    template <typename T>\n    class MultiLaneAtomic\n    {\n        struct CacheLineAlignedAtomic\n        {\n            std::atomic<T> atomic{};\n            char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(std::atomic<T>)];\n        };\n        CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES];\n\n        static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE,\n                      \"guarantee one atomic takes exactly one cache line\");\n\n    public:\n        T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; }\n\n        T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); }\n\n        T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {\n            return myAtomic().fetch_add(arg, order);\n        }\n\n        T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {\n            return myAtomic().fetch_sub(arg, order);\n        }\n\n        operator T() const DOCTEST_NOEXCEPT { return load(); }\n\n        T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT {\n            auto result = T();\n            for(auto const& c : m_atomics) {\n                result += c.atomic.load(order);\n            }\n            return result;\n        }\n\n        T operator=(T desired) DOCTEST_NOEXCEPT {\n            store(desired);\n            return desired;\n        }\n\n        void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {\n            // first value becomes desired\", all others become 0.\n            for(auto& c : m_atomics) {\n                c.atomic.store(desired, order);\n                desired = {};\n            }\n        }\n\n    private:\n        // Each thread has a different atomic that it operates on. If more than NumLanes threads\n        // use this, some will use the same atomic. So performance will degrate a bit, but still\n        // everything will work.\n        //\n        // The logic here is a bit tricky. The call should be as fast as possible, so that there\n        // is minimal to no overhead in determining the correct atomic for the current thread.\n        //\n        // 1. A global static counter laneCounter counts continuously up.\n        // 2. Each successive thread will use modulo operation of that counter so it gets an atomic\n        //    assigned in a round-robin fashion.\n        // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with\n        //    little overhead.\n        std::atomic<T>& myAtomic() DOCTEST_NOEXCEPT {\n            static std::atomic<size_t> laneCounter;\n            DOCTEST_THREAD_LOCAL size_t tlsLaneIdx =\n                    laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES;\n\n            return m_atomics[tlsLaneIdx].atomic;\n        }\n    };\n\n    template <typename T>\n    using AtomicOrMultiLaneAtomic = MultiLaneAtomic<T>;\n#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS\n\n    // this holds both parameters from the command line and runtime data for tests\n    struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats\n    {\n        AtomicOrMultiLaneAtomic<int> numAssertsCurrentTest_atomic;\n        AtomicOrMultiLaneAtomic<int> numAssertsFailedCurrentTest_atomic;\n\n        std::vector<std::vector<String>> filters = decltype(filters)(9); // 9 different filters\n\n        std::vector<IReporter*> reporters_currently_used;\n\n        assert_handler ah = nullptr;\n\n        Timer timer;\n\n        std::vector<String> stringifiedContexts; // logging from INFO() due to an exception\n\n        // stuff for subcases\n        std::vector<SubcaseSignature>     subcasesStack;\n        std::set<decltype(subcasesStack)> subcasesPassed;\n        int                               subcasesCurrentMaxLevel;\n        bool                              should_reenter;\n        std::atomic<bool>                 shouldLogCurrentException;\n\n        void resetRunData() {\n            numTestCases                = 0;\n            numTestCasesPassingFilters  = 0;\n            numTestSuitesPassingFilters = 0;\n            numTestCasesFailed          = 0;\n            numAsserts                  = 0;\n            numAssertsFailed            = 0;\n            numAssertsCurrentTest       = 0;\n            numAssertsFailedCurrentTest = 0;\n        }\n\n        void finalizeTestCaseData() {\n            seconds = timer.getElapsedSeconds();\n\n            // update the non-atomic counters\n            numAsserts += numAssertsCurrentTest_atomic;\n            numAssertsFailed += numAssertsFailedCurrentTest_atomic;\n            numAssertsCurrentTest       = numAssertsCurrentTest_atomic;\n            numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic;\n\n            if(numAssertsFailedCurrentTest)\n                failure_flags |= TestCaseFailureReason::AssertFailure;\n\n            if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 &&\n               Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout)\n                failure_flags |= TestCaseFailureReason::Timeout;\n\n            if(currentTest->m_should_fail) {\n                if(failure_flags) {\n                    failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid;\n                } else {\n                    failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt;\n                }\n            } else if(failure_flags && currentTest->m_may_fail) {\n                failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid;\n            } else if(currentTest->m_expected_failures > 0) {\n                if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) {\n                    failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes;\n                } else {\n                    failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes;\n                }\n            }\n\n            bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) ||\n                              (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) ||\n                              (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags);\n\n            // if any subcase has failed - the whole test case has failed\n            if(failure_flags && !ok_to_fail)\n                numTestCasesFailed++;\n        }\n    };\n\n    ContextState* g_cs = nullptr;\n\n    // used to avoid locks for the debug output\n    // TODO: figure out if this is indeed necessary/correct - seems like either there still\n    // could be a race or that there wouldn't be a race even if using the context directly\n    DOCTEST_THREAD_LOCAL bool g_no_colors;\n\n#endif // DOCTEST_CONFIG_DISABLE\n} // namespace detail\n\nvoid String::setOnHeap() { *reinterpret_cast<unsigned char*>(&buf[last]) = 128; }\nvoid String::setLast(unsigned in) { buf[last] = char(in); }\n\nvoid String::copy(const String& other) {\n    using namespace std;\n    if(other.isOnStack()) {\n        memcpy(buf, other.buf, len);\n    } else {\n        setOnHeap();\n        data.size     = other.data.size;\n        data.capacity = data.size + 1;\n        data.ptr      = new char[data.capacity];\n        memcpy(data.ptr, other.data.ptr, data.size + 1);\n    }\n}\n\nString::String() {\n    buf[0] = '\\0';\n    setLast();\n}\n\nString::~String() {\n    if(!isOnStack())\n        delete[] data.ptr;\n    // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\n}\n\nString::String(const char* in)\n        : String(in, strlen(in)) {}\n\nString::String(const char* in, unsigned in_size) {\n    using namespace std;\n    if(in_size <= last) {\n        memcpy(buf, in, in_size);\n        buf[in_size] = '\\0';\n        setLast(last - in_size);\n    } else {\n        setOnHeap();\n        data.size     = in_size;\n        data.capacity = data.size + 1;\n        data.ptr      = new char[data.capacity];\n        memcpy(data.ptr, in, in_size);\n        data.ptr[in_size] = '\\0';\n    }\n}\n\nString::String(const String& other) { copy(other); }\n\nString& String::operator=(const String& other) {\n    if(this != &other) {\n        if(!isOnStack())\n            delete[] data.ptr;\n\n        copy(other);\n    }\n\n    return *this;\n}\n\nString& String::operator+=(const String& other) {\n    const unsigned my_old_size = size();\n    const unsigned other_size  = other.size();\n    const unsigned total_size  = my_old_size + other_size;\n    using namespace std;\n    if(isOnStack()) {\n        if(total_size < len) {\n            // append to the current stack space\n            memcpy(buf + my_old_size, other.c_str(), other_size + 1);\n            // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\n            setLast(last - total_size);\n        } else {\n            // alloc new chunk\n            char* temp = new char[total_size + 1];\n            // copy current data to new location before writing in the union\n            memcpy(temp, buf, my_old_size); // skip the +1 ('\\0') for speed\n            // update data in union\n            setOnHeap();\n            data.size     = total_size;\n            data.capacity = data.size + 1;\n            data.ptr      = temp;\n            // transfer the rest of the data\n            memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);\n        }\n    } else {\n        if(data.capacity > total_size) {\n            // append to the current heap block\n            data.size = total_size;\n            memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);\n        } else {\n            // resize\n            data.capacity *= 2;\n            if(data.capacity <= total_size)\n                data.capacity = total_size + 1;\n            // alloc new chunk\n            char* temp = new char[data.capacity];\n            // copy current data to new location before releasing it\n            memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\\0') for speed\n            // release old chunk\n            delete[] data.ptr;\n            // update the rest of the union members\n            data.size = total_size;\n            data.ptr  = temp;\n            // transfer the rest of the data\n            memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);\n        }\n    }\n\n    return *this;\n}\n\n// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\nString String::operator+(const String& other) const { return String(*this) += other; }\n\nString::String(String&& other) {\n    using namespace std;\n    memcpy(buf, other.buf, len);\n    other.buf[0] = '\\0';\n    other.setLast();\n}\n\nString& String::operator=(String&& other) {\n    using namespace std;\n    if(this != &other) {\n        if(!isOnStack())\n            delete[] data.ptr;\n        memcpy(buf, other.buf, len);\n        other.buf[0] = '\\0';\n        other.setLast();\n    }\n    return *this;\n}\n\nchar String::operator[](unsigned i) const {\n    return const_cast<String*>(this)->operator[](i); // NOLINT\n}\n\nchar& String::operator[](unsigned i) {\n    if(isOnStack())\n        return reinterpret_cast<char*>(buf)[i];\n    return data.ptr[i];\n}\n\nDOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wmaybe-uninitialized\")\nunsigned String::size() const {\n    if(isOnStack())\n        return last - (unsigned(buf[last]) & 31); // using \"last\" would work only if \"len\" is 32\n    return data.size;\n}\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n\nunsigned String::capacity() const {\n    if(isOnStack())\n        return len;\n    return data.capacity;\n}\n\nint String::compare(const char* other, bool no_case) const {\n    if(no_case)\n        return doctest::stricmp(c_str(), other);\n    return std::strcmp(c_str(), other);\n}\n\nint String::compare(const String& other, bool no_case) const {\n    return compare(other.c_str(), no_case);\n}\n\n// clang-format off\nbool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }\nbool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }\nbool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }\nbool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }\nbool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; }\nbool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; }\n// clang-format on\n\nstd::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); }\n\nnamespace {\n    void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;)\n} // namespace\n\nnamespace Color {\n    std::ostream& operator<<(std::ostream& s, Color::Enum code) {\n        color_to_stream(s, code);\n        return s;\n    }\n} // namespace Color\n\n// clang-format off\nconst char* assertString(assertType::Enum at) {\n    DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4062) // enum 'x' in switch of enum 'y' is not handled\n    switch(at) {  //!OCLINT missing default in switch statements\n        case assertType::DT_WARN                    : return \"WARN\";\n        case assertType::DT_CHECK                   : return \"CHECK\";\n        case assertType::DT_REQUIRE                 : return \"REQUIRE\";\n\n        case assertType::DT_WARN_FALSE              : return \"WARN_FALSE\";\n        case assertType::DT_CHECK_FALSE             : return \"CHECK_FALSE\";\n        case assertType::DT_REQUIRE_FALSE           : return \"REQUIRE_FALSE\";\n\n        case assertType::DT_WARN_THROWS             : return \"WARN_THROWS\";\n        case assertType::DT_CHECK_THROWS            : return \"CHECK_THROWS\";\n        case assertType::DT_REQUIRE_THROWS          : return \"REQUIRE_THROWS\";\n\n        case assertType::DT_WARN_THROWS_AS          : return \"WARN_THROWS_AS\";\n        case assertType::DT_CHECK_THROWS_AS         : return \"CHECK_THROWS_AS\";\n        case assertType::DT_REQUIRE_THROWS_AS       : return \"REQUIRE_THROWS_AS\";\n\n        case assertType::DT_WARN_THROWS_WITH        : return \"WARN_THROWS_WITH\";\n        case assertType::DT_CHECK_THROWS_WITH       : return \"CHECK_THROWS_WITH\";\n        case assertType::DT_REQUIRE_THROWS_WITH     : return \"REQUIRE_THROWS_WITH\";\n\n        case assertType::DT_WARN_THROWS_WITH_AS     : return \"WARN_THROWS_WITH_AS\";\n        case assertType::DT_CHECK_THROWS_WITH_AS    : return \"CHECK_THROWS_WITH_AS\";\n        case assertType::DT_REQUIRE_THROWS_WITH_AS  : return \"REQUIRE_THROWS_WITH_AS\";\n\n        case assertType::DT_WARN_NOTHROW            : return \"WARN_NOTHROW\";\n        case assertType::DT_CHECK_NOTHROW           : return \"CHECK_NOTHROW\";\n        case assertType::DT_REQUIRE_NOTHROW         : return \"REQUIRE_NOTHROW\";\n\n        case assertType::DT_WARN_EQ                 : return \"WARN_EQ\";\n        case assertType::DT_CHECK_EQ                : return \"CHECK_EQ\";\n        case assertType::DT_REQUIRE_EQ              : return \"REQUIRE_EQ\";\n        case assertType::DT_WARN_NE                 : return \"WARN_NE\";\n        case assertType::DT_CHECK_NE                : return \"CHECK_NE\";\n        case assertType::DT_REQUIRE_NE              : return \"REQUIRE_NE\";\n        case assertType::DT_WARN_GT                 : return \"WARN_GT\";\n        case assertType::DT_CHECK_GT                : return \"CHECK_GT\";\n        case assertType::DT_REQUIRE_GT              : return \"REQUIRE_GT\";\n        case assertType::DT_WARN_LT                 : return \"WARN_LT\";\n        case assertType::DT_CHECK_LT                : return \"CHECK_LT\";\n        case assertType::DT_REQUIRE_LT              : return \"REQUIRE_LT\";\n        case assertType::DT_WARN_GE                 : return \"WARN_GE\";\n        case assertType::DT_CHECK_GE                : return \"CHECK_GE\";\n        case assertType::DT_REQUIRE_GE              : return \"REQUIRE_GE\";\n        case assertType::DT_WARN_LE                 : return \"WARN_LE\";\n        case assertType::DT_CHECK_LE                : return \"CHECK_LE\";\n        case assertType::DT_REQUIRE_LE              : return \"REQUIRE_LE\";\n\n        case assertType::DT_WARN_UNARY              : return \"WARN_UNARY\";\n        case assertType::DT_CHECK_UNARY             : return \"CHECK_UNARY\";\n        case assertType::DT_REQUIRE_UNARY           : return \"REQUIRE_UNARY\";\n        case assertType::DT_WARN_UNARY_FALSE        : return \"WARN_UNARY_FALSE\";\n        case assertType::DT_CHECK_UNARY_FALSE       : return \"CHECK_UNARY_FALSE\";\n        case assertType::DT_REQUIRE_UNARY_FALSE     : return \"REQUIRE_UNARY_FALSE\";\n    }\n    DOCTEST_MSVC_SUPPRESS_WARNING_POP\n    return \"\";\n}\n// clang-format on\n\nconst char* failureString(assertType::Enum at) {\n    if(at & assertType::is_warn) //!OCLINT bitwise operator in conditional\n        return \"WARNING\";\n    if(at & assertType::is_check) //!OCLINT bitwise operator in conditional\n        return \"ERROR\";\n    if(at & assertType::is_require) //!OCLINT bitwise operator in conditional\n        return \"FATAL ERROR\";\n    return \"\";\n}\n\nDOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wnull-dereference\")\nDOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wnull-dereference\")\n// depending on the current options this will remove the path of filenames\nconst char* skipPathFromFilename(const char* file) {\n#ifndef DOCTEST_CONFIG_DISABLE\n    if(getContextOptions()->no_path_in_filenames) {\n        auto back    = std::strrchr(file, '\\\\');\n        auto forward = std::strrchr(file, '/');\n        if(back || forward) {\n            if(back > forward)\n                forward = back;\n            return forward + 1;\n        }\n    }\n#endif // DOCTEST_CONFIG_DISABLE\n    return file;\n}\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n\nbool SubcaseSignature::operator<(const SubcaseSignature& other) const {\n    if(m_line != other.m_line)\n        return m_line < other.m_line;\n    if(std::strcmp(m_file, other.m_file) != 0)\n        return std::strcmp(m_file, other.m_file) < 0;\n    return m_name.compare(other.m_name) < 0;\n}\n\nIContextScope::IContextScope()  = default;\nIContextScope::~IContextScope() = default;\n\n#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\nString toString(char* in) { return toString(static_cast<const char*>(in)); }\n// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\nString toString(const char* in) { return String(\"\\\"\") + (in ? in : \"{null string}\") + \"\\\"\"; }\n#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\nString toString(bool in) { return in ? \"true\" : \"false\"; }\nString toString(float in) { return fpToString(in, 5) + \"f\"; }\nString toString(double in) { return fpToString(in, 10); }\nString toString(double long in) { return fpToString(in, 15); }\n\n#define DOCTEST_TO_STRING_OVERLOAD(type, fmt)                                                      \\\n    String toString(type in) {                                                                     \\\n        char buf[64];                                                                              \\\n        std::sprintf(buf, fmt, in);                                                                \\\n        return buf;                                                                                \\\n    }\n\nDOCTEST_TO_STRING_OVERLOAD(char, \"%d\")\nDOCTEST_TO_STRING_OVERLOAD(char signed, \"%d\")\nDOCTEST_TO_STRING_OVERLOAD(char unsigned, \"%u\")\nDOCTEST_TO_STRING_OVERLOAD(int short, \"%d\")\nDOCTEST_TO_STRING_OVERLOAD(int short unsigned, \"%u\")\nDOCTEST_TO_STRING_OVERLOAD(int, \"%d\")\nDOCTEST_TO_STRING_OVERLOAD(unsigned, \"%u\")\nDOCTEST_TO_STRING_OVERLOAD(int long, \"%ld\")\nDOCTEST_TO_STRING_OVERLOAD(int long unsigned, \"%lu\")\nDOCTEST_TO_STRING_OVERLOAD(int long long, \"%lld\")\nDOCTEST_TO_STRING_OVERLOAD(int long long unsigned, \"%llu\")\n\nString toString(std::nullptr_t) { return \"NULL\"; }\n\n#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)\n// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183\nString toString(const std::string& in) { return in.c_str(); }\n#endif // VS 2019\n\nApprox::Approx(double value)\n        : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)\n        , m_scale(1.0)\n        , m_value(value) {}\n\nApprox Approx::operator()(double value) const {\n    Approx approx(value);\n    approx.epsilon(m_epsilon);\n    approx.scale(m_scale);\n    return approx;\n}\n\nApprox& Approx::epsilon(double newEpsilon) {\n    m_epsilon = newEpsilon;\n    return *this;\n}\nApprox& Approx::scale(double newScale) {\n    m_scale = newScale;\n    return *this;\n}\n\nbool operator==(double lhs, const Approx& rhs) {\n    // Thanks to Richard Harris for his help refining this formula\n    return std::fabs(lhs - rhs.m_value) <\n           rhs.m_epsilon * (rhs.m_scale + std::max<double>(std::fabs(lhs), std::fabs(rhs.m_value)));\n}\nbool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); }\nbool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); }\nbool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); }\nbool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; }\nbool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; }\nbool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; }\nbool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; }\nbool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; }\nbool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; }\nbool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; }\nbool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }\n\nString toString(const Approx& in) {\n    // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\n    return String(\"Approx( \") + doctest::toString(in.m_value) + \" )\";\n}\nconst ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }\n\n} // namespace doctest\n\n#ifdef DOCTEST_CONFIG_DISABLE\nnamespace doctest {\nContext::Context(int, const char* const*) {}\nContext::~Context() = default;\nvoid Context::applyCommandLine(int, const char* const*) {}\nvoid Context::addFilter(const char*, const char*) {}\nvoid Context::clearFilters() {}\nvoid Context::setOption(const char*, int) {}\nvoid Context::setOption(const char*, const char*) {}\nbool Context::shouldExit() { return false; }\nvoid Context::setAsDefaultForAssertsOutOfTestCases() {}\nvoid Context::setAssertHandler(detail::assert_handler) {}\nint  Context::run() { return 0; }\n\nIReporter::~IReporter() = default;\n\nint                         IReporter::get_num_active_contexts() { return 0; }\nconst IContextScope* const* IReporter::get_active_contexts() { return nullptr; }\nint                         IReporter::get_num_stringified_contexts() { return 0; }\nconst String*               IReporter::get_stringified_contexts() { return nullptr; }\n\nint registerReporter(const char*, int, IReporter*) { return 0; }\n\n} // namespace doctest\n#else // DOCTEST_CONFIG_DISABLE\n\n#if !defined(DOCTEST_CONFIG_COLORS_NONE)\n#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)\n#ifdef DOCTEST_PLATFORM_WINDOWS\n#define DOCTEST_CONFIG_COLORS_WINDOWS\n#else // linux\n#define DOCTEST_CONFIG_COLORS_ANSI\n#endif // platform\n#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI\n#endif // DOCTEST_CONFIG_COLORS_NONE\n\nnamespace doctest_detail_test_suite_ns {\n// holds the current test suite\ndoctest::detail::TestSuite& getCurrentTestSuite() {\n    static doctest::detail::TestSuite data{};\n    return data;\n}\n} // namespace doctest_detail_test_suite_ns\n\nnamespace doctest {\nnamespace {\n    // the int (priority) is part of the key for automatic sorting - sadly one can register a\n    // reporter with a duplicate name and a different priority but hopefully that won't happen often :|\n    typedef std::map<std::pair<int, String>, reporterCreatorFunc> reporterMap;\n\n    reporterMap& getReporters() {\n        static reporterMap data;\n        return data;\n    }\n    reporterMap& getListeners() {\n        static reporterMap data;\n        return data;\n    }\n} // namespace\nnamespace detail {\n#define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...)                                           \\\n    for(auto& curr_rep : g_cs->reporters_currently_used)                                           \\\n    curr_rep->function(__VA_ARGS__)\n\n    bool checkIfShouldThrow(assertType::Enum at) {\n        if(at & assertType::is_require) //!OCLINT bitwise operator in conditional\n            return true;\n\n        if((at & assertType::is_check) //!OCLINT bitwise operator in conditional\n           && getContextOptions()->abort_after > 0 &&\n           (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >=\n                   getContextOptions()->abort_after)\n            return true;\n\n        return false;\n    }\n\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n    DOCTEST_NORETURN void throwException() {\n        g_cs->shouldLogCurrentException = false;\n        throw TestFailureException();\n    } // NOLINT(cert-err60-cpp)\n#else // DOCTEST_CONFIG_NO_EXCEPTIONS\n    void throwException() {}\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n} // namespace detail\n\nnamespace {\n    using namespace detail;\n    // matching of a string against a wildcard mask (case sensitivity configurable) taken from\n    // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing\n    int wildcmp(const char* str, const char* wild, bool caseSensitive) {\n        const char* cp = str;\n        const char* mp = wild;\n\n        while((*str) && (*wild != '*')) {\n            if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&\n               (*wild != '?')) {\n                return 0;\n            }\n            wild++;\n            str++;\n        }\n\n        while(*str) {\n            if(*wild == '*') {\n                if(!*++wild) {\n                    return 1;\n                }\n                mp = wild;\n                cp = str + 1;\n            } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||\n                      (*wild == '?')) {\n                wild++;\n                str++;\n            } else {\n                wild = mp;   //!OCLINT parameter reassignment\n                str  = cp++; //!OCLINT parameter reassignment\n            }\n        }\n\n        while(*wild == '*') {\n            wild++;\n        }\n        return !*wild;\n    }\n\n    //// C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html\n    //unsigned hashStr(unsigned const char* str) {\n    //    unsigned long hash = 5381;\n    //    char          c;\n    //    while((c = *str++))\n    //        hash = ((hash << 5) + hash) + c; // hash * 33 + c\n    //    return hash;\n    //}\n\n    // checks if the name matches any of the filters (and can be configured what to do when empty)\n    bool matchesAny(const char* name, const std::vector<String>& filters, bool matchEmpty,\n                    bool caseSensitive) {\n        if(filters.empty() && matchEmpty)\n            return true;\n        for(auto& curr : filters)\n            if(wildcmp(name, curr.c_str(), caseSensitive))\n                return true;\n        return false;\n    }\n} // namespace\nnamespace detail {\n\n    Subcase::Subcase(const String& name, const char* file, int line)\n            : m_signature({name, file, line}) {\n        auto* s = g_cs;\n\n        // check subcase filters\n        if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) {\n            if(!matchesAny(m_signature.m_name.c_str(), s->filters[6], true, s->case_sensitive))\n                return;\n            if(matchesAny(m_signature.m_name.c_str(), s->filters[7], false, s->case_sensitive))\n                return;\n        }\n        \n        // if a Subcase on the same level has already been entered\n        if(s->subcasesStack.size() < size_t(s->subcasesCurrentMaxLevel)) {\n            s->should_reenter = true;\n            return;\n        }\n\n        // push the current signature to the stack so we can check if the\n        // current stack + the current new subcase have been traversed\n        s->subcasesStack.push_back(m_signature);\n        if(s->subcasesPassed.count(s->subcasesStack) != 0) {\n            // pop - revert to previous stack since we've already passed this\n            s->subcasesStack.pop_back();\n            return;\n        }\n\n        s->subcasesCurrentMaxLevel = s->subcasesStack.size();\n        m_entered = true;\n\n        DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);\n    }\n\n    DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17\t\n    DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wdeprecated-declarations\")\t\n    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wdeprecated-declarations\")\n\n    Subcase::~Subcase() {\n        if(m_entered) {\n            // only mark the subcase stack as passed if no subcases have been skipped\n            if(g_cs->should_reenter == false)\n                g_cs->subcasesPassed.insert(g_cs->subcasesStack);\n            g_cs->subcasesStack.pop_back();\n\n#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)\n            if(std::uncaught_exceptions() > 0\n#else\n            if(std::uncaught_exception()\n#endif\n            && g_cs->shouldLogCurrentException) {\n                DOCTEST_ITERATE_THROUGH_REPORTERS(\n                        test_case_exception, {\"exception thrown in subcase - will translate later \"\n                                              \"when the whole test case has been exited (cannot \"\n                                              \"translate while there is an active exception)\",\n                                              false});\n                g_cs->shouldLogCurrentException = false;\n            }\n            DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);\n        }\n    }\n\n    DOCTEST_CLANG_SUPPRESS_WARNING_POP\t\n    DOCTEST_GCC_SUPPRESS_WARNING_POP\t\n    DOCTEST_MSVC_SUPPRESS_WARNING_POP\n\n    Subcase::operator bool() const { return m_entered; }\n\n    Result::Result(bool passed, const String& decomposition)\n            : m_passed(passed)\n            , m_decomp(decomposition) {}\n\n    ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at)\n            : m_at(at) {}\n\n    TestSuite& TestSuite::operator*(const char* in) {\n        m_test_suite = in;\n        // clear state\n        m_description       = nullptr;\n        m_skip              = false;\n        m_no_breaks         = false;\n        m_no_output         = false;\n        m_may_fail          = false;\n        m_should_fail       = false;\n        m_expected_failures = 0;\n        m_timeout           = 0;\n        return *this;\n    }\n\n    TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,\n                       const char* type, int template_id) {\n        m_file              = file;\n        m_line              = line;\n        m_name              = nullptr; // will be later overridden in operator*\n        m_test_suite        = test_suite.m_test_suite;\n        m_description       = test_suite.m_description;\n        m_skip              = test_suite.m_skip;\n        m_no_breaks         = test_suite.m_no_breaks;\n        m_no_output         = test_suite.m_no_output;\n        m_may_fail          = test_suite.m_may_fail;\n        m_should_fail       = test_suite.m_should_fail;\n        m_expected_failures = test_suite.m_expected_failures;\n        m_timeout           = test_suite.m_timeout;\n\n        m_test        = test;\n        m_type        = type;\n        m_template_id = template_id;\n    }\n\n    TestCase::TestCase(const TestCase& other)\n            : TestCaseData() {\n        *this = other;\n    }\n\n    DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function\n    DOCTEST_MSVC_SUPPRESS_WARNING(26437)           // Do not slice\n    TestCase& TestCase::operator=(const TestCase& other) {\n        static_cast<TestCaseData&>(*this) = static_cast<const TestCaseData&>(other);\n\n        m_test        = other.m_test;\n        m_type        = other.m_type;\n        m_template_id = other.m_template_id;\n        m_full_name   = other.m_full_name;\n\n        if(m_template_id != -1)\n            m_name = m_full_name.c_str();\n        return *this;\n    }\n    DOCTEST_MSVC_SUPPRESS_WARNING_POP\n\n    TestCase& TestCase::operator*(const char* in) {\n        m_name = in;\n        // make a new name with an appended type for templated test case\n        if(m_template_id != -1) {\n            m_full_name = String(m_name) + m_type;\n            // redirect the name to point to the newly constructed full name\n            m_name = m_full_name.c_str();\n        }\n        return *this;\n    }\n\n    bool TestCase::operator<(const TestCase& other) const {\n        // this will be used only to differentiate between test cases - not relevant for sorting\n        if(m_line != other.m_line)\n            return m_line < other.m_line;\n        const int name_cmp = strcmp(m_name, other.m_name);\n        if(name_cmp != 0)\n            return name_cmp < 0;\n        const int file_cmp = m_file.compare(other.m_file);\n        if(file_cmp != 0)\n            return file_cmp < 0;\n        return m_template_id < other.m_template_id;\n    }\n\n    // all the registered tests\n    std::set<TestCase>& getRegisteredTests() {\n        static std::set<TestCase> data;\n        return data;\n    }\n} // namespace detail\nnamespace {\n    using namespace detail;\n    // for sorting tests by file/line\n    bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {\n        // this is needed because MSVC gives different case for drive letters\n        // for __FILE__ when evaluated in a header and a source file\n        const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC));\n        if(res != 0)\n            return res < 0;\n        if(lhs->m_line != rhs->m_line)\n            return lhs->m_line < rhs->m_line;\n        return lhs->m_template_id < rhs->m_template_id;\n    }\n\n    // for sorting tests by suite/file/line\n    bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) {\n        const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);\n        if(res != 0)\n            return res < 0;\n        return fileOrderComparator(lhs, rhs);\n    }\n\n    // for sorting tests by name/suite/file/line\n    bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) {\n        const int res = std::strcmp(lhs->m_name, rhs->m_name);\n        if(res != 0)\n            return res < 0;\n        return suiteOrderComparator(lhs, rhs);\n    }\n\n#ifdef DOCTEST_CONFIG_COLORS_WINDOWS\n    HANDLE g_stdoutHandle;\n    WORD   g_origFgAttrs;\n    WORD   g_origBgAttrs;\n    bool   g_attrsInitted = false;\n\n    int colors_init() {\n        if(!g_attrsInitted) {\n            g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);\n            g_attrsInitted = true;\n            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;\n            GetConsoleScreenBufferInfo(g_stdoutHandle, &csbiInfo);\n            g_origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED |\n                                                     BACKGROUND_BLUE | BACKGROUND_INTENSITY);\n            g_origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED |\n                                                     FOREGROUND_BLUE | FOREGROUND_INTENSITY);\n        }\n        return 0;\n    }\n\n    int dumy_init_console_colors = colors_init();\n#endif // DOCTEST_CONFIG_COLORS_WINDOWS\n\n    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wdeprecated-declarations\")\n    void color_to_stream(std::ostream& s, Color::Enum code) {\n        static_cast<void>(s);    // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS\n        static_cast<void>(code); // for DOCTEST_CONFIG_COLORS_NONE\n#ifdef DOCTEST_CONFIG_COLORS_ANSI\n        if(g_no_colors ||\n           (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false))\n            return;\n\n        auto col = \"\";\n        // clang-format off\n            switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement\n                case Color::Red:         col = \"[0;31m\"; break;\n                case Color::Green:       col = \"[0;32m\"; break;\n                case Color::Blue:        col = \"[0;34m\"; break;\n                case Color::Cyan:        col = \"[0;36m\"; break;\n                case Color::Yellow:      col = \"[0;33m\"; break;\n                case Color::Grey:        col = \"[1;30m\"; break;\n                case Color::LightGrey:   col = \"[0;37m\"; break;\n                case Color::BrightRed:   col = \"[1;31m\"; break;\n                case Color::BrightGreen: col = \"[1;32m\"; break;\n                case Color::BrightWhite: col = \"[1;37m\"; break;\n                case Color::Bright: // invalid\n                case Color::None:\n                case Color::White:\n                default:                 col = \"[0m\";\n            }\n        // clang-format on\n        s << \"\\033\" << col;\n#endif // DOCTEST_CONFIG_COLORS_ANSI\n\n#ifdef DOCTEST_CONFIG_COLORS_WINDOWS\n        if(g_no_colors ||\n           (isatty(fileno(stdout)) == false && getContextOptions()->force_colors == false))\n            return;\n\n#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(g_stdoutHandle, x | g_origBgAttrs)\n\n        // clang-format off\n        switch (code) {\n            case Color::White:       DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;\n            case Color::Red:         DOCTEST_SET_ATTR(FOREGROUND_RED);                                      break;\n            case Color::Green:       DOCTEST_SET_ATTR(FOREGROUND_GREEN);                                    break;\n            case Color::Blue:        DOCTEST_SET_ATTR(FOREGROUND_BLUE);                                     break;\n            case Color::Cyan:        DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN);                  break;\n            case Color::Yellow:      DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN);                   break;\n            case Color::Grey:        DOCTEST_SET_ATTR(0);                                                   break;\n            case Color::LightGrey:   DOCTEST_SET_ATTR(FOREGROUND_INTENSITY);                                break;\n            case Color::BrightRed:   DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED);               break;\n            case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN);             break;\n            case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;\n            case Color::None:\n            case Color::Bright: // invalid\n            default:                 DOCTEST_SET_ATTR(g_origFgAttrs);\n        }\n            // clang-format on\n#endif // DOCTEST_CONFIG_COLORS_WINDOWS\n    }\n    DOCTEST_CLANG_SUPPRESS_WARNING_POP\n\n    std::vector<const IExceptionTranslator*>& getExceptionTranslators() {\n        static std::vector<const IExceptionTranslator*> data;\n        return data;\n    }\n\n    String translateActiveException() {\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n        String res;\n        auto&  translators = getExceptionTranslators();\n        for(auto& curr : translators)\n            if(curr->translate(res))\n                return res;\n        // clang-format off\n        DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wcatch-value\")\n        try {\n            throw;\n        } catch(std::exception& ex) {\n            return ex.what();\n        } catch(std::string& msg) {\n            return msg.c_str();\n        } catch(const char* msg) {\n            return msg;\n        } catch(...) {\n            return \"unknown exception\";\n        }\n        DOCTEST_GCC_SUPPRESS_WARNING_POP\n// clang-format on\n#else  // DOCTEST_CONFIG_NO_EXCEPTIONS\n        return \"\";\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n    }\n} // namespace\n\nnamespace detail {\n    // used by the macros for registering tests\n    int regTest(const TestCase& tc) {\n        getRegisteredTests().insert(tc);\n        return 0;\n    }\n\n    // sets the current test suite\n    int setTestSuite(const TestSuite& ts) {\n        doctest_detail_test_suite_ns::getCurrentTestSuite() = ts;\n        return 0;\n    }\n\n#ifdef DOCTEST_IS_DEBUGGER_ACTIVE\n    bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); }\n#else // DOCTEST_IS_DEBUGGER_ACTIVE\n#ifdef DOCTEST_PLATFORM_LINUX\n    class ErrnoGuard {\n    public:\n        ErrnoGuard() : m_oldErrno(errno) {}\n        ~ErrnoGuard() { errno = m_oldErrno; }\n    private:\n        int m_oldErrno;\n    };\n    // See the comments in Catch2 for the reasoning behind this implementation:\n    // https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102\n    bool isDebuggerActive() {\n        ErrnoGuard guard;\n        std::ifstream in(\"/proc/self/status\");\n        for(std::string line; std::getline(in, line);) {\n            static const int PREFIX_LEN = 11;\n            if(line.compare(0, PREFIX_LEN, \"TracerPid:\\t\") == 0) {\n                return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';\n            }\n        }\n        return false;\n    }\n#elif defined(DOCTEST_PLATFORM_MAC)\n    // The following function is taken directly from the following technical note:\n    // https://developer.apple.com/library/archive/qa/qa1361/_index.html\n    // Returns true if the current process is being debugged (either\n    // running under the debugger or has a debugger attached post facto).\n    bool isDebuggerActive() {\n        int        mib[4];\n        kinfo_proc info;\n        size_t     size;\n        // Initialize the flags so that, if sysctl fails for some bizarre\n        // reason, we get a predictable result.\n        info.kp_proc.p_flag = 0;\n        // Initialize mib, which tells sysctl the info we want, in this case\n        // we're looking for information about a specific process ID.\n        mib[0] = CTL_KERN;\n        mib[1] = KERN_PROC;\n        mib[2] = KERN_PROC_PID;\n        mib[3] = getpid();\n        // Call sysctl.\n        size = sizeof(info);\n        if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) {\n            std::cerr << \"\\nCall to sysctl failed - unable to determine if debugger is active **\\n\";\n            return false;\n        }\n        // We're being debugged if the P_TRACED flag is set.\n        return ((info.kp_proc.p_flag & P_TRACED) != 0);\n    }\n#elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__)\n    bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }\n#else\n    bool isDebuggerActive() { return false; }\n#endif // Platform\n#endif // DOCTEST_IS_DEBUGGER_ACTIVE\n\n    void registerExceptionTranslatorImpl(const IExceptionTranslator* et) {\n        if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) ==\n           getExceptionTranslators().end())\n            getExceptionTranslators().push_back(et);\n    }\n\n#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n    void toStream(std::ostream* s, char* in) { *s << in; }\n    void toStream(std::ostream* s, const char* in) { *s << in; }\n#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING\n    void toStream(std::ostream* s, bool in) { *s << std::boolalpha << in << std::noboolalpha; }\n    void toStream(std::ostream* s, float in) { *s << in; }\n    void toStream(std::ostream* s, double in) { *s << in; }\n    void toStream(std::ostream* s, double long in) { *s << in; }\n\n    void toStream(std::ostream* s, char in) { *s << in; }\n    void toStream(std::ostream* s, char signed in) { *s << in; }\n    void toStream(std::ostream* s, char unsigned in) { *s << in; }\n    void toStream(std::ostream* s, int short in) { *s << in; }\n    void toStream(std::ostream* s, int short unsigned in) { *s << in; }\n    void toStream(std::ostream* s, int in) { *s << in; }\n    void toStream(std::ostream* s, int unsigned in) { *s << in; }\n    void toStream(std::ostream* s, int long in) { *s << in; }\n    void toStream(std::ostream* s, int long unsigned in) { *s << in; }\n    void toStream(std::ostream* s, int long long in) { *s << in; }\n    void toStream(std::ostream* s, int long long unsigned in) { *s << in; }\n\n    DOCTEST_THREAD_LOCAL std::vector<IContextScope*> g_infoContexts; // for logging with INFO()\n\n    ContextScopeBase::ContextScopeBase() {\n        g_infoContexts.push_back(this);\n    }\n\n    DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17\t\n    DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(\"-Wdeprecated-declarations\")\t\n    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wdeprecated-declarations\")\n\n    // destroy cannot be inlined into the destructor because that would mean calling stringify after\n    // ContextScope has been destroyed (base class destructors run after derived class destructors).\n    // Instead, ContextScope calls this method directly from its destructor.\n    void ContextScopeBase::destroy() {\n#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)\n        if(std::uncaught_exceptions() > 0) {\n#else\n        if(std::uncaught_exception()) {\n#endif\n            std::ostringstream s;\n            this->stringify(&s);\n            g_cs->stringifiedContexts.push_back(s.str().c_str());\n        }\n        g_infoContexts.pop_back();\n    }\n\n    DOCTEST_CLANG_SUPPRESS_WARNING_POP\t\n    DOCTEST_GCC_SUPPRESS_WARNING_POP\t\n    DOCTEST_MSVC_SUPPRESS_WARNING_POP\n} // namespace detail\nnamespace {\n    using namespace detail;\n\n#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)\n    struct FatalConditionHandler\n    {\n        static void reset() {}\n        static void allocateAltStackMem() {}\n        static void freeAltStackMem() {}\n    };\n#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH\n\n    void reportFatal(const std::string&);\n\n#ifdef DOCTEST_PLATFORM_WINDOWS\n\n    struct SignalDefs\n    {\n        DWORD id;\n        const char* name;\n    };\n    // There is no 1-1 mapping between signals and windows exceptions.\n    // Windows can easily distinguish between SO and SigSegV,\n    // but SigInt, SigTerm, etc are handled differently.\n    SignalDefs signalDefs[] = {\n            {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),\n             \"SIGILL - Illegal instruction signal\"},\n            {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), \"SIGSEGV - Stack overflow\"},\n            {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION),\n             \"SIGSEGV - Segmentation violation signal\"},\n            {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), \"Divide by zero error\"},\n    };\n\n    struct FatalConditionHandler\n    {\n        static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {\n            // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the\n            // console just once no matter how many threads have crashed.\n            static std::mutex mutex;\n            static bool execute = true;\n            {\n                std::lock_guard<std::mutex> lock(mutex);\n                if(execute) {\n                    bool reported = false;\n                    for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {\n                        if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {\n                            reportFatal(signalDefs[i].name);\n                            reported = true;\n                            break;\n                        }\n                    }\n                    if(reported == false)\n                        reportFatal(\"Unhandled SEH exception caught\");\n                    if(isDebuggerActive() && !g_cs->no_breaks)\n                        DOCTEST_BREAK_INTO_DEBUGGER();\n                }\n                execute = false;\n            }\n            std::exit(EXIT_FAILURE);\n        }\n\n        static void allocateAltStackMem() {}\n        static void freeAltStackMem() {}\n\n        FatalConditionHandler() {\n            isSet = true;\n            // 32k seems enough for doctest to handle stack overflow,\n            // but the value was found experimentally, so there is no strong guarantee\n            guaranteeSize = 32 * 1024;\n            // Register an unhandled exception filter\n            previousTop = SetUnhandledExceptionFilter(handleException);\n            // Pass in guarantee size to be filled\n            SetThreadStackGuarantee(&guaranteeSize);\n\n            // On Windows uncaught exceptions from another thread, exceptions from\n            // destructors, or calls to std::terminate are not a SEH exception\n\n            // The terminal handler gets called when:\n            // - std::terminate is called FROM THE TEST RUNNER THREAD\n            // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD\n            original_terminate_handler = std::get_terminate();\n            std::set_terminate([]() DOCTEST_NOEXCEPT {\n                reportFatal(\"Terminate handler called\");\n                if(isDebuggerActive() && !g_cs->no_breaks)\n                    DOCTEST_BREAK_INTO_DEBUGGER();\n                std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well\n            });\n\n            // SIGABRT is raised when:\n            // - std::terminate is called FROM A DIFFERENT THREAD\n            // - an exception is thrown from a destructor FROM A DIFFERENT THREAD\n            // - an uncaught exception is thrown FROM A DIFFERENT THREAD\n            prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT {\n                if(signal == SIGABRT) {\n                    reportFatal(\"SIGABRT - Abort (abnormal termination) signal\");\n                    if(isDebuggerActive() && !g_cs->no_breaks)\n                        DOCTEST_BREAK_INTO_DEBUGGER();\n                    std::exit(EXIT_FAILURE);\n                }\n            });\n\n            // The following settings are taken from google test, and more\n            // specifically from UnitTest::Run() inside of gtest.cc\n\n            // the user does not want to see pop-up dialogs about crashes\n            prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |\n                                             SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);\n            // This forces the abort message to go to stderr in all circumstances.\n            prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR);\n            // In the debug version, Visual Studio pops up a separate dialog\n            // offering a choice to debug the aborted program - we want to disable that.\n            prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);\n            // In debug mode, the Windows CRT can crash with an assertion over invalid\n            // input (e.g. passing an invalid file descriptor). The default handling\n            // for these assertions is to pop up a dialog and wait for user input.\n            // Instead ask the CRT to dump such assertions to stderr non-interactively.\n            prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n            prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);\n        }\n\n        static void reset() {\n            if(isSet) {\n                // Unregister handler and restore the old guarantee\n                SetUnhandledExceptionFilter(previousTop);\n                SetThreadStackGuarantee(&guaranteeSize);\n                std::set_terminate(original_terminate_handler);\n                std::signal(SIGABRT, prev_sigabrt_handler);\n                SetErrorMode(prev_error_mode_1);\n                _set_error_mode(prev_error_mode_2);\n                _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);\n                static_cast<void>(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode));\n                static_cast<void>(_CrtSetReportFile(_CRT_ASSERT, prev_report_file));\n                isSet = false;\n            }\n        }\n\n        ~FatalConditionHandler() { reset(); }\n\n    private:\n        static UINT         prev_error_mode_1;\n        static int          prev_error_mode_2;\n        static unsigned int prev_abort_behavior;\n        static int          prev_report_mode;\n        static _HFILE       prev_report_file;\n        static void (*prev_sigabrt_handler)(int);\n        static std::terminate_handler original_terminate_handler;\n        static bool isSet;\n        static ULONG guaranteeSize;\n        static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;\n    };\n\n    UINT         FatalConditionHandler::prev_error_mode_1;\n    int          FatalConditionHandler::prev_error_mode_2;\n    unsigned int FatalConditionHandler::prev_abort_behavior;\n    int          FatalConditionHandler::prev_report_mode;\n    _HFILE       FatalConditionHandler::prev_report_file;\n    void (*FatalConditionHandler::prev_sigabrt_handler)(int);\n    std::terminate_handler FatalConditionHandler::original_terminate_handler;\n    bool FatalConditionHandler::isSet = false;\n    ULONG FatalConditionHandler::guaranteeSize = 0;\n    LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;\n\n#else // DOCTEST_PLATFORM_WINDOWS\n\n    struct SignalDefs\n    {\n        int         id;\n        const char* name;\n    };\n    SignalDefs signalDefs[] = {{SIGINT, \"SIGINT - Terminal interrupt signal\"},\n                               {SIGILL, \"SIGILL - Illegal instruction signal\"},\n                               {SIGFPE, \"SIGFPE - Floating point error signal\"},\n                               {SIGSEGV, \"SIGSEGV - Segmentation violation signal\"},\n                               {SIGTERM, \"SIGTERM - Termination request signal\"},\n                               {SIGABRT, \"SIGABRT - Abort (abnormal termination) signal\"}};\n\n    struct FatalConditionHandler\n    {\n        static bool             isSet;\n        static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)];\n        static stack_t          oldSigStack;\n        static size_t           altStackSize;\n        static char*            altStackMem;\n\n        static void handleSignal(int sig) {\n            const char* name = \"<unknown signal>\";\n            for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {\n                SignalDefs& def = signalDefs[i];\n                if(sig == def.id) {\n                    name = def.name;\n                    break;\n                }\n            }\n            reset();\n            reportFatal(name);\n            raise(sig);\n        }\n\n        static void allocateAltStackMem() {\n            altStackMem = new char[altStackSize];\n        }\n\n        static void freeAltStackMem() {\n            delete[] altStackMem;\n        }\n\n        FatalConditionHandler() {\n            isSet = true;\n            stack_t sigStack;\n            sigStack.ss_sp    = altStackMem;\n            sigStack.ss_size  = altStackSize;\n            sigStack.ss_flags = 0;\n            sigaltstack(&sigStack, &oldSigStack);\n            struct sigaction sa = {};\n            sa.sa_handler       = handleSignal; // NOLINT\n            sa.sa_flags         = SA_ONSTACK;\n            for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {\n                sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);\n            }\n        }\n\n        ~FatalConditionHandler() { reset(); }\n        static void reset() {\n            if(isSet) {\n                // Set signals back to previous values -- hopefully nobody overwrote them in the meantime\n                for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {\n                    sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);\n                }\n                // Return the old stack\n                sigaltstack(&oldSigStack, nullptr);\n                isSet = false;\n            }\n        }\n    };\n\n    bool             FatalConditionHandler::isSet = false;\n    struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {};\n    stack_t          FatalConditionHandler::oldSigStack = {};\n    size_t           FatalConditionHandler::altStackSize = 4 * SIGSTKSZ;\n    char*            FatalConditionHandler::altStackMem = nullptr;\n\n#endif // DOCTEST_PLATFORM_WINDOWS\n#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH\n\n} // namespace\n\nnamespace {\n    using namespace detail;\n\n#ifdef DOCTEST_PLATFORM_WINDOWS\n#define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text)\n#else\n    // TODO: integration with XCode and other IDEs\n#define DOCTEST_OUTPUT_DEBUG_STRING(text) // NOLINT(clang-diagnostic-unused-macros)\n#endif // Platform\n\n    void addAssert(assertType::Enum at) {\n        if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional\n            g_cs->numAssertsCurrentTest_atomic++;\n    }\n\n    void addFailedAssert(assertType::Enum at) {\n        if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional\n            g_cs->numAssertsFailedCurrentTest_atomic++;\n    }\n\n#if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH)\n    void reportFatal(const std::string& message) {\n        g_cs->failure_flags |= TestCaseFailureReason::Crash;\n\n        DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true});\n\n        while(g_cs->subcasesStack.size()) {\n            g_cs->subcasesStack.pop_back();\n            DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);\n        }\n\n        g_cs->finalizeTestCaseData();\n\n        DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);\n\n        DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);\n    }\n#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH\n} // namespace\nnamespace detail {\n\n    ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,\n                                 const char* exception_type, const char* exception_string) {\n        m_test_case        = g_cs->currentTest;\n        m_at               = at;\n        m_file             = file;\n        m_line             = line;\n        m_expr             = expr;\n        m_failed           = true;\n        m_threw            = false;\n        m_threw_as         = false;\n        m_exception_type   = exception_type;\n        m_exception_string = exception_string;\n#if DOCTEST_MSVC\n        if(m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC\n            ++m_expr;\n#endif // MSVC\n    }\n\n    void ResultBuilder::setResult(const Result& res) {\n        m_decomp = res.m_decomp;\n        m_failed = !res.m_passed;\n    }\n\n    void ResultBuilder::translateException() {\n        m_threw     = true;\n        m_exception = translateActiveException();\n    }\n\n    bool ResultBuilder::log() {\n        if(m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional\n            m_failed = !m_threw;\n        } else if((m_at & assertType::is_throws_as) && (m_at & assertType::is_throws_with)) { //!OCLINT\n            m_failed = !m_threw_as || (m_exception != m_exception_string);\n        } else if(m_at & assertType::is_throws_as) { //!OCLINT bitwise operator in conditional\n            m_failed = !m_threw_as;\n        } else if(m_at & assertType::is_throws_with) { //!OCLINT bitwise operator in conditional\n            m_failed = m_exception != m_exception_string;\n        } else if(m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional\n            m_failed = m_threw;\n        }\n\n        if(m_exception.size())\n            m_exception = String(\"\\\"\") + m_exception + \"\\\"\";\n\n        if(is_running_in_test) {\n            addAssert(m_at);\n            DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this);\n\n            if(m_failed)\n                addFailedAssert(m_at);\n        } else if(m_failed) {\n            failed_out_of_a_testing_context(*this);\n        }\n\n        return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks &&\n            (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger\n    }\n\n    void ResultBuilder::react() const {\n        if(m_failed && checkIfShouldThrow(m_at))\n            throwException();\n    }\n\n    void failed_out_of_a_testing_context(const AssertData& ad) {\n        if(g_cs->ah)\n            g_cs->ah(ad);\n        else\n            std::abort();\n    }\n\n    void decomp_assert(assertType::Enum at, const char* file, int line, const char* expr,\n                       Result result) {\n        bool failed = !result.m_passed;\n\n        // ###################################################################################\n        // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT\n        // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED\n        // ###################################################################################\n        DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp);\n        DOCTEST_ASSERT_IN_TESTS(result.m_decomp);\n        // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\n    }\n\n    MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) {\n        m_stream   = getTlsOss();\n        m_file     = file;\n        m_line     = line;\n        m_severity = severity;\n    }\n\n    IExceptionTranslator::IExceptionTranslator()  = default;\n    IExceptionTranslator::~IExceptionTranslator() = default;\n\n    bool MessageBuilder::log() {\n        m_string = getTlsOssResult();\n        DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this);\n\n        const bool isWarn = m_severity & assertType::is_warn;\n\n        // warn is just a message in this context so we don't treat it as an assert\n        if(!isWarn) {\n            addAssert(m_severity);\n            addFailedAssert(m_severity);\n        }\n\n        return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn &&\n            (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger\n    }\n\n    void MessageBuilder::react() {\n        if(m_severity & assertType::is_require) //!OCLINT bitwise operator in conditional\n            throwException();\n    }\n\n    MessageBuilder::~MessageBuilder() = default;\n} // namespace detail\nnamespace {\n    using namespace detail;\n\n    template <typename Ex>\n    DOCTEST_NORETURN void throw_exception(Ex const& e) {\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n        throw e;\n#else  // DOCTEST_CONFIG_NO_EXCEPTIONS\n        std::cerr << \"doctest will terminate because it needed to throw an exception.\\n\"\n                  << \"The message was: \" << e.what() << '\\n';\n        std::terminate();\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n    }\n\n#ifndef DOCTEST_INTERNAL_ERROR\n#define DOCTEST_INTERNAL_ERROR(msg)                                                                \\\n    throw_exception(std::logic_error(                                                              \\\n            __FILE__ \":\" DOCTEST_TOSTR(__LINE__) \": Internal doctest error: \" msg))\n#endif // DOCTEST_INTERNAL_ERROR\n\n    // clang-format off\n\n// =================================================================================================\n// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp\n// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.\n// =================================================================================================\n\n    class XmlEncode {\n    public:\n        enum ForWhat { ForTextNodes, ForAttributes };\n\n        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );\n\n        void encodeTo( std::ostream& os ) const;\n\n        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );\n\n    private:\n        std::string m_str;\n        ForWhat m_forWhat;\n    };\n\n    class XmlWriter {\n    public:\n\n        class ScopedElement {\n        public:\n            ScopedElement( XmlWriter* writer );\n\n            ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT;\n            ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT;\n\n            ~ScopedElement();\n\n            ScopedElement& writeText( std::string const& text, bool indent = true );\n\n            template<typename T>\n            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {\n                m_writer->writeAttribute( name, attribute );\n                return *this;\n            }\n\n        private:\n            mutable XmlWriter* m_writer = nullptr;\n        };\n\n        XmlWriter( std::ostream& os = std::cout );\n        ~XmlWriter();\n\n        XmlWriter( XmlWriter const& ) = delete;\n        XmlWriter& operator=( XmlWriter const& ) = delete;\n\n        XmlWriter& startElement( std::string const& name );\n\n        ScopedElement scopedElement( std::string const& name );\n\n        XmlWriter& endElement();\n\n        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );\n\n        XmlWriter& writeAttribute( std::string const& name, const char* attribute );\n\n        XmlWriter& writeAttribute( std::string const& name, bool attribute );\n\n        template<typename T>\n        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {\n        std::stringstream rss;\n            rss << attribute;\n            return writeAttribute( name, rss.str() );\n        }\n\n        XmlWriter& writeText( std::string const& text, bool indent = true );\n\n        //XmlWriter& writeComment( std::string const& text );\n\n        //void writeStylesheetRef( std::string const& url );\n\n        //XmlWriter& writeBlankLine();\n\n        void ensureTagClosed();\n\n    private:\n\n        void writeDeclaration();\n\n        void newlineIfNecessary();\n\n        bool m_tagIsOpen = false;\n        bool m_needsNewline = false;\n        std::vector<std::string> m_tags;\n        std::string m_indent;\n        std::ostream& m_os;\n    };\n\n// =================================================================================================\n// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp\n// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.\n// =================================================================================================\n\nusing uchar = unsigned char;\n\nnamespace {\n\n    size_t trailingBytes(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return 2;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return 3;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return 4;\n        }\n        DOCTEST_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    uint32_t headerValue(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return c & 0x1F;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return c & 0x0F;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return c & 0x07;\n        }\n        DOCTEST_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    void hexEscapeChar(std::ostream& os, unsigned char c) {\n        std::ios_base::fmtflags f(os.flags());\n        os << \"\\\\x\"\n            << std::uppercase << std::hex << std::setfill('0') << std::setw(2)\n            << static_cast<int>(c);\n        os.flags(f);\n    }\n\n} // anonymous namespace\n\n    XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )\n    :   m_str( str ),\n        m_forWhat( forWhat )\n    {}\n\n    void XmlEncode::encodeTo( std::ostream& os ) const {\n        // Apostrophe escaping not necessary if we always use \" to write attributes\n        // (see: https://www.w3.org/TR/xml/#syntax)\n\n        for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {\n            uchar c = m_str[idx];\n            switch (c) {\n            case '<':   os << \"&lt;\"; break;\n            case '&':   os << \"&amp;\"; break;\n\n            case '>':\n                // See: https://www.w3.org/TR/xml/#syntax\n                if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')\n                    os << \"&gt;\";\n                else\n                    os << c;\n                break;\n\n            case '\\\"':\n                if (m_forWhat == ForAttributes)\n                    os << \"&quot;\";\n                else\n                    os << c;\n                break;\n\n            default:\n                // Check for control characters and invalid utf-8\n\n                // Escape control characters in standard ascii\n                // see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0\n                if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // Plain ASCII: Write it to stream\n                if (c < 0x7F) {\n                    os << c;\n                    break;\n                }\n\n                // UTF-8 territory\n                // Check if the encoding is valid and if it is not, hex escape bytes.\n                // Important: We do not check the exact decoded values for validity, only the encoding format\n                // First check that this bytes is a valid lead byte:\n                // This means that it is not encoded as 1111 1XXX\n                // Or as 10XX XXXX\n                if (c <  0xC0 ||\n                    c >= 0xF8) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                auto encBytes = trailingBytes(c);\n                // Are there enough bytes left to avoid accessing out-of-bounds memory?\n                if (idx + encBytes - 1 >= m_str.size()) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n                // The header is valid, check data\n                // The next encBytes bytes must together be a valid utf-8\n                // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)\n                bool valid = true;\n                uint32_t value = headerValue(c);\n                for (std::size_t n = 1; n < encBytes; ++n) {\n                    uchar nc = m_str[idx + n];\n                    valid &= ((nc & 0xC0) == 0x80);\n                    value = (value << 6) | (nc & 0x3F);\n                }\n\n                if (\n                    // Wrong bit pattern of following bytes\n                    (!valid) ||\n                    // Overlong encodings\n                    (value < 0x80) ||\n                    (                 value < 0x800   && encBytes > 2) || // removed \"0x80 <= value &&\" because redundant\n                    (0x800 < value && value < 0x10000 && encBytes > 3) ||\n                    // Encoded value out of range\n                    (value >= 0x110000)\n                    ) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // If we got here, this is in fact a valid(ish) utf-8 sequence\n                for (std::size_t n = 0; n < encBytes; ++n) {\n                    os << m_str[idx + n];\n                }\n                idx += encBytes - 1;\n                break;\n            }\n        }\n    }\n\n    std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {\n        xmlEncode.encodeTo( os );\n        return os;\n    }\n\n    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )\n    :   m_writer( writer )\n    {}\n\n    XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT\n    :   m_writer( other.m_writer ){\n        other.m_writer = nullptr;\n    }\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT {\n        if ( m_writer ) {\n            m_writer->endElement();\n        }\n        m_writer = other.m_writer;\n        other.m_writer = nullptr;\n        return *this;\n    }\n\n\n    XmlWriter::ScopedElement::~ScopedElement() {\n        if( m_writer )\n            m_writer->endElement();\n    }\n\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {\n        m_writer->writeText( text, indent );\n        return *this;\n    }\n\n    XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )\n    {\n        writeDeclaration();\n    }\n\n    XmlWriter::~XmlWriter() {\n        while( !m_tags.empty() )\n            endElement();\n    }\n\n    XmlWriter& XmlWriter::startElement( std::string const& name ) {\n        ensureTagClosed();\n        newlineIfNecessary();\n        m_os << m_indent << '<' << name;\n        m_tags.push_back( name );\n        m_indent += \"  \";\n        m_tagIsOpen = true;\n        return *this;\n    }\n\n    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {\n        ScopedElement scoped( this );\n        startElement( name );\n        return scoped;\n    }\n\n    XmlWriter& XmlWriter::endElement() {\n        newlineIfNecessary();\n        m_indent = m_indent.substr( 0, m_indent.size()-2 );\n        if( m_tagIsOpen ) {\n            m_os << \"/>\";\n            m_tagIsOpen = false;\n        }\n        else {\n            m_os << m_indent << \"</\" << m_tags.back() << \">\";\n        }\n        m_os << std::endl;\n        m_tags.pop_back();\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {\n        if( !name.empty() && !attribute.empty() )\n            m_os << ' ' << name << \"=\\\"\" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) {\n        if( !name.empty() && attribute && attribute[0] != '\\0' )\n            m_os << ' ' << name << \"=\\\"\" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {\n        m_os << ' ' << name << \"=\\\"\" << ( attribute ? \"true\" : \"false\" ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {\n        if( !text.empty() ){\n            bool tagWasOpen = m_tagIsOpen;\n            ensureTagClosed();\n            if( tagWasOpen && indent )\n                m_os << m_indent;\n            m_os << XmlEncode( text );\n            m_needsNewline = true;\n        }\n        return *this;\n    }\n\n    //XmlWriter& XmlWriter::writeComment( std::string const& text ) {\n    //    ensureTagClosed();\n    //    m_os << m_indent << \"<!--\" << text << \"-->\";\n    //    m_needsNewline = true;\n    //    return *this;\n    //}\n\n    //void XmlWriter::writeStylesheetRef( std::string const& url ) {\n    //    m_os << \"<?xml-stylesheet type=\\\"text/xsl\\\" href=\\\"\" << url << \"\\\"?>\\n\";\n    //}\n\n    //XmlWriter& XmlWriter::writeBlankLine() {\n    //    ensureTagClosed();\n    //    m_os << '\\n';\n    //    return *this;\n    //}\n\n    void XmlWriter::ensureTagClosed() {\n        if( m_tagIsOpen ) {\n            m_os << \">\" << std::endl;\n            m_tagIsOpen = false;\n        }\n    }\n\n    void XmlWriter::writeDeclaration() {\n        m_os << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n    }\n\n    void XmlWriter::newlineIfNecessary() {\n        if( m_needsNewline ) {\n            m_os << std::endl;\n            m_needsNewline = false;\n        }\n    }\n\n// =================================================================================================\n// End of copy-pasted code from Catch\n// =================================================================================================\n\n    // clang-format on\n\n    struct XmlReporter : public IReporter\n    {\n        XmlWriter  xml;\n        std::mutex mutex;\n\n        // caching pointers/references to objects of these types - safe to do\n        const ContextOptions& opt;\n        const TestCaseData*   tc = nullptr;\n\n        XmlReporter(const ContextOptions& co)\n                : xml(*co.cout)\n                , opt(co) {}\n\n        void log_contexts() {\n            int num_contexts = get_num_active_contexts();\n            if(num_contexts) {\n                auto              contexts = get_active_contexts();\n                std::stringstream ss;\n                for(int i = 0; i < num_contexts; ++i) {\n                    contexts[i]->stringify(&ss);\n                    xml.scopedElement(\"Info\").writeText(ss.str());\n                    ss.str(\"\");\n                }\n            }\n        }\n\n        unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }\n\n        void test_case_start_impl(const TestCaseData& in) {\n            bool open_ts_tag = false;\n            if(tc != nullptr) { // we have already opened a test suite\n                if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) {\n                    xml.endElement();\n                    open_ts_tag = true;\n                }\n            }\n            else {\n                open_ts_tag = true; // first test case ==> first test suite\n            }\n\n            if(open_ts_tag) {\n                xml.startElement(\"TestSuite\");\n                xml.writeAttribute(\"name\", in.m_test_suite);\n            }\n\n            tc = &in;\n            xml.startElement(\"TestCase\")\n                    .writeAttribute(\"name\", in.m_name)\n                    .writeAttribute(\"filename\", skipPathFromFilename(in.m_file.c_str()))\n                    .writeAttribute(\"line\", line(in.m_line))\n                    .writeAttribute(\"description\", in.m_description);\n\n            if(Approx(in.m_timeout) != 0)\n                xml.writeAttribute(\"timeout\", in.m_timeout);\n            if(in.m_may_fail)\n                xml.writeAttribute(\"may_fail\", true);\n            if(in.m_should_fail)\n                xml.writeAttribute(\"should_fail\", true);\n        }\n\n        // =========================================================================================\n        // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE\n        // =========================================================================================\n\n        void report_query(const QueryData& in) override {\n            test_run_start();\n            if(opt.list_reporters) {\n                for(auto& curr : getListeners())\n                    xml.scopedElement(\"Listener\")\n                            .writeAttribute(\"priority\", curr.first.first)\n                            .writeAttribute(\"name\", curr.first.second);\n                for(auto& curr : getReporters())\n                    xml.scopedElement(\"Reporter\")\n                            .writeAttribute(\"priority\", curr.first.first)\n                            .writeAttribute(\"name\", curr.first.second);\n            } else if(opt.count || opt.list_test_cases) {\n                for(unsigned i = 0; i < in.num_data; ++i) {\n                    xml.scopedElement(\"TestCase\").writeAttribute(\"name\", in.data[i]->m_name)\n                        .writeAttribute(\"testsuite\", in.data[i]->m_test_suite)\n                        .writeAttribute(\"filename\", skipPathFromFilename(in.data[i]->m_file.c_str()))\n                        .writeAttribute(\"line\", line(in.data[i]->m_line));\n                }\n                xml.scopedElement(\"OverallResultsTestCases\")\n                        .writeAttribute(\"unskipped\", in.run_stats->numTestCasesPassingFilters);\n            } else if(opt.list_test_suites) {\n                for(unsigned i = 0; i < in.num_data; ++i)\n                    xml.scopedElement(\"TestSuite\").writeAttribute(\"name\", in.data[i]->m_test_suite);\n                xml.scopedElement(\"OverallResultsTestCases\")\n                        .writeAttribute(\"unskipped\", in.run_stats->numTestCasesPassingFilters);\n                xml.scopedElement(\"OverallResultsTestSuites\")\n                        .writeAttribute(\"unskipped\", in.run_stats->numTestSuitesPassingFilters);\n            }\n            xml.endElement();\n        }\n\n        void test_run_start() override {\n            // remove .exe extension - mainly to have the same output on UNIX and Windows\n            std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());\n#ifdef DOCTEST_PLATFORM_WINDOWS\n            if(binary_name.rfind(\".exe\") != std::string::npos)\n                binary_name = binary_name.substr(0, binary_name.length() - 4);\n#endif // DOCTEST_PLATFORM_WINDOWS\n\n            xml.startElement(\"doctest\").writeAttribute(\"binary\", binary_name);\n            if(opt.no_version == false)\n                xml.writeAttribute(\"version\", DOCTEST_VERSION_STR);\n\n            // only the consequential ones (TODO: filters)\n            xml.scopedElement(\"Options\")\n                    .writeAttribute(\"order_by\", opt.order_by.c_str())\n                    .writeAttribute(\"rand_seed\", opt.rand_seed)\n                    .writeAttribute(\"first\", opt.first)\n                    .writeAttribute(\"last\", opt.last)\n                    .writeAttribute(\"abort_after\", opt.abort_after)\n                    .writeAttribute(\"subcase_filter_levels\", opt.subcase_filter_levels)\n                    .writeAttribute(\"case_sensitive\", opt.case_sensitive)\n                    .writeAttribute(\"no_throw\", opt.no_throw)\n                    .writeAttribute(\"no_skip\", opt.no_skip);\n        }\n\n        void test_run_end(const TestRunStats& p) override {\n            if(tc) // the TestSuite tag - only if there has been at least 1 test case\n                xml.endElement();\n\n            xml.scopedElement(\"OverallResultsAsserts\")\n                    .writeAttribute(\"successes\", p.numAsserts - p.numAssertsFailed)\n                    .writeAttribute(\"failures\", p.numAssertsFailed);\n\n            xml.startElement(\"OverallResultsTestCases\")\n                    .writeAttribute(\"successes\",\n                                    p.numTestCasesPassingFilters - p.numTestCasesFailed)\n                    .writeAttribute(\"failures\", p.numTestCasesFailed);\n            if(opt.no_skipped_summary == false)\n                xml.writeAttribute(\"skipped\", p.numTestCases - p.numTestCasesPassingFilters);\n            xml.endElement();\n\n            xml.endElement();\n        }\n\n        void test_case_start(const TestCaseData& in) override {\n            test_case_start_impl(in);\n            xml.ensureTagClosed();\n        }\n        \n        void test_case_reenter(const TestCaseData&) override {}\n\n        void test_case_end(const CurrentTestCaseStats& st) override {\n            xml.startElement(\"OverallResultsAsserts\")\n                    .writeAttribute(\"successes\",\n                                    st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest)\n                    .writeAttribute(\"failures\", st.numAssertsFailedCurrentTest);\n            if(opt.duration)\n                xml.writeAttribute(\"duration\", st.seconds);\n            if(tc->m_expected_failures)\n                xml.writeAttribute(\"expected_failures\", tc->m_expected_failures);\n            xml.endElement();\n\n            xml.endElement();\n        }\n\n        void test_case_exception(const TestCaseException& e) override {\n            std::lock_guard<std::mutex> lock(mutex);\n\n            xml.scopedElement(\"Exception\")\n                    .writeAttribute(\"crash\", e.is_crash)\n                    .writeText(e.error_string.c_str());\n        }\n\n        void subcase_start(const SubcaseSignature& in) override {\n            std::lock_guard<std::mutex> lock(mutex);\n\n            xml.startElement(\"SubCase\")\n                    .writeAttribute(\"name\", in.m_name)\n                    .writeAttribute(\"filename\", skipPathFromFilename(in.m_file))\n                    .writeAttribute(\"line\", line(in.m_line));\n            xml.ensureTagClosed();\n        }\n\n        void subcase_end() override { xml.endElement(); }\n\n        void log_assert(const AssertData& rb) override {\n            if(!rb.m_failed && !opt.success)\n                return;\n\n            std::lock_guard<std::mutex> lock(mutex);\n\n            xml.startElement(\"Expression\")\n                    .writeAttribute(\"success\", !rb.m_failed)\n                    .writeAttribute(\"type\", assertString(rb.m_at))\n                    .writeAttribute(\"filename\", skipPathFromFilename(rb.m_file))\n                    .writeAttribute(\"line\", line(rb.m_line));\n\n            xml.scopedElement(\"Original\").writeText(rb.m_expr);\n\n            if(rb.m_threw)\n                xml.scopedElement(\"Exception\").writeText(rb.m_exception.c_str());\n\n            if(rb.m_at & assertType::is_throws_as)\n                xml.scopedElement(\"ExpectedException\").writeText(rb.m_exception_type);\n            if(rb.m_at & assertType::is_throws_with)\n                xml.scopedElement(\"ExpectedExceptionString\").writeText(rb.m_exception_string);\n            if((rb.m_at & assertType::is_normal) && !rb.m_threw)\n                xml.scopedElement(\"Expanded\").writeText(rb.m_decomp.c_str());\n\n            log_contexts();\n\n            xml.endElement();\n        }\n\n        void log_message(const MessageData& mb) override {\n            std::lock_guard<std::mutex> lock(mutex);\n\n            xml.startElement(\"Message\")\n                    .writeAttribute(\"type\", failureString(mb.m_severity))\n                    .writeAttribute(\"filename\", skipPathFromFilename(mb.m_file))\n                    .writeAttribute(\"line\", line(mb.m_line));\n\n            xml.scopedElement(\"Text\").writeText(mb.m_string.c_str());\n\n            log_contexts();\n\n            xml.endElement();\n        }\n\n        void test_case_skipped(const TestCaseData& in) override {\n            if(opt.no_skipped_summary == false) {\n                test_case_start_impl(in);\n                xml.writeAttribute(\"skipped\", \"true\");\n                xml.endElement();\n            }\n        }\n    };\n\n    DOCTEST_REGISTER_REPORTER(\"xml\", 0, XmlReporter);\n\n    void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) {\n        if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) ==\n            0) //!OCLINT bitwise operator in conditional\n            s << Color::Cyan << assertString(rb.m_at) << \"( \" << rb.m_expr << \" ) \"\n                << Color::None;\n\n        if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional\n            s << (rb.m_threw ? \"threw as expected!\" : \"did NOT throw at all!\") << \"\\n\";\n        } else if((rb.m_at & assertType::is_throws_as) &&\n                    (rb.m_at & assertType::is_throws_with)) { //!OCLINT\n            s << Color::Cyan << assertString(rb.m_at) << \"( \" << rb.m_expr << \", \\\"\"\n                << rb.m_exception_string << \"\\\", \" << rb.m_exception_type << \" ) \" << Color::None;\n            if(rb.m_threw) {\n                if(!rb.m_failed) {\n                    s << \"threw as expected!\\n\";\n                } else {\n                    s << \"threw a DIFFERENT exception! (contents: \" << rb.m_exception << \")\\n\";\n                }\n            } else {\n                s << \"did NOT throw at all!\\n\";\n            }\n        } else if(rb.m_at &\n                    assertType::is_throws_as) { //!OCLINT bitwise operator in conditional\n            s << Color::Cyan << assertString(rb.m_at) << \"( \" << rb.m_expr << \", \"\n                << rb.m_exception_type << \" ) \" << Color::None\n                << (rb.m_threw ? (rb.m_threw_as ? \"threw as expected!\" :\n                                                \"threw a DIFFERENT exception: \") :\n                                \"did NOT throw at all!\")\n                << Color::Cyan << rb.m_exception << \"\\n\";\n        } else if(rb.m_at &\n                    assertType::is_throws_with) { //!OCLINT bitwise operator in conditional\n            s << Color::Cyan << assertString(rb.m_at) << \"( \" << rb.m_expr << \", \\\"\"\n                << rb.m_exception_string << \"\\\" ) \" << Color::None\n                << (rb.m_threw ? (!rb.m_failed ? \"threw as expected!\" :\n                                                \"threw a DIFFERENT exception: \") :\n                                \"did NOT throw at all!\")\n                << Color::Cyan << rb.m_exception << \"\\n\";\n        } else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional\n            s << (rb.m_threw ? \"THREW exception: \" : \"didn't throw!\") << Color::Cyan\n                << rb.m_exception << \"\\n\";\n        } else {\n            s << (rb.m_threw ? \"THREW exception: \" :\n                                (!rb.m_failed ? \"is correct!\\n\" : \"is NOT correct!\\n\"));\n            if(rb.m_threw)\n                s << rb.m_exception << \"\\n\";\n            else\n                s << \"  values: \" << assertString(rb.m_at) << \"( \" << rb.m_decomp << \" )\\n\";\n        }\n    }\n\n    // TODO:\n    // - log_message()\n    // - respond to queries\n    // - honor remaining options\n    // - more attributes in tags\n    struct JUnitReporter : public IReporter\n    {\n        XmlWriter  xml;\n        std::mutex mutex;\n        Timer timer;\n        std::vector<String> deepestSubcaseStackNames;\n\n        struct JUnitTestCaseData\n        {\n            static std::string getCurrentTimestamp() {\n                // Beware, this is not reentrant because of backward compatibility issues\n                // Also, UTC only, again because of backward compatibility (%z is C++11)\n                time_t rawtime;\n                std::time(&rawtime);\n                auto const timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n\n                std::tm timeInfo;\n#ifdef DOCTEST_PLATFORM_WINDOWS\n                gmtime_s(&timeInfo, &rawtime);\n#else // DOCTEST_PLATFORM_WINDOWS\n                gmtime_r(&rawtime, &timeInfo);\n#endif // DOCTEST_PLATFORM_WINDOWS\n\n                char timeStamp[timeStampSize];\n                const char* const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n                std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n                return std::string(timeStamp);\n            }\n\n            struct JUnitTestMessage\n            {\n                JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details)\n                    : message(_message), type(_type), details(_details) {}\n\n                JUnitTestMessage(const std::string& _message, const std::string& _details)\n                    : message(_message), type(), details(_details) {}\n\n                std::string message, type, details;\n            };\n\n            struct JUnitTestCase\n            {\n                JUnitTestCase(const std::string& _classname, const std::string& _name)\n                    : classname(_classname), name(_name), time(0), failures() {}\n\n                std::string classname, name;\n                double time;\n                std::vector<JUnitTestMessage> failures, errors;\n            };\n\n            void add(const std::string& classname, const std::string& name) {\n                testcases.emplace_back(classname, name);\n            }\n\n            void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) {\n                for(auto& curr: nameStack)\n                    if(curr.size())\n                        testcases.back().name += std::string(\"/\") + curr.c_str();\n            }\n\n            void addTime(double time) {\n                if(time < 1e-4)\n                    time = 0;\n                testcases.back().time = time;\n                totalSeconds += time;\n            }\n\n            void addFailure(const std::string& message, const std::string& type, const std::string& details) {\n                testcases.back().failures.emplace_back(message, type, details);\n                ++totalFailures;\n            }\n\n            void addError(const std::string& message, const std::string& details) {\n                testcases.back().errors.emplace_back(message, details);\n                ++totalErrors;\n            }\n\n            std::vector<JUnitTestCase> testcases;\n            double totalSeconds = 0;\n            int totalErrors = 0, totalFailures = 0;\n        };\n\n        JUnitTestCaseData testCaseData;\n\n        // caching pointers/references to objects of these types - safe to do\n        const ContextOptions& opt;\n        const TestCaseData*   tc = nullptr;\n\n        JUnitReporter(const ContextOptions& co)\n                : xml(*co.cout)\n                , opt(co) {}\n\n        unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }\n\n        // =========================================================================================\n        // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE\n        // =========================================================================================\n\n        void report_query(const QueryData&) override {}\n\n        void test_run_start() override {}\n\n        void test_run_end(const TestRunStats& p) override {\n            // remove .exe extension - mainly to have the same output on UNIX and Windows\n            std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());\n#ifdef DOCTEST_PLATFORM_WINDOWS\n            if(binary_name.rfind(\".exe\") != std::string::npos)\n                binary_name = binary_name.substr(0, binary_name.length() - 4);\n#endif // DOCTEST_PLATFORM_WINDOWS\n            xml.startElement(\"testsuites\");\n            xml.startElement(\"testsuite\").writeAttribute(\"name\", binary_name)\n                    .writeAttribute(\"errors\", testCaseData.totalErrors)\n                    .writeAttribute(\"failures\", testCaseData.totalFailures)\n                    .writeAttribute(\"tests\", p.numAsserts);\n            if(opt.no_time_in_output == false) {\n                xml.writeAttribute(\"time\", testCaseData.totalSeconds);\n                xml.writeAttribute(\"timestamp\", JUnitTestCaseData::getCurrentTimestamp());\n            }\n            if(opt.no_version == false)\n                xml.writeAttribute(\"doctest_version\", DOCTEST_VERSION_STR);\n\n            for(const auto& testCase : testCaseData.testcases) {\n                xml.startElement(\"testcase\")\n                    .writeAttribute(\"classname\", testCase.classname)\n                    .writeAttribute(\"name\", testCase.name);\n                if(opt.no_time_in_output == false)\n                    xml.writeAttribute(\"time\", testCase.time);\n                // This is not ideal, but it should be enough to mimic gtest's junit output.\n                xml.writeAttribute(\"status\", \"run\");\n\n                for(const auto& failure : testCase.failures) {\n                    xml.scopedElement(\"failure\")\n                        .writeAttribute(\"message\", failure.message)\n                        .writeAttribute(\"type\", failure.type)\n                        .writeText(failure.details, false);\n                }\n\n                for(const auto& error : testCase.errors) {\n                    xml.scopedElement(\"error\")\n                        .writeAttribute(\"message\", error.message)\n                        .writeText(error.details);\n                }\n\n                xml.endElement();\n            }\n            xml.endElement();\n            xml.endElement();\n        }\n\n        void test_case_start(const TestCaseData& in) override {\n            testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);\n            timer.start();\n        }\n\n        void test_case_reenter(const TestCaseData& in) override {\n            testCaseData.addTime(timer.getElapsedSeconds());\n            testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);\n            deepestSubcaseStackNames.clear();\n\n            timer.start();\n            testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);\n        }\n\n        void test_case_end(const CurrentTestCaseStats&) override {\n            testCaseData.addTime(timer.getElapsedSeconds());\n            testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);\n            deepestSubcaseStackNames.clear();\n        }\n\n        void test_case_exception(const TestCaseException& e) override {\n            std::lock_guard<std::mutex> lock(mutex);\n            testCaseData.addError(\"exception\", e.error_string.c_str());\n        }\n\n        void subcase_start(const SubcaseSignature& in) override {\n            std::lock_guard<std::mutex> lock(mutex);\n            deepestSubcaseStackNames.push_back(in.m_name);\n        }\n\n        void subcase_end() override {}\n\n        void log_assert(const AssertData& rb) override {\n            if(!rb.m_failed) // report only failures & ignore the `success` option\n                return;\n\n            std::lock_guard<std::mutex> lock(mutex);\n\n            std::ostringstream os;\n            os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? \":\" : \"(\")\n              << line(rb.m_line) << (opt.gnu_file_line ? \":\" : \"):\") << std::endl;\n\n            fulltext_log_assert_to_stream(os, rb);\n            log_contexts(os);\n            testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str());\n        }\n\n        void log_message(const MessageData&) override {}\n\n        void test_case_skipped(const TestCaseData&) override {}\n\n        void log_contexts(std::ostringstream& s) {\n            int num_contexts = get_num_active_contexts();\n            if(num_contexts) {\n                auto contexts = get_active_contexts();\n\n                s << \"  logged: \";\n                for(int i = 0; i < num_contexts; ++i) {\n                    s << (i == 0 ? \"\" : \"          \");\n                    contexts[i]->stringify(&s);\n                    s << std::endl;\n                }\n            }\n        }\n    };\n\n    DOCTEST_REGISTER_REPORTER(\"junit\", 0, JUnitReporter);\n\n    struct Whitespace\n    {\n        int nrSpaces;\n        explicit Whitespace(int nr)\n                : nrSpaces(nr) {}\n    };\n\n    std::ostream& operator<<(std::ostream& out, const Whitespace& ws) {\n        if(ws.nrSpaces != 0)\n            out << std::setw(ws.nrSpaces) << ' ';\n        return out;\n    }\n\n    struct ConsoleReporter : public IReporter\n    {\n        std::ostream&                 s;\n        bool                          hasLoggedCurrentTestStart;\n        std::vector<SubcaseSignature> subcasesStack;\n        size_t                        currentSubcaseLevel;\n        std::mutex                    mutex;\n\n        // caching pointers/references to objects of these types - safe to do\n        const ContextOptions& opt;\n        const TestCaseData*   tc;\n\n        ConsoleReporter(const ContextOptions& co)\n                : s(*co.cout)\n                , opt(co) {}\n\n        ConsoleReporter(const ContextOptions& co, std::ostream& ostr)\n                : s(ostr)\n                , opt(co) {}\n\n        // =========================================================================================\n        // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF THE INTERFACE\n        // =========================================================================================\n\n        void separator_to_stream() {\n            s << Color::Yellow\n              << \"===============================================================================\"\n                 \"\\n\";\n        }\n\n        const char* getSuccessOrFailString(bool success, assertType::Enum at,\n                                           const char* success_str) {\n            if(success)\n                return success_str;\n            return failureString(at);\n        }\n\n        Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) {\n            return success ? Color::BrightGreen :\n                             (at & assertType::is_warn) ? Color::Yellow : Color::Red;\n        }\n\n        void successOrFailColoredStringToStream(bool success, assertType::Enum at,\n                                                const char* success_str = \"SUCCESS\") {\n            s << getSuccessOrFailColor(success, at)\n              << getSuccessOrFailString(success, at, success_str) << \": \";\n        }\n\n        void log_contexts() {\n            int num_contexts = get_num_active_contexts();\n            if(num_contexts) {\n                auto contexts = get_active_contexts();\n\n                s << Color::None << \"  logged: \";\n                for(int i = 0; i < num_contexts; ++i) {\n                    s << (i == 0 ? \"\" : \"          \");\n                    contexts[i]->stringify(&s);\n                    s << \"\\n\";\n                }\n            }\n\n            s << \"\\n\";\n        }\n\n        // this was requested to be made virtual so users could override it\n        virtual void file_line_to_stream(const char* file, int line,\n                                        const char* tail = \"\") {\n            s << Color::LightGrey << skipPathFromFilename(file) << (opt.gnu_file_line ? \":\" : \"(\")\n            << (opt.no_line_numbers ? 0 : line) // 0 or the real num depending on the option\n            << (opt.gnu_file_line ? \":\" : \"):\") << tail;\n        }\n\n        void logTestStart() {\n            if(hasLoggedCurrentTestStart)\n                return;\n\n            separator_to_stream();\n            file_line_to_stream(tc->m_file.c_str(), tc->m_line, \"\\n\");\n            if(tc->m_description)\n                s << Color::Yellow << \"DESCRIPTION: \" << Color::None << tc->m_description << \"\\n\";\n            if(tc->m_test_suite && tc->m_test_suite[0] != '\\0')\n                s << Color::Yellow << \"TEST SUITE: \" << Color::None << tc->m_test_suite << \"\\n\";\n            if(strncmp(tc->m_name, \"  Scenario:\", 11) != 0)\n                s << Color::Yellow << \"TEST CASE:  \";\n            s << Color::None << tc->m_name << \"\\n\";\n\n            for(size_t i = 0; i < currentSubcaseLevel; ++i) {\n                if(subcasesStack[i].m_name[0] != '\\0')\n                    s << \"  \" << subcasesStack[i].m_name << \"\\n\";\n            }\n\n            if(currentSubcaseLevel != subcasesStack.size()) {\n                s << Color::Yellow << \"\\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\\n\" << Color::None;\n                for(size_t i = 0; i < subcasesStack.size(); ++i) {\n                    if(subcasesStack[i].m_name[0] != '\\0')\n                        s << \"  \" << subcasesStack[i].m_name << \"\\n\";\n                }\n            }\n\n            s << \"\\n\";\n\n            hasLoggedCurrentTestStart = true;\n        }\n\n        void printVersion() {\n            if(opt.no_version == false)\n                s << Color::Cyan << \"[doctest] \" << Color::None << \"doctest version is \\\"\"\n                  << DOCTEST_VERSION_STR << \"\\\"\\n\";\n        }\n\n        void printIntro() {\n            printVersion();\n            s << Color::Cyan << \"[doctest] \" << Color::None\n              << \"run with \\\"--\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"help\\\" for options\\n\";\n        }\n\n        void printHelp() {\n            int sizePrefixDisplay = static_cast<int>(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY));\n            printVersion();\n            // clang-format off\n            s << Color::Cyan << \"[doctest]\\n\" << Color::None;\n            s << Color::Cyan << \"[doctest] \" << Color::None;\n            s << \"boolean values: \\\"1/on/yes/true\\\" or \\\"0/off/no/false\\\"\\n\";\n            s << Color::Cyan << \"[doctest] \" << Color::None;\n            s << \"filter  values: \\\"str1,str2,str3\\\" (comma separated strings)\\n\";\n            s << Color::Cyan << \"[doctest]\\n\" << Color::None;\n            s << Color::Cyan << \"[doctest] \" << Color::None;\n            s << \"filters use wildcards for matching strings\\n\";\n            s << Color::Cyan << \"[doctest] \" << Color::None;\n            s << \"something passes a filter if any of the strings in a filter matches\\n\";\n#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS\n            s << Color::Cyan << \"[doctest]\\n\" << Color::None;\n            s << Color::Cyan << \"[doctest] \" << Color::None;\n            s << \"ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \\\"\" DOCTEST_CONFIG_OPTIONS_PREFIX \"\\\" PREFIX!!!\\n\";\n#endif\n            s << Color::Cyan << \"[doctest]\\n\" << Color::None;\n            s << Color::Cyan << \"[doctest] \" << Color::None;\n            s << \"Query flags - the program quits after them. Available:\\n\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"?,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"help, -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"h                      \"\n              << Whitespace(sizePrefixDisplay*0) <<  \"prints this message\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"v,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"version                       \"\n              << Whitespace(sizePrefixDisplay*1) << \"prints the version\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"c,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"count                         \"\n              << Whitespace(sizePrefixDisplay*1) << \"prints the number of matching tests\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"ltc, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"list-test-cases               \"\n              << Whitespace(sizePrefixDisplay*1) << \"lists all matching tests by name\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"lts, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"list-test-suites              \"\n              << Whitespace(sizePrefixDisplay*1) << \"lists all matching test suites\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"lr,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"list-reporters                \"\n              << Whitespace(sizePrefixDisplay*1) << \"lists all registered reporters\\n\\n\";\n            // ================================================================================== << 79\n            s << Color::Cyan << \"[doctest] \" << Color::None;\n            s << \"The available <int>/<string> options/filters are:\\n\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"tc,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"test-case=<filters>           \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters     tests by their name\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"tce, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"test-case-exclude=<filters>   \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters OUT tests by their name\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"sf,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"source-file=<filters>         \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters     tests by their file\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"sfe, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"source-file-exclude=<filters> \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters OUT tests by their file\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"ts,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"test-suite=<filters>          \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters     tests by their test suite\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"tse, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"test-suite-exclude=<filters>  \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters OUT tests by their test suite\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"sc,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"subcase=<filters>             \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters     subcases by their name\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"sce, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"subcase-exclude=<filters>     \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters OUT subcases by their name\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"r,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"reporters=<filters>           \"\n              << Whitespace(sizePrefixDisplay*1) << \"reporters to use (console is default)\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"o,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"out=<string>                  \"\n              << Whitespace(sizePrefixDisplay*1) << \"output filename\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"ob,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"order-by=<string>             \"\n              << Whitespace(sizePrefixDisplay*1) << \"how the tests should be ordered\\n\";\n            s << Whitespace(sizePrefixDisplay*3) << \"                                       <string> - [file/suite/name/rand/none]\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"rs,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"rand-seed=<int>               \"\n              << Whitespace(sizePrefixDisplay*1) << \"seed for random ordering\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"f,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"first=<int>                   \"\n              << Whitespace(sizePrefixDisplay*1) << \"the first test passing the filters to\\n\";\n            s << Whitespace(sizePrefixDisplay*3) << \"                                       execute - for range-based execution\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"l,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"last=<int>                    \"\n              << Whitespace(sizePrefixDisplay*1) << \"the last test passing the filters to\\n\";\n            s << Whitespace(sizePrefixDisplay*3) << \"                                       execute - for range-based execution\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"aa,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"abort-after=<int>             \"\n              << Whitespace(sizePrefixDisplay*1) << \"stop after <int> failed assertions\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"scfl,--\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"subcase-filter-levels=<int>   \"\n              << Whitespace(sizePrefixDisplay*1) << \"apply filters for the first <int> levels\\n\";\n            s << Color::Cyan << \"\\n[doctest] \" << Color::None;\n            s << \"Bool options - can be used like flags and true is assumed. Available:\\n\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"s,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"success=<bool>                \"\n              << Whitespace(sizePrefixDisplay*1) << \"include successful assertions in output\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"cs,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"case-sensitive=<bool>         \"\n              << Whitespace(sizePrefixDisplay*1) << \"filters being treated as case sensitive\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"e,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"exit=<bool>                   \"\n              << Whitespace(sizePrefixDisplay*1) << \"exits after the tests finish\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"d,   --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"duration=<bool>               \"\n              << Whitespace(sizePrefixDisplay*1) << \"prints the time duration of each test\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"nt,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-throw=<bool>               \"\n              << Whitespace(sizePrefixDisplay*1) << \"skips exceptions-related assert checks\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"ne,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-exitcode=<bool>            \"\n              << Whitespace(sizePrefixDisplay*1) << \"returns (or exits) always with success\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"nr,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-run=<bool>                 \"\n              << Whitespace(sizePrefixDisplay*1) << \"skips all runtime doctest operations\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"nv,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-version=<bool>             \"\n              << Whitespace(sizePrefixDisplay*1) << \"omit the framework version in the output\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"nc,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-colors=<bool>              \"\n              << Whitespace(sizePrefixDisplay*1) << \"disables colors in output\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"fc,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"force-colors=<bool>           \"\n              << Whitespace(sizePrefixDisplay*1) << \"use colors even when not in a tty\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"nb,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-breaks=<bool>              \"\n              << Whitespace(sizePrefixDisplay*1) << \"disables breakpoints in debuggers\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"ns,  --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-skip=<bool>                \"\n              << Whitespace(sizePrefixDisplay*1) << \"don't skip test cases marked as skip\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"gfl, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"gnu-file-line=<bool>          \"\n              << Whitespace(sizePrefixDisplay*1) << \":n: vs (n): for line numbers in output\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"npf, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-path-filenames=<bool>      \"\n              << Whitespace(sizePrefixDisplay*1) << \"only filenames and no paths in output\\n\";\n            s << \" -\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"nln, --\" DOCTEST_OPTIONS_PREFIX_DISPLAY \"no-line-numbers=<bool>        \"\n              << Whitespace(sizePrefixDisplay*1) << \"0 instead of real line numbers in output\\n\";\n            // ================================================================================== << 79\n            // clang-format on\n\n            s << Color::Cyan << \"\\n[doctest] \" << Color::None;\n            s << \"for more information visit the project documentation\\n\\n\";\n        }\n\n        void printRegisteredReporters() {\n            printVersion();\n            auto printReporters = [this] (const reporterMap& reporters, const char* type) {\n                if(reporters.size()) {\n                    s << Color::Cyan << \"[doctest] \" << Color::None << \"listing all registered \" << type << \"\\n\";\n                    for(auto& curr : reporters)\n                        s << \"priority: \" << std::setw(5) << curr.first.first\n                          << \" name: \" << curr.first.second << \"\\n\";\n                }\n            };\n            printReporters(getListeners(), \"listeners\");\n            printReporters(getReporters(), \"reporters\");\n        }\n\n        void list_query_results() {\n            separator_to_stream();\n            if(opt.count || opt.list_test_cases) {\n                s << Color::Cyan << \"[doctest] \" << Color::None\n                  << \"unskipped test cases passing the current filters: \"\n                  << g_cs->numTestCasesPassingFilters << \"\\n\";\n            } else if(opt.list_test_suites) {\n                s << Color::Cyan << \"[doctest] \" << Color::None\n                  << \"unskipped test cases passing the current filters: \"\n                  << g_cs->numTestCasesPassingFilters << \"\\n\";\n                s << Color::Cyan << \"[doctest] \" << Color::None\n                  << \"test suites with unskipped test cases passing the current filters: \"\n                  << g_cs->numTestSuitesPassingFilters << \"\\n\";\n            }\n        }\n\n        // =========================================================================================\n        // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE\n        // =========================================================================================\n\n        void report_query(const QueryData& in) override {\n            if(opt.version) {\n                printVersion();\n            } else if(opt.help) {\n                printHelp();\n            } else if(opt.list_reporters) {\n                printRegisteredReporters();\n            } else if(opt.count || opt.list_test_cases) {\n                if(opt.list_test_cases) {\n                    s << Color::Cyan << \"[doctest] \" << Color::None\n                      << \"listing all test case names\\n\";\n                    separator_to_stream();\n                }\n\n                for(unsigned i = 0; i < in.num_data; ++i)\n                    s << Color::None << in.data[i]->m_name << \"\\n\";\n\n                separator_to_stream();\n\n                s << Color::Cyan << \"[doctest] \" << Color::None\n                  << \"unskipped test cases passing the current filters: \"\n                  << g_cs->numTestCasesPassingFilters << \"\\n\";\n\n            } else if(opt.list_test_suites) {\n                s << Color::Cyan << \"[doctest] \" << Color::None << \"listing all test suites\\n\";\n                separator_to_stream();\n\n                for(unsigned i = 0; i < in.num_data; ++i)\n                    s << Color::None << in.data[i]->m_test_suite << \"\\n\";\n\n                separator_to_stream();\n\n                s << Color::Cyan << \"[doctest] \" << Color::None\n                  << \"unskipped test cases passing the current filters: \"\n                  << g_cs->numTestCasesPassingFilters << \"\\n\";\n                s << Color::Cyan << \"[doctest] \" << Color::None\n                  << \"test suites with unskipped test cases passing the current filters: \"\n                  << g_cs->numTestSuitesPassingFilters << \"\\n\";\n            }\n        }\n\n        void test_run_start() override { printIntro(); }\n\n        void test_run_end(const TestRunStats& p) override {\n            separator_to_stream();\n            s << std::dec;\n\n            auto totwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters, static_cast<unsigned>(p.numAsserts))) + 1)));\n            auto passwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast<unsigned>(p.numAsserts - p.numAssertsFailed))) + 1)));\n            auto failwidth = int(std::ceil(log10((std::max(p.numTestCasesFailed, static_cast<unsigned>(p.numAssertsFailed))) + 1)));\n            const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;\n            s << Color::Cyan << \"[doctest] \" << Color::None << \"test cases: \" << std::setw(totwidth)\n              << p.numTestCasesPassingFilters << \" | \"\n              << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None :\n                                                                          Color::Green)\n              << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << \" passed\"\n              << Color::None << \" | \" << (p.numTestCasesFailed > 0 ? Color::Red : Color::None)\n              << std::setw(failwidth) << p.numTestCasesFailed << \" failed\" << Color::None << \" |\";\n            if(opt.no_skipped_summary == false) {\n                const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters;\n                s << \" \" << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped\n                  << \" skipped\" << Color::None;\n            }\n            s << \"\\n\";\n            s << Color::Cyan << \"[doctest] \" << Color::None << \"assertions: \" << std::setw(totwidth)\n              << p.numAsserts << \" | \"\n              << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green)\n              << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << \" passed\" << Color::None\n              << \" | \" << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth)\n              << p.numAssertsFailed << \" failed\" << Color::None << \" |\\n\";\n            s << Color::Cyan << \"[doctest] \" << Color::None\n              << \"Status: \" << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)\n              << ((p.numTestCasesFailed > 0) ? \"FAILURE!\" : \"SUCCESS!\") << Color::None << std::endl;\n        }\n\n        void test_case_start(const TestCaseData& in) override {\n            hasLoggedCurrentTestStart = false;\n            tc                        = &in;\n            subcasesStack.clear();\n            currentSubcaseLevel = 0;\n        }\n        \n        void test_case_reenter(const TestCaseData&) override {\n            subcasesStack.clear();\n        }\n\n        void test_case_end(const CurrentTestCaseStats& st) override {\n            if(tc->m_no_output)\n                return;\n\n            // log the preamble of the test case only if there is something\n            // else to print - something other than that an assert has failed\n            if(opt.duration ||\n               (st.failure_flags && st.failure_flags != TestCaseFailureReason::AssertFailure))\n                logTestStart();\n\n            if(opt.duration)\n                s << Color::None << std::setprecision(6) << std::fixed << st.seconds\n                  << \" s: \" << tc->m_name << \"\\n\";\n\n            if(st.failure_flags & TestCaseFailureReason::Timeout)\n                s << Color::Red << \"Test case exceeded time limit of \" << std::setprecision(6)\n                  << std::fixed << tc->m_timeout << \"!\\n\";\n\n            if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) {\n                s << Color::Red << \"Should have failed but didn't! Marking it as failed!\\n\";\n            } else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) {\n                s << Color::Yellow << \"Failed as expected so marking it as not failed\\n\";\n            } else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) {\n                s << Color::Yellow << \"Allowed to fail so marking it as not failed\\n\";\n            } else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) {\n                s << Color::Red << \"Didn't fail exactly \" << tc->m_expected_failures\n                  << \" times so marking it as failed!\\n\";\n            } else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) {\n                s << Color::Yellow << \"Failed exactly \" << tc->m_expected_failures\n                  << \" times as expected so marking it as not failed!\\n\";\n            }\n            if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) {\n                s << Color::Red << \"Aborting - too many failed asserts!\\n\";\n            }\n            s << Color::None; // lgtm [cpp/useless-expression]\n        }\n\n        void test_case_exception(const TestCaseException& e) override {\n            if(tc->m_no_output)\n                return;\n\n            logTestStart();\n\n            file_line_to_stream(tc->m_file.c_str(), tc->m_line, \" \");\n            successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require :\n                                                                   assertType::is_check);\n            s << Color::Red << (e.is_crash ? \"test case CRASHED: \" : \"test case THREW exception: \")\n              << Color::Cyan << e.error_string << \"\\n\";\n\n            int num_stringified_contexts = get_num_stringified_contexts();\n            if(num_stringified_contexts) {\n                auto stringified_contexts = get_stringified_contexts();\n                s << Color::None << \"  logged: \";\n                for(int i = num_stringified_contexts; i > 0; --i) {\n                    s << (i == num_stringified_contexts ? \"\" : \"          \")\n                      << stringified_contexts[i - 1] << \"\\n\";\n                }\n            }\n            s << \"\\n\" << Color::None;\n        }\n\n        void subcase_start(const SubcaseSignature& subc) override {\n            std::lock_guard<std::mutex> lock(mutex);\n            subcasesStack.push_back(subc);\n            ++currentSubcaseLevel;\n            hasLoggedCurrentTestStart = false;\n        }\n\n        void subcase_end() override {\n            std::lock_guard<std::mutex> lock(mutex);\n            --currentSubcaseLevel;\n            hasLoggedCurrentTestStart = false;\n        }\n\n        void log_assert(const AssertData& rb) override {\n            if((!rb.m_failed && !opt.success) || tc->m_no_output)\n                return;\n\n            std::lock_guard<std::mutex> lock(mutex);\n\n            logTestStart();\n\n            file_line_to_stream(rb.m_file, rb.m_line, \" \");\n            successOrFailColoredStringToStream(!rb.m_failed, rb.m_at);\n\n            fulltext_log_assert_to_stream(s, rb);\n\n            log_contexts();\n        }\n\n        void log_message(const MessageData& mb) override {\n            if(tc->m_no_output)\n                return;\n\n            std::lock_guard<std::mutex> lock(mutex);\n\n            logTestStart();\n\n            file_line_to_stream(mb.m_file, mb.m_line, \" \");\n            s << getSuccessOrFailColor(false, mb.m_severity)\n              << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity,\n                                        \"MESSAGE\") << \": \";\n            s << Color::None << mb.m_string << \"\\n\";\n            log_contexts();\n        }\n\n        void test_case_skipped(const TestCaseData&) override {}\n    };\n\n    DOCTEST_REGISTER_REPORTER(\"console\", 0, ConsoleReporter);\n\n#ifdef DOCTEST_PLATFORM_WINDOWS\n    struct DebugOutputWindowReporter : public ConsoleReporter\n    {\n        DOCTEST_THREAD_LOCAL static std::ostringstream oss;\n\n        DebugOutputWindowReporter(const ContextOptions& co)\n                : ConsoleReporter(co, oss) {}\n\n#define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg)                                    \\\n    void func(type arg) override {                                                                 \\\n        bool with_col = g_no_colors;                                                               \\\n        g_no_colors   = false;                                                                     \\\n        ConsoleReporter::func(arg);                                                                \\\n        if(oss.tellp() != std::streampos{}) {                                                      \\\n            DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str());                                        \\\n            oss.str(\"\");                                                                           \\\n        }                                                                                          \\\n        g_no_colors = with_col;                                                                    \\\n    }\n\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, DOCTEST_EMPTY, DOCTEST_EMPTY)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, const TestCaseData&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter, const TestCaseData&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, const CurrentTestCaseStats&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, const TestCaseException&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, const SubcaseSignature&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, DOCTEST_EMPTY, DOCTEST_EMPTY)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in)\n        DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, const TestCaseData&, in)\n    };\n\n    DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss;\n#endif // DOCTEST_PLATFORM_WINDOWS\n\n    // the implementation of parseOption()\n    bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String* value) {\n        // going from the end to the beginning and stopping on the first occurrence from the end\n        for(int i = argc; i > 0; --i) {\n            auto index = i - 1;\n            auto temp = std::strstr(argv[index], pattern);\n            if(temp && (value || strlen(temp) == strlen(pattern))) { //!OCLINT prefer early exits and continue\n                // eliminate matches in which the chars before the option are not '-'\n                bool noBadCharsFound = true;\n                auto curr            = argv[index];\n                while(curr != temp) {\n                    if(*curr++ != '-') {\n                        noBadCharsFound = false;\n                        break;\n                    }\n                }\n                if(noBadCharsFound && argv[index][0] == '-') {\n                    if(value) {\n                        // parsing the value of an option\n                        temp += strlen(pattern);\n                        const unsigned len = strlen(temp);\n                        if(len) {\n                            *value = temp;\n                            return true;\n                        }\n                    } else {\n                        // just a flag - no value\n                        return true;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    // parses an option and returns the string after the '=' character\n    bool parseOption(int argc, const char* const* argv, const char* pattern, String* value = nullptr,\n                     const String& defaultVal = String()) {\n        if(value)\n            *value = defaultVal;\n#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS\n        // offset (normally 3 for \"dt-\") to skip prefix\n        if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), value))\n            return true;\n#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS\n        return parseOptionImpl(argc, argv, pattern, value);\n    }\n\n    // locates a flag on the command line\n    bool parseFlag(int argc, const char* const* argv, const char* pattern) {\n        return parseOption(argc, argv, pattern);\n    }\n\n    // parses a comma separated list of words after a pattern in one of the arguments in argv\n    bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern,\n                           std::vector<String>& res) {\n        String filtersString;\n        if(parseOption(argc, argv, pattern, &filtersString)) {\n            // tokenize with \",\" as a separator\n            // cppcheck-suppress strtokCalled\n            DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(\"-Wdeprecated-declarations\")\n            auto pch = std::strtok(filtersString.c_str(), \",\"); // modifies the string\n            while(pch != nullptr) {\n                if(strlen(pch))\n                    res.push_back(pch);\n                // uses the strtok() internal state to go to the next token\n                // cppcheck-suppress strtokCalled\n                pch = std::strtok(nullptr, \",\");\n            }\n            DOCTEST_CLANG_SUPPRESS_WARNING_POP\n            return true;\n        }\n        return false;\n    }\n\n    enum optionType\n    {\n        option_bool,\n        option_int\n    };\n\n    // parses an int/bool option from the command line\n    bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type,\n                        int& res) {\n        String parsedValue;\n        if(!parseOption(argc, argv, pattern, &parsedValue))\n            return false;\n\n        if(type == 0) {\n            // boolean\n            const char positive[][5] = {\"1\", \"true\", \"on\", \"yes\"};  // 5 - strlen(\"true\") + 1\n            const char negative[][6] = {\"0\", \"false\", \"off\", \"no\"}; // 6 - strlen(\"false\") + 1\n\n            // if the value matches any of the positive/negative possibilities\n            for(unsigned i = 0; i < 4; i++) {\n                if(parsedValue.compare(positive[i], true) == 0) {\n                    res = 1; //!OCLINT parameter reassignment\n                    return true;\n                }\n                if(parsedValue.compare(negative[i], true) == 0) {\n                    res = 0; //!OCLINT parameter reassignment\n                    return true;\n                }\n            }\n        } else {\n            // integer\n            // TODO: change this to use std::stoi or something else! currently it uses undefined behavior - assumes '0' on failed parse...\n            int theInt = std::atoi(parsedValue.c_str()); // NOLINT\n            if(theInt != 0) {\n                res = theInt; //!OCLINT parameter reassignment\n                return true;\n            }\n        }\n        return false;\n    }\n} // namespace\n\nContext::Context(int argc, const char* const* argv)\n        : p(new detail::ContextState) {\n    parseArgs(argc, argv, true);\n    if(argc)\n        p->binary_name = argv[0];\n}\n\nContext::~Context() {\n    if(g_cs == p)\n        g_cs = nullptr;\n    delete p;\n}\n\nvoid Context::applyCommandLine(int argc, const char* const* argv) {\n    parseArgs(argc, argv);\n    if(argc)\n        p->binary_name = argv[0];\n}\n\n// parses args\nvoid Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {\n    using namespace detail;\n\n    // clang-format off\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"source-file=\",        p->filters[0]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"sf=\",                 p->filters[0]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"source-file-exclude=\",p->filters[1]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"sfe=\",                p->filters[1]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"test-suite=\",         p->filters[2]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"ts=\",                 p->filters[2]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"test-suite-exclude=\", p->filters[3]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"tse=\",                p->filters[3]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"test-case=\",          p->filters[4]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"tc=\",                 p->filters[4]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"test-case-exclude=\",  p->filters[5]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"tce=\",                p->filters[5]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"subcase=\",            p->filters[6]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"sc=\",                 p->filters[6]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"subcase-exclude=\",    p->filters[7]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"sce=\",                p->filters[7]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"reporters=\",          p->filters[8]);\n    parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"r=\",                  p->filters[8]);\n    // clang-format on\n\n    int    intRes = 0;\n    String strRes;\n\n#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default)                                   \\\n    if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name \"=\", option_bool, intRes) ||  \\\n       parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname \"=\", option_bool, intRes))   \\\n        p->var = static_cast<bool>(intRes);                                                        \\\n    else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) ||                           \\\n            parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname))                            \\\n        p->var = true;                                                                             \\\n    else if(withDefaults)                                                                          \\\n    p->var = default\n\n#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default)                                        \\\n    if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name \"=\", option_int, intRes) ||   \\\n       parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname \"=\", option_int, intRes))    \\\n        p->var = intRes;                                                                           \\\n    else if(withDefaults)                                                                          \\\n    p->var = default\n\n#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default)                                        \\\n    if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name \"=\", &strRes, default) ||        \\\n       parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname \"=\", &strRes, default) ||       \\\n       withDefaults)                                                                               \\\n    p->var = strRes\n\n    // clang-format off\n    DOCTEST_PARSE_STR_OPTION(\"out\", \"o\", out, \"\");\n    DOCTEST_PARSE_STR_OPTION(\"order-by\", \"ob\", order_by, \"file\");\n    DOCTEST_PARSE_INT_OPTION(\"rand-seed\", \"rs\", rand_seed, 0);\n\n    DOCTEST_PARSE_INT_OPTION(\"first\", \"f\", first, 0);\n    DOCTEST_PARSE_INT_OPTION(\"last\", \"l\", last, UINT_MAX);\n\n    DOCTEST_PARSE_INT_OPTION(\"abort-after\", \"aa\", abort_after, 0);\n    DOCTEST_PARSE_INT_OPTION(\"subcase-filter-levels\", \"scfl\", subcase_filter_levels, INT_MAX);\n\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"success\", \"s\", success, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"case-sensitive\", \"cs\", case_sensitive, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"exit\", \"e\", exit, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"duration\", \"d\", duration, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-throw\", \"nt\", no_throw, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-exitcode\", \"ne\", no_exitcode, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-run\", \"nr\", no_run, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-version\", \"nv\", no_version, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-colors\", \"nc\", no_colors, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"force-colors\", \"fc\", force_colors, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-breaks\", \"nb\", no_breaks, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-skip\", \"ns\", no_skip, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"gnu-file-line\", \"gfl\", gnu_file_line, !bool(DOCTEST_MSVC));\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-path-filenames\", \"npf\", no_path_in_filenames, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-line-numbers\", \"nln\", no_line_numbers, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-debug-output\", \"ndo\", no_debug_output, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-skipped-summary\", \"nss\", no_skipped_summary, false);\n    DOCTEST_PARSE_AS_BOOL_OR_FLAG(\"no-time-in-output\", \"ntio\", no_time_in_output, false);\n    // clang-format on\n\n    if(withDefaults) {\n        p->help             = false;\n        p->version          = false;\n        p->count            = false;\n        p->list_test_cases  = false;\n        p->list_test_suites = false;\n        p->list_reporters   = false;\n    }\n    if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"help\") ||\n       parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"h\") ||\n       parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"?\")) {\n        p->help = true;\n        p->exit = true;\n    }\n    if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"version\") ||\n       parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"v\")) {\n        p->version = true;\n        p->exit    = true;\n    }\n    if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"count\") ||\n       parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"c\")) {\n        p->count = true;\n        p->exit  = true;\n    }\n    if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"list-test-cases\") ||\n       parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"ltc\")) {\n        p->list_test_cases = true;\n        p->exit            = true;\n    }\n    if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"list-test-suites\") ||\n       parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"lts\")) {\n        p->list_test_suites = true;\n        p->exit             = true;\n    }\n    if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"list-reporters\") ||\n       parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX \"lr\")) {\n        p->list_reporters = true;\n        p->exit           = true;\n    }\n}\n\n// allows the user to add procedurally to the filters from the command line\nvoid Context::addFilter(const char* filter, const char* value) { setOption(filter, value); }\n\n// allows the user to clear all filters from the command line\nvoid Context::clearFilters() {\n    for(auto& curr : p->filters)\n        curr.clear();\n}\n\n// allows the user to override procedurally the int/bool options from the command line\nvoid Context::setOption(const char* option, int value) {\n    setOption(option, toString(value).c_str());\n    // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)\n}\n\n// allows the user to override procedurally the string options from the command line\nvoid Context::setOption(const char* option, const char* value) {\n    auto argv   = String(\"-\") + option + \"=\" + value;\n    auto lvalue = argv.c_str();\n    parseArgs(1, &lvalue);\n}\n\n// users should query this in their main() and exit the program if true\nbool Context::shouldExit() { return p->exit; }\n\nvoid Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; }\n\nvoid Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; }\n\n// the main function that does all the filtering and test running\nint Context::run() {\n    using namespace detail;\n\n    // save the old context state in case such was setup - for using asserts out of a testing context\n    auto old_cs = g_cs;\n    // this is the current contest\n    g_cs               = p;\n    is_running_in_test = true;\n\n    g_no_colors = p->no_colors;\n    p->resetRunData();\n\n    // stdout by default\n    p->cout = &std::cout;\n    p->cerr = &std::cerr;\n\n    // or to a file if specified\n    std::fstream fstr;\n    if(p->out.size()) {\n        fstr.open(p->out.c_str(), std::fstream::out);\n        p->cout = &fstr;\n    }\n\n    FatalConditionHandler::allocateAltStackMem();\n\n    auto cleanup_and_return = [&]() {\n        FatalConditionHandler::freeAltStackMem();\n\n        if(fstr.is_open())\n            fstr.close();\n\n        // restore context\n        g_cs               = old_cs;\n        is_running_in_test = false;\n\n        // we have to free the reporters which were allocated when the run started\n        for(auto& curr : p->reporters_currently_used)\n            delete curr;\n        p->reporters_currently_used.clear();\n\n        if(p->numTestCasesFailed && !p->no_exitcode)\n            return EXIT_FAILURE;\n        return EXIT_SUCCESS;\n    };\n\n    // setup default reporter if none is given through the command line\n    if(p->filters[8].empty())\n        p->filters[8].push_back(\"console\");\n\n    // check to see if any of the registered reporters has been selected\n    for(auto& curr : getReporters()) {\n        if(matchesAny(curr.first.second.c_str(), p->filters[8], false, p->case_sensitive))\n            p->reporters_currently_used.push_back(curr.second(*g_cs));\n    }\n\n    // TODO: check if there is nothing in reporters_currently_used\n\n    // prepend all listeners\n    for(auto& curr : getListeners())\n        p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));\n\n#ifdef DOCTEST_PLATFORM_WINDOWS\n    if(isDebuggerActive() && p->no_debug_output == false)\n        p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs));\n#endif // DOCTEST_PLATFORM_WINDOWS\n\n    // handle version, help and no_run\n    if(p->no_run || p->version || p->help || p->list_reporters) {\n        DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData());\n\n        return cleanup_and_return();\n    }\n\n    std::vector<const TestCase*> testArray;\n    for(auto& curr : getRegisteredTests())\n        testArray.push_back(&curr);\n    p->numTestCases = testArray.size();\n\n    // sort the collected records\n    if(!testArray.empty()) {\n        if(p->order_by.compare(\"file\", true) == 0) {\n            std::sort(testArray.begin(), testArray.end(), fileOrderComparator);\n        } else if(p->order_by.compare(\"suite\", true) == 0) {\n            std::sort(testArray.begin(), testArray.end(), suiteOrderComparator);\n        } else if(p->order_by.compare(\"name\", true) == 0) {\n            std::sort(testArray.begin(), testArray.end(), nameOrderComparator);\n        } else if(p->order_by.compare(\"rand\", true) == 0) {\n            std::srand(p->rand_seed);\n\n            // random_shuffle implementation\n            const auto first = &testArray[0];\n            for(size_t i = testArray.size() - 1; i > 0; --i) {\n                int idxToSwap = std::rand() % (i + 1); // NOLINT\n\n                const auto temp = first[i];\n\n                first[i]         = first[idxToSwap];\n                first[idxToSwap] = temp;\n            }\n        } else if(p->order_by.compare(\"none\", true) == 0) {\n            // means no sorting - beneficial for death tests which call into the executable\n            // with a specific test case in mind - we don't want to slow down the startup times\n        }\n    }\n\n    std::set<String> testSuitesPassingFilt;\n\n    bool                             query_mode = p->count || p->list_test_cases || p->list_test_suites;\n    std::vector<const TestCaseData*> queryResults;\n\n    if(!query_mode)\n        DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY);\n\n    // invoke the registered functions if they match the filter criteria (or just count them)\n    for(auto& curr : testArray) {\n        const auto& tc = *curr;\n\n        bool skip_me = false;\n        if(tc.m_skip && !p->no_skip)\n            skip_me = true;\n\n        if(!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive))\n            skip_me = true;\n        if(matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive))\n            skip_me = true;\n        if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive))\n            skip_me = true;\n        if(matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive))\n            skip_me = true;\n        if(!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive))\n            skip_me = true;\n        if(matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive))\n            skip_me = true;\n\n        if(!skip_me)\n            p->numTestCasesPassingFilters++;\n\n        // skip the test if it is not in the execution range\n        if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) ||\n           (p->first > p->numTestCasesPassingFilters))\n            skip_me = true;\n\n        if(skip_me) {\n            if(!query_mode)\n                DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc);\n            continue;\n        }\n\n        // do not execute the test if we are to only count the number of filter passing tests\n        if(p->count)\n            continue;\n\n        // print the name of the test and don't execute it\n        if(p->list_test_cases) {\n            queryResults.push_back(&tc);\n            continue;\n        }\n\n        // print the name of the test suite if not done already and don't execute it\n        if(p->list_test_suites) {\n            if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\\0') {\n                queryResults.push_back(&tc);\n                testSuitesPassingFilt.insert(tc.m_test_suite);\n                p->numTestSuitesPassingFilters++;\n            }\n            continue;\n        }\n\n        // execute the test if it passes all the filtering\n        {\n            p->currentTest = &tc;\n\n            p->failure_flags = TestCaseFailureReason::None;\n            p->seconds       = 0;\n\n            // reset atomic counters\n            p->numAssertsFailedCurrentTest_atomic = 0;\n            p->numAssertsCurrentTest_atomic       = 0;\n\n            p->subcasesPassed.clear();\n\n            DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc);\n\n            p->timer.start();\n            \n            bool run_test = true;\n\n            do {\n                // reset some of the fields for subcases (except for the set of fully passed ones)\n                p->should_reenter          = false;\n                p->subcasesCurrentMaxLevel = 0;\n                p->subcasesStack.clear();\n\n                p->shouldLogCurrentException = true;\n\n                // reset stuff for logging with INFO()\n                p->stringifiedContexts.clear();\n\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n                try {\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n// MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method)\nDOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable\n                    FatalConditionHandler fatalConditionHandler; // Handle signals\n                    // execute the test\n                    tc.m_test();\n                    fatalConditionHandler.reset();\nDOCTEST_MSVC_SUPPRESS_WARNING_POP\n#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS\n                } catch(const TestFailureException&) {\n                    p->failure_flags |= TestCaseFailureReason::AssertFailure;\n                } catch(...) {\n                    DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception,\n                                                      {translateActiveException(), false});\n                    p->failure_flags |= TestCaseFailureReason::Exception;\n                }\n#endif // DOCTEST_CONFIG_NO_EXCEPTIONS\n\n                // exit this loop if enough assertions have failed - even if there are more subcases\n                if(p->abort_after > 0 &&\n                   p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) {\n                    run_test = false;\n                    p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts;\n                }\n                \n                if(p->should_reenter && run_test)\n                    DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc);\n                if(!p->should_reenter)\n                    run_test = false;\n            } while(run_test);\n\n            p->finalizeTestCaseData();\n\n            DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);\n\n            p->currentTest = nullptr;\n\n            // stop executing tests if enough assertions have failed\n            if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after)\n                break;\n        }\n    }\n\n    if(!query_mode) {\n        DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);\n    } else {\n        QueryData qdata;\n        qdata.run_stats = g_cs;\n        qdata.data      = queryResults.data();\n        qdata.num_data  = unsigned(queryResults.size());\n        DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata);\n    }\n\n    // see these issues on the reasoning for this:\n    // - https://github.com/onqtam/doctest/issues/143#issuecomment-414418903\n    // - https://github.com/onqtam/doctest/issues/126\n    auto DOCTEST_FIX_FOR_MACOS_LIBCPP_IOSFWD_STRING_LINK_ERRORS = []() DOCTEST_NOINLINE\n        { std::cout << std::string(); };\n    DOCTEST_FIX_FOR_MACOS_LIBCPP_IOSFWD_STRING_LINK_ERRORS();\n\n    return cleanup_and_return();\n}\n\nIReporter::~IReporter() = default;\n\nint IReporter::get_num_active_contexts() { return detail::g_infoContexts.size(); }\nconst IContextScope* const* IReporter::get_active_contexts() {\n    return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr;\n}\n\nint IReporter::get_num_stringified_contexts() { return detail::g_cs->stringifiedContexts.size(); }\nconst String* IReporter::get_stringified_contexts() {\n    return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] : nullptr;\n}\n\nnamespace detail {\n    void registerReporterImpl(const char* name, int priority, reporterCreatorFunc c, bool isReporter) {\n        if(isReporter)\n            getReporters().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));\n        else\n            getListeners().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));\n    }\n} // namespace detail\n\n} // namespace doctest\n\n#endif // DOCTEST_CONFIG_DISABLE\n\n#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN\nDOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) // 'function' : must be 'attribute' - see issue #182\nint main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }\nDOCTEST_MSVC_SUPPRESS_WARNING_POP\n#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN\n\nDOCTEST_CLANG_SUPPRESS_WARNING_POP\nDOCTEST_MSVC_SUPPRESS_WARNING_POP\nDOCTEST_GCC_SUPPRESS_WARNING_POP\n\n#endif // DOCTEST_LIBRARY_IMPLEMENTATION\n#endif // DOCTEST_CONFIG_IMPLEMENT\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/doctest/doctest_compatibility.h",
    "content": "#ifndef DOCTEST_COMPATIBILITY\n#define DOCTEST_COMPATIBILITY\n\n#define DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS\n#define DOCTEST_THREAD_LOCAL // enable single-threaded builds on XCode 6/7 - https://github.com/onqtam/doctest/issues/172\n#include \"doctest.h\"\n\n// Catch doesn't require a semicolon after CAPTURE but doctest does\n#undef CAPTURE\n#define CAPTURE(x) DOCTEST_CAPTURE(x);\n\n// Sections from Catch are called Subcases in doctest and don't work with std::string by default\n#undef SUBCASE\n#define SECTION(x) DOCTEST_SUBCASE(x)\n\n// convenience macro around INFO since it doesn't support temporaries (it is optimized to avoid allocations for runtime speed)\n#define INFO_WITH_TEMP_IMPL(x, var_name) const auto var_name = x; INFO(var_name) // lvalue!\n#define INFO_WITH_TEMP(x) INFO_WITH_TEMP_IMPL(x, DOCTEST_ANONYMOUS(DOCTEST_STD_STRING_))\n\n// doctest doesn't support THROWS_WITH for std::string out of the box (has to include <string>...)\n#define CHECK_THROWS_WITH_STD_STR_IMPL(expr, str, var_name)                    \\\n    do {                                                                       \\\n        std::string var_name = str;                                            \\\n        CHECK_THROWS_WITH(expr, var_name.c_str());                             \\\n    } while (false)\n#define CHECK_THROWS_WITH_STD_STR(expr, str)                                   \\\n    CHECK_THROWS_WITH_STD_STR_IMPL(expr, str, DOCTEST_ANONYMOUS(DOCTEST_STD_STRING_))\n\n// included here because for some tests in the json repository private is defined as\n// public and if no STL header is included before that then in the json include when STL\n// stuff is included the MSVC STL complains (errors) that C++ keywords are being redefined\n#include <iosfwd>\n\n// Catch does this by default\nusing doctest::Approx;\n\n#endif\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/fifo_map/LICENSE.MIT",
    "content": "MIT License \n\nCopyright (c) 2015-2017 Niels Lohmann\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/fifo_map/fifo_map.hpp",
    "content": "/*\nThe code is licensed under the MIT License <http://opensource.org/licenses/MIT>:\n\nCopyright (c) 2015-2017 Niels Lohmann.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#ifndef NLOHMANN_FIFO_MAP_HPP\n#define NLOHMANN_FIFO_MAP_HPP\n\n#include <algorithm>\n#include <cstdlib>\n#include <functional>\n#include <iostream>\n#include <limits>\n#include <map>\n#include <memory>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n\n/*!\n@brief namespace for Niels Lohmann\n@see https://github.com/nlohmann\n*/\nnamespace nlohmann\n{\n\ntemplate<class Key>\nclass fifo_map_compare\n{\n  public:\n    /// constructor given a pointer to a key storage\n    fifo_map_compare(std::unordered_map<Key, std::size_t>* k) : keys(k) {}\n\n    /*!\n    This function compares two keys with respect to the order in which they\n    were added to the container. For this, the mapping keys is used.\n    */\n    bool operator()(const Key& lhs, const Key& rhs) const\n    {\n        // look up timestamps for both keys\n        const auto timestamp_lhs = keys->find(lhs);\n        const auto timestamp_rhs = keys->find(rhs);\n\n        if (timestamp_lhs == keys->end())\n        {\n            // timestamp for lhs not found - cannot be smaller than for rhs\n            return false;\n        }\n\n        if (timestamp_rhs == keys->end())\n        {\n            // timestamp for rhs not found - timestamp for lhs is smaller\n            return true;\n        }\n\n        // compare timestamps\n        return timestamp_lhs->second < timestamp_rhs->second;\n    }\n\n    void add_key(const Key& key)\n    {\n        keys->insert({key, timestamp++});\n    }\n\n    void remove_key(const Key& key)\n    {\n        keys->erase(key);\n    }\n\n  private:\n    /// pointer to a mapping from keys to insertion timestamps\n    std::unordered_map<Key, std::size_t>* keys = nullptr;\n    /// the next valid insertion timestamp\n    size_t timestamp = 1;\n};\n\n\ntemplate <\n    class Key,\n    class T,\n    class Compare = fifo_map_compare<Key>,\n    class Allocator = std::allocator<std::pair<const Key, T>>\n    > class fifo_map // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions,-warnings-as-errors)\n{\n  public:\n    using key_type = Key;\n    using mapped_type = T;\n    using value_type = std::pair<const Key, T>;\n    using size_type = std::size_t;\n    using difference_type = std::ptrdiff_t;\n    using key_compare = Compare;\n    using allocator_type = Allocator;\n    using reference = value_type&;\n    using const_reference = const value_type&;\n    using pointer = typename std::allocator_traits<Allocator>::pointer;\n    using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;\n\n    using internal_map_type = std::map<Key, T, Compare, Allocator>;\n\n    using iterator = typename internal_map_type::iterator;\n    using const_iterator = typename internal_map_type::const_iterator;\n    using reverse_iterator = typename internal_map_type::reverse_iterator;\n    using const_reverse_iterator = typename internal_map_type::const_reverse_iterator;\n\n  public:\n    /// default constructor\n    fifo_map() : m_keys(), m_compare(&m_keys), m_map(m_compare) {}\n\n    /// copy constructor\n    fifo_map(const fifo_map &f) : m_keys(f.m_keys), m_compare(&m_keys), m_map(f.m_map.begin(), f.m_map.end(), m_compare) {}\n\n    /// constructor for a range of elements\n    template<class InputIterator>\n    fifo_map(InputIterator first, InputIterator last)\n        : m_keys(), m_compare(&m_keys), m_map(m_compare)\n    {\n        for (auto it = first; it != last; ++it)\n        {\n            insert(*it);\n        }\n    }\n\n    /// constructor for a list of elements\n    fifo_map(std::initializer_list<value_type> init) : fifo_map()\n    {\n        for (auto x : init)\n        {\n            insert(x);\n        }\n    }\n\n\n    /*\n     * Element access\n     */\n\n    /// access specified element with bounds checking\n    T& at(const Key& key)\n    {\n        return m_map.at(key);\n    }\n\n    /// access specified element with bounds checking\n    const T& at(const Key& key) const\n    {\n        return m_map.at(key);\n    }\n\n    /// access specified element\n    T& operator[](const Key& key)\n    {\n        m_compare.add_key(key);\n        return m_map[key];\n    }\n\n    /// access specified element\n    T& operator[](Key&& key)\n    {\n        m_compare.add_key(key);\n        return m_map[key];\n    }\n\n\n    /*\n     * Iterators\n     */\n\n    /// returns an iterator to the beginning\n    iterator begin() noexcept\n    {\n        return m_map.begin();\n    }\n\n    /// returns an iterator to the end\n    iterator end() noexcept\n    {\n        return m_map.end();\n    }\n\n    /// returns an iterator to the beginning\n    const_iterator begin() const noexcept\n    {\n        return m_map.begin();\n    }\n\n    /// returns an iterator to the end\n    const_iterator end() const noexcept\n    {\n        return m_map.end();\n    }\n\n    /// returns an iterator to the beginning\n    const_iterator cbegin() const noexcept\n    {\n        return m_map.cbegin();\n    }\n\n    /// returns an iterator to the end\n    const_iterator cend() const noexcept\n    {\n        return m_map.cend();\n    }\n\n    /// returns a reverse iterator to the beginning\n    reverse_iterator rbegin() noexcept\n    {\n        return m_map.rbegin();\n    }\n\n    /// returns a reverse iterator to the end\n    reverse_iterator rend() noexcept\n    {\n        return m_map.rend();\n    }\n\n    /// returns a reverse iterator to the beginning\n    const_reverse_iterator rbegin() const noexcept\n    {\n        return m_map.rbegin();\n    }\n\n    /// returns a reverse iterator to the end\n    const_reverse_iterator rend() const noexcept\n    {\n        return m_map.rend();\n    }\n\n    /// returns a reverse iterator to the beginning\n    const_reverse_iterator crbegin() const noexcept\n    {\n        return m_map.crbegin();\n    }\n\n    /// returns a reverse iterator to the end\n    const_reverse_iterator crend() const noexcept\n    {\n        return m_map.crend();\n    }\n\n\n    /*\n     * Capacity\n     */\n\n    /// checks whether the container is empty\n    bool empty() const noexcept\n    {\n        return m_map.empty();\n    }\n\n    /// returns the number of elements\n    size_type size() const noexcept\n    {\n        return m_map.size();\n    }\n\n    /// returns the maximum possible number of elements\n    size_type max_size() const noexcept\n    {\n        return m_map.max_size();\n    }\n\n\n    /*\n     * Modifiers\n     */\n\n    /// clears the contents\n    void clear() noexcept\n    {\n        m_map.clear();\n        m_keys.clear();\n    }\n\n    /// insert value\n    std::pair<iterator, bool> insert(const value_type& value)\n    {\n        m_compare.add_key(value.first);\n        return m_map.insert(value);\n    }\n\n    /// insert value\n    template<class P>\n    std::pair<iterator, bool> insert( P&& value )\n    {\n        m_compare.add_key(value.first);\n        return m_map.insert(value);\n    }\n\n    /// insert value with hint\n    iterator insert(const_iterator hint, const value_type& value)\n    {\n        m_compare.add_key(value.first);\n        return m_map.insert(hint, value);\n    }\n\n    /// insert value with hint\n    iterator insert(const_iterator hint, value_type&& value)\n    {\n        m_compare.add_key(value.first);\n        return m_map.insert(hint, value);\n    }\n\n    /// insert value range\n    template<class InputIt>\n    void insert(InputIt first, InputIt last)\n    {\n        for (const_iterator it = first; it != last; ++it)\n        {\n            m_compare.add_key(it->first);\n        }\n\n        m_map.insert(first, last);\n    }\n\n    /// insert value list\n    void insert(std::initializer_list<value_type> ilist)\n    {\n        for (auto value : ilist)\n        {\n            m_compare.add_key(value.first);\n        }\n\n        m_map.insert(ilist);\n    }\n\n    /// constructs element in-place\n    template<class... Args>\n    std::pair<iterator, bool> emplace(Args&& ... args)\n    {\n        typename fifo_map::value_type value(std::forward<Args>(args)...);\n        m_compare.add_key(value.first);\n        return m_map.emplace(std::move(value));\n    }\n\n    /// constructs element in-place with hint\n    template<class... Args>\n    iterator emplace_hint(const_iterator hint, Args&& ... args)\n    {\n        typename fifo_map::value_type value(std::forward<Args>(args)...);\n        m_compare.add_key(value.first);\n        return m_map.emplace_hint(hint, std::move(value));\n    }\n\n    /// remove element at position\n    iterator erase(const_iterator pos)\n    {\n        m_compare.remove_key(pos->first);\n        return m_map.erase(pos);\n    }\n\n    /// remove elements in range\n    iterator erase(const_iterator first, const_iterator last)\n    {\n        for (const_iterator it = first; it != last; ++it)\n        {\n            m_compare.remove_key(it->first);\n        }\n\n        return m_map.erase(first, last);\n    }\n\n    /// remove elements with key\n    size_type erase(const key_type& key)\n    {\n        size_type res = m_map.erase(key);\n\n        if (res > 0)\n        {\n            m_compare.remove_key(key);\n        }\n\n        return res;\n    }\n\n    /// swaps the contents\n    void swap(fifo_map& other)\n    {\n        std::swap(m_map, other.m_map);\n        std::swap(m_compare, other.m_compare);\n        std::swap(m_keys, other.m_keys);\n    }\n\n\n    /*\n     * Lookup\n     */\n\n    /// returns the number of elements matching specific key\n    size_type count(const Key& key) const\n    {\n        return m_map.count(key);\n    }\n\n    /// finds element with specific key\n    iterator find(const Key& key)\n    {\n        return m_map.find(key);\n    }\n\n    /// finds element with specific key\n    const_iterator find(const Key& key) const\n    {\n        return m_map.find(key);\n    }\n\n    /// returns range of elements matching a specific key\n    std::pair<iterator, iterator> equal_range(const Key& key)\n    {\n        return m_map.equal_range(key);\n    }\n\n    /// returns range of elements matching a specific key\n    std::pair<const_iterator, const_iterator> equal_range(const Key& key) const\n    {\n        return m_map.equal_range(key);\n    }\n\n    /// returns an iterator to the first element not less than the given key\n    iterator lower_bound(const Key& key)\n    {\n        return m_map.lower_bound(key);\n    }\n\n    /// returns an iterator to the first element not less than the given key\n    const_iterator lower_bound(const Key& key) const\n    {\n        return m_map.lower_bound(key);\n    }\n\n    /// returns an iterator to the first element greater than the given key\n    iterator upper_bound(const Key& key)\n    {\n        return m_map.upper_bound(key);\n    }\n\n    /// returns an iterator to the first element greater than the given key\n    const_iterator upper_bound(const Key& key) const\n    {\n        return m_map.upper_bound(key);\n    }\n\n\n    /*\n     * Observers\n     */\n\n    /// returns the function that compares keys\n    key_compare key_comp() const\n    {\n        return m_compare;\n    }\n\n\n    /*\n     * Non-member functions\n     */\n\n    friend bool operator==(const fifo_map& lhs, const fifo_map& rhs)\n    {\n        return lhs.m_map == rhs.m_map;\n    }\n\n    friend bool operator!=(const fifo_map& lhs, const fifo_map& rhs)\n    {\n        return lhs.m_map != rhs.m_map;\n    }\n\n    friend bool operator<(const fifo_map& lhs, const fifo_map& rhs)\n    {\n        return lhs.m_map < rhs.m_map;\n    }\n\n    friend bool operator<=(const fifo_map& lhs, const fifo_map& rhs)\n    {\n        return lhs.m_map <= rhs.m_map;\n    }\n\n    friend bool operator>(const fifo_map& lhs, const fifo_map& rhs)\n    {\n        return lhs.m_map > rhs.m_map;\n    }\n\n    friend bool operator>=(const fifo_map& lhs, const fifo_map& rhs)\n    {\n        return lhs.m_map >= rhs.m_map;\n    }\n\n  private:\n    /// the keys\n    std::unordered_map<Key, std::size_t> m_keys;\n    /// the comparison object\n    Compare m_compare;\n    /// the internal data structure\n    internal_map_type m_map;\n};\n\n} // namespace nlohmann\n\n// specialization of std::swap\nnamespace std // NOLINT(cert-dcl58-cpp,-warnings-as-errors)\n{\ntemplate <class Key, class T, class Compare, class Allocator>\ninline void swap(nlohmann::fifo_map<Key, T, Compare, Allocator>& m1,\n                 nlohmann::fifo_map<Key, T, Compare, Allocator>& m2)\n{\n    m1.swap(m2);\n}\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/imapdl/filterbr.py",
    "content": "#!/usr/bin/env python3\n\n# 2017, Georg Sauthoff <mail@gms.tf>, GPLv3\n\nimport sys\n\ndef skip_comments(lines):\n  state = 0\n  for line in lines:\n    n = len(line)\n    l = ''\n    p = 0\n    while p < n:\n      if state == 0:\n        a = line.find('//', p)\n        b = line.find('/*', p)\n        if a > -1 and (a < b or b == -1):\n          l += line[p:a]\n          p = n\n        elif b > -1 and (b < a or a == -1):\n          l += line[p:b]\n          p = b+2\n          state = 1\n        else:\n          l += line[p:]\n          p = n\n      elif state == 1:\n        a = line.rfind('*/', p)\n        if a == -1:\n          p = n\n        else:\n          p = a + 2\n          state = 0\n    yield l\n\ndef cond_lines(lines):\n  state = 0\n  pcnt = 0\n  for nr, line in enumerate(lines, 1):\n    if not line:\n      continue\n    n = len(line)\n    p = 0\n    do_yield = False\n    while p < n:\n      if state == 0:\n        p = line.find('if', p)\n        if p == -1:\n          p = n\n          continue\n        if (p == 0 or not line[p-1].isalpha()) \\\n            and (p+2 == len(line) or not line[p+2].isalpha()):\n          do_yield = True\n          state = 1\n        p += 2\n      elif state == 1:\n        do_yield = True\n        p = line.find('(', p)\n        if p == -1:\n          p = n\n        else:\n          p += 1\n          state = 2\n          pcnt = 1\n      elif state == 2:\n        do_yield = True\n        for p in range(p, n):\n          if line[p] == '(':\n            pcnt += 1\n          elif line[p] == ')':\n            pcnt -= 1\n          if not pcnt:\n            state = 0\n            break\n        p += 1\n    if do_yield:\n      yield nr\n\ndef cond_lines_from_file(filename):\n  with open(filename) as f:\n    yield from cond_lines(skip_comments(f))\n\ndef filter_lcov_trace(lines):\n  nrs = set()\n  for line in lines:\n    if line.startswith('SF:'):\n      nrs = set(cond_lines_from_file(line[3:-1]))\n    elif line.startswith('BRDA:'):\n      xs = line[5:].split(',')\n      nr = int(xs[0]) if xs else 0\n      if nr not in nrs:\n        continue\n    yield line\n\ndef filter_lcov_trace_file(s_filename, d_file):\n  with open(s_filename) as f:\n    for l in filter_lcov_trace(f):\n      print(l, end='', file=d_file)\n\nif __name__ == '__main__':\n  #for l in cond_lines_from_file(sys.argv[1]):\n  #  print(l)\n\n  filter_lcov_trace_file(sys.argv[1], sys.stdout)\n\n  #with open(sys.argv[1]) as f:\n  #  for l in skip_comments(f):\n  #    print(l)\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/test/thirdparty/imapdl/gpl-3.0.txt",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/amalgamate/CHANGES.md",
    "content": "The following changes have been made to the code with respect to <https://github.com/edlund/amalgamate/commit/c91f07eea1133aa184f652b8f1398eaf03586208>:\n\n- Resolved inspection results from PyCharm:\n  - replaced tabs with spaces\n  - added encoding annotation\n  - reindented file to remove trailing whitespaces\n  - unused import `sys`\n  - membership check\n  - made function from `_is_within`\n  - removed unused variable `actual_path`\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/amalgamate/LICENSE.md",
    "content": "amalgamate.py - Amalgamate C source and header files\nCopyright (c) 2012, Erik Edlund <erik.edlund@32767.se>\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n * Neither the name of Erik Edlund, nor the names of its contributors may\n   be used to endorse or promote products derived from this software without\n   specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/amalgamate/README.md",
    "content": "\n# amalgamate.py - Amalgamate C source and header files\n\nOrigin: https://bitbucket.org/erikedlund/amalgamate\n\nMirror: https://github.com/edlund/amalgamate\n\n`amalgamate.py` aims to make it easy to use SQLite-style C source and header\namalgamation in projects.\n\nFor more information, please refer to: http://sqlite.org/amalgamation.html\n\n## Here be dragons\n\n`amalgamate.py` is quite dumb, it only knows the bare minimum about C code\nrequired in order to be able to handle trivial include directives. It can\nproduce weird results for unexpected code.\n\nThings to be aware of:\n\n`amalgamate.py` will not handle complex include directives correctly:\n\n        #define HEADER_PATH \"path/to/header.h\"\n        #include HEADER_PATH\n\nIn the above example, `path/to/header.h` will not be included in the\namalgamation (HEADER_PATH is never expanded).\n\n`amalgamate.py` makes the assumption that each source and header file which\nis not empty will end in a new-line character, which is not immediately\npreceded by a backslash character (see 5.1.1.2p1.2 of ISO C99).\n\n`amalgamate.py` should be usable with C++ code, but raw string literals from\nC++11 will definitely cause problems:\n\n        R\"delimiter(Terrible raw \\ data \" #include <sneaky.hpp>)delimiter\"\n        R\"delimiter(Terrible raw \\ data \" escaping)delimiter\"\n\nIn the examples above, `amalgamate.py` will stop parsing the raw string literal\nwhen it encounters the first quotation mark, which will produce unexpected\nresults.\n\n## Installing amalgamate.py\n\nPython v.2.7.0 or higher is required.\n\n`amalgamate.py` can be tested and installed using the following commands:\n\n        ./test.sh && sudo -k cp ./amalgamate.py /usr/local/bin/\n\n## Using amalgamate.py\n\n        amalgamate.py [-v] -c path/to/config.json -s path/to/source/dir \\\n                [-p path/to/prologue.(c|h)]\n\n * The `-c, --config` option should specify the path to a JSON config file which\n   lists the source files, include paths and where to write the resulting\n   amalgamation. Have a look at `test/source.c.json` and `test/include.h.json`\n   to see two examples.\n\n * The `-s, --source` option should specify the path to the source directory.\n   This is useful for supporting separate source and build directories.\n\n * The `-p, --prologue` option should specify the path to a file which will be\n   added to the beginning of the amalgamation. It is optional.\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/amalgamate/amalgamate.py",
    "content": "#!/usr/bin/env python\n# coding=utf-8\n\n# amalgamate.py - Amalgamate C source and header files.\n# Copyright (c) 2012, Erik Edlund <erik.edlund@32767.se>\n# \n# Redistribution and use in source and binary forms, with or without modification,\n# are permitted provided that the following conditions are met:\n# \n#  * Redistributions of source code must retain the above copyright notice,\n#  this list of conditions and the following disclaimer.\n# \n#  * Redistributions in binary form must reproduce the above copyright notice,\n#  this list of conditions and the following disclaimer in the documentation\n#  and/or other materials provided with the distribution.\n# \n#  * Neither the name of Erik Edlund, nor the names of its contributors may\n#  be used to endorse or promote products derived from this software without\n#  specific prior written permission.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nfrom __future__ import division\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport argparse\nimport datetime\nimport json\nimport os\nimport re\n\n\nclass Amalgamation(object):\n\n    # Prepends self.source_path to file_path if needed.\n    def actual_path(self, file_path):\n        if not os.path.isabs(file_path):\n            file_path = os.path.join(self.source_path, file_path)\n        return file_path\n\n    # Search included file_path in self.include_paths and\n    # in source_dir if specified.\n    def find_included_file(self, file_path, source_dir):\n        search_dirs = self.include_paths[:]\n        if source_dir:\n            search_dirs.insert(0, source_dir)\n\n        for search_dir in search_dirs:\n            search_path = os.path.join(search_dir, file_path)\n            if os.path.isfile(self.actual_path(search_path)):\n                return search_path\n        return None\n\n    def __init__(self, args):\n        with open(args.config, 'r') as f:\n            config = json.loads(f.read())\n            for key in config:\n                setattr(self, key, config[key])\n\n            self.verbose = args.verbose == \"yes\"\n            self.prologue = args.prologue\n            self.source_path = args.source_path\n            self.included_files = []\n\n    # Generate the amalgamation and write it to the target file.\n    def generate(self):\n        amalgamation = \"\"\n\n        if self.prologue:\n            with open(self.prologue, 'r') as f:\n                amalgamation += datetime.datetime.now().strftime(f.read())\n\n        if self.verbose:\n            print(\"Config:\")\n            print(\" target        = {0}\".format(self.target))\n            print(\" working_dir   = {0}\".format(os.getcwd()))\n            print(\" include_paths = {0}\".format(self.include_paths))\n        print(\"Creating amalgamation:\")\n        for file_path in self.sources:\n            # Do not check the include paths while processing the source\n            # list, all given source paths must be correct.\n            # actual_path = self.actual_path(file_path)\n            print(\" - processing \\\"{0}\\\"\".format(file_path))\n            t = TranslationUnit(file_path, self, True)\n            amalgamation += t.content\n\n        with open(self.target, 'w') as f:\n            f.write(amalgamation)\n\n        print(\"...done!\\n\")\n        if self.verbose:\n            print(\"Files processed: {0}\".format(self.sources))\n            print(\"Files included: {0}\".format(self.included_files))\n        print(\"\")\n\n\ndef _is_within(match, matches):\n    for m in matches:\n        if match.start() > m.start() and \\\n                match.end() < m.end():\n            return True\n    return False\n\n\nclass TranslationUnit(object):\n    # // C++ comment.\n    cpp_comment_pattern = re.compile(r\"//.*?\\n\")\n\n    # /* C comment. */\n    c_comment_pattern = re.compile(r\"/\\*.*?\\*/\", re.S)\n\n    # \"complex \\\"stri\\\\\\ng\\\" value\".\n    string_pattern = re.compile(\"[^']\" r'\".*?(?<=[^\\\\])\"', re.S)\n\n    # Handle simple include directives. Support for advanced\n    # directives where macros and defines needs to expanded is\n    # not a concern right now.\n    include_pattern = re.compile(\n        r'#\\s*include\\s+(<|\")(?P<path>.*?)(\"|>)', re.S)\n\n    # #pragma once\n    pragma_once_pattern = re.compile(r'#\\s*pragma\\s+once', re.S)\n\n    # Search for pattern in self.content, add the match to\n    # contexts if found and update the index accordingly.\n    def _search_content(self, index, pattern, contexts):\n        match = pattern.search(self.content, index)\n        if match:\n            contexts.append(match)\n            return match.end()\n        return index + 2\n\n    # Return all the skippable contexts, i.e., comments and strings\n    def _find_skippable_contexts(self):\n        # Find contexts in the content in which a found include\n        # directive should not be processed.\n        skippable_contexts = []\n\n        # Walk through the content char by char, and try to grab\n        # skippable contexts using regular expressions when found.\n        i = 1\n        content_len = len(self.content)\n        while i < content_len:\n            j = i - 1\n            current = self.content[i]\n            previous = self.content[j]\n\n            if current == '\"':\n                # String value.\n                i = self._search_content(j, self.string_pattern,\n                                         skippable_contexts)\n            elif current == '*' and previous == '/':\n                # C style comment.\n                i = self._search_content(j, self.c_comment_pattern,\n                                         skippable_contexts)\n            elif current == '/' and previous == '/':\n                # C++ style comment.\n                i = self._search_content(j, self.cpp_comment_pattern,\n                                         skippable_contexts)\n            else:\n                # Skip to the next char.\n                i += 1\n\n        return skippable_contexts\n\n    # Returns True if the match is within list of other matches\n\n    # Removes pragma once from content\n    def _process_pragma_once(self):\n        content_len = len(self.content)\n        if content_len < len(\"#include <x>\"):\n            return 0\n\n        # Find contexts in the content in which a found include\n        # directive should not be processed.\n        skippable_contexts = self._find_skippable_contexts()\n\n        pragmas = []\n        pragma_once_match = self.pragma_once_pattern.search(self.content)\n        while pragma_once_match:\n            if not _is_within(pragma_once_match, skippable_contexts):\n                pragmas.append(pragma_once_match)\n\n            pragma_once_match = self.pragma_once_pattern.search(self.content,\n                                                                pragma_once_match.end())\n\n        # Handle all collected pragma once directives.\n        prev_end = 0\n        tmp_content = ''\n        for pragma_match in pragmas:\n            tmp_content += self.content[prev_end:pragma_match.start()]\n            prev_end = pragma_match.end()\n        tmp_content += self.content[prev_end:]\n        self.content = tmp_content\n\n    # Include all trivial #include directives into self.content.\n    def _process_includes(self):\n        content_len = len(self.content)\n        if content_len < len(\"#include <x>\"):\n            return 0\n\n        # Find contexts in the content in which a found include\n        # directive should not be processed.\n        skippable_contexts = self._find_skippable_contexts()\n\n        # Search for include directives in the content, collect those\n        # which should be included into the content.\n        includes = []\n        include_match = self.include_pattern.search(self.content)\n        while include_match:\n            if not _is_within(include_match, skippable_contexts):\n                include_path = include_match.group(\"path\")\n                search_same_dir = include_match.group(1) == '\"'\n                found_included_path = self.amalgamation.find_included_file(\n                    include_path, self.file_dir if search_same_dir else None)\n                if found_included_path:\n                    includes.append((include_match, found_included_path))\n\n            include_match = self.include_pattern.search(self.content,\n                                                        include_match.end())\n\n        # Handle all collected include directives.\n        prev_end = 0\n        tmp_content = ''\n        for include in includes:\n            include_match, found_included_path = include\n            tmp_content += self.content[prev_end:include_match.start()]\n            tmp_content += \"// {0}\\n\".format(include_match.group(0))\n            if found_included_path not in self.amalgamation.included_files:\n                t = TranslationUnit(found_included_path, self.amalgamation, False)\n                tmp_content += t.content\n            prev_end = include_match.end()\n        tmp_content += self.content[prev_end:]\n        self.content = tmp_content\n\n        return len(includes)\n\n    # Make all content processing\n    def _process(self):\n        if not self.is_root:\n            self._process_pragma_once()\n        self._process_includes()\n\n    def __init__(self, file_path, amalgamation, is_root):\n        self.file_path = file_path\n        self.file_dir = os.path.dirname(file_path)\n        self.amalgamation = amalgamation\n        self.is_root = is_root\n\n        self.amalgamation.included_files.append(self.file_path)\n\n        actual_path = self.amalgamation.actual_path(file_path)\n        if not os.path.isfile(actual_path):\n            raise IOError(\"File not found: \\\"{0}\\\"\".format(file_path))\n        with open(actual_path, 'r') as f:\n            self.content = f.read()\n            self._process()\n\n\ndef main():\n    description = \"Amalgamate C source and header files.\"\n    usage = \" \".join([\n        \"amalgamate.py\",\n        \"[-v]\",\n        \"-c path/to/config.json\",\n        \"-s path/to/source/dir\",\n        \"[-p path/to/prologue.(c|h)]\"\n    ])\n    argsparser = argparse.ArgumentParser(\n        description=description, usage=usage)\n\n    argsparser.add_argument(\"-v\", \"--verbose\", dest=\"verbose\",\n                            choices=[\"yes\", \"no\"], metavar=\"\", help=\"be verbose\")\n\n    argsparser.add_argument(\"-c\", \"--config\", dest=\"config\",\n                            required=True, metavar=\"\", help=\"path to a JSON config file\")\n\n    argsparser.add_argument(\"-s\", \"--source\", dest=\"source_path\",\n                            required=True, metavar=\"\", help=\"source code path\")\n\n    argsparser.add_argument(\"-p\", \"--prologue\", dest=\"prologue\",\n                            required=False, metavar=\"\", help=\"path to a C prologue file\")\n\n    amalgamation = Amalgamation(argsparser.parse_args())\n    amalgamation.generate()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/amalgamate/config.json",
    "content": "{\n\t\"project\": \"JSON for Modern C++\",\n\t\"target\": \"single_include/nlohmann/json.hpp\",\n\t\"sources\": [\n\t\t\"include/nlohmann/json.hpp\"\n\t],\n\t\"include_paths\": [\"include\"]\n}\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/cpplint/LICENSE",
    "content": "cpplint.py and its corresponding unit tests are Copyright (C) 2009 Google Inc.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/cpplint/README.rst",
    "content": "cpplint - static code checker for C++\n=====================================\n\n.. image:: https://travis-ci.org/cpplint/cpplint.svg?branch=master\n    :target: https://travis-ci.org/cpplint/cpplint\n\n.. image:: https://img.shields.io/pypi/v/cpplint.svg\n    :target: https://pypi.python.org/pypi/cpplint\n\n.. image:: https://img.shields.io/pypi/pyversions/cpplint.svg\n    :target: https://pypi.python.org/pypi/cpplint\n\n.. image:: https://img.shields.io/pypi/status/cpplint.svg\n    :target: https://pypi.python.org/pypi/cpplint\n\n.. image:: https://img.shields.io/pypi/l/cpplint.svg\n    :target: https://pypi.python.org/pypi/cpplint\n\n.. image:: https://img.shields.io/pypi/dd/cpplint.svg\n    :target: https://pypi.python.org/pypi/cpplint\n\n.. image:: https://img.shields.io/pypi/dw/cpplint.svg\n    :target: https://pypi.python.org/pypi/cpplint\n\n.. image:: https://img.shields.io/pypi/dm/cpplint.svg\n    :target: https://pypi.python.org/pypi/cpplint\n\nCpplint is a command-line tool to check C/C++ files for style issues following `Google's C++ style guide <http://google.github.io/styleguide/cppguide.html>`_.\nCpplint is developed and maintained by Google Inc. at `google/styleguide <https://github.com/google/styleguide>`_, also see the `wikipedia entry <http://en.wikipedia.org/wiki/Cpplint>`_\n\nWhile Google maintains cpplint, Google is not (very) responsive to issues and pull requests, this fork aims to be (somewhat) more open to add fixes to cpplint to enable fixes, when those fixes make cpplint usable in wider contexts.\nAlso see discussion here https://github.com/google/styleguide/pull/528.\n\n\nInstallation\n============\n\n\nTo install cpplint from PyPI, run:\n\n.. code-block:: bash\n\n    $ pip install cpplint\n\nThen run it with:\n\n.. code-block:: bash\n\n    $ cpplint [OPTIONS] files\n\nFor full usage instructions, run:\n\n.. code-block:: bash\n\n    $ cpplint --help\n\nChanges\n-------\n\nThe modifications in this fork are minor fixes and cosmetic changes, such as:\n\n* python 3 compatibility\n* more default file extensions\n* customizable file extensions with the --extensions argument\n* continuous integration on travis\n* support for recursive file discovery via the --recursive argument\n* support for excluding files via --exclude\n* JUnit XML output format\n* Overriding repository root auto-detection via --repository\n* Support ``#pragma once`` as an alternative to header include guards\n* ... and a few more (most of which are open PRs on upstream)\n\n\nAcknowledgements\n----------------\n\nThanks to Google Inc. for open-sourcing their in-house tool.\nThanks to maintainers of the fork\n\n* `tkruse <https://github.com/tkruse>`_  \n* `mattyclarkson <https://github.com/mattyclarkson>`_\n* `theandrewdavis <https://github.com/theandrewdavis>`_\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/cpplint/cpplint.py",
    "content": "#!/usr/bin/env python\n#\n# Copyright (c) 2009 Google Inc. All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n#\n#    * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#    * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#    * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\"\"\"Does google-lint on c++ files.\n\nThe goal of this script is to identify places in the code that *may*\nbe in non-compliance with google style.  It does not attempt to fix\nup these problems -- the point is to educate.  It does also not\nattempt to find all problems, or to ensure that everything it does\nfind is legitimately a problem.\n\nIn particular, we can get very confused by /* and // inside strings!\nWe do a small hack, which is to ignore //'s with \"'s after them on the\nsame line, but it is far from perfect (in either direction).\n\"\"\"\n\nimport codecs\nimport copy\nimport getopt\nimport glob\nimport itertools\nimport math  # for log\nimport os\nimport re\nimport sre_compile\nimport string\nimport sys\nimport sysconfig\nimport unicodedata\nimport xml.etree.ElementTree\n\n# if empty, use defaults\n_valid_extensions = set([])\n\n__VERSION__ = '1.5.5'\n\ntry:\n  xrange          # Python 2\nexcept NameError:\n  #  -- pylint: disable=redefined-builtin\n  xrange = range  # Python 3\n\n\n_USAGE = \"\"\"\nSyntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit|sed|gsed]\n                   [--filter=-x,+y,...]\n                   [--counting=total|toplevel|detailed] [--root=subdir]\n                   [--repository=path]\n                   [--linelength=digits] [--headers=x,y,...]\n                   [--recursive]\n                   [--exclude=path]\n                   [--extensions=hpp,cpp,...]\n                   [--includeorder=default|standardcfirst]\n                   [--quiet]\n                   [--version]\n        <file> [file] ...\n\n  Style checker for C/C++ source files.\n  This is a fork of the Google style checker with minor extensions.\n\n  The style guidelines this tries to follow are those in\n    https://google.github.io/styleguide/cppguide.html\n\n  Every problem is given a confidence score from 1-5, with 5 meaning we are\n  certain of the problem, and 1 meaning it could be a legitimate construct.\n  This will miss some errors, and is not a substitute for a code review.\n\n  To suppress false-positive errors of a certain category, add a\n  'NOLINT(category)' comment to the line.  NOLINT or NOLINT(*)\n  suppresses errors of all categories on that line.\n\n  The files passed in will be linted; at least one file must be provided.\n  Default linted extensions are %s.\n  Other file types will be ignored.\n  Change the extensions with the --extensions flag.\n\n  Flags:\n\n    output=emacs|eclipse|vs7|junit|sed|gsed\n      By default, the output is formatted to ease emacs parsing.  Visual Studio\n      compatible output (vs7) may also be used.  Further support exists for\n      eclipse (eclipse), and JUnit (junit). XML parsers such as those used\n      in Jenkins and Bamboo may also be used.\n      The sed format outputs sed commands that should fix some of the errors.\n      Note that this requires gnu sed. If that is installed as gsed on your\n      system (common e.g. on macOS with homebrew) you can use the gsed output\n      format. Sed commands are written to stdout, not stderr, so you should be\n      able to pipe output straight to a shell to run the fixes.\n\n    verbose=#\n      Specify a number 0-5 to restrict errors to certain verbosity levels.\n      Errors with lower verbosity levels have lower confidence and are more\n      likely to be false positives.\n\n    quiet\n      Don't print anything if no errors are found.\n\n    filter=-x,+y,...\n      Specify a comma-separated list of category-filters to apply: only\n      error messages whose category names pass the filters will be printed.\n      (Category names are printed with the message and look like\n      \"[whitespace/indent]\".)  Filters are evaluated left to right.\n      \"-FOO\" means \"do not print categories that start with FOO\".\n      \"+FOO\" means \"do print categories that start with FOO\".\n\n      Examples: --filter=-whitespace,+whitespace/braces\n                --filter=-whitespace,-runtime/printf,+runtime/printf_format\n                --filter=-,+build/include_what_you_use\n\n      To see a list of all the categories used in cpplint, pass no arg:\n         --filter=\n\n    counting=total|toplevel|detailed\n      The total number of errors found is always printed. If\n      'toplevel' is provided, then the count of errors in each of\n      the top-level categories like 'build' and 'whitespace' will\n      also be printed. If 'detailed' is provided, then a count\n      is provided for each category like 'build/class'.\n\n    repository=path\n      The top level directory of the repository, used to derive the header\n      guard CPP variable. By default, this is determined by searching for a\n      path that contains .git, .hg, or .svn. When this flag is specified, the\n      given path is used instead. This option allows the header guard CPP\n      variable to remain consistent even if members of a team have different\n      repository root directories (such as when checking out a subdirectory\n      with SVN). In addition, users of non-mainstream version control systems\n      can use this flag to ensure readable header guard CPP variables.\n\n      Examples:\n        Assuming that Alice checks out ProjectName and Bob checks out\n        ProjectName/trunk and trunk contains src/chrome/ui/browser.h, then\n        with no --repository flag, the header guard CPP variable will be:\n\n        Alice => TRUNK_SRC_CHROME_BROWSER_UI_BROWSER_H_\n        Bob   => SRC_CHROME_BROWSER_UI_BROWSER_H_\n\n        If Alice uses the --repository=trunk flag and Bob omits the flag or\n        uses --repository=. then the header guard CPP variable will be:\n\n        Alice => SRC_CHROME_BROWSER_UI_BROWSER_H_\n        Bob   => SRC_CHROME_BROWSER_UI_BROWSER_H_\n\n    root=subdir\n      The root directory used for deriving header guard CPP variable.\n      This directory is relative to the top level directory of the repository\n      which by default is determined by searching for a directory that contains\n      .git, .hg, or .svn but can also be controlled with the --repository flag.\n      If the specified directory does not exist, this flag is ignored.\n\n      Examples:\n        Assuming that src is the top level directory of the repository (and\n        cwd=top/src), the header guard CPP variables for\n        src/chrome/browser/ui/browser.h are:\n\n        No flag => CHROME_BROWSER_UI_BROWSER_H_\n        --root=chrome => BROWSER_UI_BROWSER_H_\n        --root=chrome/browser => UI_BROWSER_H_\n        --root=.. => SRC_CHROME_BROWSER_UI_BROWSER_H_\n\n    linelength=digits\n      This is the allowed line length for the project. The default value is\n      80 characters.\n\n      Examples:\n        --linelength=120\n\n    recursive\n      Search for files to lint recursively. Each directory given in the list\n      of files to be linted is replaced by all files that descend from that\n      directory. Files with extensions not in the valid extensions list are\n      excluded.\n\n    exclude=path\n      Exclude the given path from the list of files to be linted. Relative\n      paths are evaluated relative to the current directory and shell globbing\n      is performed. This flag can be provided multiple times to exclude\n      multiple files.\n\n      Examples:\n        --exclude=one.cc\n        --exclude=src/*.cc\n        --exclude=src/*.cc --exclude=test/*.cc\n\n    extensions=extension,extension,...\n      The allowed file extensions that cpplint will check\n\n      Examples:\n        --extensions=%s\n\n    includeorder=default|standardcfirst\n      For the build/include_order rule, the default is to blindly assume angle\n      bracket includes with file extension are c-system-headers (default),\n      even knowing this will have false classifications.\n      The default is established at google.\n      standardcfirst means to instead use an allow-list of known c headers and\n      treat all others as separate group of \"other system headers\". The C headers\n      included are those of the C-standard lib and closely related ones.\n\n    headers=x,y,...\n      The header extensions that cpplint will treat as .h in checks. Values are\n      automatically added to --extensions list.\n     (by default, only files with extensions %s will be assumed to be headers)\n\n      Examples:\n        --headers=%s\n        --headers=hpp,hxx\n        --headers=hpp\n\n    cpplint.py supports per-directory configurations specified in CPPLINT.cfg\n    files. CPPLINT.cfg file can contain a number of key=value pairs.\n    Currently the following options are supported:\n\n      set noparent\n      filter=+filter1,-filter2,...\n      exclude_files=regex\n      linelength=80\n      root=subdir\n      headers=x,y,...\n\n    \"set noparent\" option prevents cpplint from traversing directory tree\n    upwards looking for more .cfg files in parent directories. This option\n    is usually placed in the top-level project directory.\n\n    The \"filter\" option is similar in function to --filter flag. It specifies\n    message filters in addition to the |_DEFAULT_FILTERS| and those specified\n    through --filter command-line flag.\n\n    \"exclude_files\" allows to specify a regular expression to be matched against\n    a file name. If the expression matches, the file is skipped and not run\n    through the linter.\n\n    \"linelength\" allows to specify the allowed line length for the project.\n\n    The \"root\" option is similar in function to the --root flag (see example\n    above). Paths are relative to the directory of the CPPLINT.cfg.\n\n    The \"headers\" option is similar in function to the --headers flag\n    (see example above).\n\n    CPPLINT.cfg has an effect on files in the same directory and all\n    sub-directories, unless overridden by a nested configuration file.\n\n      Example file:\n        filter=-build/include_order,+build/include_alpha\n        exclude_files=.*\\\\.cc\n\n    The above example disables build/include_order warning and enables\n    build/include_alpha as well as excludes all .cc from being\n    processed by linter, in the current directory (where the .cfg\n    file is located) and all sub-directories.\n\"\"\"\n\n# We categorize each error message we print.  Here are the categories.\n# We want an explicit list so we can list them all in cpplint --filter=.\n# If you add a new error message with a new category, add it to the list\n# here!  cpplint_unittest.py should tell you if you forget to do this.\n_ERROR_CATEGORIES = [\n    'build/class',\n    'build/c++11',\n    'build/c++14',\n    'build/c++tr1',\n    'build/deprecated',\n    'build/endif_comment',\n    'build/explicit_make_pair',\n    'build/forward_decl',\n    'build/header_guard',\n    'build/include',\n    'build/include_subdir',\n    'build/include_alpha',\n    'build/include_order',\n    'build/include_what_you_use',\n    'build/namespaces_headers',\n    'build/namespaces_literals',\n    'build/namespaces',\n    'build/printf_format',\n    'build/storage_class',\n    'legal/copyright',\n    'readability/alt_tokens',\n    'readability/braces',\n    'readability/casting',\n    'readability/check',\n    'readability/constructors',\n    'readability/fn_size',\n    'readability/inheritance',\n    'readability/multiline_comment',\n    'readability/multiline_string',\n    'readability/namespace',\n    'readability/nolint',\n    'readability/nul',\n    'readability/strings',\n    'readability/todo',\n    'readability/utf8',\n    'runtime/arrays',\n    'runtime/casting',\n    'runtime/explicit',\n    'runtime/int',\n    'runtime/init',\n    'runtime/invalid_increment',\n    'runtime/member_string_references',\n    'runtime/memset',\n    'runtime/indentation_namespace',\n    'runtime/operator',\n    'runtime/printf',\n    'runtime/printf_format',\n    'runtime/references',\n    'runtime/string',\n    'runtime/threadsafe_fn',\n    'runtime/vlog',\n    'whitespace/blank_line',\n    'whitespace/braces',\n    'whitespace/comma',\n    'whitespace/comments',\n    'whitespace/empty_conditional_body',\n    'whitespace/empty_if_body',\n    'whitespace/empty_loop_body',\n    'whitespace/end_of_line',\n    'whitespace/ending_newline',\n    'whitespace/forcolon',\n    'whitespace/indent',\n    'whitespace/line_length',\n    'whitespace/newline',\n    'whitespace/operators',\n    'whitespace/parens',\n    'whitespace/semicolon',\n    'whitespace/tab',\n    'whitespace/todo',\n    ]\n\n# keywords to use with --outputs which generate stdout for machine processing\n_MACHINE_OUTPUTS = [\n  'junit',\n  'sed',\n  'gsed'\n]\n\n# These error categories are no longer enforced by cpplint, but for backwards-\n# compatibility they may still appear in NOLINT comments.\n_LEGACY_ERROR_CATEGORIES = [\n    'readability/streams',\n    'readability/function',\n    ]\n\n# The default state of the category filter. This is overridden by the --filter=\n# flag. By default all errors are on, so only add here categories that should be\n# off by default (i.e., categories that must be enabled by the --filter= flags).\n# All entries here should start with a '-' or '+', as in the --filter= flag.\n_DEFAULT_FILTERS = ['-build/include_alpha']\n\n# The default list of categories suppressed for C (not C++) files.\n_DEFAULT_C_SUPPRESSED_CATEGORIES = [\n    'readability/casting',\n    ]\n\n# The default list of categories suppressed for Linux Kernel files.\n_DEFAULT_KERNEL_SUPPRESSED_CATEGORIES = [\n    'whitespace/tab',\n    ]\n\n# We used to check for high-bit characters, but after much discussion we\n# decided those were OK, as long as they were in UTF-8 and didn't represent\n# hard-coded international strings, which belong in a separate i18n file.\n\n# C++ headers\n_CPP_HEADERS = frozenset([\n    # Legacy\n    'algobase.h',\n    'algo.h',\n    'alloc.h',\n    'builtinbuf.h',\n    'bvector.h',\n    'complex.h',\n    'defalloc.h',\n    'deque.h',\n    'editbuf.h',\n    'fstream.h',\n    'function.h',\n    'hash_map',\n    'hash_map.h',\n    'hash_set',\n    'hash_set.h',\n    'hashtable.h',\n    'heap.h',\n    'indstream.h',\n    'iomanip.h',\n    'iostream.h',\n    'istream.h',\n    'iterator.h',\n    'list.h',\n    'map.h',\n    'multimap.h',\n    'multiset.h',\n    'ostream.h',\n    'pair.h',\n    'parsestream.h',\n    'pfstream.h',\n    'procbuf.h',\n    'pthread_alloc',\n    'pthread_alloc.h',\n    'rope',\n    'rope.h',\n    'ropeimpl.h',\n    'set.h',\n    'slist',\n    'slist.h',\n    'stack.h',\n    'stdiostream.h',\n    'stl_alloc.h',\n    'stl_relops.h',\n    'streambuf.h',\n    'stream.h',\n    'strfile.h',\n    'strstream.h',\n    'tempbuf.h',\n    'tree.h',\n    'type_traits.h',\n    'vector.h',\n    # 17.6.1.2 C++ library headers\n    'algorithm',\n    'array',\n    'atomic',\n    'bitset',\n    'chrono',\n    'codecvt',\n    'complex',\n    'condition_variable',\n    'deque',\n    'exception',\n    'forward_list',\n    'fstream',\n    'functional',\n    'future',\n    'initializer_list',\n    'iomanip',\n    'ios',\n    'iosfwd',\n    'iostream',\n    'istream',\n    'iterator',\n    'limits',\n    'list',\n    'locale',\n    'map',\n    'memory',\n    'mutex',\n    'new',\n    'numeric',\n    'ostream',\n    'queue',\n    'random',\n    'ratio',\n    'regex',\n    'scoped_allocator',\n    'set',\n    'sstream',\n    'stack',\n    'stdexcept',\n    'streambuf',\n    'string',\n    'strstream',\n    'system_error',\n    'thread',\n    'tuple',\n    'typeindex',\n    'typeinfo',\n    'type_traits',\n    'unordered_map',\n    'unordered_set',\n    'utility',\n    'valarray',\n    'vector',\n    # 17.6.1.2 C++14 headers\n    'shared_mutex',\n    # 17.6.1.2 C++17 headers\n    'any',\n    'charconv',\n    'codecvt',\n    'execution',\n    'filesystem',\n    'memory_resource',\n    'optional',\n    'string_view',\n    'variant',\n    # 17.6.1.2 C++ headers for C library facilities\n    'cassert',\n    'ccomplex',\n    'cctype',\n    'cerrno',\n    'cfenv',\n    'cfloat',\n    'cinttypes',\n    'ciso646',\n    'climits',\n    'clocale',\n    'cmath',\n    'csetjmp',\n    'csignal',\n    'cstdalign',\n    'cstdarg',\n    'cstdbool',\n    'cstddef',\n    'cstdint',\n    'cstdio',\n    'cstdlib',\n    'cstring',\n    'ctgmath',\n    'ctime',\n    'cuchar',\n    'cwchar',\n    'cwctype',\n    ])\n\n# C headers\n_C_HEADERS = frozenset([\n    # System C headers\n    'assert.h',\n    'complex.h',\n    'ctype.h',\n    'errno.h',\n    'fenv.h',\n    'float.h',\n    'inttypes.h',\n    'iso646.h',\n    'limits.h',\n    'locale.h',\n    'math.h',\n    'setjmp.h',\n    'signal.h',\n    'stdalign.h',\n    'stdarg.h',\n    'stdatomic.h',\n    'stdbool.h',\n    'stddef.h',\n    'stdint.h',\n    'stdio.h',\n    'stdlib.h',\n    'stdnoreturn.h',\n    'string.h',\n    'tgmath.h',\n    'threads.h',\n    'time.h',\n    'uchar.h',\n    'wchar.h',\n    'wctype.h',\n    # additional POSIX C headers\n    'aio.h',\n    'arpa/inet.h',\n    'cpio.h',\n    'dirent.h',\n    'dlfcn.h',\n    'fcntl.h',\n    'fmtmsg.h',\n    'fnmatch.h',\n    'ftw.h',\n    'glob.h',\n    'grp.h',\n    'iconv.h',\n    'langinfo.h',\n    'libgen.h',\n    'monetary.h',\n    'mqueue.h',\n    'ndbm.h',\n    'net/if.h',\n    'netdb.h',\n    'netinet/in.h',\n    'netinet/tcp.h',\n    'nl_types.h',\n    'poll.h',\n    'pthread.h',\n    'pwd.h',\n    'regex.h',\n    'sched.h',\n    'search.h',\n    'semaphore.h',\n    'setjmp.h',\n    'signal.h',\n    'spawn.h',\n    'strings.h',\n    'stropts.h',\n    'syslog.h',\n    'tar.h',\n    'termios.h',\n    'trace.h',\n    'ulimit.h',\n    'unistd.h',\n    'utime.h',\n    'utmpx.h',\n    'wordexp.h',\n    # additional GNUlib headers\n    'a.out.h',\n    'aliases.h',\n    'alloca.h',\n    'ar.h',\n    'argp.h',\n    'argz.h',\n    'byteswap.h',\n    'crypt.h',\n    'endian.h',\n    'envz.h',\n    'err.h',\n    'error.h',\n    'execinfo.h',\n    'fpu_control.h',\n    'fstab.h',\n    'fts.h',\n    'getopt.h',\n    'gshadow.h',\n    'ieee754.h',\n    'ifaddrs.h',\n    'libintl.h',\n    'mcheck.h',\n    'mntent.h',\n    'obstack.h',\n    'paths.h',\n    'printf.h',\n    'pty.h',\n    'resolv.h',\n    'shadow.h',\n    'sysexits.h',\n    'ttyent.h',\n    # Additional linux glibc headers\n    'dlfcn.h',\n    'elf.h',\n    'features.h',\n    'gconv.h',\n    'gnu-versions.h',\n    'lastlog.h',\n    'libio.h',\n    'link.h',\n    'malloc.h',\n    'memory.h',\n    'netash/ash.h',\n    'netatalk/at.h',\n    'netax25/ax25.h',\n    'neteconet/ec.h',\n    'netipx/ipx.h',\n    'netiucv/iucv.h',\n    'netpacket/packet.h',\n    'netrom/netrom.h',\n    'netrose/rose.h',\n    'nfs/nfs.h',\n    'nl_types.h',\n    'nss.h',\n    're_comp.h',\n    'regexp.h',\n    'sched.h',\n    'sgtty.h',\n    'stab.h',\n    'stdc-predef.h',\n    'stdio_ext.h',\n    'syscall.h',\n    'termio.h',\n    'thread_db.h',\n    'ucontext.h',\n    'ustat.h',\n    'utmp.h',\n    'values.h',\n    'wait.h',\n    'xlocale.h',\n    # Hardware specific headers\n    'arm_neon.h',\n    'emmintrin.h',\n    'xmmintin.h',\n    ])\n\n# Folders of C libraries so commonly used in C++,\n# that they have parity with standard C libraries.\nC_STANDARD_HEADER_FOLDERS = frozenset([\n    # standard C library\n    \"sys\",\n    # glibc for linux\n    \"arpa\",\n    \"asm-generic\",\n    \"bits\",\n    \"gnu\",\n    \"net\",\n    \"netinet\",\n    \"protocols\",\n    \"rpc\",\n    \"rpcsvc\",\n    \"scsi\",\n    # linux kernel header\n    \"drm\",\n    \"linux\",\n    \"misc\",\n    \"mtd\",\n    \"rdma\",\n    \"sound\",\n    \"video\",\n    \"xen\",\n  ])\n\n# Type names\n_TYPES = re.compile(\n    r'^(?:'\n    # [dcl.type.simple]\n    r'(char(16_t|32_t)?)|wchar_t|'\n    r'bool|short|int|long|signed|unsigned|float|double|'\n    # [support.types]\n    r'(ptrdiff_t|size_t|max_align_t|nullptr_t)|'\n    # [cstdint.syn]\n    r'(u?int(_fast|_least)?(8|16|32|64)_t)|'\n    r'(u?int(max|ptr)_t)|'\n    r')$')\n\n\n# These headers are excluded from [build/include] and [build/include_order]\n# checks:\n# - Anything not following google file name conventions (containing an\n#   uppercase character, such as Python.h or nsStringAPI.h, for example).\n# - Lua headers.\n_THIRD_PARTY_HEADERS_PATTERN = re.compile(\n    r'^(?:[^/]*[A-Z][^/]*\\.h|lua\\.h|lauxlib\\.h|lualib\\.h)$')\n\n# Pattern for matching FileInfo.BaseName() against test file name\n_test_suffixes = ['_test', '_regtest', '_unittest']\n_TEST_FILE_SUFFIX = '(' + '|'.join(_test_suffixes) + r')$'\n\n# Pattern that matches only complete whitespace, possibly across multiple lines.\n_EMPTY_CONDITIONAL_BODY_PATTERN = re.compile(r'^\\s*$', re.DOTALL)\n\n# Assertion macros.  These are defined in base/logging.h and\n# testing/base/public/gunit.h.\n_CHECK_MACROS = [\n    'DCHECK', 'CHECK',\n    'EXPECT_TRUE', 'ASSERT_TRUE',\n    'EXPECT_FALSE', 'ASSERT_FALSE',\n    ]\n\n# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE\n_CHECK_REPLACEMENT = dict([(macro_var, {}) for macro_var in _CHECK_MACROS])\n\nfor op, replacement in [('==', 'EQ'), ('!=', 'NE'),\n                        ('>=', 'GE'), ('>', 'GT'),\n                        ('<=', 'LE'), ('<', 'LT')]:\n  _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement\n  _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement\n  _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement\n  _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement\n\nfor op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),\n                            ('>=', 'LT'), ('>', 'LE'),\n                            ('<=', 'GT'), ('<', 'GE')]:\n  _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement\n  _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement\n\n# Alternative tokens and their replacements.  For full list, see section 2.5\n# Alternative tokens [lex.digraph] in the C++ standard.\n#\n# Digraphs (such as '%:') are not included here since it's a mess to\n# match those on a word boundary.\n_ALT_TOKEN_REPLACEMENT = {\n    'and': '&&',\n    'bitor': '|',\n    'or': '||',\n    'xor': '^',\n    'compl': '~',\n    'bitand': '&',\n    'and_eq': '&=',\n    'or_eq': '|=',\n    'xor_eq': '^=',\n    'not': '!',\n    'not_eq': '!='\n    }\n\n# Compile regular expression that matches all the above keywords.  The \"[ =()]\"\n# bit is meant to avoid matching these keywords outside of boolean expressions.\n#\n# False positives include C-style multi-line comments and multi-line strings\n# but those have always been troublesome for cpplint.\n_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile(\n    r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)')\n\n\n# These constants define types of headers for use with\n# _IncludeState.CheckNextIncludeOrder().\n_C_SYS_HEADER = 1\n_CPP_SYS_HEADER = 2\n_OTHER_SYS_HEADER = 3\n_LIKELY_MY_HEADER = 4\n_POSSIBLE_MY_HEADER = 5\n_OTHER_HEADER = 6\n\n# These constants define the current inline assembly state\n_NO_ASM = 0       # Outside of inline assembly block\n_INSIDE_ASM = 1   # Inside inline assembly block\n_END_ASM = 2      # Last line of inline assembly block\n_BLOCK_ASM = 3    # The whole block is an inline assembly block\n\n# Match start of assembly blocks\n_MATCH_ASM = re.compile(r'^\\s*(?:asm|_asm|__asm|__asm__)'\n                        r'(?:\\s+(volatile|__volatile__))?'\n                        r'\\s*[{(]')\n\n# Match strings that indicate we're working on a C (not C++) file.\n_SEARCH_C_FILE = re.compile(r'\\b(?:LINT_C_FILE|'\n                            r'vim?:\\s*.*(\\s*|:)filetype=c(\\s*|:|$))')\n\n# Match string that indicates we're working on a Linux Kernel file.\n_SEARCH_KERNEL_FILE = re.compile(r'\\b(?:LINT_KERNEL_FILE)')\n\n# Commands for sed to fix the problem\n_SED_FIXUPS = {\n  'Remove spaces around =': r's/ = /=/',\n  'Remove spaces around !=': r's/ != /!=/',\n  'Remove space before ( in if (': r's/if (/if(/',\n  'Remove space before ( in for (': r's/for (/for(/',\n  'Remove space before ( in while (': r's/while (/while(/',\n  'Remove space before ( in switch (': r's/switch (/switch(/',\n  'Should have a space between // and comment': r's/\\/\\//\\/\\/ /',\n  'Missing space before {': r's/\\([^ ]\\){/\\1 {/',\n  'Tab found, replace by spaces': r's/\\t/  /g',\n  'Line ends in whitespace.  Consider deleting these extra spaces.': r's/\\s*$//',\n  'You don\\'t need a ; after a }': r's/};/}/',\n  'Missing space after ,': r's/,\\([^ ]\\)/, \\1/g',\n}\n\n_regexp_compile_cache = {}\n\n# {str, set(int)}: a map from error categories to sets of linenumbers\n# on which those errors are expected and should be suppressed.\n_error_suppressions = {}\n\n# The root directory used for deriving header guard CPP variable.\n# This is set by --root flag.\n_root = None\n_root_debug = False\n\n# The top level repository directory. If set, _root is calculated relative to\n# this directory instead of the directory containing version control artifacts.\n# This is set by the --repository flag.\n_repository = None\n\n# Files to exclude from linting. This is set by the --exclude flag.\n_excludes = None\n\n# Whether to supress all PrintInfo messages, UNRELATED to --quiet flag\n_quiet = False\n\n# The allowed line length of files.\n# This is set by --linelength flag.\n_line_length = 80\n\n# This allows to use different include order rule than default\n_include_order = \"default\"\n\ntry:\n  unicode\nexcept NameError:\n  #  -- pylint: disable=redefined-builtin\n  basestring = unicode = str\n\ntry:\n  long\nexcept NameError:\n  #  -- pylint: disable=redefined-builtin\n  long = int\n\nif sys.version_info < (3,):\n  #  -- pylint: disable=no-member\n  # BINARY_TYPE = str\n  itervalues = dict.itervalues\n  iteritems = dict.iteritems\nelse:\n  # BINARY_TYPE = bytes\n  itervalues = dict.values\n  iteritems = dict.items\n\ndef unicode_escape_decode(x):\n  if sys.version_info < (3,):\n    return codecs.unicode_escape_decode(x)[0]\n  else:\n    return x\n\n# Treat all headers starting with 'h' equally: .h, .hpp, .hxx etc.\n# This is set by --headers flag.\n_hpp_headers = set([])\n\n# {str, bool}: a map from error categories to booleans which indicate if the\n# category should be suppressed for every line.\n_global_error_suppressions = {}\n\ndef ProcessHppHeadersOption(val):\n  global _hpp_headers\n  try:\n    _hpp_headers = {ext.strip() for ext in val.split(',')}\n  except ValueError:\n    PrintUsage('Header extensions must be comma separated list.')\n\ndef ProcessIncludeOrderOption(val):\n  if val is None or val == \"default\":\n    pass\n  elif val == \"standardcfirst\":\n    global _include_order\n    _include_order = val\n  else:\n    PrintUsage('Invalid includeorder value %s. Expected default|standardcfirst')\n\ndef IsHeaderExtension(file_extension):\n  return file_extension in GetHeaderExtensions()\n\ndef GetHeaderExtensions():\n  if _hpp_headers:\n    return _hpp_headers\n  if _valid_extensions:\n    return {h for h in _valid_extensions if 'h' in h}\n  return set(['h', 'hh', 'hpp', 'hxx', 'h++', 'cuh'])\n\n# The allowed extensions for file names\n# This is set by --extensions flag\ndef GetAllExtensions():\n  return GetHeaderExtensions().union(_valid_extensions or set(\n    ['c', 'cc', 'cpp', 'cxx', 'c++', 'cu']))\n\ndef ProcessExtensionsOption(val):\n  global _valid_extensions\n  try:\n    extensions = [ext.strip() for ext in val.split(',')]\n    _valid_extensions = set(extensions)\n  except ValueError:\n    PrintUsage('Extensions should be a comma-separated list of values;'\n               'for example: extensions=hpp,cpp\\n'\n               'This could not be parsed: \"%s\"' % (val,))\n\ndef GetNonHeaderExtensions():\n  return GetAllExtensions().difference(GetHeaderExtensions())\n\ndef ParseNolintSuppressions(filename, raw_line, linenum, error):\n  \"\"\"Updates the global list of line error-suppressions.\n\n  Parses any NOLINT comments on the current line, updating the global\n  error_suppressions store.  Reports an error if the NOLINT comment\n  was malformed.\n\n  Args:\n    filename: str, the name of the input file.\n    raw_line: str, the line of input text, with comments.\n    linenum: int, the number of the current line.\n    error: function, an error handler.\n  \"\"\"\n  matched = Search(r'\\bNOLINT(NEXTLINE)?\\b(\\([^)]+\\))?', raw_line)\n  if matched:\n    if matched.group(1):\n      suppressed_line = linenum + 1\n    else:\n      suppressed_line = linenum\n    category = matched.group(2)\n    if category in (None, '(*)'):  # => \"suppress all\"\n      _error_suppressions.setdefault(None, set()).add(suppressed_line)\n    else:\n      if category.startswith('(') and category.endswith(')'):\n        category = category[1:-1]\n        if category in _ERROR_CATEGORIES:\n          _error_suppressions.setdefault(category, set()).add(suppressed_line)\n        elif category not in _LEGACY_ERROR_CATEGORIES:\n          error(filename, linenum, 'readability/nolint', 5,\n                'Unknown NOLINT error category: %s' % category)\n\n\ndef ProcessGlobalSuppresions(lines):\n  \"\"\"Updates the list of global error suppressions.\n\n  Parses any lint directives in the file that have global effect.\n\n  Args:\n    lines: An array of strings, each representing a line of the file, with the\n           last element being empty if the file is terminated with a newline.\n  \"\"\"\n  for line in lines:\n    if _SEARCH_C_FILE.search(line):\n      for category in _DEFAULT_C_SUPPRESSED_CATEGORIES:\n        _global_error_suppressions[category] = True\n    if _SEARCH_KERNEL_FILE.search(line):\n      for category in _DEFAULT_KERNEL_SUPPRESSED_CATEGORIES:\n        _global_error_suppressions[category] = True\n\n\ndef ResetNolintSuppressions():\n  \"\"\"Resets the set of NOLINT suppressions to empty.\"\"\"\n  _error_suppressions.clear()\n  _global_error_suppressions.clear()\n\n\ndef IsErrorSuppressedByNolint(category, linenum):\n  \"\"\"Returns true if the specified error category is suppressed on this line.\n\n  Consults the global error_suppressions map populated by\n  ParseNolintSuppressions/ProcessGlobalSuppresions/ResetNolintSuppressions.\n\n  Args:\n    category: str, the category of the error.\n    linenum: int, the current line number.\n  Returns:\n    bool, True iff the error should be suppressed due to a NOLINT comment or\n    global suppression.\n  \"\"\"\n  return (_global_error_suppressions.get(category, False) or\n          linenum in _error_suppressions.get(category, set()) or\n          linenum in _error_suppressions.get(None, set()))\n\n\ndef Match(pattern, s):\n  \"\"\"Matches the string with the pattern, caching the compiled regexp.\"\"\"\n  # The regexp compilation caching is inlined in both Match and Search for\n  # performance reasons; factoring it out into a separate function turns out\n  # to be noticeably expensive.\n  if pattern not in _regexp_compile_cache:\n    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)\n  return _regexp_compile_cache[pattern].match(s)\n\n\ndef ReplaceAll(pattern, rep, s):\n  \"\"\"Replaces instances of pattern in a string with a replacement.\n\n  The compiled regex is kept in a cache shared by Match and Search.\n\n  Args:\n    pattern: regex pattern\n    rep: replacement text\n    s: search string\n\n  Returns:\n    string with replacements made (or original string if no replacements)\n  \"\"\"\n  if pattern not in _regexp_compile_cache:\n    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)\n  return _regexp_compile_cache[pattern].sub(rep, s)\n\n\ndef Search(pattern, s):\n  \"\"\"Searches the string for the pattern, caching the compiled regexp.\"\"\"\n  if pattern not in _regexp_compile_cache:\n    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)\n  return _regexp_compile_cache[pattern].search(s)\n\n\ndef _IsSourceExtension(s):\n  \"\"\"File extension (excluding dot) matches a source file extension.\"\"\"\n  return s in GetNonHeaderExtensions()\n\n\nclass _IncludeState(object):\n  \"\"\"Tracks line numbers for includes, and the order in which includes appear.\n\n  include_list contains list of lists of (header, line number) pairs.\n  It's a lists of lists rather than just one flat list to make it\n  easier to update across preprocessor boundaries.\n\n  Call CheckNextIncludeOrder() once for each header in the file, passing\n  in the type constants defined above. Calls in an illegal order will\n  raise an _IncludeError with an appropriate error message.\n\n  \"\"\"\n  # self._section will move monotonically through this set. If it ever\n  # needs to move backwards, CheckNextIncludeOrder will raise an error.\n  _INITIAL_SECTION = 0\n  _MY_H_SECTION = 1\n  _C_SECTION = 2\n  _CPP_SECTION = 3\n  _OTHER_SYS_SECTION = 4\n  _OTHER_H_SECTION = 5\n\n  _TYPE_NAMES = {\n      _C_SYS_HEADER: 'C system header',\n      _CPP_SYS_HEADER: 'C++ system header',\n      _OTHER_SYS_HEADER: 'other system header',\n      _LIKELY_MY_HEADER: 'header this file implements',\n      _POSSIBLE_MY_HEADER: 'header this file may implement',\n      _OTHER_HEADER: 'other header',\n      }\n  _SECTION_NAMES = {\n      _INITIAL_SECTION: \"... nothing. (This can't be an error.)\",\n      _MY_H_SECTION: 'a header this file implements',\n      _C_SECTION: 'C system header',\n      _CPP_SECTION: 'C++ system header',\n      _OTHER_SYS_SECTION: 'other system header',\n      _OTHER_H_SECTION: 'other header',\n      }\n\n  def __init__(self):\n    self.include_list = [[]]\n    self._section = None\n    self._last_header = None\n    self.ResetSection('')\n\n  def FindHeader(self, header):\n    \"\"\"Check if a header has already been included.\n\n    Args:\n      header: header to check.\n    Returns:\n      Line number of previous occurrence, or -1 if the header has not\n      been seen before.\n    \"\"\"\n    for section_list in self.include_list:\n      for f in section_list:\n        if f[0] == header:\n          return f[1]\n    return -1\n\n  def ResetSection(self, directive):\n    \"\"\"Reset section checking for preprocessor directive.\n\n    Args:\n      directive: preprocessor directive (e.g. \"if\", \"else\").\n    \"\"\"\n    # The name of the current section.\n    self._section = self._INITIAL_SECTION\n    # The path of last found header.\n    self._last_header = ''\n\n    # Update list of includes.  Note that we never pop from the\n    # include list.\n    if directive in ('if', 'ifdef', 'ifndef'):\n      self.include_list.append([])\n    elif directive in ('else', 'elif'):\n      self.include_list[-1] = []\n\n  def SetLastHeader(self, header_path):\n    self._last_header = header_path\n\n  def CanonicalizeAlphabeticalOrder(self, header_path):\n    \"\"\"Returns a path canonicalized for alphabetical comparison.\n\n    - replaces \"-\" with \"_\" so they both cmp the same.\n    - removes '-inl' since we don't require them to be after the main header.\n    - lowercase everything, just in case.\n\n    Args:\n      header_path: Path to be canonicalized.\n\n    Returns:\n      Canonicalized path.\n    \"\"\"\n    return header_path.replace('-inl.h', '.h').replace('-', '_').lower()\n\n  def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path):\n    \"\"\"Check if a header is in alphabetical order with the previous header.\n\n    Args:\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      header_path: Canonicalized header to be checked.\n\n    Returns:\n      Returns true if the header is in alphabetical order.\n    \"\"\"\n    # If previous section is different from current section, _last_header will\n    # be reset to empty string, so it's always less than current header.\n    #\n    # If previous line was a blank line, assume that the headers are\n    # intentionally sorted the way they are.\n    if (self._last_header > header_path and\n        Match(r'^\\s*#\\s*include\\b', clean_lines.elided[linenum - 1])):\n      return False\n    return True\n\n  def CheckNextIncludeOrder(self, header_type):\n    \"\"\"Returns a non-empty error message if the next header is out of order.\n\n    This function also updates the internal state to be ready to check\n    the next include.\n\n    Args:\n      header_type: One of the _XXX_HEADER constants defined above.\n\n    Returns:\n      The empty string if the header is in the right order, or an\n      error message describing what's wrong.\n\n    \"\"\"\n    error_message = ('Found %s after %s' %\n                     (self._TYPE_NAMES[header_type],\n                      self._SECTION_NAMES[self._section]))\n\n    last_section = self._section\n\n    if header_type == _C_SYS_HEADER:\n      if self._section <= self._C_SECTION:\n        self._section = self._C_SECTION\n      else:\n        self._last_header = ''\n        return error_message\n    elif header_type == _CPP_SYS_HEADER:\n      if self._section <= self._CPP_SECTION:\n        self._section = self._CPP_SECTION\n      else:\n        self._last_header = ''\n        return error_message\n    elif header_type == _OTHER_SYS_HEADER:\n      if self._section <= self._OTHER_SYS_SECTION:\n        self._section = self._OTHER_SYS_SECTION\n      else:\n        self._last_header = ''\n        return error_message\n    elif header_type == _LIKELY_MY_HEADER:\n      if self._section <= self._MY_H_SECTION:\n        self._section = self._MY_H_SECTION\n      else:\n        self._section = self._OTHER_H_SECTION\n    elif header_type == _POSSIBLE_MY_HEADER:\n      if self._section <= self._MY_H_SECTION:\n        self._section = self._MY_H_SECTION\n      else:\n        # This will always be the fallback because we're not sure\n        # enough that the header is associated with this file.\n        self._section = self._OTHER_H_SECTION\n    else:\n      assert header_type == _OTHER_HEADER\n      self._section = self._OTHER_H_SECTION\n\n    if last_section != self._section:\n      self._last_header = ''\n\n    return ''\n\n\nclass _CppLintState(object):\n  \"\"\"Maintains module-wide state..\"\"\"\n\n  def __init__(self):\n    self.verbose_level = 1  # global setting.\n    self.error_count = 0    # global count of reported errors\n    # filters to apply when emitting error messages\n    self.filters = _DEFAULT_FILTERS[:]\n    # backup of filter list. Used to restore the state after each file.\n    self._filters_backup = self.filters[:]\n    self.counting = 'total'  # In what way are we counting errors?\n    self.errors_by_category = {}  # string to int dict storing error counts\n    self.quiet = False  # Suppress non-error messagess?\n\n    # output format:\n    # \"emacs\" - format that emacs can parse (default)\n    # \"eclipse\" - format that eclipse can parse\n    # \"vs7\" - format that Microsoft Visual Studio 7 can parse\n    # \"junit\" - format that Jenkins, Bamboo, etc can parse\n    # \"sed\" - returns a gnu sed command to fix the problem\n    # \"gsed\" - like sed, but names the command gsed, e.g. for macOS homebrew users\n    self.output_format = 'emacs'\n\n    # For JUnit output, save errors and failures until the end so that they\n    # can be written into the XML\n    self._junit_errors = []\n    self._junit_failures = []\n\n  def SetOutputFormat(self, output_format):\n    \"\"\"Sets the output format for errors.\"\"\"\n    self.output_format = output_format\n\n  def SetQuiet(self, quiet):\n    \"\"\"Sets the module's quiet settings, and returns the previous setting.\"\"\"\n    last_quiet = self.quiet\n    self.quiet = quiet\n    return last_quiet\n\n  def SetVerboseLevel(self, level):\n    \"\"\"Sets the module's verbosity, and returns the previous setting.\"\"\"\n    last_verbose_level = self.verbose_level\n    self.verbose_level = level\n    return last_verbose_level\n\n  def SetCountingStyle(self, counting_style):\n    \"\"\"Sets the module's counting options.\"\"\"\n    self.counting = counting_style\n\n  def SetFilters(self, filters):\n    \"\"\"Sets the error-message filters.\n\n    These filters are applied when deciding whether to emit a given\n    error message.\n\n    Args:\n      filters: A string of comma-separated filters (eg \"+whitespace/indent\").\n               Each filter should start with + or -; else we die.\n\n    Raises:\n      ValueError: The comma-separated filters did not all start with '+' or '-'.\n                  E.g. \"-,+whitespace,-whitespace/indent,whitespace/badfilter\"\n    \"\"\"\n    # Default filters always have less priority than the flag ones.\n    self.filters = _DEFAULT_FILTERS[:]\n    self.AddFilters(filters)\n\n  def AddFilters(self, filters):\n    \"\"\" Adds more filters to the existing list of error-message filters. \"\"\"\n    for filt in filters.split(','):\n      clean_filt = filt.strip()\n      if clean_filt:\n        self.filters.append(clean_filt)\n    for filt in self.filters:\n      if not (filt.startswith('+') or filt.startswith('-')):\n        raise ValueError('Every filter in --filters must start with + or -'\n                         ' (%s does not)' % filt)\n\n  def BackupFilters(self):\n    \"\"\" Saves the current filter list to backup storage.\"\"\"\n    self._filters_backup = self.filters[:]\n\n  def RestoreFilters(self):\n    \"\"\" Restores filters previously backed up.\"\"\"\n    self.filters = self._filters_backup[:]\n\n  def ResetErrorCounts(self):\n    \"\"\"Sets the module's error statistic back to zero.\"\"\"\n    self.error_count = 0\n    self.errors_by_category = {}\n\n  def IncrementErrorCount(self, category):\n    \"\"\"Bumps the module's error statistic.\"\"\"\n    self.error_count += 1\n    if self.counting in ('toplevel', 'detailed'):\n      if self.counting != 'detailed':\n        category = category.split('/')[0]\n      if category not in self.errors_by_category:\n        self.errors_by_category[category] = 0\n      self.errors_by_category[category] += 1\n\n  def PrintErrorCounts(self):\n    \"\"\"Print a summary of errors by category, and the total.\"\"\"\n    for category, count in sorted(iteritems(self.errors_by_category)):\n      self.PrintInfo('Category \\'%s\\' errors found: %d\\n' %\n                       (category, count))\n    if self.error_count > 0:\n      self.PrintInfo('Total errors found: %d\\n' % self.error_count)\n\n  def PrintInfo(self, message):\n    # _quiet does not represent --quiet flag.\n    # Hide infos from stdout to keep stdout pure for machine consumption\n    if not _quiet and self.output_format not in _MACHINE_OUTPUTS:\n      sys.stdout.write(message)\n\n  def PrintError(self, message):\n    if self.output_format == 'junit':\n      self._junit_errors.append(message)\n    else:\n      sys.stderr.write(message)\n\n  def AddJUnitFailure(self, filename, linenum, message, category, confidence):\n    self._junit_failures.append((filename, linenum, message, category,\n        confidence))\n\n  def FormatJUnitXML(self):\n    num_errors = len(self._junit_errors)\n    num_failures = len(self._junit_failures)\n\n    testsuite = xml.etree.ElementTree.Element('testsuite')\n    testsuite.attrib['errors'] = str(num_errors)\n    testsuite.attrib['failures'] = str(num_failures)\n    testsuite.attrib['name'] = 'cpplint'\n\n    if num_errors == 0 and num_failures == 0:\n      testsuite.attrib['tests'] = str(1)\n      xml.etree.ElementTree.SubElement(testsuite, 'testcase', name='passed')\n\n    else:\n      testsuite.attrib['tests'] = str(num_errors + num_failures)\n      if num_errors > 0:\n        testcase = xml.etree.ElementTree.SubElement(testsuite, 'testcase')\n        testcase.attrib['name'] = 'errors'\n        error = xml.etree.ElementTree.SubElement(testcase, 'error')\n        error.text = '\\n'.join(self._junit_errors)\n      if num_failures > 0:\n        # Group failures by file\n        failed_file_order = []\n        failures_by_file = {}\n        for failure in self._junit_failures:\n          failed_file = failure[0]\n          if failed_file not in failed_file_order:\n            failed_file_order.append(failed_file)\n            failures_by_file[failed_file] = []\n          failures_by_file[failed_file].append(failure)\n        # Create a testcase for each file\n        for failed_file in failed_file_order:\n          failures = failures_by_file[failed_file]\n          testcase = xml.etree.ElementTree.SubElement(testsuite, 'testcase')\n          testcase.attrib['name'] = failed_file\n          failure = xml.etree.ElementTree.SubElement(testcase, 'failure')\n          template = '{0}: {1} [{2}] [{3}]'\n          texts = [template.format(f[1], f[2], f[3], f[4]) for f in failures]\n          failure.text = '\\n'.join(texts)\n\n    xml_decl = '<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\\n'\n    return xml_decl + xml.etree.ElementTree.tostring(testsuite, 'utf-8').decode('utf-8')\n\n\n_cpplint_state = _CppLintState()\n\n\ndef _OutputFormat():\n  \"\"\"Gets the module's output format.\"\"\"\n  return _cpplint_state.output_format\n\n\ndef _SetOutputFormat(output_format):\n  \"\"\"Sets the module's output format.\"\"\"\n  _cpplint_state.SetOutputFormat(output_format)\n\ndef _Quiet():\n  \"\"\"Return's the module's quiet setting.\"\"\"\n  return _cpplint_state.quiet\n\ndef _SetQuiet(quiet):\n  \"\"\"Set the module's quiet status, and return previous setting.\"\"\"\n  return _cpplint_state.SetQuiet(quiet)\n\n\ndef _VerboseLevel():\n  \"\"\"Returns the module's verbosity setting.\"\"\"\n  return _cpplint_state.verbose_level\n\n\ndef _SetVerboseLevel(level):\n  \"\"\"Sets the module's verbosity, and returns the previous setting.\"\"\"\n  return _cpplint_state.SetVerboseLevel(level)\n\n\ndef _SetCountingStyle(level):\n  \"\"\"Sets the module's counting options.\"\"\"\n  _cpplint_state.SetCountingStyle(level)\n\n\ndef _Filters():\n  \"\"\"Returns the module's list of output filters, as a list.\"\"\"\n  return _cpplint_state.filters\n\n\ndef _SetFilters(filters):\n  \"\"\"Sets the module's error-message filters.\n\n  These filters are applied when deciding whether to emit a given\n  error message.\n\n  Args:\n    filters: A string of comma-separated filters (eg \"whitespace/indent\").\n             Each filter should start with + or -; else we die.\n  \"\"\"\n  _cpplint_state.SetFilters(filters)\n\ndef _AddFilters(filters):\n  \"\"\"Adds more filter overrides.\n\n  Unlike _SetFilters, this function does not reset the current list of filters\n  available.\n\n  Args:\n    filters: A string of comma-separated filters (eg \"whitespace/indent\").\n             Each filter should start with + or -; else we die.\n  \"\"\"\n  _cpplint_state.AddFilters(filters)\n\ndef _BackupFilters():\n  \"\"\" Saves the current filter list to backup storage.\"\"\"\n  _cpplint_state.BackupFilters()\n\ndef _RestoreFilters():\n  \"\"\" Restores filters previously backed up.\"\"\"\n  _cpplint_state.RestoreFilters()\n\nclass _FunctionState(object):\n  \"\"\"Tracks current function name and the number of lines in its body.\"\"\"\n\n  _NORMAL_TRIGGER = 250  # for --v=0, 500 for --v=1, etc.\n  _TEST_TRIGGER = 400    # about 50% more than _NORMAL_TRIGGER.\n\n  def __init__(self):\n    self.in_a_function = False\n    self.lines_in_function = 0\n    self.current_function = ''\n\n  def Begin(self, function_name):\n    \"\"\"Start analyzing function body.\n\n    Args:\n      function_name: The name of the function being tracked.\n    \"\"\"\n    self.in_a_function = True\n    self.lines_in_function = 0\n    self.current_function = function_name\n\n  def Count(self):\n    \"\"\"Count line in current function body.\"\"\"\n    if self.in_a_function:\n      self.lines_in_function += 1\n\n  def Check(self, error, filename, linenum):\n    \"\"\"Report if too many lines in function body.\n\n    Args:\n      error: The function to call with any errors found.\n      filename: The name of the current file.\n      linenum: The number of the line to check.\n    \"\"\"\n    if not self.in_a_function:\n      return\n\n    if Match(r'T(EST|est)', self.current_function):\n      base_trigger = self._TEST_TRIGGER\n    else:\n      base_trigger = self._NORMAL_TRIGGER\n    trigger = base_trigger * 2**_VerboseLevel()\n\n    if self.lines_in_function > trigger:\n      error_level = int(math.log(self.lines_in_function / base_trigger, 2))\n      # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...\n      if error_level > 5:\n        error_level = 5\n      error(filename, linenum, 'readability/fn_size', error_level,\n            'Small and focused functions are preferred:'\n            ' %s has %d non-comment lines'\n            ' (error triggered by exceeding %d lines).'  % (\n                self.current_function, self.lines_in_function, trigger))\n\n  def End(self):\n    \"\"\"Stop analyzing function body.\"\"\"\n    self.in_a_function = False\n\n\nclass _IncludeError(Exception):\n  \"\"\"Indicates a problem with the include order in a file.\"\"\"\n  pass\n\n\nclass FileInfo(object):\n  \"\"\"Provides utility functions for filenames.\n\n  FileInfo provides easy access to the components of a file's path\n  relative to the project root.\n  \"\"\"\n\n  def __init__(self, filename):\n    self._filename = filename\n\n  def FullName(self):\n    \"\"\"Make Windows paths like Unix.\"\"\"\n    return os.path.abspath(self._filename).replace('\\\\', '/')\n\n  def RepositoryName(self):\n    r\"\"\"FullName after removing the local path to the repository.\n\n    If we have a real absolute path name here we can try to do something smart:\n    detecting the root of the checkout and truncating /path/to/checkout from\n    the name so that we get header guards that don't include things like\n    \"C:\\\\Documents and Settings\\\\...\" or \"/home/username/...\" in them and thus\n    people on different computers who have checked the source out to different\n    locations won't see bogus errors.\n    \"\"\"\n    fullname = self.FullName()\n\n    if os.path.exists(fullname):\n      project_dir = os.path.dirname(fullname)\n\n      # If the user specified a repository path, it exists, and the file is\n      # contained in it, use the specified repository path\n      if _repository:\n        repo = FileInfo(_repository).FullName()\n        root_dir = project_dir\n        while os.path.exists(root_dir):\n          # allow case insensitive compare on Windows\n          if os.path.normcase(root_dir) == os.path.normcase(repo):\n            return os.path.relpath(fullname, root_dir).replace('\\\\', '/')\n          one_up_dir = os.path.dirname(root_dir)\n          if one_up_dir == root_dir:\n            break\n          root_dir = one_up_dir\n\n      if os.path.exists(os.path.join(project_dir, \".svn\")):\n        # If there's a .svn file in the current directory, we recursively look\n        # up the directory tree for the top of the SVN checkout\n        root_dir = project_dir\n        one_up_dir = os.path.dirname(root_dir)\n        while os.path.exists(os.path.join(one_up_dir, \".svn\")):\n          root_dir = os.path.dirname(root_dir)\n          one_up_dir = os.path.dirname(one_up_dir)\n\n        prefix = os.path.commonprefix([root_dir, project_dir])\n        return fullname[len(prefix) + 1:]\n\n      # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by\n      # searching up from the current path.\n      root_dir = current_dir = os.path.dirname(fullname)\n      while current_dir != os.path.dirname(current_dir):\n        if (os.path.exists(os.path.join(current_dir, \".git\")) or\n            os.path.exists(os.path.join(current_dir, \".hg\")) or\n            os.path.exists(os.path.join(current_dir, \".svn\"))):\n          root_dir = current_dir\n        current_dir = os.path.dirname(current_dir)\n\n      if (os.path.exists(os.path.join(root_dir, \".git\")) or\n          os.path.exists(os.path.join(root_dir, \".hg\")) or\n          os.path.exists(os.path.join(root_dir, \".svn\"))):\n        prefix = os.path.commonprefix([root_dir, project_dir])\n        return fullname[len(prefix) + 1:]\n\n    # Don't know what to do; header guard warnings may be wrong...\n    return fullname\n\n  def Split(self):\n    \"\"\"Splits the file into the directory, basename, and extension.\n\n    For 'chrome/browser/browser.cc', Split() would\n    return ('chrome/browser', 'browser', '.cc')\n\n    Returns:\n      A tuple of (directory, basename, extension).\n    \"\"\"\n\n    googlename = self.RepositoryName()\n    project, rest = os.path.split(googlename)\n    return (project,) + os.path.splitext(rest)\n\n  def BaseName(self):\n    \"\"\"File base name - text after the final slash, before the final period.\"\"\"\n    return self.Split()[1]\n\n  def Extension(self):\n    \"\"\"File extension - text following the final period, includes that period.\"\"\"\n    return self.Split()[2]\n\n  def NoExtension(self):\n    \"\"\"File has no source file extension.\"\"\"\n    return '/'.join(self.Split()[0:2])\n\n  def IsSource(self):\n    \"\"\"File has a source file extension.\"\"\"\n    return _IsSourceExtension(self.Extension()[1:])\n\n\ndef _ShouldPrintError(category, confidence, linenum):\n  \"\"\"If confidence >= verbose, category passes filter and is not suppressed.\"\"\"\n\n  # There are three ways we might decide not to print an error message:\n  # a \"NOLINT(category)\" comment appears in the source,\n  # the verbosity level isn't high enough, or the filters filter it out.\n  if IsErrorSuppressedByNolint(category, linenum):\n    return False\n\n  if confidence < _cpplint_state.verbose_level:\n    return False\n\n  is_filtered = False\n  for one_filter in _Filters():\n    if one_filter.startswith('-'):\n      if category.startswith(one_filter[1:]):\n        is_filtered = True\n    elif one_filter.startswith('+'):\n      if category.startswith(one_filter[1:]):\n        is_filtered = False\n    else:\n      assert False  # should have been checked for in SetFilter.\n  if is_filtered:\n    return False\n\n  return True\n\n\ndef Error(filename, linenum, category, confidence, message):\n  \"\"\"Logs the fact we've found a lint error.\n\n  We log where the error was found, and also our confidence in the error,\n  that is, how certain we are this is a legitimate style regression, and\n  not a misidentification or a use that's sometimes justified.\n\n  False positives can be suppressed by the use of\n  \"cpplint(category)\"  comments on the offending line.  These are\n  parsed into _error_suppressions.\n\n  Args:\n    filename: The name of the file containing the error.\n    linenum: The number of the line containing the error.\n    category: A string used to describe the \"category\" this bug\n      falls under: \"whitespace\", say, or \"runtime\".  Categories\n      may have a hierarchy separated by slashes: \"whitespace/indent\".\n    confidence: A number from 1-5 representing a confidence score for\n      the error, with 5 meaning that we are certain of the problem,\n      and 1 meaning that it could be a legitimate construct.\n    message: The error message.\n  \"\"\"\n  if _ShouldPrintError(category, confidence, linenum):\n    _cpplint_state.IncrementErrorCount(category)\n    if _cpplint_state.output_format == 'vs7':\n      _cpplint_state.PrintError('%s(%s): error cpplint: [%s] %s [%d]\\n' % (\n          filename, linenum, category, message, confidence))\n    elif _cpplint_state.output_format == 'eclipse':\n      sys.stderr.write('%s:%s: warning: %s  [%s] [%d]\\n' % (\n          filename, linenum, message, category, confidence))\n    elif _cpplint_state.output_format == 'junit':\n      _cpplint_state.AddJUnitFailure(filename, linenum, message, category,\n          confidence)\n    elif _cpplint_state.output_format in ['sed', 'gsed']:\n      if message in _SED_FIXUPS:\n        sys.stdout.write(_cpplint_state.output_format + \" -i '%s%s' %s # %s  [%s] [%d]\\n\" % (\n            linenum, _SED_FIXUPS[message], filename, message, category, confidence))\n      else:\n        sys.stderr.write('# %s:%s:  \"%s\"  [%s] [%d]\\n' % (\n            filename, linenum, message, category, confidence))\n    else:\n      final_message = '%s:%s:  %s  [%s] [%d]\\n' % (\n          filename, linenum, message, category, confidence)\n      sys.stderr.write(final_message)\n\n# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard.\n_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(\n    r'\\\\([abfnrtv?\"\\\\\\']|\\d+|x[0-9a-fA-F]+)')\n# Match a single C style comment on the same line.\n_RE_PATTERN_C_COMMENTS = r'/\\*(?:[^*]|\\*(?!/))*\\*/'\n# Matches multi-line C style comments.\n# This RE is a little bit more complicated than one might expect, because we\n# have to take care of space removals tools so we can handle comments inside\n# statements better.\n# The current rule is: We only clear spaces from both sides when we're at the\n# end of the line. Otherwise, we try to remove spaces from the right side,\n# if this doesn't work we try on left side but only if there's a non-character\n# on the right.\n_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(\n    r'(\\s*' + _RE_PATTERN_C_COMMENTS + r'\\s*$|' +\n    _RE_PATTERN_C_COMMENTS + r'\\s+|' +\n    r'\\s+' + _RE_PATTERN_C_COMMENTS + r'(?=\\W)|' +\n    _RE_PATTERN_C_COMMENTS + r')')\n\n\ndef IsCppString(line):\n  \"\"\"Does line terminate so, that the next symbol is in string constant.\n\n  This function does not consider single-line nor multi-line comments.\n\n  Args:\n    line: is a partial line of code starting from the 0..n.\n\n  Returns:\n    True, if next character appended to 'line' is inside a\n    string constant.\n  \"\"\"\n\n  line = line.replace(r'\\\\', 'XX')  # after this, \\\\\" does not match to \\\"\n  return ((line.count('\"') - line.count(r'\\\"') - line.count(\"'\\\"'\")) & 1) == 1\n\n\ndef CleanseRawStrings(raw_lines):\n  \"\"\"Removes C++11 raw strings from lines.\n\n    Before:\n      static const char kData[] = R\"(\n          multi-line string\n          )\";\n\n    After:\n      static const char kData[] = \"\"\n          (replaced by blank line)\n          \"\";\n\n  Args:\n    raw_lines: list of raw lines.\n\n  Returns:\n    list of lines with C++11 raw strings replaced by empty strings.\n  \"\"\"\n\n  delimiter = None\n  lines_without_raw_strings = []\n  for line in raw_lines:\n    if delimiter:\n      # Inside a raw string, look for the end\n      end = line.find(delimiter)\n      if end >= 0:\n        # Found the end of the string, match leading space for this\n        # line and resume copying the original lines, and also insert\n        # a \"\" on the last line.\n        leading_space = Match(r'^(\\s*)\\S', line)\n        line = leading_space.group(1) + '\"\"' + line[end + len(delimiter):]\n        delimiter = None\n      else:\n        # Haven't found the end yet, append a blank line.\n        line = '\"\"'\n\n    # Look for beginning of a raw string, and replace them with\n    # empty strings.  This is done in a loop to handle multiple raw\n    # strings on the same line.\n    while delimiter is None:\n      # Look for beginning of a raw string.\n      # See 2.14.15 [lex.string] for syntax.\n      #\n      # Once we have matched a raw string, we check the prefix of the\n      # line to make sure that the line is not part of a single line\n      # comment.  It's done this way because we remove raw strings\n      # before removing comments as opposed to removing comments\n      # before removing raw strings.  This is because there are some\n      # cpplint checks that requires the comments to be preserved, but\n      # we don't want to check comments that are inside raw strings.\n      matched = Match(r'^(.*?)\\b(?:R|u8R|uR|UR|LR)\"([^\\s\\\\()]*)\\((.*)$', line)\n      if (matched and\n          not Match(r'^([^\\'\"]|\\'(\\\\.|[^\\'])*\\'|\"(\\\\.|[^\"])*\")*//',\n                    matched.group(1))):\n        delimiter = ')' + matched.group(2) + '\"'\n\n        end = matched.group(3).find(delimiter)\n        if end >= 0:\n          # Raw string ended on same line\n          line = (matched.group(1) + '\"\"' +\n                  matched.group(3)[end + len(delimiter):])\n          delimiter = None\n        else:\n          # Start of a multi-line raw string\n          line = matched.group(1) + '\"\"'\n      else:\n        break\n\n    lines_without_raw_strings.append(line)\n\n  # TODO(unknown): if delimiter is not None here, we might want to\n  # emit a warning for unterminated string.\n  return lines_without_raw_strings\n\n\ndef FindNextMultiLineCommentStart(lines, lineix):\n  \"\"\"Find the beginning marker for a multiline comment.\"\"\"\n  while lineix < len(lines):\n    if lines[lineix].strip().startswith('/*'):\n      # Only return this marker if the comment goes beyond this line\n      if lines[lineix].strip().find('*/', 2) < 0:\n        return lineix\n    lineix += 1\n  return len(lines)\n\n\ndef FindNextMultiLineCommentEnd(lines, lineix):\n  \"\"\"We are inside a comment, find the end marker.\"\"\"\n  while lineix < len(lines):\n    if lines[lineix].strip().endswith('*/'):\n      return lineix\n    lineix += 1\n  return len(lines)\n\n\ndef RemoveMultiLineCommentsFromRange(lines, begin, end):\n  \"\"\"Clears a range of lines for multi-line comments.\"\"\"\n  # Having // <empty> comments makes the lines non-empty, so we will not get\n  # unnecessary blank line warnings later in the code.\n  for i in range(begin, end):\n    lines[i] = '/**/'\n\n\ndef RemoveMultiLineComments(filename, lines, error):\n  \"\"\"Removes multiline (c-style) comments from lines.\"\"\"\n  lineix = 0\n  while lineix < len(lines):\n    lineix_begin = FindNextMultiLineCommentStart(lines, lineix)\n    if lineix_begin >= len(lines):\n      return\n    lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)\n    if lineix_end >= len(lines):\n      error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,\n            'Could not find end of multi-line comment')\n      return\n    RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)\n    lineix = lineix_end + 1\n\n\ndef CleanseComments(line):\n  \"\"\"Removes //-comments and single-line C-style /* */ comments.\n\n  Args:\n    line: A line of C++ source.\n\n  Returns:\n    The line with single-line comments removed.\n  \"\"\"\n  commentpos = line.find('//')\n  if commentpos != -1 and not IsCppString(line[:commentpos]):\n    line = line[:commentpos].rstrip()\n  # get rid of /* ... */\n  return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)\n\n\nclass CleansedLines(object):\n  \"\"\"Holds 4 copies of all lines with different preprocessing applied to them.\n\n  1) elided member contains lines without strings and comments.\n  2) lines member contains lines without comments.\n  3) raw_lines member contains all the lines without processing.\n  4) lines_without_raw_strings member is same as raw_lines, but with C++11 raw\n     strings removed.\n  All these members are of <type 'list'>, and of the same length.\n  \"\"\"\n\n  def __init__(self, lines):\n    self.elided = []\n    self.lines = []\n    self.raw_lines = lines\n    self.num_lines = len(lines)\n    self.lines_without_raw_strings = CleanseRawStrings(lines)\n    for linenum in range(len(self.lines_without_raw_strings)):\n      self.lines.append(CleanseComments(\n          self.lines_without_raw_strings[linenum]))\n      elided = self._CollapseStrings(self.lines_without_raw_strings[linenum])\n      self.elided.append(CleanseComments(elided))\n\n  def NumLines(self):\n    \"\"\"Returns the number of lines represented.\"\"\"\n    return self.num_lines\n\n  @staticmethod\n  def _CollapseStrings(elided):\n    \"\"\"Collapses strings and chars on a line to simple \"\" or '' blocks.\n\n    We nix strings first so we're not fooled by text like '\"http://\"'\n\n    Args:\n      elided: The line being processed.\n\n    Returns:\n      The line with collapsed strings.\n    \"\"\"\n    if _RE_PATTERN_INCLUDE.match(elided):\n      return elided\n\n    # Remove escaped characters first to make quote/single quote collapsing\n    # basic.  Things that look like escaped characters shouldn't occur\n    # outside of strings and chars.\n    elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)\n\n    # Replace quoted strings and digit separators.  Both single quotes\n    # and double quotes are processed in the same loop, otherwise\n    # nested quotes wouldn't work.\n    collapsed = ''\n    while True:\n      # Find the first quote character\n      match = Match(r'^([^\\'\"]*)([\\'\"])(.*)$', elided)\n      if not match:\n        collapsed += elided\n        break\n      head, quote, tail = match.groups()\n\n      if quote == '\"':\n        # Collapse double quoted strings\n        second_quote = tail.find('\"')\n        if second_quote >= 0:\n          collapsed += head + '\"\"'\n          elided = tail[second_quote + 1:]\n        else:\n          # Unmatched double quote, don't bother processing the rest\n          # of the line since this is probably a multiline string.\n          collapsed += elided\n          break\n      else:\n        # Found single quote, check nearby text to eliminate digit separators.\n        #\n        # There is no special handling for floating point here, because\n        # the integer/fractional/exponent parts would all be parsed\n        # correctly as long as there are digits on both sides of the\n        # separator.  So we are fine as long as we don't see something\n        # like \"0.'3\" (gcc 4.9.0 will not allow this literal).\n        if Search(r'\\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$', head):\n          match_literal = Match(r'^((?:\\'?[0-9a-zA-Z_])*)(.*)$', \"'\" + tail)\n          collapsed += head + match_literal.group(1).replace(\"'\", '')\n          elided = match_literal.group(2)\n        else:\n          second_quote = tail.find('\\'')\n          if second_quote >= 0:\n            collapsed += head + \"''\"\n            elided = tail[second_quote + 1:]\n          else:\n            # Unmatched single quote\n            collapsed += elided\n            break\n\n    return collapsed\n\n\ndef FindEndOfExpressionInLine(line, startpos, stack):\n  \"\"\"Find the position just after the end of current parenthesized expression.\n\n  Args:\n    line: a CleansedLines line.\n    startpos: start searching at this position.\n    stack: nesting stack at startpos.\n\n  Returns:\n    On finding matching end: (index just after matching end, None)\n    On finding an unclosed expression: (-1, None)\n    Otherwise: (-1, new stack at end of this line)\n  \"\"\"\n  for i in xrange(startpos, len(line)):\n    char = line[i]\n    if char in '([{':\n      # Found start of parenthesized expression, push to expression stack\n      stack.append(char)\n    elif char == '<':\n      # Found potential start of template argument list\n      if i > 0 and line[i - 1] == '<':\n        # Left shift operator\n        if stack and stack[-1] == '<':\n          stack.pop()\n          if not stack:\n            return (-1, None)\n      elif i > 0 and Search(r'\\boperator\\s*$', line[0:i]):\n        # operator<, don't add to stack\n        continue\n      else:\n        # Tentative start of template argument list\n        stack.append('<')\n    elif char in ')]}':\n      # Found end of parenthesized expression.\n      #\n      # If we are currently expecting a matching '>', the pending '<'\n      # must have been an operator.  Remove them from expression stack.\n      while stack and stack[-1] == '<':\n        stack.pop()\n      if not stack:\n        return (-1, None)\n      if ((stack[-1] == '(' and char == ')') or\n          (stack[-1] == '[' and char == ']') or\n          (stack[-1] == '{' and char == '}')):\n        stack.pop()\n        if not stack:\n          return (i + 1, None)\n      else:\n        # Mismatched parentheses\n        return (-1, None)\n    elif char == '>':\n      # Found potential end of template argument list.\n\n      # Ignore \"->\" and operator functions\n      if (i > 0 and\n          (line[i - 1] == '-' or Search(r'\\boperator\\s*$', line[0:i - 1]))):\n        continue\n\n      # Pop the stack if there is a matching '<'.  Otherwise, ignore\n      # this '>' since it must be an operator.\n      if stack:\n        if stack[-1] == '<':\n          stack.pop()\n          if not stack:\n            return (i + 1, None)\n    elif char == ';':\n      # Found something that look like end of statements.  If we are currently\n      # expecting a '>', the matching '<' must have been an operator, since\n      # template argument list should not contain statements.\n      while stack and stack[-1] == '<':\n        stack.pop()\n      if not stack:\n        return (-1, None)\n\n  # Did not find end of expression or unbalanced parentheses on this line\n  return (-1, stack)\n\n\ndef CloseExpression(clean_lines, linenum, pos):\n  \"\"\"If input points to ( or { or [ or <, finds the position that closes it.\n\n  If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the\n  linenum/pos that correspond to the closing of the expression.\n\n  TODO(unknown): cpplint spends a fair bit of time matching parentheses.\n  Ideally we would want to index all opening and closing parentheses once\n  and have CloseExpression be just a simple lookup, but due to preprocessor\n  tricks, this is not so easy.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    pos: A position on the line.\n\n  Returns:\n    A tuple (line, linenum, pos) pointer *past* the closing brace, or\n    (line, len(lines), -1) if we never find a close.  Note we ignore\n    strings and comments when matching; and the line we return is the\n    'cleansed' line at linenum.\n  \"\"\"\n\n  line = clean_lines.elided[linenum]\n  if (line[pos] not in '({[<') or Match(r'<[<=]', line[pos:]):\n    return (line, clean_lines.NumLines(), -1)\n\n  # Check first line\n  (end_pos, stack) = FindEndOfExpressionInLine(line, pos, [])\n  if end_pos > -1:\n    return (line, linenum, end_pos)\n\n  # Continue scanning forward\n  while stack and linenum < clean_lines.NumLines() - 1:\n    linenum += 1\n    line = clean_lines.elided[linenum]\n    (end_pos, stack) = FindEndOfExpressionInLine(line, 0, stack)\n    if end_pos > -1:\n      return (line, linenum, end_pos)\n\n  # Did not find end of expression before end of file, give up\n  return (line, clean_lines.NumLines(), -1)\n\n\ndef FindStartOfExpressionInLine(line, endpos, stack):\n  \"\"\"Find position at the matching start of current expression.\n\n  This is almost the reverse of FindEndOfExpressionInLine, but note\n  that the input position and returned position differs by 1.\n\n  Args:\n    line: a CleansedLines line.\n    endpos: start searching at this position.\n    stack: nesting stack at endpos.\n\n  Returns:\n    On finding matching start: (index at matching start, None)\n    On finding an unclosed expression: (-1, None)\n    Otherwise: (-1, new stack at beginning of this line)\n  \"\"\"\n  i = endpos\n  while i >= 0:\n    char = line[i]\n    if char in ')]}':\n      # Found end of expression, push to expression stack\n      stack.append(char)\n    elif char == '>':\n      # Found potential end of template argument list.\n      #\n      # Ignore it if it's a \"->\" or \">=\" or \"operator>\"\n      if (i > 0 and\n          (line[i - 1] == '-' or\n           Match(r'\\s>=\\s', line[i - 1:]) or\n           Search(r'\\boperator\\s*$', line[0:i]))):\n        i -= 1\n      else:\n        stack.append('>')\n    elif char == '<':\n      # Found potential start of template argument list\n      if i > 0 and line[i - 1] == '<':\n        # Left shift operator\n        i -= 1\n      else:\n        # If there is a matching '>', we can pop the expression stack.\n        # Otherwise, ignore this '<' since it must be an operator.\n        if stack and stack[-1] == '>':\n          stack.pop()\n          if not stack:\n            return (i, None)\n    elif char in '([{':\n      # Found start of expression.\n      #\n      # If there are any unmatched '>' on the stack, they must be\n      # operators.  Remove those.\n      while stack and stack[-1] == '>':\n        stack.pop()\n      if not stack:\n        return (-1, None)\n      if ((char == '(' and stack[-1] == ')') or\n          (char == '[' and stack[-1] == ']') or\n          (char == '{' and stack[-1] == '}')):\n        stack.pop()\n        if not stack:\n          return (i, None)\n      else:\n        # Mismatched parentheses\n        return (-1, None)\n    elif char == ';':\n      # Found something that look like end of statements.  If we are currently\n      # expecting a '<', the matching '>' must have been an operator, since\n      # template argument list should not contain statements.\n      while stack and stack[-1] == '>':\n        stack.pop()\n      if not stack:\n        return (-1, None)\n\n    i -= 1\n\n  return (-1, stack)\n\n\ndef ReverseCloseExpression(clean_lines, linenum, pos):\n  \"\"\"If input points to ) or } or ] or >, finds the position that opens it.\n\n  If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the\n  linenum/pos that correspond to the opening of the expression.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    pos: A position on the line.\n\n  Returns:\n    A tuple (line, linenum, pos) pointer *at* the opening brace, or\n    (line, 0, -1) if we never find the matching opening brace.  Note\n    we ignore strings and comments when matching; and the line we\n    return is the 'cleansed' line at linenum.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  if line[pos] not in ')}]>':\n    return (line, 0, -1)\n\n  # Check last line\n  (start_pos, stack) = FindStartOfExpressionInLine(line, pos, [])\n  if start_pos > -1:\n    return (line, linenum, start_pos)\n\n  # Continue scanning backward\n  while stack and linenum > 0:\n    linenum -= 1\n    line = clean_lines.elided[linenum]\n    (start_pos, stack) = FindStartOfExpressionInLine(line, len(line) - 1, stack)\n    if start_pos > -1:\n      return (line, linenum, start_pos)\n\n  # Did not find start of expression before beginning of file, give up\n  return (line, 0, -1)\n\n\ndef CheckForCopyright(filename, lines, error):\n  \"\"\"Logs an error if no Copyright message appears at the top of the file.\"\"\"\n\n  # We'll say it should occur by line 10. Don't forget there's a\n  # placeholder line at the front.\n  for line in xrange(1, min(len(lines), 11)):\n    if re.search(r'Copyright', lines[line], re.I): break\n  else:                       # means no copyright line was found\n    error(filename, 0, 'legal/copyright', 5,\n          'No copyright message found.  '\n          'You should have a line: \"Copyright [year] <Copyright Owner>\"')\n\n\ndef GetIndentLevel(line):\n  \"\"\"Return the number of leading spaces in line.\n\n  Args:\n    line: A string to check.\n\n  Returns:\n    An integer count of leading spaces, possibly zero.\n  \"\"\"\n  indent = Match(r'^( *)\\S', line)\n  if indent:\n    return len(indent.group(1))\n  else:\n    return 0\n\ndef PathSplitToList(path):\n  \"\"\"Returns the path split into a list by the separator.\n\n  Args:\n    path: An absolute or relative path (e.g. '/a/b/c/' or '../a')\n\n  Returns:\n    A list of path components (e.g. ['a', 'b', 'c]).\n  \"\"\"\n  lst = []\n  while True:\n    (head, tail) = os.path.split(path)\n    if head == path:  # absolute paths end\n      lst.append(head)\n      break\n    if tail == path:  # relative paths end\n      lst.append(tail)\n      break\n\n    path = head\n    lst.append(tail)\n\n  lst.reverse()\n  return lst\n\ndef GetHeaderGuardCPPVariable(filename):\n  \"\"\"Returns the CPP variable that should be used as a header guard.\n\n  Args:\n    filename: The name of a C++ header file.\n\n  Returns:\n    The CPP variable that should be used as a header guard in the\n    named file.\n\n  \"\"\"\n\n  # Restores original filename in case that cpplint is invoked from Emacs's\n  # flymake.\n  filename = re.sub(r'_flymake\\.h$', '.h', filename)\n  filename = re.sub(r'/\\.flymake/([^/]*)$', r'/\\1', filename)\n  # Replace 'c++' with 'cpp'.\n  filename = filename.replace('C++', 'cpp').replace('c++', 'cpp')\n\n  fileinfo = FileInfo(filename)\n  file_path_from_root = fileinfo.RepositoryName()\n\n  def FixupPathFromRoot():\n    if _root_debug:\n      sys.stderr.write(\"\\n_root fixup, _root = '%s', repository name = '%s'\\n\"\n          % (_root, fileinfo.RepositoryName()))\n\n    # Process the file path with the --root flag if it was set.\n    if not _root:\n      if _root_debug:\n        sys.stderr.write(\"_root unspecified\\n\")\n      return file_path_from_root\n\n    def StripListPrefix(lst, prefix):\n      # f(['x', 'y'], ['w, z']) -> None  (not a valid prefix)\n      if lst[:len(prefix)] != prefix:\n        return None\n      # f(['a, 'b', 'c', 'd'], ['a', 'b']) -> ['c', 'd']\n      return lst[(len(prefix)):]\n\n    # root behavior:\n    #   --root=subdir , lstrips subdir from the header guard\n    maybe_path = StripListPrefix(PathSplitToList(file_path_from_root),\n                                 PathSplitToList(_root))\n\n    if _root_debug:\n      sys.stderr.write((\"_root lstrip (maybe_path=%s, file_path_from_root=%s,\" +\n          \" _root=%s)\\n\") % (maybe_path, file_path_from_root, _root))\n\n    if maybe_path:\n      return os.path.join(*maybe_path)\n\n    #   --root=.. , will prepend the outer directory to the header guard\n    full_path = fileinfo.FullName()\n    # adapt slashes for windows\n    root_abspath = os.path.abspath(_root).replace('\\\\', '/')\n\n    maybe_path = StripListPrefix(PathSplitToList(full_path),\n                                 PathSplitToList(root_abspath))\n\n    if _root_debug:\n      sys.stderr.write((\"_root prepend (maybe_path=%s, full_path=%s, \" +\n          \"root_abspath=%s)\\n\") % (maybe_path, full_path, root_abspath))\n\n    if maybe_path:\n      return os.path.join(*maybe_path)\n\n    if _root_debug:\n      sys.stderr.write(\"_root ignore, returning %s\\n\" % (file_path_from_root))\n\n    #   --root=FAKE_DIR is ignored\n    return file_path_from_root\n\n  file_path_from_root = FixupPathFromRoot()\n  return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_'\n\n\ndef CheckForHeaderGuard(filename, clean_lines, error):\n  \"\"\"Checks that the file contains a header guard.\n\n  Logs an error if no #ifndef header guard is present.  For other\n  headers, checks that the full pathname is used.\n\n  Args:\n    filename: The name of the C++ header file.\n    clean_lines: A CleansedLines instance containing the file.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Don't check for header guards if there are error suppression\n  # comments somewhere in this file.\n  #\n  # Because this is silencing a warning for a nonexistent line, we\n  # only support the very specific NOLINT(build/header_guard) syntax,\n  # and not the general NOLINT or NOLINT(*) syntax.\n  raw_lines = clean_lines.lines_without_raw_strings\n  for i in raw_lines:\n    if Search(r'//\\s*NOLINT\\(build/header_guard\\)', i):\n      return\n\n  # Allow pragma once instead of header guards\n  for i in raw_lines:\n    if Search(r'^\\s*#pragma\\s+once', i):\n      return\n\n  cppvar = GetHeaderGuardCPPVariable(filename)\n\n  ifndef = ''\n  ifndef_linenum = 0\n  define = ''\n  endif = ''\n  endif_linenum = 0\n  for linenum, line in enumerate(raw_lines):\n    linesplit = line.split()\n    if len(linesplit) >= 2:\n      # find the first occurrence of #ifndef and #define, save arg\n      if not ifndef and linesplit[0] == '#ifndef':\n        # set ifndef to the header guard presented on the #ifndef line.\n        ifndef = linesplit[1]\n        ifndef_linenum = linenum\n      if not define and linesplit[0] == '#define':\n        define = linesplit[1]\n    # find the last occurrence of #endif, save entire line\n    if line.startswith('#endif'):\n      endif = line\n      endif_linenum = linenum\n\n  if not ifndef or not define or ifndef != define:\n    error(filename, 0, 'build/header_guard', 5,\n          'No #ifndef header guard found, suggested CPP variable is: %s' %\n          cppvar)\n    return\n\n  # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__\n  # for backward compatibility.\n  if ifndef != cppvar:\n    error_level = 0\n    if ifndef != cppvar + '_':\n      error_level = 5\n\n    ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum,\n                            error)\n    error(filename, ifndef_linenum, 'build/header_guard', error_level,\n          '#ifndef header guard has wrong style, please use: %s' % cppvar)\n\n  # Check for \"//\" comments on endif line.\n  ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum,\n                          error)\n  match = Match(r'#endif\\s*//\\s*' + cppvar + r'(_)?\\b', endif)\n  if match:\n    if match.group(1) == '_':\n      # Issue low severity warning for deprecated double trailing underscore\n      error(filename, endif_linenum, 'build/header_guard', 0,\n            '#endif line should be \"#endif  // %s\"' % cppvar)\n    return\n\n  # Didn't find the corresponding \"//\" comment.  If this file does not\n  # contain any \"//\" comments at all, it could be that the compiler\n  # only wants \"/**/\" comments, look for those instead.\n  no_single_line_comments = True\n  for i in xrange(1, len(raw_lines) - 1):\n    line = raw_lines[i]\n    if Match(r'^(?:(?:\\'(?:\\.|[^\\'])*\\')|(?:\"(?:\\.|[^\"])*\")|[^\\'\"])*//', line):\n      no_single_line_comments = False\n      break\n\n  if no_single_line_comments:\n    match = Match(r'#endif\\s*/\\*\\s*' + cppvar + r'(_)?\\s*\\*/', endif)\n    if match:\n      if match.group(1) == '_':\n        # Low severity warning for double trailing underscore\n        error(filename, endif_linenum, 'build/header_guard', 0,\n              '#endif line should be \"#endif  /* %s */\"' % cppvar)\n      return\n\n  # Didn't find anything\n  error(filename, endif_linenum, 'build/header_guard', 5,\n        '#endif line should be \"#endif  // %s\"' % cppvar)\n\n\ndef CheckHeaderFileIncluded(filename, include_state, error):\n  \"\"\"Logs an error if a source file does not include its header.\"\"\"\n\n  # Do not check test files\n  fileinfo = FileInfo(filename)\n  if Search(_TEST_FILE_SUFFIX, fileinfo.BaseName()):\n    return\n\n  for ext in GetHeaderExtensions():\n    basefilename = filename[0:len(filename) - len(fileinfo.Extension())]\n    headerfile = basefilename + '.' + ext\n    if not os.path.exists(headerfile):\n      continue\n    headername = FileInfo(headerfile).RepositoryName()\n    first_include = None\n    include_uses_unix_dir_aliases = False\n    for section_list in include_state.include_list:\n      for f in section_list:\n        include_text = f[0]\n        if \"./\" in include_text:\n          include_uses_unix_dir_aliases = True\n        if headername in include_text or include_text in headername:\n          return\n        if not first_include:\n          first_include = f[1]\n\n    message = '%s should include its header file %s' % (fileinfo.RepositoryName(), headername)\n    if include_uses_unix_dir_aliases:\n      message += \". Relative paths like . and .. are not allowed.\"\n\n    error(filename, first_include, 'build/include', 5, message)\n\n\ndef CheckForBadCharacters(filename, lines, error):\n  \"\"\"Logs an error for each line containing bad characters.\n\n  Two kinds of bad characters:\n\n  1. Unicode replacement characters: These indicate that either the file\n  contained invalid UTF-8 (likely) or Unicode replacement characters (which\n  it shouldn't).  Note that it's possible for this to throw off line\n  numbering if the invalid UTF-8 occurred adjacent to a newline.\n\n  2. NUL bytes.  These are problematic for some tools.\n\n  Args:\n    filename: The name of the current file.\n    lines: An array of strings, each representing a line of the file.\n    error: The function to call with any errors found.\n  \"\"\"\n  for linenum, line in enumerate(lines):\n    if unicode_escape_decode('\\ufffd') in line:\n      error(filename, linenum, 'readability/utf8', 5,\n            'Line contains invalid UTF-8 (or Unicode replacement character).')\n    if '\\0' in line:\n      error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.')\n\n\ndef CheckForNewlineAtEOF(filename, lines, error):\n  \"\"\"Logs an error if there is no newline char at the end of the file.\n\n  Args:\n    filename: The name of the current file.\n    lines: An array of strings, each representing a line of the file.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # The array lines() was created by adding two newlines to the\n  # original file (go figure), then splitting on \\n.\n  # To verify that the file ends in \\n, we just have to make sure the\n  # last-but-two element of lines() exists and is empty.\n  if len(lines) < 3 or lines[-2]:\n    error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,\n          'Could not find a newline character at the end of the file.')\n\n\ndef CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):\n  \"\"\"Logs an error if we see /* ... */ or \"...\" that extend past one line.\n\n  /* ... */ comments are legit inside macros, for one line.\n  Otherwise, we prefer // comments, so it's ok to warn about the\n  other.  Likewise, it's ok for strings to extend across multiple\n  lines, as long as a line continuation character (backslash)\n  terminates each line. Although not currently prohibited by the C++\n  style guide, it's ugly and unnecessary. We don't do well with either\n  in this lint program, so we warn about both.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Remove all \\\\ (escaped backslashes) from the line. They are OK, and the\n  # second (escaped) slash may trigger later \\\" detection erroneously.\n  line = line.replace('\\\\\\\\', '')\n\n  if line.count('/*') > line.count('*/'):\n    error(filename, linenum, 'readability/multiline_comment', 5,\n          'Complex multi-line /*...*/-style comment found. '\n          'Lint may give bogus warnings.  '\n          'Consider replacing these with //-style comments, '\n          'with #if 0...#endif, '\n          'or with more clearly structured multi-line comments.')\n\n  if (line.count('\"') - line.count('\\\\\"')) % 2:\n    error(filename, linenum, 'readability/multiline_string', 5,\n          'Multi-line string (\"...\") found.  This lint script doesn\\'t '\n          'do well with such strings, and may give bogus warnings.  '\n          'Use C++11 raw strings or concatenation instead.')\n\n\n# (non-threadsafe name, thread-safe alternative, validation pattern)\n#\n# The validation pattern is used to eliminate false positives such as:\n#  _rand();               // false positive due to substring match.\n#  ->rand();              // some member function rand().\n#  ACMRandom rand(seed);  // some variable named rand.\n#  ISAACRandom rand();    // another variable named rand.\n#\n# Basically we require the return value of these functions to be used\n# in some expression context on the same line by matching on some\n# operator before the function name.  This eliminates constructors and\n# member function calls.\n_UNSAFE_FUNC_PREFIX = r'(?:[-+*/=%^&|(<]\\s*|>\\s+)'\n_THREADING_LIST = (\n    ('asctime(', 'asctime_r(', _UNSAFE_FUNC_PREFIX + r'asctime\\([^)]+\\)'),\n    ('ctime(', 'ctime_r(', _UNSAFE_FUNC_PREFIX + r'ctime\\([^)]+\\)'),\n    ('getgrgid(', 'getgrgid_r(', _UNSAFE_FUNC_PREFIX + r'getgrgid\\([^)]+\\)'),\n    ('getgrnam(', 'getgrnam_r(', _UNSAFE_FUNC_PREFIX + r'getgrnam\\([^)]+\\)'),\n    ('getlogin(', 'getlogin_r(', _UNSAFE_FUNC_PREFIX + r'getlogin\\(\\)'),\n    ('getpwnam(', 'getpwnam_r(', _UNSAFE_FUNC_PREFIX + r'getpwnam\\([^)]+\\)'),\n    ('getpwuid(', 'getpwuid_r(', _UNSAFE_FUNC_PREFIX + r'getpwuid\\([^)]+\\)'),\n    ('gmtime(', 'gmtime_r(', _UNSAFE_FUNC_PREFIX + r'gmtime\\([^)]+\\)'),\n    ('localtime(', 'localtime_r(', _UNSAFE_FUNC_PREFIX + r'localtime\\([^)]+\\)'),\n    ('rand(', 'rand_r(', _UNSAFE_FUNC_PREFIX + r'rand\\(\\)'),\n    ('strtok(', 'strtok_r(',\n     _UNSAFE_FUNC_PREFIX + r'strtok\\([^)]+\\)'),\n    ('ttyname(', 'ttyname_r(', _UNSAFE_FUNC_PREFIX + r'ttyname\\([^)]+\\)'),\n    )\n\n\ndef CheckPosixThreading(filename, clean_lines, linenum, error):\n  \"\"\"Checks for calls to thread-unsafe functions.\n\n  Much code has been originally written without consideration of\n  multi-threading. Also, engineers are relying on their old experience;\n  they have learned posix before threading extensions were added. These\n  tests guide the engineers to use thread-safe functions (when using\n  posix directly).\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  for single_thread_func, multithread_safe_func, pattern in _THREADING_LIST:\n    # Additional pattern matching check to confirm that this is the\n    # function we are looking for\n    if Search(pattern, line):\n      error(filename, linenum, 'runtime/threadsafe_fn', 2,\n            'Consider using ' + multithread_safe_func +\n            '...) instead of ' + single_thread_func +\n            '...) for improved thread safety.')\n\n\ndef CheckVlogArguments(filename, clean_lines, linenum, error):\n  \"\"\"Checks that VLOG() is only used for defining a logging level.\n\n  For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and\n  VLOG(FATAL) are not.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  if Search(r'\\bVLOG\\((INFO|ERROR|WARNING|DFATAL|FATAL)\\)', line):\n    error(filename, linenum, 'runtime/vlog', 5,\n          'VLOG() should be used with numeric verbosity level.  '\n          'Use LOG() if you want symbolic severity levels.')\n\n# Matches invalid increment: *count++, which moves pointer instead of\n# incrementing a value.\n_RE_PATTERN_INVALID_INCREMENT = re.compile(\n    r'^\\s*\\*\\w+(\\+\\+|--);')\n\n\ndef CheckInvalidIncrement(filename, clean_lines, linenum, error):\n  \"\"\"Checks for invalid increment *count++.\n\n  For example following function:\n  void increment_counter(int* count) {\n    *count++;\n  }\n  is invalid, because it effectively does count++, moving pointer, and should\n  be replaced with ++*count, (*count)++ or *count += 1.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  if _RE_PATTERN_INVALID_INCREMENT.match(line):\n    error(filename, linenum, 'runtime/invalid_increment', 5,\n          'Changing pointer instead of value (or unused value of operator*).')\n\n\ndef IsMacroDefinition(clean_lines, linenum):\n  if Search(r'^#define', clean_lines[linenum]):\n    return True\n\n  if linenum > 0 and Search(r'\\\\$', clean_lines[linenum - 1]):\n    return True\n\n  return False\n\n\ndef IsForwardClassDeclaration(clean_lines, linenum):\n  return Match(r'^\\s*(\\btemplate\\b)*.*class\\s+\\w+;\\s*$', clean_lines[linenum])\n\n\nclass _BlockInfo(object):\n  \"\"\"Stores information about a generic block of code.\"\"\"\n\n  def __init__(self, linenum, seen_open_brace):\n    self.starting_linenum = linenum\n    self.seen_open_brace = seen_open_brace\n    self.open_parentheses = 0\n    self.inline_asm = _NO_ASM\n    self.check_namespace_indentation = False\n\n  def CheckBegin(self, filename, clean_lines, linenum, error):\n    \"\"\"Run checks that applies to text up to the opening brace.\n\n    This is mostly for checking the text after the class identifier\n    and the \"{\", usually where the base class is specified.  For other\n    blocks, there isn't much to check, so we always pass.\n\n    Args:\n      filename: The name of the current file.\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      error: The function to call with any errors found.\n    \"\"\"\n    pass\n\n  def CheckEnd(self, filename, clean_lines, linenum, error):\n    \"\"\"Run checks that applies to text after the closing brace.\n\n    This is mostly used for checking end of namespace comments.\n\n    Args:\n      filename: The name of the current file.\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      error: The function to call with any errors found.\n    \"\"\"\n    pass\n\n  def IsBlockInfo(self):\n    \"\"\"Returns true if this block is a _BlockInfo.\n\n    This is convenient for verifying that an object is an instance of\n    a _BlockInfo, but not an instance of any of the derived classes.\n\n    Returns:\n      True for this class, False for derived classes.\n    \"\"\"\n    return self.__class__ == _BlockInfo\n\n\nclass _ExternCInfo(_BlockInfo):\n  \"\"\"Stores information about an 'extern \"C\"' block.\"\"\"\n\n  def __init__(self, linenum):\n    _BlockInfo.__init__(self, linenum, True)\n\n\nclass _ClassInfo(_BlockInfo):\n  \"\"\"Stores information about a class.\"\"\"\n\n  def __init__(self, name, class_or_struct, clean_lines, linenum):\n    _BlockInfo.__init__(self, linenum, False)\n    self.name = name\n    self.is_derived = False\n    self.check_namespace_indentation = True\n    if class_or_struct == 'struct':\n      self.access = 'public'\n      self.is_struct = True\n    else:\n      self.access = 'private'\n      self.is_struct = False\n\n    # Remember initial indentation level for this class.  Using raw_lines here\n    # instead of elided to account for leading comments.\n    self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum])\n\n    # Try to find the end of the class.  This will be confused by things like:\n    #   class A {\n    #   } *x = { ...\n    #\n    # But it's still good enough for CheckSectionSpacing.\n    self.last_line = 0\n    depth = 0\n    for i in range(linenum, clean_lines.NumLines()):\n      line = clean_lines.elided[i]\n      depth += line.count('{') - line.count('}')\n      if not depth:\n        self.last_line = i\n        break\n\n  def CheckBegin(self, filename, clean_lines, linenum, error):\n    # Look for a bare ':'\n    if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]):\n      self.is_derived = True\n\n  def CheckEnd(self, filename, clean_lines, linenum, error):\n    # If there is a DISALLOW macro, it should appear near the end of\n    # the class.\n    seen_last_thing_in_class = False\n    for i in xrange(linenum - 1, self.starting_linenum, -1):\n      match = Search(\n          r'\\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\\(' +\n          self.name + r'\\)',\n          clean_lines.elided[i])\n      if match:\n        if seen_last_thing_in_class:\n          error(filename, i, 'readability/constructors', 3,\n                match.group(1) + ' should be the last thing in the class')\n        break\n\n      if not Match(r'^\\s*$', clean_lines.elided[i]):\n        seen_last_thing_in_class = True\n\n    # Check that closing brace is aligned with beginning of the class.\n    # Only do this if the closing brace is indented by only whitespaces.\n    # This means we will not check single-line class definitions.\n    indent = Match(r'^( *)\\}', clean_lines.elided[linenum])\n    if indent and len(indent.group(1)) != self.class_indent:\n      if self.is_struct:\n        parent = 'struct ' + self.name\n      else:\n        parent = 'class ' + self.name\n      error(filename, linenum, 'whitespace/indent', 3,\n            'Closing brace should be aligned with beginning of %s' % parent)\n\n\nclass _NamespaceInfo(_BlockInfo):\n  \"\"\"Stores information about a namespace.\"\"\"\n\n  def __init__(self, name, linenum):\n    _BlockInfo.__init__(self, linenum, False)\n    self.name = name or ''\n    self.check_namespace_indentation = True\n\n  def CheckEnd(self, filename, clean_lines, linenum, error):\n    \"\"\"Check end of namespace comments.\"\"\"\n    line = clean_lines.raw_lines[linenum]\n\n    # Check how many lines is enclosed in this namespace.  Don't issue\n    # warning for missing namespace comments if there aren't enough\n    # lines.  However, do apply checks if there is already an end of\n    # namespace comment and it's incorrect.\n    #\n    # TODO(unknown): We always want to check end of namespace comments\n    # if a namespace is large, but sometimes we also want to apply the\n    # check if a short namespace contained nontrivial things (something\n    # other than forward declarations).  There is currently no logic on\n    # deciding what these nontrivial things are, so this check is\n    # triggered by namespace size only, which works most of the time.\n    if (linenum - self.starting_linenum < 10\n        and not Match(r'^\\s*};*\\s*(//|/\\*).*\\bnamespace\\b', line)):\n      return\n\n    # Look for matching comment at end of namespace.\n    #\n    # Note that we accept C style \"/* */\" comments for terminating\n    # namespaces, so that code that terminate namespaces inside\n    # preprocessor macros can be cpplint clean.\n    #\n    # We also accept stuff like \"// end of namespace <name>.\" with the\n    # period at the end.\n    #\n    # Besides these, we don't accept anything else, otherwise we might\n    # get false negatives when existing comment is a substring of the\n    # expected namespace.\n    if self.name:\n      # Named namespace\n      if not Match((r'^\\s*};*\\s*(//|/\\*).*\\bnamespace\\s+' +\n                    re.escape(self.name) + r'[\\*/\\.\\\\\\s]*$'),\n                   line):\n        error(filename, linenum, 'readability/namespace', 5,\n              'Namespace should be terminated with \"// namespace %s\"' %\n              self.name)\n    else:\n      # Anonymous namespace\n      if not Match(r'^\\s*};*\\s*(//|/\\*).*\\bnamespace[\\*/\\.\\\\\\s]*$', line):\n        # If \"// namespace anonymous\" or \"// anonymous namespace (more text)\",\n        # mention \"// anonymous namespace\" as an acceptable form\n        if Match(r'^\\s*}.*\\b(namespace anonymous|anonymous namespace)\\b', line):\n          error(filename, linenum, 'readability/namespace', 5,\n                'Anonymous namespace should be terminated with \"// namespace\"'\n                ' or \"// anonymous namespace\"')\n        else:\n          error(filename, linenum, 'readability/namespace', 5,\n                'Anonymous namespace should be terminated with \"// namespace\"')\n\n\nclass _PreprocessorInfo(object):\n  \"\"\"Stores checkpoints of nesting stacks when #if/#else is seen.\"\"\"\n\n  def __init__(self, stack_before_if):\n    # The entire nesting stack before #if\n    self.stack_before_if = stack_before_if\n\n    # The entire nesting stack up to #else\n    self.stack_before_else = []\n\n    # Whether we have already seen #else or #elif\n    self.seen_else = False\n\n\nclass NestingState(object):\n  \"\"\"Holds states related to parsing braces.\"\"\"\n\n  def __init__(self):\n    # Stack for tracking all braces.  An object is pushed whenever we\n    # see a \"{\", and popped when we see a \"}\".  Only 3 types of\n    # objects are possible:\n    # - _ClassInfo: a class or struct.\n    # - _NamespaceInfo: a namespace.\n    # - _BlockInfo: some other type of block.\n    self.stack = []\n\n    # Top of the previous stack before each Update().\n    #\n    # Because the nesting_stack is updated at the end of each line, we\n    # had to do some convoluted checks to find out what is the current\n    # scope at the beginning of the line.  This check is simplified by\n    # saving the previous top of nesting stack.\n    #\n    # We could save the full stack, but we only need the top.  Copying\n    # the full nesting stack would slow down cpplint by ~10%.\n    self.previous_stack_top = []\n\n    # Stack of _PreprocessorInfo objects.\n    self.pp_stack = []\n\n  def SeenOpenBrace(self):\n    \"\"\"Check if we have seen the opening brace for the innermost block.\n\n    Returns:\n      True if we have seen the opening brace, False if the innermost\n      block is still expecting an opening brace.\n    \"\"\"\n    return (not self.stack) or self.stack[-1].seen_open_brace\n\n  def InNamespaceBody(self):\n    \"\"\"Check if we are currently one level inside a namespace body.\n\n    Returns:\n      True if top of the stack is a namespace block, False otherwise.\n    \"\"\"\n    return self.stack and isinstance(self.stack[-1], _NamespaceInfo)\n\n  def InExternC(self):\n    \"\"\"Check if we are currently one level inside an 'extern \"C\"' block.\n\n    Returns:\n      True if top of the stack is an extern block, False otherwise.\n    \"\"\"\n    return self.stack and isinstance(self.stack[-1], _ExternCInfo)\n\n  def InClassDeclaration(self):\n    \"\"\"Check if we are currently one level inside a class or struct declaration.\n\n    Returns:\n      True if top of the stack is a class/struct, False otherwise.\n    \"\"\"\n    return self.stack and isinstance(self.stack[-1], _ClassInfo)\n\n  def InAsmBlock(self):\n    \"\"\"Check if we are currently one level inside an inline ASM block.\n\n    Returns:\n      True if the top of the stack is a block containing inline ASM.\n    \"\"\"\n    return self.stack and self.stack[-1].inline_asm != _NO_ASM\n\n  def InTemplateArgumentList(self, clean_lines, linenum, pos):\n    \"\"\"Check if current position is inside template argument list.\n\n    Args:\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      pos: position just after the suspected template argument.\n    Returns:\n      True if (linenum, pos) is inside template arguments.\n    \"\"\"\n    while linenum < clean_lines.NumLines():\n      # Find the earliest character that might indicate a template argument\n      line = clean_lines.elided[linenum]\n      match = Match(r'^[^{};=\\[\\]\\.<>]*(.)', line[pos:])\n      if not match:\n        linenum += 1\n        pos = 0\n        continue\n      token = match.group(1)\n      pos += len(match.group(0))\n\n      # These things do not look like template argument list:\n      #   class Suspect {\n      #   class Suspect x; }\n      if token in ('{', '}', ';'): return False\n\n      # These things look like template argument list:\n      #   template <class Suspect>\n      #   template <class Suspect = default_value>\n      #   template <class Suspect[]>\n      #   template <class Suspect...>\n      if token in ('>', '=', '[', ']', '.'): return True\n\n      # Check if token is an unmatched '<'.\n      # If not, move on to the next character.\n      if token != '<':\n        pos += 1\n        if pos >= len(line):\n          linenum += 1\n          pos = 0\n        continue\n\n      # We can't be sure if we just find a single '<', and need to\n      # find the matching '>'.\n      (_, end_line, end_pos) = CloseExpression(clean_lines, linenum, pos - 1)\n      if end_pos < 0:\n        # Not sure if template argument list or syntax error in file\n        return False\n      linenum = end_line\n      pos = end_pos\n    return False\n\n  def UpdatePreprocessor(self, line):\n    \"\"\"Update preprocessor stack.\n\n    We need to handle preprocessors due to classes like this:\n      #ifdef SWIG\n      struct ResultDetailsPageElementExtensionPoint {\n      #else\n      struct ResultDetailsPageElementExtensionPoint : public Extension {\n      #endif\n\n    We make the following assumptions (good enough for most files):\n    - Preprocessor condition evaluates to true from #if up to first\n      #else/#elif/#endif.\n\n    - Preprocessor condition evaluates to false from #else/#elif up\n      to #endif.  We still perform lint checks on these lines, but\n      these do not affect nesting stack.\n\n    Args:\n      line: current line to check.\n    \"\"\"\n    if Match(r'^\\s*#\\s*(if|ifdef|ifndef)\\b', line):\n      # Beginning of #if block, save the nesting stack here.  The saved\n      # stack will allow us to restore the parsing state in the #else case.\n      self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack)))\n    elif Match(r'^\\s*#\\s*(else|elif)\\b', line):\n      # Beginning of #else block\n      if self.pp_stack:\n        if not self.pp_stack[-1].seen_else:\n          # This is the first #else or #elif block.  Remember the\n          # whole nesting stack up to this point.  This is what we\n          # keep after the #endif.\n          self.pp_stack[-1].seen_else = True\n          self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack)\n\n        # Restore the stack to how it was before the #if\n        self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if)\n      else:\n        # TODO(unknown): unexpected #else, issue warning?\n        pass\n    elif Match(r'^\\s*#\\s*endif\\b', line):\n      # End of #if or #else blocks.\n      if self.pp_stack:\n        # If we saw an #else, we will need to restore the nesting\n        # stack to its former state before the #else, otherwise we\n        # will just continue from where we left off.\n        if self.pp_stack[-1].seen_else:\n          # Here we can just use a shallow copy since we are the last\n          # reference to it.\n          self.stack = self.pp_stack[-1].stack_before_else\n        # Drop the corresponding #if\n        self.pp_stack.pop()\n      else:\n        # TODO(unknown): unexpected #endif, issue warning?\n        pass\n\n  # TODO(unknown): Update() is too long, but we will refactor later.\n  def Update(self, filename, clean_lines, linenum, error):\n    \"\"\"Update nesting state with current line.\n\n    Args:\n      filename: The name of the current file.\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      error: The function to call with any errors found.\n    \"\"\"\n    line = clean_lines.elided[linenum]\n\n    # Remember top of the previous nesting stack.\n    #\n    # The stack is always pushed/popped and not modified in place, so\n    # we can just do a shallow copy instead of copy.deepcopy.  Using\n    # deepcopy would slow down cpplint by ~28%.\n    if self.stack:\n      self.previous_stack_top = self.stack[-1]\n    else:\n      self.previous_stack_top = None\n\n    # Update pp_stack\n    self.UpdatePreprocessor(line)\n\n    # Count parentheses.  This is to avoid adding struct arguments to\n    # the nesting stack.\n    if self.stack:\n      inner_block = self.stack[-1]\n      depth_change = line.count('(') - line.count(')')\n      inner_block.open_parentheses += depth_change\n\n      # Also check if we are starting or ending an inline assembly block.\n      if inner_block.inline_asm in (_NO_ASM, _END_ASM):\n        if (depth_change != 0 and\n            inner_block.open_parentheses == 1 and\n            _MATCH_ASM.match(line)):\n          # Enter assembly block\n          inner_block.inline_asm = _INSIDE_ASM\n        else:\n          # Not entering assembly block.  If previous line was _END_ASM,\n          # we will now shift to _NO_ASM state.\n          inner_block.inline_asm = _NO_ASM\n      elif (inner_block.inline_asm == _INSIDE_ASM and\n            inner_block.open_parentheses == 0):\n        # Exit assembly block\n        inner_block.inline_asm = _END_ASM\n\n    # Consume namespace declaration at the beginning of the line.  Do\n    # this in a loop so that we catch same line declarations like this:\n    #   namespace proto2 { namespace bridge { class MessageSet; } }\n    while True:\n      # Match start of namespace.  The \"\\b\\s*\" below catches namespace\n      # declarations even if it weren't followed by a whitespace, this\n      # is so that we don't confuse our namespace checker.  The\n      # missing spaces will be flagged by CheckSpacing.\n      namespace_decl_match = Match(r'^\\s*namespace\\b\\s*([:\\w]+)?(.*)$', line)\n      if not namespace_decl_match:\n        break\n\n      new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum)\n      self.stack.append(new_namespace)\n\n      line = namespace_decl_match.group(2)\n      if line.find('{') != -1:\n        new_namespace.seen_open_brace = True\n        line = line[line.find('{') + 1:]\n\n    # Look for a class declaration in whatever is left of the line\n    # after parsing namespaces.  The regexp accounts for decorated classes\n    # such as in:\n    #   class LOCKABLE API Object {\n    #   };\n    class_decl_match = Match(\n        r'^(\\s*(?:template\\s*<[\\w\\s<>,:=]*>\\s*)?'\n        r'(class|struct)\\s+(?:[a-zA-Z0-9_]+\\s+)*(\\w+(?:::\\w+)*))'\n        r'(.*)$', line)\n    if (class_decl_match and\n        (not self.stack or self.stack[-1].open_parentheses == 0)):\n      # We do not want to accept classes that are actually template arguments:\n      #   template <class Ignore1,\n      #             class Ignore2 = Default<Args>,\n      #             template <Args> class Ignore3>\n      #   void Function() {};\n      #\n      # To avoid template argument cases, we scan forward and look for\n      # an unmatched '>'.  If we see one, assume we are inside a\n      # template argument list.\n      end_declaration = len(class_decl_match.group(1))\n      if not self.InTemplateArgumentList(clean_lines, linenum, end_declaration):\n        self.stack.append(_ClassInfo(\n            class_decl_match.group(3), class_decl_match.group(2),\n            clean_lines, linenum))\n        line = class_decl_match.group(4)\n\n    # If we have not yet seen the opening brace for the innermost block,\n    # run checks here.\n    if not self.SeenOpenBrace():\n      self.stack[-1].CheckBegin(filename, clean_lines, linenum, error)\n\n    # Update access control if we are inside a class/struct\n    if self.stack and isinstance(self.stack[-1], _ClassInfo):\n      classinfo = self.stack[-1]\n      access_match = Match(\n          r'^(.*)\\b(public|private|protected|signals)(\\s+(?:slots\\s*)?)?'\n          r':(?:[^:]|$)',\n          line)\n      if access_match:\n        classinfo.access = access_match.group(2)\n\n        # Check that access keywords are indented +1 space.  Skip this\n        # check if the keywords are not preceded by whitespaces.\n        indent = access_match.group(1)\n        if (len(indent) != classinfo.class_indent + 1 and\n            Match(r'^\\s*$', indent)):\n          if classinfo.is_struct:\n            parent = 'struct ' + classinfo.name\n          else:\n            parent = 'class ' + classinfo.name\n          slots = ''\n          if access_match.group(3):\n            slots = access_match.group(3)\n          error(filename, linenum, 'whitespace/indent', 3,\n                '%s%s: should be indented +1 space inside %s' % (\n                    access_match.group(2), slots, parent))\n\n    # Consume braces or semicolons from what's left of the line\n    while True:\n      # Match first brace, semicolon, or closed parenthesis.\n      matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line)\n      if not matched:\n        break\n\n      token = matched.group(1)\n      if token == '{':\n        # If namespace or class hasn't seen a opening brace yet, mark\n        # namespace/class head as complete.  Push a new block onto the\n        # stack otherwise.\n        if not self.SeenOpenBrace():\n          self.stack[-1].seen_open_brace = True\n        elif Match(r'^extern\\s*\"[^\"]*\"\\s*\\{', line):\n          self.stack.append(_ExternCInfo(linenum))\n        else:\n          self.stack.append(_BlockInfo(linenum, True))\n          if _MATCH_ASM.match(line):\n            self.stack[-1].inline_asm = _BLOCK_ASM\n\n      elif token == ';' or token == ')':\n        # If we haven't seen an opening brace yet, but we already saw\n        # a semicolon, this is probably a forward declaration.  Pop\n        # the stack for these.\n        #\n        # Similarly, if we haven't seen an opening brace yet, but we\n        # already saw a closing parenthesis, then these are probably\n        # function arguments with extra \"class\" or \"struct\" keywords.\n        # Also pop these stack for these.\n        if not self.SeenOpenBrace():\n          self.stack.pop()\n      else:  # token == '}'\n        # Perform end of block checks and pop the stack.\n        if self.stack:\n          self.stack[-1].CheckEnd(filename, clean_lines, linenum, error)\n          self.stack.pop()\n      line = matched.group(2)\n\n  def InnermostClass(self):\n    \"\"\"Get class info on the top of the stack.\n\n    Returns:\n      A _ClassInfo object if we are inside a class, or None otherwise.\n    \"\"\"\n    for i in range(len(self.stack), 0, -1):\n      classinfo = self.stack[i - 1]\n      if isinstance(classinfo, _ClassInfo):\n        return classinfo\n    return None\n\n  def CheckCompletedBlocks(self, filename, error):\n    \"\"\"Checks that all classes and namespaces have been completely parsed.\n\n    Call this when all lines in a file have been processed.\n    Args:\n      filename: The name of the current file.\n      error: The function to call with any errors found.\n    \"\"\"\n    # Note: This test can result in false positives if #ifdef constructs\n    # get in the way of brace matching. See the testBuildClass test in\n    # cpplint_unittest.py for an example of this.\n    for obj in self.stack:\n      if isinstance(obj, _ClassInfo):\n        error(filename, obj.starting_linenum, 'build/class', 5,\n              'Failed to find complete declaration of class %s' %\n              obj.name)\n      elif isinstance(obj, _NamespaceInfo):\n        error(filename, obj.starting_linenum, 'build/namespaces', 5,\n              'Failed to find complete declaration of namespace %s' %\n              obj.name)\n\n\ndef CheckForNonStandardConstructs(filename, clean_lines, linenum,\n                                  nesting_state, error):\n  r\"\"\"Logs an error if we see certain non-ANSI constructs ignored by gcc-2.\n\n  Complain about several constructs which gcc-2 accepts, but which are\n  not standard C++.  Warning about these in lint is one way to ease the\n  transition to new compilers.\n  - put storage class first (e.g. \"static const\" instead of \"const static\").\n  - \"%lld\" instead of %qd\" in printf-type functions.\n  - \"%1$d\" is non-standard in printf-type functions.\n  - \"\\%\" is an undefined character escape sequence.\n  - text after #endif is not allowed.\n  - invalid inner-style forward declaration.\n  - >? and <? operators, and their >?= and <?= cousins.\n\n  Additionally, check for constructor/destructor style violations and reference\n  members, as it is very convenient to do so while checking for\n  gcc-2 compliance.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: A callable to which errors are reported, which takes 4 arguments:\n           filename, line number, error level, and message\n  \"\"\"\n\n  # Remove comments from the line, but leave in strings for now.\n  line = clean_lines.lines[linenum]\n\n  if Search(r'printf\\s*\\(.*\".*%[-+ ]?\\d*q', line):\n    error(filename, linenum, 'runtime/printf_format', 3,\n          '%q in format strings is deprecated.  Use %ll instead.')\n\n  if Search(r'printf\\s*\\(.*\".*%\\d+\\$', line):\n    error(filename, linenum, 'runtime/printf_format', 2,\n          '%N$ formats are unconventional.  Try rewriting to avoid them.')\n\n  # Remove escaped backslashes before looking for undefined escapes.\n  line = line.replace('\\\\\\\\', '')\n\n  if Search(r'(\"|\\').*\\\\(%|\\[|\\(|{)', line):\n    error(filename, linenum, 'build/printf_format', 3,\n          '%, [, (, and { are undefined character escapes.  Unescape them.')\n\n  # For the rest, work with both comments and strings removed.\n  line = clean_lines.elided[linenum]\n\n  if Search(r'\\b(const|volatile|void|char|short|int|long'\n            r'|float|double|signed|unsigned'\n            r'|schar|u?int8|u?int16|u?int32|u?int64)'\n            r'\\s+(register|static|extern|typedef)\\b',\n            line):\n    error(filename, linenum, 'build/storage_class', 5,\n          'Storage-class specifier (static, extern, typedef, etc) should be '\n          'at the beginning of the declaration.')\n\n  if Match(r'\\s*#\\s*endif\\s*[^/\\s]+', line):\n    error(filename, linenum, 'build/endif_comment', 5,\n          'Uncommented text after #endif is non-standard.  Use a comment.')\n\n  if Match(r'\\s*class\\s+(\\w+\\s*::\\s*)+\\w+\\s*;', line):\n    error(filename, linenum, 'build/forward_decl', 5,\n          'Inner-style forward declarations are invalid.  Remove this line.')\n\n  if Search(r'(\\w+|[+-]?\\d+(\\.\\d*)?)\\s*(<|>)\\?=?\\s*(\\w+|[+-]?\\d+)(\\.\\d*)?',\n            line):\n    error(filename, linenum, 'build/deprecated', 3,\n          '>? and <? (max and min) operators are non-standard and deprecated.')\n\n  if Search(r'^\\s*const\\s*string\\s*&\\s*\\w+\\s*;', line):\n    # TODO(unknown): Could it be expanded safely to arbitrary references,\n    # without triggering too many false positives? The first\n    # attempt triggered 5 warnings for mostly benign code in the regtest, hence\n    # the restriction.\n    # Here's the original regexp, for the reference:\n    # type_name = r'\\w+((\\s*::\\s*\\w+)|(\\s*<\\s*\\w+?\\s*>))?'\n    # r'\\s*const\\s*' + type_name + '\\s*&\\s*\\w+\\s*;'\n    error(filename, linenum, 'runtime/member_string_references', 2,\n          'const string& members are dangerous. It is much better to use '\n          'alternatives, such as pointers or simple constants.')\n\n  # Everything else in this function operates on class declarations.\n  # Return early if the top of the nesting stack is not a class, or if\n  # the class head is not completed yet.\n  classinfo = nesting_state.InnermostClass()\n  if not classinfo or not classinfo.seen_open_brace:\n    return\n\n  # The class may have been declared with namespace or classname qualifiers.\n  # The constructor and destructor will not have those qualifiers.\n  base_classname = classinfo.name.split('::')[-1]\n\n  # Look for single-argument constructors that aren't marked explicit.\n  # Technically a valid construct, but against style.\n  explicit_constructor_match = Match(\n      r'\\s+(?:(?:inline|constexpr)\\s+)*(explicit\\s+)?'\n      r'(?:(?:inline|constexpr)\\s+)*%s\\s*'\n      r'\\(((?:[^()]|\\([^()]*\\))*)\\)'\n      % re.escape(base_classname),\n      line)\n\n  if explicit_constructor_match:\n    is_marked_explicit = explicit_constructor_match.group(1)\n\n    if not explicit_constructor_match.group(2):\n      constructor_args = []\n    else:\n      constructor_args = explicit_constructor_match.group(2).split(',')\n\n    # collapse arguments so that commas in template parameter lists and function\n    # argument parameter lists don't split arguments in two\n    i = 0\n    while i < len(constructor_args):\n      constructor_arg = constructor_args[i]\n      while (constructor_arg.count('<') > constructor_arg.count('>') or\n             constructor_arg.count('(') > constructor_arg.count(')')):\n        constructor_arg += ',' + constructor_args[i + 1]\n        del constructor_args[i + 1]\n      constructor_args[i] = constructor_arg\n      i += 1\n\n    variadic_args = [arg for arg in constructor_args if '&&...' in arg]\n    defaulted_args = [arg for arg in constructor_args if '=' in arg]\n    noarg_constructor = (not constructor_args or  # empty arg list\n                         # 'void' arg specifier\n                         (len(constructor_args) == 1 and\n                          constructor_args[0].strip() == 'void'))\n    onearg_constructor = ((len(constructor_args) == 1 and  # exactly one arg\n                           not noarg_constructor) or\n                          # all but at most one arg defaulted\n                          (len(constructor_args) >= 1 and\n                           not noarg_constructor and\n                           len(defaulted_args) >= len(constructor_args) - 1) or\n                          # variadic arguments with zero or one argument\n                          (len(constructor_args) <= 2 and\n                           len(variadic_args) >= 1))\n    initializer_list_constructor = bool(\n        onearg_constructor and\n        Search(r'\\bstd\\s*::\\s*initializer_list\\b', constructor_args[0]))\n    copy_constructor = bool(\n        onearg_constructor and\n        Match(r'((const\\s+(volatile\\s+)?)?|(volatile\\s+(const\\s+)?))?'\n              r'%s(\\s*<[^>]*>)?(\\s+const)?\\s*(?:<\\w+>\\s*)?&'\n              % re.escape(base_classname), constructor_args[0].strip()))\n\n    if (not is_marked_explicit and\n        onearg_constructor and\n        not initializer_list_constructor and\n        not copy_constructor):\n      if defaulted_args or variadic_args:\n        error(filename, linenum, 'runtime/explicit', 5,\n              'Constructors callable with one argument '\n              'should be marked explicit.')\n      else:\n        error(filename, linenum, 'runtime/explicit', 5,\n              'Single-parameter constructors should be marked explicit.')\n    elif is_marked_explicit and not onearg_constructor:\n      if noarg_constructor:\n        error(filename, linenum, 'runtime/explicit', 5,\n              'Zero-parameter constructors should not be marked explicit.')\n\n\ndef CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):\n  \"\"\"Checks for the correctness of various spacing around function calls.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Since function calls often occur inside if/for/while/switch\n  # expressions - which have their own, more liberal conventions - we\n  # first see if we should be looking inside such an expression for a\n  # function call, to which we can apply more strict standards.\n  fncall = line    # if there's no control flow construct, look at whole line\n  for pattern in (r'\\bif\\s*\\((.*)\\)\\s*{',\n                  r'\\bfor\\s*\\((.*)\\)\\s*{',\n                  r'\\bwhile\\s*\\((.*)\\)\\s*[{;]',\n                  r'\\bswitch\\s*\\((.*)\\)\\s*{'):\n    match = Search(pattern, line)\n    if match:\n      fncall = match.group(1)    # look inside the parens for function calls\n      break\n\n  # Except in if/for/while/switch, there should never be space\n  # immediately inside parens (eg \"f( 3, 4 )\").  We make an exception\n  # for nested parens ( (a+b) + c ).  Likewise, there should never be\n  # a space before a ( when it's a function argument.  I assume it's a\n  # function argument when the char before the whitespace is legal in\n  # a function name (alnum + _) and we're not starting a macro. Also ignore\n  # pointers and references to arrays and functions coz they're too tricky:\n  # we use a very simple way to recognize these:\n  # \" (something)(maybe-something)\" or\n  # \" (something)(maybe-something,\" or\n  # \" (something)[something]\"\n  # Note that we assume the contents of [] to be short enough that\n  # they'll never need to wrap.\n  if (  # Ignore control structures.\n      not Search(r'\\b(if|elif|for|while|switch|return|new|delete|catch|sizeof)\\b',\n                 fncall) and\n      # Ignore pointers/references to functions.\n      not Search(r' \\([^)]+\\)\\([^)]*(\\)|,$)', fncall) and\n      # Ignore pointers/references to arrays.\n      not Search(r' \\([^)]+\\)\\[[^\\]]+\\]', fncall)):\n    if Search(r'\\w\\s*\\(\\s(?!\\s*\\\\$)', fncall):      # a ( used for a fn call\n      error(filename, linenum, 'whitespace/parens', 4,\n            'Extra space after ( in function call')\n    elif Search(r'\\(\\s+(?!(\\s*\\\\)|\\()', fncall):\n      error(filename, linenum, 'whitespace/parens', 2,\n            'Extra space after (')\n    if (Search(r'\\w\\s+\\(', fncall) and\n        not Search(r'_{0,2}asm_{0,2}\\s+_{0,2}volatile_{0,2}\\s+\\(', fncall) and\n        not Search(r'#\\s*define|typedef|using\\s+\\w+\\s*=', fncall) and\n        not Search(r'\\w\\s+\\((\\w+::)*\\*\\w+\\)\\(', fncall) and\n        not Search(r'\\bcase\\s+\\(', fncall)):\n      # TODO(unknown): Space after an operator function seem to be a common\n      # error, silence those for now by restricting them to highest verbosity.\n      if Search(r'\\boperator_*\\b', line):\n        error(filename, linenum, 'whitespace/parens', 0,\n              'Extra space before ( in function call')\n      else:\n        error(filename, linenum, 'whitespace/parens', 4,\n              'Extra space before ( in function call')\n    # If the ) is followed only by a newline or a { + newline, assume it's\n    # part of a control statement (if/while/etc), and don't complain\n    if Search(r'[^)]\\s+\\)\\s*[^{\\s]', fncall):\n      # If the closing parenthesis is preceded by only whitespaces,\n      # try to give a more descriptive error message.\n      if Search(r'^\\s+\\)', fncall):\n        error(filename, linenum, 'whitespace/parens', 2,\n              'Closing ) should be moved to the previous line')\n      else:\n        error(filename, linenum, 'whitespace/parens', 2,\n              'Extra space before )')\n\n\ndef IsBlankLine(line):\n  \"\"\"Returns true if the given line is blank.\n\n  We consider a line to be blank if the line is empty or consists of\n  only white spaces.\n\n  Args:\n    line: A line of a string.\n\n  Returns:\n    True, if the given line is blank.\n  \"\"\"\n  return not line or line.isspace()\n\n\ndef CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line,\n                                 error):\n  is_namespace_indent_item = (\n      len(nesting_state.stack) > 1 and\n      nesting_state.stack[-1].check_namespace_indentation and\n      isinstance(nesting_state.previous_stack_top, _NamespaceInfo) and\n      nesting_state.previous_stack_top == nesting_state.stack[-2])\n\n  if ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item,\n                                     clean_lines.elided, line):\n    CheckItemIndentationInNamespace(filename, clean_lines.elided,\n                                    line, error)\n\n\ndef CheckForFunctionLengths(filename, clean_lines, linenum,\n                            function_state, error):\n  \"\"\"Reports for long function bodies.\n\n  For an overview why this is done, see:\n  https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions\n\n  Uses a simplistic algorithm assuming other style guidelines\n  (especially spacing) are followed.\n  Only checks unindented functions, so class members are unchecked.\n  Trivial bodies are unchecked, so constructors with huge initializer lists\n  may be missed.\n  Blank/comment lines are not counted so as to avoid encouraging the removal\n  of vertical space and comments just to get through a lint check.\n  NOLINT *on the last line of a function* disables this check.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    function_state: Current function name and lines in body so far.\n    error: The function to call with any errors found.\n  \"\"\"\n  lines = clean_lines.lines\n  line = lines[linenum]\n  joined_line = ''\n\n  starting_func = False\n  regexp = r'(\\w(\\w|::|\\*|\\&|\\s)*)\\('  # decls * & space::name( ...\n  match_result = Match(regexp, line)\n  if match_result:\n    # If the name is all caps and underscores, figure it's a macro and\n    # ignore it, unless it's TEST or TEST_F.\n    function_name = match_result.group(1).split()[-1]\n    if function_name == 'TEST' or function_name == 'TEST_F' or (\n        not Match(r'[A-Z_]+$', function_name)):\n      starting_func = True\n\n  if starting_func:\n    body_found = False\n    for start_linenum in xrange(linenum, clean_lines.NumLines()):\n      start_line = lines[start_linenum]\n      joined_line += ' ' + start_line.lstrip()\n      if Search(r'(;|})', start_line):  # Declarations and trivial functions\n        body_found = True\n        break                              # ... ignore\n      if Search(r'{', start_line):\n        body_found = True\n        function = Search(r'((\\w|:)*)\\(', line).group(1)\n        if Match(r'TEST', function):    # Handle TEST... macros\n          parameter_regexp = Search(r'(\\(.*\\))', joined_line)\n          if parameter_regexp:             # Ignore bad syntax\n            function += parameter_regexp.group(1)\n        else:\n          function += '()'\n        function_state.Begin(function)\n        break\n    if not body_found:\n      # No body for the function (or evidence of a non-function) was found.\n      error(filename, linenum, 'readability/fn_size', 5,\n            'Lint failed to find start of function body.')\n  elif Match(r'^\\}\\s*$', line):  # function end\n    function_state.Check(error, filename, linenum)\n    function_state.End()\n  elif not Match(r'^\\s*$', line):\n    function_state.Count()  # Count non-blank/non-comment lines.\n\n\n_RE_PATTERN_TODO = re.compile(r'^//(\\s*)TODO(\\(.+?\\))?:?(\\s|$)?')\n\n\ndef CheckComment(line, filename, linenum, next_line_start, error):\n  \"\"\"Checks for common mistakes in comments.\n\n  Args:\n    line: The line in question.\n    filename: The name of the current file.\n    linenum: The number of the line to check.\n    next_line_start: The first non-whitespace column of the next line.\n    error: The function to call with any errors found.\n  \"\"\"\n  commentpos = line.find('//')\n  if commentpos != -1:\n    # Check if the // may be in quotes.  If so, ignore it\n    if re.sub(r'\\\\.', '', line[0:commentpos]).count('\"') % 2 == 0:\n      # Allow one space for new scopes, two spaces otherwise:\n      if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and\n          ((commentpos >= 1 and\n            line[commentpos-1] not in string.whitespace) or\n           (commentpos >= 2 and\n            line[commentpos-2] not in string.whitespace))):\n        error(filename, linenum, 'whitespace/comments', 2,\n              'At least two spaces is best between code and comments')\n\n      # Checks for common mistakes in TODO comments.\n      comment = line[commentpos:]\n      match = _RE_PATTERN_TODO.match(comment)\n      if match:\n        # One whitespace is correct; zero whitespace is handled elsewhere.\n        leading_whitespace = match.group(1)\n        if len(leading_whitespace) > 1:\n          error(filename, linenum, 'whitespace/todo', 2,\n                'Too many spaces before TODO')\n\n        username = match.group(2)\n        if not username:\n          error(filename, linenum, 'readability/todo', 2,\n                'Missing username in TODO; it should look like '\n                '\"// TODO(my_username): Stuff.\"')\n\n        middle_whitespace = match.group(3)\n        # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bool-comparison\n        if middle_whitespace != ' ' and middle_whitespace != '':\n          error(filename, linenum, 'whitespace/todo', 2,\n                'TODO(my_username) should be followed by a space')\n\n      # If the comment contains an alphanumeric character, there\n      # should be a space somewhere between it and the // unless\n      # it's a /// or //! Doxygen comment.\n      if (Match(r'//[^ ]*\\w', comment) and\n          not Match(r'(///|//\\!)(\\s+|$)', comment)):\n        error(filename, linenum, 'whitespace/comments', 4,\n              'Should have a space between // and comment')\n\n\ndef CheckSpacing(filename, clean_lines, linenum, nesting_state, error):\n  \"\"\"Checks for the correctness of various spacing issues in the code.\n\n  Things we check for: spaces around operators, spaces after\n  if/for/while/switch, no spaces around parens in function calls, two\n  spaces between code and comment, don't start a block with a blank\n  line, don't end a function with a blank line, don't add a blank line\n  after public/protected/private, don't have too many blank lines in a row.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Don't use \"elided\" lines here, otherwise we can't check commented lines.\n  # Don't want to use \"raw\" either, because we don't want to check inside C++11\n  # raw strings,\n  raw = clean_lines.lines_without_raw_strings\n  line = raw[linenum]\n\n  # Before nixing comments, check if the line is blank for no good\n  # reason.  This includes the first line after a block is opened, and\n  # blank lines at the end of a function (ie, right before a line like '}'\n  #\n  # Skip all the blank line checks if we are immediately inside a\n  # namespace body.  In other words, don't issue blank line warnings\n  # for this block:\n  #   namespace {\n  #\n  #   }\n  #\n  # A warning about missing end of namespace comments will be issued instead.\n  #\n  # Also skip blank line checks for 'extern \"C\"' blocks, which are formatted\n  # like namespaces.\n  if (IsBlankLine(line) and\n      not nesting_state.InNamespaceBody() and\n      not nesting_state.InExternC()):\n    elided = clean_lines.elided\n    prev_line = elided[linenum - 1]\n    prevbrace = prev_line.rfind('{')\n    # TODO(unknown): Don't complain if line before blank line, and line after,\n    #                both start with alnums and are indented the same amount.\n    #                This ignores whitespace at the start of a namespace block\n    #                because those are not usually indented.\n    if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1:\n      # OK, we have a blank line at the start of a code block.  Before we\n      # complain, we check if it is an exception to the rule: The previous\n      # non-empty line has the parameters of a function header that are indented\n      # 4 spaces (because they did not fit in a 80 column line when placed on\n      # the same line as the function name).  We also check for the case where\n      # the previous line is indented 6 spaces, which may happen when the\n      # initializers of a constructor do not fit into a 80 column line.\n      exception = False\n      if Match(r' {6}\\w', prev_line):  # Initializer list?\n        # We are looking for the opening column of initializer list, which\n        # should be indented 4 spaces to cause 6 space indentation afterwards.\n        search_position = linenum-2\n        while (search_position >= 0\n               and Match(r' {6}\\w', elided[search_position])):\n          search_position -= 1\n        exception = (search_position >= 0\n                     and elided[search_position][:5] == '    :')\n      else:\n        # Search for the function arguments or an initializer list.  We use a\n        # simple heuristic here: If the line is indented 4 spaces; and we have a\n        # closing paren, without the opening paren, followed by an opening brace\n        # or colon (for initializer lists) we assume that it is the last line of\n        # a function header.  If we have a colon indented 4 spaces, it is an\n        # initializer list.\n        exception = (Match(r' {4}\\w[^\\(]*\\)\\s*(const\\s*)?(\\{\\s*$|:)',\n                           prev_line)\n                     or Match(r' {4}:', prev_line))\n\n      if not exception:\n        error(filename, linenum, 'whitespace/blank_line', 2,\n              'Redundant blank line at the start of a code block '\n              'should be deleted.')\n    # Ignore blank lines at the end of a block in a long if-else\n    # chain, like this:\n    #   if (condition1) {\n    #     // Something followed by a blank line\n    #\n    #   } else if (condition2) {\n    #     // Something else\n    #   }\n    if linenum + 1 < clean_lines.NumLines():\n      next_line = raw[linenum + 1]\n      if (next_line\n          and Match(r'\\s*}', next_line)\n          and next_line.find('} else ') == -1):\n        error(filename, linenum, 'whitespace/blank_line', 3,\n              'Redundant blank line at the end of a code block '\n              'should be deleted.')\n\n    matched = Match(r'\\s*(public|protected|private):', prev_line)\n    if matched:\n      error(filename, linenum, 'whitespace/blank_line', 3,\n            'Do not leave a blank line after \"%s:\"' % matched.group(1))\n\n  # Next, check comments\n  next_line_start = 0\n  if linenum + 1 < clean_lines.NumLines():\n    next_line = raw[linenum + 1]\n    next_line_start = len(next_line) - len(next_line.lstrip())\n  CheckComment(line, filename, linenum, next_line_start, error)\n\n  # get rid of comments and strings\n  line = clean_lines.elided[linenum]\n\n  # You shouldn't have spaces before your brackets, except for C++11 attributes\n  # or maybe after 'delete []', 'return []() {};', or 'auto [abc, ...] = ...;'.\n  if (Search(r'\\w\\s+\\[(?!\\[)', line) and\n      not Search(r'(?:auto&?|delete|return)\\s+\\[', line)):\n    error(filename, linenum, 'whitespace/braces', 5,\n          'Extra space before [')\n\n  # In range-based for, we wanted spaces before and after the colon, but\n  # not around \"::\" tokens that might appear.\n  if (Search(r'for *\\(.*[^:]:[^: ]', line) or\n      Search(r'for *\\(.*[^: ]:[^:]', line)):\n    error(filename, linenum, 'whitespace/forcolon', 2,\n          'Missing space around colon in range-based for loop')\n\n\ndef CheckOperatorSpacing(filename, clean_lines, linenum, error):\n  \"\"\"Checks for horizontal spacing around operators.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Don't try to do spacing checks for operator methods.  Do this by\n  # replacing the troublesome characters with something else,\n  # preserving column position for all other characters.\n  #\n  # The replacement is done repeatedly to avoid false positives from\n  # operators that call operators.\n  while True:\n    match = Match(r'^(.*\\boperator\\b)(\\S+)(\\s*\\(.*)$', line)\n    if match:\n      line = match.group(1) + ('_' * len(match.group(2))) + match.group(3)\n    else:\n      break\n\n  # We allow no-spaces around = within an if: \"if ( (a=Foo()) == 0 )\".\n  # Otherwise not.  Note we only check for non-spaces on *both* sides;\n  # sometimes people put non-spaces on one side when aligning ='s among\n  # many lines (not that this is behavior that I approve of...)\n  if ((Search(r'[\\w.]=', line) or\n       Search(r'=[\\w.]', line))\n      and not Search(r'\\b(if|while|for) ', line)\n      # Operators taken from [lex.operators] in C++11 standard.\n      and not Search(r'(>=|<=|==|!=|&=|\\^=|\\|=|\\+=|\\*=|\\/=|\\%=)', line)\n      and not Search(r'operator=', line)):\n    error(filename, linenum, 'whitespace/operators', 4,\n          'Missing spaces around =')\n\n  # It's ok not to have spaces around binary operators like + - * /, but if\n  # there's too little whitespace, we get concerned.  It's hard to tell,\n  # though, so we punt on this one for now.  TODO.\n\n  # You should always have whitespace around binary operators.\n  #\n  # Check <= and >= first to avoid false positives with < and >, then\n  # check non-include lines for spacing around < and >.\n  #\n  # If the operator is followed by a comma, assume it's be used in a\n  # macro context and don't do any checks.  This avoids false\n  # positives.\n  #\n  # Note that && is not included here.  This is because there are too\n  # many false positives due to RValue references.\n  match = Search(r'[^<>=!\\s](==|!=|<=|>=|\\|\\|)[^<>=!\\s,;\\)]', line)\n  if match:\n    error(filename, linenum, 'whitespace/operators', 3,\n          'Missing spaces around %s' % match.group(1))\n  elif not Match(r'#.*include', line):\n    # Look for < that is not surrounded by spaces.  This is only\n    # triggered if both sides are missing spaces, even though\n    # technically should should flag if at least one side is missing a\n    # space.  This is done to avoid some false positives with shifts.\n    match = Match(r'^(.*[^\\s<])<[^\\s=<,]', line)\n    if match:\n      (_, _, end_pos) = CloseExpression(\n          clean_lines, linenum, len(match.group(1)))\n      if end_pos <= -1:\n        error(filename, linenum, 'whitespace/operators', 3,\n              'Missing spaces around <')\n\n    # Look for > that is not surrounded by spaces.  Similar to the\n    # above, we only trigger if both sides are missing spaces to avoid\n    # false positives with shifts.\n    match = Match(r'^(.*[^-\\s>])>[^\\s=>,]', line)\n    if match:\n      (_, _, start_pos) = ReverseCloseExpression(\n          clean_lines, linenum, len(match.group(1)))\n      if start_pos <= -1:\n        error(filename, linenum, 'whitespace/operators', 3,\n              'Missing spaces around >')\n\n  # We allow no-spaces around << when used like this: 10<<20, but\n  # not otherwise (particularly, not when used as streams)\n  #\n  # We also allow operators following an opening parenthesis, since\n  # those tend to be macros that deal with operators.\n  match = Search(r'(operator|[^\\s(<])(?:L|UL|LL|ULL|l|ul|ll|ull)?<<([^\\s,=<])', line)\n  if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and\n      not (match.group(1) == 'operator' and match.group(2) == ';')):\n    error(filename, linenum, 'whitespace/operators', 3,\n          'Missing spaces around <<')\n\n  # We allow no-spaces around >> for almost anything.  This is because\n  # C++11 allows \">>\" to close nested templates, which accounts for\n  # most cases when \">>\" is not followed by a space.\n  #\n  # We still warn on \">>\" followed by alpha character, because that is\n  # likely due to \">>\" being used for right shifts, e.g.:\n  #   value >> alpha\n  #\n  # When \">>\" is used to close templates, the alphanumeric letter that\n  # follows would be part of an identifier, and there should still be\n  # a space separating the template type and the identifier.\n  #   type<type<type>> alpha\n  match = Search(r'>>[a-zA-Z_]', line)\n  if match:\n    error(filename, linenum, 'whitespace/operators', 3,\n          'Missing spaces around >>')\n\n  # There shouldn't be space around unary operators\n  match = Search(r'(!\\s|~\\s|[\\s]--[\\s;]|[\\s]\\+\\+[\\s;])', line)\n  if match:\n    error(filename, linenum, 'whitespace/operators', 4,\n          'Extra space for operator %s' % match.group(1))\n\n\ndef CheckParenthesisSpacing(filename, clean_lines, linenum, error):\n  \"\"\"Checks for horizontal spacing around parentheses.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # No spaces after an if, while, switch, or for\n  match = Search(r' (if\\(|for\\(|while\\(|switch\\()', line)\n  if match:\n    error(filename, linenum, 'whitespace/parens', 5,\n          'Missing space before ( in %s' % match.group(1))\n\n  # For if/for/while/switch, the left and right parens should be\n  # consistent about how many spaces are inside the parens, and\n  # there should either be zero or one spaces inside the parens.\n  # We don't want: \"if ( foo)\" or \"if ( foo   )\".\n  # Exception: \"for ( ; foo; bar)\" and \"for (foo; bar; )\" are allowed.\n  match = Search(r'\\b(if|for|while|switch)\\s*'\n                 r'\\(([ ]*)(.).*[^ ]+([ ]*)\\)\\s*{\\s*$',\n                 line)\n  if match:\n    if len(match.group(2)) != len(match.group(4)):\n      if not (match.group(3) == ';' and\n              len(match.group(2)) == 1 + len(match.group(4)) or\n              not match.group(2) and Search(r'\\bfor\\s*\\(.*; \\)', line)):\n        error(filename, linenum, 'whitespace/parens', 5,\n              'Mismatching spaces inside () in %s' % match.group(1))\n    if len(match.group(2)) not in [0, 1]:\n      error(filename, linenum, 'whitespace/parens', 5,\n            'Should have zero or one spaces inside ( and ) in %s' %\n            match.group(1))\n\n\ndef CheckCommaSpacing(filename, clean_lines, linenum, error):\n  \"\"\"Checks for horizontal spacing near commas and semicolons.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  raw = clean_lines.lines_without_raw_strings\n  line = clean_lines.elided[linenum]\n\n  # You should always have a space after a comma (either as fn arg or operator)\n  #\n  # This does not apply when the non-space character following the\n  # comma is another comma, since the only time when that happens is\n  # for empty macro arguments.\n  #\n  # We run this check in two passes: first pass on elided lines to\n  # verify that lines contain missing whitespaces, second pass on raw\n  # lines to confirm that those missing whitespaces are not due to\n  # elided comments.\n  if (Search(r',[^,\\s]', ReplaceAll(r'\\boperator\\s*,\\s*\\(', 'F(', line)) and\n      Search(r',[^,\\s]', raw[linenum])):\n    error(filename, linenum, 'whitespace/comma', 3,\n          'Missing space after ,')\n\n  # You should always have a space after a semicolon\n  # except for few corner cases\n  # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more\n  # space after ;\n  if Search(r';[^\\s};\\\\)/]', line):\n    error(filename, linenum, 'whitespace/semicolon', 3,\n          'Missing space after ;')\n\n\ndef _IsType(clean_lines, nesting_state, expr):\n  \"\"\"Check if expression looks like a type name, returns true if so.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    expr: The expression to check.\n  Returns:\n    True, if token looks like a type.\n  \"\"\"\n  # Keep only the last token in the expression\n  last_word = Match(r'^.*(\\b\\S+)$', expr)\n  if last_word:\n    token = last_word.group(1)\n  else:\n    token = expr\n\n  # Match native types and stdint types\n  if _TYPES.match(token):\n    return True\n\n  # Try a bit harder to match templated types.  Walk up the nesting\n  # stack until we find something that resembles a typename\n  # declaration for what we are looking for.\n  typename_pattern = (r'\\b(?:typename|class|struct)\\s+' + re.escape(token) +\n                      r'\\b')\n  block_index = len(nesting_state.stack) - 1\n  while block_index >= 0:\n    if isinstance(nesting_state.stack[block_index], _NamespaceInfo):\n      return False\n\n    # Found where the opening brace is.  We want to scan from this\n    # line up to the beginning of the function, minus a few lines.\n    #   template <typename Type1,  // stop scanning here\n    #             ...>\n    #   class C\n    #     : public ... {  // start scanning here\n    last_line = nesting_state.stack[block_index].starting_linenum\n\n    next_block_start = 0\n    if block_index > 0:\n      next_block_start = nesting_state.stack[block_index - 1].starting_linenum\n    first_line = last_line\n    while first_line >= next_block_start:\n      if clean_lines.elided[first_line].find('template') >= 0:\n        break\n      first_line -= 1\n    if first_line < next_block_start:\n      # Didn't find any \"template\" keyword before reaching the next block,\n      # there are probably no template things to check for this block\n      block_index -= 1\n      continue\n\n    # Look for typename in the specified range\n    for i in xrange(first_line, last_line + 1, 1):\n      if Search(typename_pattern, clean_lines.elided[i]):\n        return True\n    block_index -= 1\n\n  return False\n\n\ndef CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error):\n  \"\"\"Checks for horizontal spacing near commas.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Except after an opening paren, or after another opening brace (in case of\n  # an initializer list, for instance), you should have spaces before your\n  # braces when they are delimiting blocks, classes, namespaces etc.\n  # And since you should never have braces at the beginning of a line,\n  # this is an easy test.  Except that braces used for initialization don't\n  # follow the same rule; we often don't want spaces before those.\n  match = Match(r'^(.*[^ ({>]){', line)\n\n  if match:\n    # Try a bit harder to check for brace initialization.  This\n    # happens in one of the following forms:\n    #   Constructor() : initializer_list_{} { ... }\n    #   Constructor{}.MemberFunction()\n    #   Type variable{};\n    #   FunctionCall(type{}, ...);\n    #   LastArgument(..., type{});\n    #   LOG(INFO) << type{} << \" ...\";\n    #   map_of_type[{...}] = ...;\n    #   ternary = expr ? new type{} : nullptr;\n    #   OuterTemplate<InnerTemplateConstructor<Type>{}>\n    #\n    # We check for the character following the closing brace, and\n    # silence the warning if it's one of those listed above, i.e.\n    # \"{.;,)<>]:\".\n    #\n    # To account for nested initializer list, we allow any number of\n    # closing braces up to \"{;,)<\".  We can't simply silence the\n    # warning on first sight of closing brace, because that would\n    # cause false negatives for things that are not initializer lists.\n    #   Silence this:         But not this:\n    #     Outer{                if (...) {\n    #       Inner{...}            if (...){  // Missing space before {\n    #     };                    }\n    #\n    # There is a false negative with this approach if people inserted\n    # spurious semicolons, e.g. \"if (cond){};\", but we will catch the\n    # spurious semicolon with a separate check.\n    leading_text = match.group(1)\n    (endline, endlinenum, endpos) = CloseExpression(\n        clean_lines, linenum, len(match.group(1)))\n    trailing_text = ''\n    if endpos > -1:\n      trailing_text = endline[endpos:]\n    for offset in xrange(endlinenum + 1,\n                         min(endlinenum + 3, clean_lines.NumLines() - 1)):\n      trailing_text += clean_lines.elided[offset]\n    # We also suppress warnings for `uint64_t{expression}` etc., as the style\n    # guide recommends brace initialization for integral types to avoid\n    # overflow/truncation.\n    if (not Match(r'^[\\s}]*[{.;,)<>\\]:]', trailing_text)\n        and not _IsType(clean_lines, nesting_state, leading_text)):\n      error(filename, linenum, 'whitespace/braces', 5,\n            'Missing space before {')\n\n  # Make sure '} else {' has spaces.\n  if Search(r'}else', line):\n    error(filename, linenum, 'whitespace/braces', 5,\n          'Missing space before else')\n\n  # You shouldn't have a space before a semicolon at the end of the line.\n  # There's a special case for \"for\" since the style guide allows space before\n  # the semicolon there.\n  if Search(r':\\s*;\\s*$', line):\n    error(filename, linenum, 'whitespace/semicolon', 5,\n          'Semicolon defining empty statement. Use {} instead.')\n  elif Search(r'^\\s*;\\s*$', line):\n    error(filename, linenum, 'whitespace/semicolon', 5,\n          'Line contains only semicolon. If this should be an empty statement, '\n          'use {} instead.')\n  elif (Search(r'\\s+;\\s*$', line) and\n        not Search(r'\\bfor\\b', line)):\n    error(filename, linenum, 'whitespace/semicolon', 5,\n          'Extra space before last semicolon. If this should be an empty '\n          'statement, use {} instead.')\n\n\ndef IsDecltype(clean_lines, linenum, column):\n  \"\"\"Check if the token ending on (linenum, column) is decltype().\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: the number of the line to check.\n    column: end column of the token to check.\n  Returns:\n    True if this token is decltype() expression, False otherwise.\n  \"\"\"\n  (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column)\n  if start_col < 0:\n    return False\n  if Search(r'\\bdecltype\\s*$', text[0:start_col]):\n    return True\n  return False\n\ndef CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):\n  \"\"\"Checks for additional blank line issues related to sections.\n\n  Currently the only thing checked here is blank line before protected/private.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    class_info: A _ClassInfo objects.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  # Skip checks if the class is small, where small means 25 lines or less.\n  # 25 lines seems like a good cutoff since that's the usual height of\n  # terminals, and any class that can't fit in one screen can't really\n  # be considered \"small\".\n  #\n  # Also skip checks if we are on the first line.  This accounts for\n  # classes that look like\n  #   class Foo { public: ... };\n  #\n  # If we didn't find the end of the class, last_line would be zero,\n  # and the check will be skipped by the first condition.\n  if (class_info.last_line - class_info.starting_linenum <= 24 or\n      linenum <= class_info.starting_linenum):\n    return\n\n  matched = Match(r'\\s*(public|protected|private):', clean_lines.lines[linenum])\n  if matched:\n    # Issue warning if the line before public/protected/private was\n    # not a blank line, but don't do this if the previous line contains\n    # \"class\" or \"struct\".  This can happen two ways:\n    #  - We are at the beginning of the class.\n    #  - We are forward-declaring an inner class that is semantically\n    #    private, but needed to be public for implementation reasons.\n    # Also ignores cases where the previous line ends with a backslash as can be\n    # common when defining classes in C macros.\n    prev_line = clean_lines.lines[linenum - 1]\n    if (not IsBlankLine(prev_line) and\n        not Search(r'\\b(class|struct)\\b', prev_line) and\n        not Search(r'\\\\$', prev_line)):\n      # Try a bit harder to find the beginning of the class.  This is to\n      # account for multi-line base-specifier lists, e.g.:\n      #   class Derived\n      #       : public Base {\n      end_class_head = class_info.starting_linenum\n      for i in range(class_info.starting_linenum, linenum):\n        if Search(r'\\{\\s*$', clean_lines.lines[i]):\n          end_class_head = i\n          break\n      if end_class_head < linenum - 1:\n        error(filename, linenum, 'whitespace/blank_line', 3,\n              '\"%s:\" should be preceded by a blank line' % matched.group(1))\n\n\ndef GetPreviousNonBlankLine(clean_lines, linenum):\n  \"\"\"Return the most recent non-blank line and its line number.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file contents.\n    linenum: The number of the line to check.\n\n  Returns:\n    A tuple with two elements.  The first element is the contents of the last\n    non-blank line before the current line, or the empty string if this is the\n    first non-blank line.  The second is the line number of that line, or -1\n    if this is the first non-blank line.\n  \"\"\"\n\n  prevlinenum = linenum - 1\n  while prevlinenum >= 0:\n    prevline = clean_lines.elided[prevlinenum]\n    if not IsBlankLine(prevline):     # if not a blank line...\n      return (prevline, prevlinenum)\n    prevlinenum -= 1\n  return ('', -1)\n\n\ndef CheckBraces(filename, clean_lines, linenum, error):\n  \"\"\"Looks for misplaced braces (e.g. at the end of line).\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  line = clean_lines.elided[linenum]        # get rid of comments and strings\n\n  if Match(r'\\s*{\\s*$', line):\n    # We allow an open brace to start a line in the case where someone is using\n    # braces in a block to explicitly create a new scope, which is commonly used\n    # to control the lifetime of stack-allocated variables.  Braces are also\n    # used for brace initializers inside function calls.  We don't detect this\n    # perfectly: we just don't complain if the last non-whitespace character on\n    # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the\n    # previous line starts a preprocessor block. We also allow a brace on the\n    # following line if it is part of an array initialization and would not fit\n    # within the 80 character limit of the preceding line.\n    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]\n    if (not Search(r'[,;:}{(]\\s*$', prevline) and\n        not Match(r'\\s*#', prevline) and\n        not (GetLineWidth(prevline) > _line_length - 2 and '[]' in prevline)):\n      error(filename, linenum, 'whitespace/braces', 4,\n            '{ should almost always be at the end of the previous line')\n\n  # An else clause should be on the same line as the preceding closing brace.\n  if Match(r'\\s*else\\b\\s*(?:if\\b|\\{|$)', line):\n    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]\n    if Match(r'\\s*}\\s*$', prevline):\n      error(filename, linenum, 'whitespace/newline', 4,\n            'An else should appear on the same line as the preceding }')\n\n  # If braces come on one side of an else, they should be on both.\n  # However, we have to worry about \"else if\" that spans multiple lines!\n  if Search(r'else if\\s*\\(', line):       # could be multi-line if\n    brace_on_left = bool(Search(r'}\\s*else if\\s*\\(', line))\n    # find the ( after the if\n    pos = line.find('else if')\n    pos = line.find('(', pos)\n    if pos > 0:\n      (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)\n      brace_on_right = endline[endpos:].find('{') != -1\n      if brace_on_left != brace_on_right:    # must be brace after if\n        error(filename, linenum, 'readability/braces', 5,\n              'If an else has a brace on one side, it should have it on both')\n  elif Search(r'}\\s*else[^{]*$', line) or Match(r'[^}]*else\\s*{', line):\n    error(filename, linenum, 'readability/braces', 5,\n          'If an else has a brace on one side, it should have it on both')\n\n  # Likewise, an else should never have the else clause on the same line\n  if Search(r'\\belse [^\\s{]', line) and not Search(r'\\belse if\\b', line):\n    error(filename, linenum, 'whitespace/newline', 4,\n          'Else clause should never be on same line as else (use 2 lines)')\n\n  # In the same way, a do/while should never be on one line\n  if Match(r'\\s*do [^\\s{]', line):\n    error(filename, linenum, 'whitespace/newline', 4,\n          'do/while clauses should not be on a single line')\n\n  # Check single-line if/else bodies. The style guide says 'curly braces are not\n  # required for single-line statements'. We additionally allow multi-line,\n  # single statements, but we reject anything with more than one semicolon in\n  # it. This means that the first semicolon after the if should be at the end of\n  # its line, and the line after that should have an indent level equal to or\n  # lower than the if. We also check for ambiguous if/else nesting without\n  # braces.\n  if_else_match = Search(r'\\b(if\\s*(|constexpr)\\s*\\(|else\\b)', line)\n  if if_else_match and not Match(r'\\s*#', line):\n    if_indent = GetIndentLevel(line)\n    endline, endlinenum, endpos = line, linenum, if_else_match.end()\n    if_match = Search(r'\\bif\\s*(|constexpr)\\s*\\(', line)\n    if if_match:\n      # This could be a multiline if condition, so find the end first.\n      pos = if_match.end() - 1\n      (endline, endlinenum, endpos) = CloseExpression(clean_lines, linenum, pos)\n    # Check for an opening brace, either directly after the if or on the next\n    # line. If found, this isn't a single-statement conditional.\n    if (not Match(r'\\s*{', endline[endpos:])\n        and not (Match(r'\\s*$', endline[endpos:])\n                 and endlinenum < (len(clean_lines.elided) - 1)\n                 and Match(r'\\s*{', clean_lines.elided[endlinenum + 1]))):\n      while (endlinenum < len(clean_lines.elided)\n             and ';' not in clean_lines.elided[endlinenum][endpos:]):\n        endlinenum += 1\n        endpos = 0\n      if endlinenum < len(clean_lines.elided):\n        endline = clean_lines.elided[endlinenum]\n        # We allow a mix of whitespace and closing braces (e.g. for one-liner\n        # methods) and a single \\ after the semicolon (for macros)\n        endpos = endline.find(';')\n        if not Match(r';[\\s}]*(\\\\?)$', endline[endpos:]):\n          # Semicolon isn't the last character, there's something trailing.\n          # Output a warning if the semicolon is not contained inside\n          # a lambda expression.\n          if not Match(r'^[^{};]*\\[[^\\[\\]]*\\][^{}]*\\{[^{}]*\\}\\s*\\)*[;,]\\s*$',\n                       endline):\n            error(filename, linenum, 'readability/braces', 4,\n                  'If/else bodies with multiple statements require braces')\n        elif endlinenum < len(clean_lines.elided) - 1:\n          # Make sure the next line is dedented\n          next_line = clean_lines.elided[endlinenum + 1]\n          next_indent = GetIndentLevel(next_line)\n          # With ambiguous nested if statements, this will error out on the\n          # if that *doesn't* match the else, regardless of whether it's the\n          # inner one or outer one.\n          if (if_match and Match(r'\\s*else\\b', next_line)\n              and next_indent != if_indent):\n            error(filename, linenum, 'readability/braces', 4,\n                  'Else clause should be indented at the same level as if. '\n                  'Ambiguous nested if/else chains require braces.')\n          elif next_indent > if_indent:\n            error(filename, linenum, 'readability/braces', 4,\n                  'If/else bodies with multiple statements require braces')\n\n\ndef CheckTrailingSemicolon(filename, clean_lines, linenum, error):\n  \"\"\"Looks for redundant trailing semicolon.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  line = clean_lines.elided[linenum]\n\n  # Block bodies should not be followed by a semicolon.  Due to C++11\n  # brace initialization, there are more places where semicolons are\n  # required than not, so we explicitly list the allowed rules rather\n  # than listing the disallowed ones.  These are the places where \"};\"\n  # should be replaced by just \"}\":\n  # 1. Some flavor of block following closing parenthesis:\n  #    for (;;) {};\n  #    while (...) {};\n  #    switch (...) {};\n  #    Function(...) {};\n  #    if (...) {};\n  #    if (...) else if (...) {};\n  #\n  # 2. else block:\n  #    if (...) else {};\n  #\n  # 3. const member function:\n  #    Function(...) const {};\n  #\n  # 4. Block following some statement:\n  #    x = 42;\n  #    {};\n  #\n  # 5. Block at the beginning of a function:\n  #    Function(...) {\n  #      {};\n  #    }\n  #\n  #    Note that naively checking for the preceding \"{\" will also match\n  #    braces inside multi-dimensional arrays, but this is fine since\n  #    that expression will not contain semicolons.\n  #\n  # 6. Block following another block:\n  #    while (true) {}\n  #    {};\n  #\n  # 7. End of namespaces:\n  #    namespace {};\n  #\n  #    These semicolons seems far more common than other kinds of\n  #    redundant semicolons, possibly due to people converting classes\n  #    to namespaces.  For now we do not warn for this case.\n  #\n  # Try matching case 1 first.\n  match = Match(r'^(.*\\)\\s*)\\{', line)\n  if match:\n    # Matched closing parenthesis (case 1).  Check the token before the\n    # matching opening parenthesis, and don't warn if it looks like a\n    # macro.  This avoids these false positives:\n    #  - macro that defines a base class\n    #  - multi-line macro that defines a base class\n    #  - macro that defines the whole class-head\n    #\n    # But we still issue warnings for macros that we know are safe to\n    # warn, specifically:\n    #  - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P\n    #  - TYPED_TEST\n    #  - INTERFACE_DEF\n    #  - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED:\n    #\n    # We implement a list of safe macros instead of a list of\n    # unsafe macros, even though the latter appears less frequently in\n    # google code and would have been easier to implement.  This is because\n    # the downside for getting the allowed checks wrong means some extra\n    # semicolons, while the downside for getting disallowed checks wrong\n    # would result in compile errors.\n    #\n    # In addition to macros, we also don't want to warn on\n    #  - Compound literals\n    #  - Lambdas\n    #  - alignas specifier with anonymous structs\n    #  - decltype\n    closing_brace_pos = match.group(1).rfind(')')\n    opening_parenthesis = ReverseCloseExpression(\n        clean_lines, linenum, closing_brace_pos)\n    if opening_parenthesis[2] > -1:\n      line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]]\n      macro = Search(r'\\b([A-Z_][A-Z0-9_]*)\\s*$', line_prefix)\n      func = Match(r'^(.*\\])\\s*$', line_prefix)\n      if ((macro and\n           macro.group(1) not in (\n               'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST',\n               'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED',\n               'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or\n          (func and not Search(r'\\boperator\\s*\\[\\s*\\]', func.group(1))) or\n          Search(r'\\b(?:struct|union)\\s+alignas\\s*$', line_prefix) or\n          Search(r'\\bdecltype$', line_prefix) or\n          Search(r'\\s+=\\s*$', line_prefix)):\n        match = None\n    if (match and\n        opening_parenthesis[1] > 1 and\n        Search(r'\\]\\s*$', clean_lines.elided[opening_parenthesis[1] - 1])):\n      # Multi-line lambda-expression\n      match = None\n\n  else:\n    # Try matching cases 2-3.\n    match = Match(r'^(.*(?:else|\\)\\s*const)\\s*)\\{', line)\n    if not match:\n      # Try matching cases 4-6.  These are always matched on separate lines.\n      #\n      # Note that we can't simply concatenate the previous line to the\n      # current line and do a single match, otherwise we may output\n      # duplicate warnings for the blank line case:\n      #   if (cond) {\n      #     // blank line\n      #   }\n      prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]\n      if prevline and Search(r'[;{}]\\s*$', prevline):\n        match = Match(r'^(\\s*)\\{', line)\n\n  # Check matching closing brace\n  if match:\n    (endline, endlinenum, endpos) = CloseExpression(\n        clean_lines, linenum, len(match.group(1)))\n    if endpos > -1 and Match(r'^\\s*;', endline[endpos:]):\n      # Current {} pair is eligible for semicolon check, and we have found\n      # the redundant semicolon, output warning here.\n      #\n      # Note: because we are scanning forward for opening braces, and\n      # outputting warnings for the matching closing brace, if there are\n      # nested blocks with trailing semicolons, we will get the error\n      # messages in reversed order.\n\n      # We need to check the line forward for NOLINT\n      raw_lines = clean_lines.raw_lines\n      ParseNolintSuppressions(filename, raw_lines[endlinenum-1], endlinenum-1,\n                              error)\n      ParseNolintSuppressions(filename, raw_lines[endlinenum], endlinenum,\n                              error)\n\n      error(filename, endlinenum, 'readability/braces', 4,\n            \"You don't need a ; after a }\")\n\n\ndef CheckEmptyBlockBody(filename, clean_lines, linenum, error):\n  \"\"\"Look for empty loop/conditional body with only a single semicolon.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Search for loop keywords at the beginning of the line.  Because only\n  # whitespaces are allowed before the keywords, this will also ignore most\n  # do-while-loops, since those lines should start with closing brace.\n  #\n  # We also check \"if\" blocks here, since an empty conditional block\n  # is likely an error.\n  line = clean_lines.elided[linenum]\n  matched = Match(r'\\s*(for|while|if)\\s*\\(', line)\n  if matched:\n    # Find the end of the conditional expression.\n    (end_line, end_linenum, end_pos) = CloseExpression(\n        clean_lines, linenum, line.find('('))\n\n    # Output warning if what follows the condition expression is a semicolon.\n    # No warning for all other cases, including whitespace or newline, since we\n    # have a separate check for semicolons preceded by whitespace.\n    if end_pos >= 0 and Match(r';', end_line[end_pos:]):\n      if matched.group(1) == 'if':\n        error(filename, end_linenum, 'whitespace/empty_conditional_body', 5,\n              'Empty conditional bodies should use {}')\n      else:\n        error(filename, end_linenum, 'whitespace/empty_loop_body', 5,\n              'Empty loop bodies should use {} or continue')\n\n    # Check for if statements that have completely empty bodies (no comments)\n    # and no else clauses.\n    if end_pos >= 0 and matched.group(1) == 'if':\n      # Find the position of the opening { for the if statement.\n      # Return without logging an error if it has no brackets.\n      opening_linenum = end_linenum\n      opening_line_fragment = end_line[end_pos:]\n      # Loop until EOF or find anything that's not whitespace or opening {.\n      while not Search(r'^\\s*\\{', opening_line_fragment):\n        if Search(r'^(?!\\s*$)', opening_line_fragment):\n          # Conditional has no brackets.\n          return\n        opening_linenum += 1\n        if opening_linenum == len(clean_lines.elided):\n          # Couldn't find conditional's opening { or any code before EOF.\n          return\n        opening_line_fragment = clean_lines.elided[opening_linenum]\n      # Set opening_line (opening_line_fragment may not be entire opening line).\n      opening_line = clean_lines.elided[opening_linenum]\n\n      # Find the position of the closing }.\n      opening_pos = opening_line_fragment.find('{')\n      if opening_linenum == end_linenum:\n        # We need to make opening_pos relative to the start of the entire line.\n        opening_pos += end_pos\n      (closing_line, closing_linenum, closing_pos) = CloseExpression(\n          clean_lines, opening_linenum, opening_pos)\n      if closing_pos < 0:\n        return\n\n      # Now construct the body of the conditional. This consists of the portion\n      # of the opening line after the {, all lines until the closing line,\n      # and the portion of the closing line before the }.\n      if (clean_lines.raw_lines[opening_linenum] !=\n          CleanseComments(clean_lines.raw_lines[opening_linenum])):\n        # Opening line ends with a comment, so conditional isn't empty.\n        return\n      if closing_linenum > opening_linenum:\n        # Opening line after the {. Ignore comments here since we checked above.\n        bodylist = list(opening_line[opening_pos+1:])\n        # All lines until closing line, excluding closing line, with comments.\n        bodylist.extend(clean_lines.raw_lines[opening_linenum+1:closing_linenum])\n        # Closing line before the }. Won't (and can't) have comments.\n        bodylist.append(clean_lines.elided[closing_linenum][:closing_pos-1])\n        body = '\\n'.join(bodylist)\n      else:\n        # If statement has brackets and fits on a single line.\n        body = opening_line[opening_pos+1:closing_pos-1]\n\n      # Check if the body is empty\n      if not _EMPTY_CONDITIONAL_BODY_PATTERN.search(body):\n        return\n      # The body is empty. Now make sure there's not an else clause.\n      current_linenum = closing_linenum\n      current_line_fragment = closing_line[closing_pos:]\n      # Loop until EOF or find anything that's not whitespace or else clause.\n      while Search(r'^\\s*$|^(?=\\s*else)', current_line_fragment):\n        if Search(r'^(?=\\s*else)', current_line_fragment):\n          # Found an else clause, so don't log an error.\n          return\n        current_linenum += 1\n        if current_linenum == len(clean_lines.elided):\n          break\n        current_line_fragment = clean_lines.elided[current_linenum]\n\n      # The body is empty and there's no else clause until EOF or other code.\n      error(filename, end_linenum, 'whitespace/empty_if_body', 4,\n            ('If statement had no body and no else clause'))\n\n\ndef FindCheckMacro(line):\n  \"\"\"Find a replaceable CHECK-like macro.\n\n  Args:\n    line: line to search on.\n  Returns:\n    (macro name, start position), or (None, -1) if no replaceable\n    macro is found.\n  \"\"\"\n  for macro in _CHECK_MACROS:\n    i = line.find(macro)\n    if i >= 0:\n      # Find opening parenthesis.  Do a regular expression match here\n      # to make sure that we are matching the expected CHECK macro, as\n      # opposed to some other macro that happens to contain the CHECK\n      # substring.\n      matched = Match(r'^(.*\\b' + macro + r'\\s*)\\(', line)\n      if not matched:\n        continue\n      return (macro, len(matched.group(1)))\n  return (None, -1)\n\n\ndef CheckCheck(filename, clean_lines, linenum, error):\n  \"\"\"Checks the use of CHECK and EXPECT macros.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Decide the set of replacement macros that should be suggested\n  lines = clean_lines.elided\n  (check_macro, start_pos) = FindCheckMacro(lines[linenum])\n  if not check_macro:\n    return\n\n  # Find end of the boolean expression by matching parentheses\n  (last_line, end_line, end_pos) = CloseExpression(\n      clean_lines, linenum, start_pos)\n  if end_pos < 0:\n    return\n\n  # If the check macro is followed by something other than a\n  # semicolon, assume users will log their own custom error messages\n  # and don't suggest any replacements.\n  if not Match(r'\\s*;', last_line[end_pos:]):\n    return\n\n  if linenum == end_line:\n    expression = lines[linenum][start_pos + 1:end_pos - 1]\n  else:\n    expression = lines[linenum][start_pos + 1:]\n    for i in xrange(linenum + 1, end_line):\n      expression += lines[i]\n    expression += last_line[0:end_pos - 1]\n\n  # Parse expression so that we can take parentheses into account.\n  # This avoids false positives for inputs like \"CHECK((a < 4) == b)\",\n  # which is not replaceable by CHECK_LE.\n  lhs = ''\n  rhs = ''\n  operator = None\n  while expression:\n    matched = Match(r'^\\s*(<<|<<=|>>|>>=|->\\*|->|&&|\\|\\||'\n                    r'==|!=|>=|>|<=|<|\\()(.*)$', expression)\n    if matched:\n      token = matched.group(1)\n      if token == '(':\n        # Parenthesized operand\n        expression = matched.group(2)\n        (end, _) = FindEndOfExpressionInLine(expression, 0, ['('])\n        if end < 0:\n          return  # Unmatched parenthesis\n        lhs += '(' + expression[0:end]\n        expression = expression[end:]\n      elif token in ('&&', '||'):\n        # Logical and/or operators.  This means the expression\n        # contains more than one term, for example:\n        #   CHECK(42 < a && a < b);\n        #\n        # These are not replaceable with CHECK_LE, so bail out early.\n        return\n      elif token in ('<<', '<<=', '>>', '>>=', '->*', '->'):\n        # Non-relational operator\n        lhs += token\n        expression = matched.group(2)\n      else:\n        # Relational operator\n        operator = token\n        rhs = matched.group(2)\n        break\n    else:\n      # Unparenthesized operand.  Instead of appending to lhs one character\n      # at a time, we do another regular expression match to consume several\n      # characters at once if possible.  Trivial benchmark shows that this\n      # is more efficient when the operands are longer than a single\n      # character, which is generally the case.\n      matched = Match(r'^([^-=!<>()&|]+)(.*)$', expression)\n      if not matched:\n        matched = Match(r'^(\\s*\\S)(.*)$', expression)\n        if not matched:\n          break\n      lhs += matched.group(1)\n      expression = matched.group(2)\n\n  # Only apply checks if we got all parts of the boolean expression\n  if not (lhs and operator and rhs):\n    return\n\n  # Check that rhs do not contain logical operators.  We already know\n  # that lhs is fine since the loop above parses out && and ||.\n  if rhs.find('&&') > -1 or rhs.find('||') > -1:\n    return\n\n  # At least one of the operands must be a constant literal.  This is\n  # to avoid suggesting replacements for unprintable things like\n  # CHECK(variable != iterator)\n  #\n  # The following pattern matches decimal, hex integers, strings, and\n  # characters (in that order).\n  lhs = lhs.strip()\n  rhs = rhs.strip()\n  match_constant = r'^([-+]?(\\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|\".*\"|\\'.*\\')$'\n  if Match(match_constant, lhs) or Match(match_constant, rhs):\n    # Note: since we know both lhs and rhs, we can provide a more\n    # descriptive error message like:\n    #   Consider using CHECK_EQ(x, 42) instead of CHECK(x == 42)\n    # Instead of:\n    #   Consider using CHECK_EQ instead of CHECK(a == b)\n    #\n    # We are still keeping the less descriptive message because if lhs\n    # or rhs gets long, the error message might become unreadable.\n    error(filename, linenum, 'readability/check', 2,\n          'Consider using %s instead of %s(a %s b)' % (\n              _CHECK_REPLACEMENT[check_macro][operator],\n              check_macro, operator))\n\n\ndef CheckAltTokens(filename, clean_lines, linenum, error):\n  \"\"\"Check alternative keywords being used in boolean expressions.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Avoid preprocessor lines\n  if Match(r'^\\s*#', line):\n    return\n\n  # Last ditch effort to avoid multi-line comments.  This will not help\n  # if the comment started before the current line or ended after the\n  # current line, but it catches most of the false positives.  At least,\n  # it provides a way to workaround this warning for people who use\n  # multi-line comments in preprocessor macros.\n  #\n  # TODO(unknown): remove this once cpplint has better support for\n  # multi-line comments.\n  if line.find('/*') >= 0 or line.find('*/') >= 0:\n    return\n\n  for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line):\n    error(filename, linenum, 'readability/alt_tokens', 2,\n          'Use operator %s instead of %s' % (\n              _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1)))\n\n\ndef GetLineWidth(line):\n  \"\"\"Determines the width of the line in column positions.\n\n  Args:\n    line: A string, which may be a Unicode string.\n\n  Returns:\n    The width of the line in column positions, accounting for Unicode\n    combining characters and wide characters.\n  \"\"\"\n  if isinstance(line, unicode):\n    width = 0\n    for uc in unicodedata.normalize('NFC', line):\n      if unicodedata.east_asian_width(uc) in ('W', 'F'):\n        width += 2\n      elif not unicodedata.combining(uc):\n        # Issue 337\n        # https://mail.python.org/pipermail/python-list/2012-August/628809.html\n        if (sys.version_info.major, sys.version_info.minor) <= (3, 2):\n          # https://github.com/python/cpython/blob/2.7/Include/unicodeobject.h#L81\n          is_wide_build = sysconfig.get_config_var(\"Py_UNICODE_SIZE\") >= 4\n          # https://github.com/python/cpython/blob/2.7/Objects/unicodeobject.c#L564\n          is_low_surrogate = 0xDC00 <= ord(uc) <= 0xDFFF\n          if not is_wide_build and is_low_surrogate:\n            width -= 1\n\n        width += 1\n    return width\n  else:\n    return len(line)\n\n\ndef CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,\n               error):\n  \"\"\"Checks rules from the 'C++ style rules' section of cppguide.html.\n\n  Most of these rules are hard to test (naming, comment style), but we\n  do what we can.  In particular we check for 2-space indents, line lengths,\n  tab usage, spaces inside code, etc.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    file_extension: The extension (without the dot) of the filename.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Don't use \"elided\" lines here, otherwise we can't check commented lines.\n  # Don't want to use \"raw\" either, because we don't want to check inside C++11\n  # raw strings,\n  raw_lines = clean_lines.lines_without_raw_strings\n  line = raw_lines[linenum]\n  prev = raw_lines[linenum - 1] if linenum > 0 else ''\n\n  if line.find('\\t') != -1:\n    error(filename, linenum, 'whitespace/tab', 1,\n          'Tab found; better to use spaces')\n\n  # One or three blank spaces at the beginning of the line is weird; it's\n  # hard to reconcile that with 2-space indents.\n  # NOTE: here are the conditions rob pike used for his tests.  Mine aren't\n  # as sophisticated, but it may be worth becoming so:  RLENGTH==initial_spaces\n  # if(RLENGTH > 20) complain = 0;\n  # if(match($0, \" +(error|private|public|protected):\")) complain = 0;\n  # if(match(prev, \"&& *$\")) complain = 0;\n  # if(match(prev, \"\\\\|\\\\| *$\")) complain = 0;\n  # if(match(prev, \"[\\\",=><] *$\")) complain = 0;\n  # if(match($0, \" <<\")) complain = 0;\n  # if(match(prev, \" +for \\\\(\")) complain = 0;\n  # if(prevodd && match(prevprev, \" +for \\\\(\")) complain = 0;\n  scope_or_label_pattern = r'\\s*(?:public|private|protected|signals)(?:\\s+(?:slots\\s*)?)?:\\s*\\\\?$'\n  classinfo = nesting_state.InnermostClass()\n  initial_spaces = 0\n  cleansed_line = clean_lines.elided[linenum]\n  while initial_spaces < len(line) and line[initial_spaces] == ' ':\n    initial_spaces += 1\n  # There are certain situations we allow one space, notably for\n  # section labels, and also lines containing multi-line raw strings.\n  # We also don't check for lines that look like continuation lines\n  # (of lines ending in double quotes, commas, equals, or angle brackets)\n  # because the rules for how to indent those are non-trivial.\n  if (not Search(r'[\",=><] *$', prev) and\n      (initial_spaces == 1 or initial_spaces == 3) and\n      not Match(scope_or_label_pattern, cleansed_line) and\n      not (clean_lines.raw_lines[linenum] != line and\n           Match(r'^\\s*\"\"', line))):\n    error(filename, linenum, 'whitespace/indent', 3,\n          'Weird number of spaces at line-start.  '\n          'Are you using a 2-space indent?')\n\n  if line and line[-1].isspace():\n    error(filename, linenum, 'whitespace/end_of_line', 4,\n          'Line ends in whitespace.  Consider deleting these extra spaces.')\n\n  # Check if the line is a header guard.\n  is_header_guard = False\n  if IsHeaderExtension(file_extension):\n    cppvar = GetHeaderGuardCPPVariable(filename)\n    if (line.startswith('#ifndef %s' % cppvar) or\n        line.startswith('#define %s' % cppvar) or\n        line.startswith('#endif  // %s' % cppvar)):\n      is_header_guard = True\n  # #include lines and header guards can be long, since there's no clean way to\n  # split them.\n  #\n  # URLs can be long too.  It's possible to split these, but it makes them\n  # harder to cut&paste.\n  #\n  # The \"$Id:...$\" comment may also get very long without it being the\n  # developers fault.\n  #\n  # Doxygen documentation copying can get pretty long when using an overloaded\n  # function declaration\n  if (not line.startswith('#include') and not is_header_guard and\n      not Match(r'^\\s*//.*http(s?)://\\S*$', line) and\n      not Match(r'^\\s*//\\s*[^\\s]*$', line) and\n      not Match(r'^// \\$Id:.*#[0-9]+ \\$$', line) and\n      not Match(r'^\\s*/// [@\\\\](copydoc|copydetails|copybrief) .*$', line)):\n    line_width = GetLineWidth(line)\n    if line_width > _line_length:\n      error(filename, linenum, 'whitespace/line_length', 2,\n            'Lines should be <= %i characters long' % _line_length)\n\n  if (cleansed_line.count(';') > 1 and\n      # allow simple single line lambdas\n      not Match(r'^[^{};]*\\[[^\\[\\]]*\\][^{}]*\\{[^{}\\n\\r]*\\}',\n                line) and\n      # for loops are allowed two ;'s (and may run over two lines).\n      cleansed_line.find('for') == -1 and\n      (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or\n       GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and\n      # It's ok to have many commands in a switch case that fits in 1 line\n      not ((cleansed_line.find('case ') != -1 or\n            cleansed_line.find('default:') != -1) and\n           cleansed_line.find('break;') != -1)):\n    error(filename, linenum, 'whitespace/newline', 0,\n          'More than one command on the same line')\n\n  # Some more style checks\n  CheckBraces(filename, clean_lines, linenum, error)\n  CheckTrailingSemicolon(filename, clean_lines, linenum, error)\n  CheckEmptyBlockBody(filename, clean_lines, linenum, error)\n  CheckSpacing(filename, clean_lines, linenum, nesting_state, error)\n  CheckOperatorSpacing(filename, clean_lines, linenum, error)\n  CheckParenthesisSpacing(filename, clean_lines, linenum, error)\n  CheckCommaSpacing(filename, clean_lines, linenum, error)\n  CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error)\n  CheckSpacingForFunctionCall(filename, clean_lines, linenum, error)\n  CheckCheck(filename, clean_lines, linenum, error)\n  CheckAltTokens(filename, clean_lines, linenum, error)\n  classinfo = nesting_state.InnermostClass()\n  if classinfo:\n    CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)\n\n\n_RE_PATTERN_INCLUDE = re.compile(r'^\\s*#\\s*include\\s*([<\"])([^>\"]*)[>\"].*$')\n# Matches the first component of a filename delimited by -s and _s. That is:\n#  _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'\n#  _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'\n#  _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'\n#  _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'\n_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')\n\n\ndef _DropCommonSuffixes(filename):\n  \"\"\"Drops common suffixes like _test.cc or -inl.h from filename.\n\n  For example:\n    >>> _DropCommonSuffixes('foo/foo-inl.h')\n    'foo/foo'\n    >>> _DropCommonSuffixes('foo/bar/foo.cc')\n    'foo/bar/foo'\n    >>> _DropCommonSuffixes('foo/foo_internal.h')\n    'foo/foo'\n    >>> _DropCommonSuffixes('foo/foo_unusualinternal.h')\n    'foo/foo_unusualinternal'\n\n  Args:\n    filename: The input filename.\n\n  Returns:\n    The filename with the common suffix removed.\n  \"\"\"\n  for suffix in itertools.chain(\n      ('%s.%s' % (test_suffix.lstrip('_'), ext)\n       for test_suffix, ext in itertools.product(_test_suffixes, GetNonHeaderExtensions())),\n      ('%s.%s' % (suffix, ext)\n       for suffix, ext in itertools.product(['inl', 'imp', 'internal'], GetHeaderExtensions()))):\n    if (filename.endswith(suffix) and len(filename) > len(suffix) and\n        filename[-len(suffix) - 1] in ('-', '_')):\n      return filename[:-len(suffix) - 1]\n  return os.path.splitext(filename)[0]\n\n\ndef _ClassifyInclude(fileinfo, include, used_angle_brackets, include_order=\"default\"):\n  \"\"\"Figures out what kind of header 'include' is.\n\n  Args:\n    fileinfo: The current file cpplint is running over. A FileInfo instance.\n    include: The path to a #included file.\n    used_angle_brackets: True if the #include used <> rather than \"\".\n    include_order: \"default\" or other value allowed in program arguments\n\n  Returns:\n    One of the _XXX_HEADER constants.\n\n  For example:\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)\n    _C_SYS_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)\n    _CPP_SYS_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', True, \"standardcfirst\")\n    _OTHER_SYS_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)\n    _LIKELY_MY_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),\n    ...                  'bar/foo_other_ext.h', False)\n    _POSSIBLE_MY_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)\n    _OTHER_HEADER\n  \"\"\"\n  # This is a list of all standard c++ header files, except\n  # those already checked for above.\n  is_cpp_header = include in _CPP_HEADERS\n\n  # Mark include as C header if in list or in a known folder for standard-ish C headers.\n  is_std_c_header = (include_order == \"default\") or (include in _C_HEADERS\n            # additional linux glibc header folders\n            or Search(r'(?:%s)\\/.*\\.h' % \"|\".join(C_STANDARD_HEADER_FOLDERS), include))\n\n  # Headers with C++ extensions shouldn't be considered C system headers\n  is_system = used_angle_brackets and not os.path.splitext(include)[1] in ['.hpp', '.hxx', '.h++']\n\n  if is_system:\n    if is_cpp_header:\n      return _CPP_SYS_HEADER\n    if is_std_c_header:\n      return _C_SYS_HEADER\n    else:\n      return _OTHER_SYS_HEADER\n\n  # If the target file and the include we're checking share a\n  # basename when we drop common extensions, and the include\n  # lives in . , then it's likely to be owned by the target file.\n  target_dir, target_base = (\n      os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))\n  include_dir, include_base = os.path.split(_DropCommonSuffixes(include))\n  target_dir_pub = os.path.normpath(target_dir + '/../public')\n  target_dir_pub = target_dir_pub.replace('\\\\', '/')\n  if target_base == include_base and (\n      include_dir == target_dir or\n      include_dir == target_dir_pub):\n    return _LIKELY_MY_HEADER\n\n  # If the target and include share some initial basename\n  # component, it's possible the target is implementing the\n  # include, so it's allowed to be first, but we'll never\n  # complain if it's not there.\n  target_first_component = _RE_FIRST_COMPONENT.match(target_base)\n  include_first_component = _RE_FIRST_COMPONENT.match(include_base)\n  if (target_first_component and include_first_component and\n      target_first_component.group(0) ==\n      include_first_component.group(0)):\n    return _POSSIBLE_MY_HEADER\n\n  return _OTHER_HEADER\n\n\n\ndef CheckIncludeLine(filename, clean_lines, linenum, include_state, error):\n  \"\"\"Check rules that are applicable to #include lines.\n\n  Strings on #include lines are NOT removed from elided line, to make\n  certain tasks easier. However, to prevent false positives, checks\n  applicable to #include lines in CheckLanguage must be put here.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    include_state: An _IncludeState instance in which the headers are inserted.\n    error: The function to call with any errors found.\n  \"\"\"\n  fileinfo = FileInfo(filename)\n  line = clean_lines.lines[linenum]\n\n  # \"include\" should use the new style \"foo/bar.h\" instead of just \"bar.h\"\n  # Only do this check if the included header follows google naming\n  # conventions.  If not, assume that it's a 3rd party API that\n  # requires special include conventions.\n  #\n  # We also make an exception for Lua headers, which follow google\n  # naming convention but not the include convention.\n  match = Match(r'#include\\s*\"([^/]+\\.h)\"', line)\n  if match and not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1)):\n    error(filename, linenum, 'build/include_subdir', 4,\n          'Include the directory when naming .h files')\n\n  # we shouldn't include a file more than once. actually, there are a\n  # handful of instances where doing so is okay, but in general it's\n  # not.\n  match = _RE_PATTERN_INCLUDE.search(line)\n  if match:\n    include = match.group(2)\n    used_angle_brackets = (match.group(1) == '<')\n    duplicate_line = include_state.FindHeader(include)\n    if duplicate_line >= 0:\n      error(filename, linenum, 'build/include', 4,\n            '\"%s\" already included at %s:%s' %\n            (include, filename, duplicate_line))\n      return\n\n    for extension in GetNonHeaderExtensions():\n      if (include.endswith('.' + extension) and\n          os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)):\n        error(filename, linenum, 'build/include', 4,\n              'Do not include .' + extension + ' files from other packages')\n        return\n\n    # We DO want to include a 3rd party looking header if it matches the\n    # filename. Otherwise we get an erroneous error \"...should include its\n    # header\" error later.\n    third_src_header = False\n    for ext in GetHeaderExtensions():\n      basefilename = filename[0:len(filename) - len(fileinfo.Extension())]\n      headerfile = basefilename + '.' + ext\n      headername = FileInfo(headerfile).RepositoryName()\n      if headername in include or include in headername:\n        third_src_header = True\n        break\n\n    if third_src_header or not _THIRD_PARTY_HEADERS_PATTERN.match(include):\n      include_state.include_list[-1].append((include, linenum))\n\n      # We want to ensure that headers appear in the right order:\n      # 1) for foo.cc, foo.h  (preferred location)\n      # 2) c system files\n      # 3) cpp system files\n      # 4) for foo.cc, foo.h  (deprecated location)\n      # 5) other google headers\n      #\n      # We classify each include statement as one of those 5 types\n      # using a number of techniques. The include_state object keeps\n      # track of the highest type seen, and complains if we see a\n      # lower type after that.\n      error_message = include_state.CheckNextIncludeOrder(\n          _ClassifyInclude(fileinfo, include, used_angle_brackets, _include_order))\n      if error_message:\n        error(filename, linenum, 'build/include_order', 4,\n              '%s. Should be: %s.h, c system, c++ system, other.' %\n              (error_message, fileinfo.BaseName()))\n      canonical_include = include_state.CanonicalizeAlphabeticalOrder(include)\n      if not include_state.IsInAlphabeticalOrder(\n          clean_lines, linenum, canonical_include):\n        error(filename, linenum, 'build/include_alpha', 4,\n              'Include \"%s\" not in alphabetical order' % include)\n      include_state.SetLastHeader(canonical_include)\n\n\n\ndef _GetTextInside(text, start_pattern):\n  r\"\"\"Retrieves all the text between matching open and close parentheses.\n\n  Given a string of lines and a regular expression string, retrieve all the text\n  following the expression and between opening punctuation symbols like\n  (, [, or {, and the matching close-punctuation symbol. This properly nested\n  occurrences of the punctuations, so for the text like\n    printf(a(), b(c()));\n  a call to _GetTextInside(text, r'printf\\(') will return 'a(), b(c())'.\n  start_pattern must match string having an open punctuation symbol at the end.\n\n  Args:\n    text: The lines to extract text. Its comments and strings must be elided.\n           It can be single line and can span multiple lines.\n    start_pattern: The regexp string indicating where to start extracting\n                   the text.\n  Returns:\n    The extracted text.\n    None if either the opening string or ending punctuation could not be found.\n  \"\"\"\n  # TODO(unknown): Audit cpplint.py to see what places could be profitably\n  # rewritten to use _GetTextInside (and use inferior regexp matching today).\n\n  # Give opening punctuations to get the matching close-punctuations.\n  matching_punctuation = {'(': ')', '{': '}', '[': ']'}\n  closing_punctuation = set(itervalues(matching_punctuation))\n\n  # Find the position to start extracting text.\n  match = re.search(start_pattern, text, re.M)\n  if not match:  # start_pattern not found in text.\n    return None\n  start_position = match.end(0)\n\n  assert start_position > 0, (\n      'start_pattern must ends with an opening punctuation.')\n  assert text[start_position - 1] in matching_punctuation, (\n      'start_pattern must ends with an opening punctuation.')\n  # Stack of closing punctuations we expect to have in text after position.\n  punctuation_stack = [matching_punctuation[text[start_position - 1]]]\n  position = start_position\n  while punctuation_stack and position < len(text):\n    if text[position] == punctuation_stack[-1]:\n      punctuation_stack.pop()\n    elif text[position] in closing_punctuation:\n      # A closing punctuation without matching opening punctuations.\n      return None\n    elif text[position] in matching_punctuation:\n      punctuation_stack.append(matching_punctuation[text[position]])\n    position += 1\n  if punctuation_stack:\n    # Opening punctuations left without matching close-punctuations.\n    return None\n  # punctuations match.\n  return text[start_position:position - 1]\n\n\n# Patterns for matching call-by-reference parameters.\n#\n# Supports nested templates up to 2 levels deep using this messy pattern:\n#   < (?: < (?: < [^<>]*\n#               >\n#           |   [^<>] )*\n#         >\n#     |   [^<>] )*\n#   >\n_RE_PATTERN_IDENT = r'[_a-zA-Z]\\w*'  # =~ [[:alpha:]][[:alnum:]]*\n_RE_PATTERN_TYPE = (\n    r'(?:const\\s+)?(?:typename\\s+|class\\s+|struct\\s+|union\\s+|enum\\s+)?'\n    r'(?:\\w|'\n    r'\\s*<(?:<(?:<[^<>]*>|[^<>])*>|[^<>])*>|'\n    r'::)+')\n# A call-by-reference parameter ends with '& identifier'.\n_RE_PATTERN_REF_PARAM = re.compile(\n    r'(' + _RE_PATTERN_TYPE + r'(?:\\s*(?:\\bconst\\b|[*]))*\\s*'\n    r'&\\s*' + _RE_PATTERN_IDENT + r')\\s*(?:=[^,()]+)?[,)]')\n# A call-by-const-reference parameter either ends with 'const& identifier'\n# or looks like 'const type& identifier' when 'type' is atomic.\n_RE_PATTERN_CONST_REF_PARAM = (\n    r'(?:.*\\s*\\bconst\\s*&\\s*' + _RE_PATTERN_IDENT +\n    r'|const\\s+' + _RE_PATTERN_TYPE + r'\\s*&\\s*' + _RE_PATTERN_IDENT + r')')\n# Stream types.\n_RE_PATTERN_REF_STREAM_PARAM = (\n    r'(?:.*stream\\s*&\\s*' + _RE_PATTERN_IDENT + r')')\n\n\ndef CheckLanguage(filename, clean_lines, linenum, file_extension,\n                  include_state, nesting_state, error):\n  \"\"\"Checks rules from the 'C++ language rules' section of cppguide.html.\n\n  Some of these rules are hard to test (function overloading, using\n  uint32 inappropriately), but we do the best we can.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    file_extension: The extension (without the dot) of the filename.\n    include_state: An _IncludeState instance in which the headers are inserted.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n  # If the line is empty or consists of entirely a comment, no need to\n  # check it.\n  line = clean_lines.elided[linenum]\n  if not line:\n    return\n\n  match = _RE_PATTERN_INCLUDE.search(line)\n  if match:\n    CheckIncludeLine(filename, clean_lines, linenum, include_state, error)\n    return\n\n  # Reset include state across preprocessor directives.  This is meant\n  # to silence warnings for conditional includes.\n  match = Match(r'^\\s*#\\s*(if|ifdef|ifndef|elif|else|endif)\\b', line)\n  if match:\n    include_state.ResetSection(match.group(1))\n\n\n  # Perform other checks now that we are sure that this is not an include line\n  CheckCasts(filename, clean_lines, linenum, error)\n  CheckGlobalStatic(filename, clean_lines, linenum, error)\n  CheckPrintf(filename, clean_lines, linenum, error)\n\n  if IsHeaderExtension(file_extension):\n    # TODO(unknown): check that 1-arg constructors are explicit.\n    #                How to tell it's a constructor?\n    #                (handled in CheckForNonStandardConstructs for now)\n    # TODO(unknown): check that classes declare or disable copy/assign\n    #                (level 1 error)\n    pass\n\n  # Check if people are using the verboten C basic types.  The only exception\n  # we regularly allow is \"unsigned short port\" for port.\n  if Search(r'\\bshort port\\b', line):\n    if not Search(r'\\bunsigned short port\\b', line):\n      error(filename, linenum, 'runtime/int', 4,\n            'Use \"unsigned short\" for ports, not \"short\"')\n  else:\n    match = Search(r'\\b(short|long(?! +double)|long long)\\b', line)\n    if match:\n      error(filename, linenum, 'runtime/int', 4,\n            'Use int16/int64/etc, rather than the C type %s' % match.group(1))\n\n  # Check if some verboten operator overloading is going on\n  # TODO(unknown): catch out-of-line unary operator&:\n  #   class X {};\n  #   int operator&(const X& x) { return 42; }  // unary operator&\n  # The trick is it's hard to tell apart from binary operator&:\n  #   class Y { int operator&(const Y& x) { return 23; } }; // binary operator&\n  if Search(r'\\boperator\\s*&\\s*\\(\\s*\\)', line):\n    error(filename, linenum, 'runtime/operator', 4,\n          'Unary operator& is dangerous.  Do not use it.')\n\n  # Check for suspicious usage of \"if\" like\n  # } if (a == b) {\n  if Search(r'\\}\\s*if\\s*\\(', line):\n    error(filename, linenum, 'readability/braces', 4,\n          'Did you mean \"else if\"? If not, start a new line for \"if\".')\n\n  # Check for potential format string bugs like printf(foo).\n  # We constrain the pattern not to pick things like DocidForPrintf(foo).\n  # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())\n  # TODO(unknown): Catch the following case. Need to change the calling\n  # convention of the whole function to process multiple line to handle it.\n  #   printf(\n  #       boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line);\n  printf_args = _GetTextInside(line, r'(?i)\\b(string)?printf\\s*\\(')\n  if printf_args:\n    match = Match(r'([\\w.\\->()]+)$', printf_args)\n    if match and match.group(1) != '__VA_ARGS__':\n      function_name = re.search(r'\\b((?:string)?printf)\\s*\\(',\n                                line, re.I).group(1)\n      error(filename, linenum, 'runtime/printf', 4,\n            'Potential format string bug. Do %s(\"%%s\", %s) instead.'\n            % (function_name, match.group(1)))\n\n  # Check for potential memset bugs like memset(buf, sizeof(buf), 0).\n  match = Search(r'memset\\s*\\(([^,]*),\\s*([^,]*),\\s*0\\s*\\)', line)\n  if match and not Match(r\"^''|-?[0-9]+|0x[0-9A-Fa-f]$\", match.group(2)):\n    error(filename, linenum, 'runtime/memset', 4,\n          'Did you mean \"memset(%s, 0, %s)\"?'\n          % (match.group(1), match.group(2)))\n\n  if Search(r'\\busing namespace\\b', line):\n    if Search(r'\\bliterals\\b', line):\n      error(filename, linenum, 'build/namespaces_literals', 5,\n            'Do not use namespace using-directives.  '\n            'Use using-declarations instead.')\n    else:\n      error(filename, linenum, 'build/namespaces', 5,\n            'Do not use namespace using-directives.  '\n            'Use using-declarations instead.')\n\n  # Detect variable-length arrays.\n  match = Match(r'\\s*(.+::)?(\\w+) [a-z]\\w*\\[(.+)];', line)\n  if (match and match.group(2) != 'return' and match.group(2) != 'delete' and\n      match.group(3).find(']') == -1):\n    # Split the size using space and arithmetic operators as delimiters.\n    # If any of the resulting tokens are not compile time constants then\n    # report the error.\n    tokens = re.split(r'\\s|\\+|\\-|\\*|\\/|<<|>>]', match.group(3))\n    is_const = True\n    skip_next = False\n    for tok in tokens:\n      if skip_next:\n        skip_next = False\n        continue\n\n      if Search(r'sizeof\\(.+\\)', tok): continue\n      if Search(r'arraysize\\(\\w+\\)', tok): continue\n\n      tok = tok.lstrip('(')\n      tok = tok.rstrip(')')\n      if not tok: continue\n      if Match(r'\\d+', tok): continue\n      if Match(r'0[xX][0-9a-fA-F]+', tok): continue\n      if Match(r'k[A-Z0-9]\\w*', tok): continue\n      if Match(r'(.+::)?k[A-Z0-9]\\w*', tok): continue\n      if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue\n      # A catch all for tricky sizeof cases, including 'sizeof expression',\n      # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'\n      # requires skipping the next token because we split on ' ' and '*'.\n      if tok.startswith('sizeof'):\n        skip_next = True\n        continue\n      is_const = False\n      break\n    if not is_const:\n      error(filename, linenum, 'runtime/arrays', 1,\n            'Do not use variable-length arrays.  Use an appropriately named '\n            \"('k' followed by CamelCase) compile-time constant for the size.\")\n\n  # Check for use of unnamed namespaces in header files.  Registration\n  # macros are typically OK, so we allow use of \"namespace {\" on lines\n  # that end with backslashes.\n  if (IsHeaderExtension(file_extension)\n      and Search(r'\\bnamespace\\s*{', line)\n      and line[-1] != '\\\\'):\n    error(filename, linenum, 'build/namespaces_headers', 4,\n          'Do not use unnamed namespaces in header files.  See '\n          'https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'\n          ' for more information.')\n\n\ndef CheckGlobalStatic(filename, clean_lines, linenum, error):\n  \"\"\"Check for unsafe global or static objects.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Match two lines at a time to support multiline declarations\n  if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line):\n    line += clean_lines.elided[linenum + 1].strip()\n\n  # Check for people declaring static/global STL strings at the top level.\n  # This is dangerous because the C++ language does not guarantee that\n  # globals with constructors are initialized before the first access, and\n  # also because globals can be destroyed when some threads are still running.\n  # TODO(unknown): Generalize this to also find static unique_ptr instances.\n  # TODO(unknown): File bugs for clang-tidy to find these.\n  match = Match(\n      r'((?:|static +)(?:|const +))(?::*std::)?string( +const)? +'\n      r'([a-zA-Z0-9_:]+)\\b(.*)',\n      line)\n\n  # Remove false positives:\n  # - String pointers (as opposed to values).\n  #    string *pointer\n  #    const string *pointer\n  #    string const *pointer\n  #    string *const pointer\n  #\n  # - Functions and template specializations.\n  #    string Function<Type>(...\n  #    string Class<Type>::Method(...\n  #\n  # - Operators.  These are matched separately because operator names\n  #   cross non-word boundaries, and trying to match both operators\n  #   and functions at the same time would decrease accuracy of\n  #   matching identifiers.\n  #    string Class::operator*()\n  if (match and\n      not Search(r'\\bstring\\b(\\s+const)?\\s*[\\*\\&]\\s*(const\\s+)?\\w', line) and\n      not Search(r'\\boperator\\W', line) and\n      not Match(r'\\s*(<.*>)?(::[a-zA-Z0-9_]+)*\\s*\\(([^\"]|$)', match.group(4))):\n    if Search(r'\\bconst\\b', line):\n      error(filename, linenum, 'runtime/string', 4,\n            'For a static/global string constant, use a C style string '\n            'instead: \"%schar%s %s[]\".' %\n            (match.group(1), match.group(2) or '', match.group(3)))\n    else:\n      error(filename, linenum, 'runtime/string', 4,\n            'Static/global string variables are not permitted.')\n\n  if (Search(r'\\b([A-Za-z0-9_]*_)\\(\\1\\)', line) or\n      Search(r'\\b([A-Za-z0-9_]*_)\\(CHECK_NOTNULL\\(\\1\\)\\)', line)):\n    error(filename, linenum, 'runtime/init', 4,\n          'You seem to be initializing a member variable with itself.')\n\n\ndef CheckPrintf(filename, clean_lines, linenum, error):\n  \"\"\"Check for printf related issues.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # When snprintf is used, the second argument shouldn't be a literal.\n  match = Search(r'snprintf\\s*\\(([^,]*),\\s*([0-9]*)\\s*,', line)\n  if match and match.group(2) != '0':\n    # If 2nd arg is zero, snprintf is used to calculate size.\n    error(filename, linenum, 'runtime/printf', 3,\n          'If you can, use sizeof(%s) instead of %s as the 2nd arg '\n          'to snprintf.' % (match.group(1), match.group(2)))\n\n  # Check if some verboten C functions are being used.\n  if Search(r'\\bsprintf\\s*\\(', line):\n    error(filename, linenum, 'runtime/printf', 5,\n          'Never use sprintf. Use snprintf instead.')\n  match = Search(r'\\b(strcpy|strcat)\\s*\\(', line)\n  if match:\n    error(filename, linenum, 'runtime/printf', 4,\n          'Almost always, snprintf is better than %s' % match.group(1))\n\n\ndef IsDerivedFunction(clean_lines, linenum):\n  \"\"\"Check if current line contains an inherited function.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n  Returns:\n    True if current line contains a function with \"override\"\n    virt-specifier.\n  \"\"\"\n  # Scan back a few lines for start of current function\n  for i in xrange(linenum, max(-1, linenum - 10), -1):\n    match = Match(r'^([^()]*\\w+)\\(', clean_lines.elided[i])\n    if match:\n      # Look for \"override\" after the matching closing parenthesis\n      line, _, closing_paren = CloseExpression(\n          clean_lines, i, len(match.group(1)))\n      return (closing_paren >= 0 and\n              Search(r'\\boverride\\b', line[closing_paren:]))\n  return False\n\n\ndef IsOutOfLineMethodDefinition(clean_lines, linenum):\n  \"\"\"Check if current line contains an out-of-line method definition.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n  Returns:\n    True if current line contains an out-of-line method definition.\n  \"\"\"\n  # Scan back a few lines for start of current function\n  for i in xrange(linenum, max(-1, linenum - 10), -1):\n    if Match(r'^([^()]*\\w+)\\(', clean_lines.elided[i]):\n      return Match(r'^[^()]*\\w+::\\w+\\(', clean_lines.elided[i]) is not None\n  return False\n\n\ndef IsInitializerList(clean_lines, linenum):\n  \"\"\"Check if current line is inside constructor initializer list.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n  Returns:\n    True if current line appears to be inside constructor initializer\n    list, False otherwise.\n  \"\"\"\n  for i in xrange(linenum, 1, -1):\n    line = clean_lines.elided[i]\n    if i == linenum:\n      remove_function_body = Match(r'^(.*)\\{\\s*$', line)\n      if remove_function_body:\n        line = remove_function_body.group(1)\n\n    if Search(r'\\s:\\s*\\w+[({]', line):\n      # A lone colon tend to indicate the start of a constructor\n      # initializer list.  It could also be a ternary operator, which\n      # also tend to appear in constructor initializer lists as\n      # opposed to parameter lists.\n      return True\n    if Search(r'\\}\\s*,\\s*$', line):\n      # A closing brace followed by a comma is probably the end of a\n      # brace-initialized member in constructor initializer list.\n      return True\n    if Search(r'[{};]\\s*$', line):\n      # Found one of the following:\n      # - A closing brace or semicolon, probably the end of the previous\n      #   function.\n      # - An opening brace, probably the start of current class or namespace.\n      #\n      # Current line is probably not inside an initializer list since\n      # we saw one of those things without seeing the starting colon.\n      return False\n\n  # Got to the beginning of the file without seeing the start of\n  # constructor initializer list.\n  return False\n\n\ndef CheckForNonConstReference(filename, clean_lines, linenum,\n                              nesting_state, error):\n  \"\"\"Check for non-const references.\n\n  Separate from CheckLanguage since it scans backwards from current\n  line, instead of scanning forward.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n  # Do nothing if there is no '&' on current line.\n  line = clean_lines.elided[linenum]\n  if '&' not in line:\n    return\n\n  # If a function is inherited, current function doesn't have much of\n  # a choice, so any non-const references should not be blamed on\n  # derived function.\n  if IsDerivedFunction(clean_lines, linenum):\n    return\n\n  # Don't warn on out-of-line method definitions, as we would warn on the\n  # in-line declaration, if it isn't marked with 'override'.\n  if IsOutOfLineMethodDefinition(clean_lines, linenum):\n    return\n\n  # Long type names may be broken across multiple lines, usually in one\n  # of these forms:\n  #   LongType\n  #       ::LongTypeContinued &identifier\n  #   LongType::\n  #       LongTypeContinued &identifier\n  #   LongType<\n  #       ...>::LongTypeContinued &identifier\n  #\n  # If we detected a type split across two lines, join the previous\n  # line to current line so that we can match const references\n  # accordingly.\n  #\n  # Note that this only scans back one line, since scanning back\n  # arbitrary number of lines would be expensive.  If you have a type\n  # that spans more than 2 lines, please use a typedef.\n  if linenum > 1:\n    previous = None\n    if Match(r'\\s*::(?:[\\w<>]|::)+\\s*&\\s*\\S', line):\n      # previous_line\\n + ::current_line\n      previous = Search(r'\\b((?:const\\s*)?(?:[\\w<>]|::)+[\\w<>])\\s*$',\n                        clean_lines.elided[linenum - 1])\n    elif Match(r'\\s*[a-zA-Z_]([\\w<>]|::)+\\s*&\\s*\\S', line):\n      # previous_line::\\n + current_line\n      previous = Search(r'\\b((?:const\\s*)?(?:[\\w<>]|::)+::)\\s*$',\n                        clean_lines.elided[linenum - 1])\n    if previous:\n      line = previous.group(1) + line.lstrip()\n    else:\n      # Check for templated parameter that is split across multiple lines\n      endpos = line.rfind('>')\n      if endpos > -1:\n        (_, startline, startpos) = ReverseCloseExpression(\n            clean_lines, linenum, endpos)\n        if startpos > -1 and startline < linenum:\n          # Found the matching < on an earlier line, collect all\n          # pieces up to current line.\n          line = ''\n          for i in xrange(startline, linenum + 1):\n            line += clean_lines.elided[i].strip()\n\n  # Check for non-const references in function parameters.  A single '&' may\n  # found in the following places:\n  #   inside expression: binary & for bitwise AND\n  #   inside expression: unary & for taking the address of something\n  #   inside declarators: reference parameter\n  # We will exclude the first two cases by checking that we are not inside a\n  # function body, including one that was just introduced by a trailing '{'.\n  # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare].\n  if (nesting_state.previous_stack_top and\n      not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or\n           isinstance(nesting_state.previous_stack_top, _NamespaceInfo))):\n    # Not at toplevel, not within a class, and not within a namespace\n    return\n\n  # Avoid initializer lists.  We only need to scan back from the\n  # current line for something that starts with ':'.\n  #\n  # We don't need to check the current line, since the '&' would\n  # appear inside the second set of parentheses on the current line as\n  # opposed to the first set.\n  if linenum > 0:\n    for i in xrange(linenum - 1, max(0, linenum - 10), -1):\n      previous_line = clean_lines.elided[i]\n      if not Search(r'[),]\\s*$', previous_line):\n        break\n      if Match(r'^\\s*:\\s+\\S', previous_line):\n        return\n\n  # Avoid preprocessors\n  if Search(r'\\\\\\s*$', line):\n    return\n\n  # Avoid constructor initializer lists\n  if IsInitializerList(clean_lines, linenum):\n    return\n\n  # We allow non-const references in a few standard places, like functions\n  # called \"swap()\" or iostream operators like \"<<\" or \">>\".  Do not check\n  # those function parameters.\n  #\n  # We also accept & in static_assert, which looks like a function but\n  # it's actually a declaration expression.\n  allowed_functions = (r'(?:[sS]wap(?:<\\w:+>)?|'\n                           r'operator\\s*[<>][<>]|'\n                           r'static_assert|COMPILE_ASSERT'\n                           r')\\s*\\(')\n  if Search(allowed_functions, line):\n    return\n  elif not Search(r'\\S+\\([^)]*$', line):\n    # Don't see an allowed function on this line.  Actually we\n    # didn't see any function name on this line, so this is likely a\n    # multi-line parameter list.  Try a bit harder to catch this case.\n    for i in xrange(2):\n      if (linenum > i and\n          Search(allowed_functions, clean_lines.elided[linenum - i - 1])):\n        return\n\n  decls = ReplaceAll(r'{[^}]*}', ' ', line)  # exclude function body\n  for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls):\n    if (not Match(_RE_PATTERN_CONST_REF_PARAM, parameter) and\n        not Match(_RE_PATTERN_REF_STREAM_PARAM, parameter)):\n      error(filename, linenum, 'runtime/references', 2,\n            'Is this a non-const reference? '\n            'If so, make const or use a pointer: ' +\n            ReplaceAll(' *<', '<', parameter))\n\n\ndef CheckCasts(filename, clean_lines, linenum, error):\n  \"\"\"Various cast related checks.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Check to see if they're using an conversion function cast.\n  # I just try to capture the most common basic types, though there are more.\n  # Parameterless conversion functions, such as bool(), are allowed as they are\n  # probably a member operator declaration or default constructor.\n  match = Search(\n      r'(\\bnew\\s+(?:const\\s+)?|\\S<\\s*(?:const\\s+)?)?\\b'\n      r'(int|float|double|bool|char|int32|uint32|int64|uint64)'\n      r'(\\([^)].*)', line)\n  expecting_function = ExpectingFunctionArgs(clean_lines, linenum)\n  if match and not expecting_function:\n    matched_type = match.group(2)\n\n    # matched_new_or_template is used to silence two false positives:\n    # - New operators\n    # - Template arguments with function types\n    #\n    # For template arguments, we match on types immediately following\n    # an opening bracket without any spaces.  This is a fast way to\n    # silence the common case where the function type is the first\n    # template argument.  False negative with less-than comparison is\n    # avoided because those operators are usually followed by a space.\n    #\n    #   function<double(double)>   // bracket + no space = false positive\n    #   value < double(42)         // bracket + space = true positive\n    matched_new_or_template = match.group(1)\n\n    # Avoid arrays by looking for brackets that come after the closing\n    # parenthesis.\n    if Match(r'\\([^()]+\\)\\s*\\[', match.group(3)):\n      return\n\n    # Other things to ignore:\n    # - Function pointers\n    # - Casts to pointer types\n    # - Placement new\n    # - Alias declarations\n    matched_funcptr = match.group(3)\n    if (matched_new_or_template is None and\n        not (matched_funcptr and\n             (Match(r'\\((?:[^() ]+::\\s*\\*\\s*)?[^() ]+\\)\\s*\\(',\n                    matched_funcptr) or\n              matched_funcptr.startswith('(*)'))) and\n        not Match(r'\\s*using\\s+\\S+\\s*=\\s*' + matched_type, line) and\n        not Search(r'new\\(\\S+\\)\\s*' + matched_type, line)):\n      error(filename, linenum, 'readability/casting', 4,\n            'Using deprecated casting style.  '\n            'Use static_cast<%s>(...) instead' %\n            matched_type)\n\n  if not expecting_function:\n    CheckCStyleCast(filename, clean_lines, linenum, 'static_cast',\n                    r'\\((int|float|double|bool|char|u?int(16|32|64)|size_t)\\)', error)\n\n  # This doesn't catch all cases. Consider (const char * const)\"hello\".\n  #\n  # (char *) \"foo\" should always be a const_cast (reinterpret_cast won't\n  # compile).\n  if CheckCStyleCast(filename, clean_lines, linenum, 'const_cast',\n                     r'\\((char\\s?\\*+\\s?)\\)\\s*\"', error):\n    pass\n  else:\n    # Check pointer casts for other than string constants\n    CheckCStyleCast(filename, clean_lines, linenum, 'reinterpret_cast',\n                    r'\\((\\w+\\s?\\*+\\s?)\\)', error)\n\n  # In addition, we look for people taking the address of a cast.  This\n  # is dangerous -- casts can assign to temporaries, so the pointer doesn't\n  # point where you think.\n  #\n  # Some non-identifier character is required before the '&' for the\n  # expression to be recognized as a cast.  These are casts:\n  #   expression = &static_cast<int*>(temporary());\n  #   function(&(int*)(temporary()));\n  #\n  # This is not a cast:\n  #   reference_type&(int* function_param);\n  match = Search(\n      r'(?:[^\\w]&\\(([^)*][^)]*)\\)[\\w(])|'\n      r'(?:[^\\w]&(static|dynamic|down|reinterpret)_cast\\b)', line)\n  if match:\n    # Try a better error message when the & is bound to something\n    # dereferenced by the casted pointer, as opposed to the casted\n    # pointer itself.\n    parenthesis_error = False\n    match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\\b)<', line)\n    if match:\n      _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1)))\n      if x1 >= 0 and clean_lines.elided[y1][x1] == '(':\n        _, y2, x2 = CloseExpression(clean_lines, y1, x1)\n        if x2 >= 0:\n          extended_line = clean_lines.elided[y2][x2:]\n          if y2 < clean_lines.NumLines() - 1:\n            extended_line += clean_lines.elided[y2 + 1]\n          if Match(r'\\s*(?:->|\\[)', extended_line):\n            parenthesis_error = True\n\n    if parenthesis_error:\n      error(filename, linenum, 'readability/casting', 4,\n            ('Are you taking an address of something dereferenced '\n             'from a cast?  Wrapping the dereferenced expression in '\n             'parentheses will make the binding more obvious'))\n    else:\n      error(filename, linenum, 'runtime/casting', 4,\n            ('Are you taking an address of a cast?  '\n             'This is dangerous: could be a temp var.  '\n             'Take the address before doing the cast, rather than after'))\n\n\ndef CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error):\n  \"\"\"Checks for a C-style cast by looking for the pattern.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    cast_type: The string for the C++ cast to recommend.  This is either\n      reinterpret_cast, static_cast, or const_cast, depending.\n    pattern: The regular expression used to find C-style casts.\n    error: The function to call with any errors found.\n\n  Returns:\n    True if an error was emitted.\n    False otherwise.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  match = Search(pattern, line)\n  if not match:\n    return False\n\n  # Exclude lines with keywords that tend to look like casts\n  context = line[0:match.start(1) - 1]\n  if Match(r'.*\\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\\s*$', context):\n    return False\n\n  # Try expanding current context to see if we one level of\n  # parentheses inside a macro.\n  if linenum > 0:\n    for i in xrange(linenum - 1, max(0, linenum - 5), -1):\n      context = clean_lines.elided[i] + context\n  if Match(r'.*\\b[_A-Z][_A-Z0-9]*\\s*\\((?:\\([^()]*\\)|[^()])*$', context):\n    return False\n\n  # operator++(int) and operator--(int)\n  if context.endswith(' operator++') or context.endswith(' operator--'):\n    return False\n\n  # A single unnamed argument for a function tends to look like old style cast.\n  # If we see those, don't issue warnings for deprecated casts.\n  remainder = line[match.end(0):]\n  if Match(r'^\\s*(?:;|const\\b|throw\\b|final\\b|override\\b|[=>{),]|->)',\n           remainder):\n    return False\n\n  # At this point, all that should be left is actual casts.\n  error(filename, linenum, 'readability/casting', 4,\n        'Using C-style cast.  Use %s<%s>(...) instead' %\n        (cast_type, match.group(1)))\n\n  return True\n\n\ndef ExpectingFunctionArgs(clean_lines, linenum):\n  \"\"\"Checks whether where function type arguments are expected.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n\n  Returns:\n    True if the line at 'linenum' is inside something that expects arguments\n    of function types.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  return (Match(r'^\\s*MOCK_(CONST_)?METHOD\\d+(_T)?\\(', line) or\n          (linenum >= 2 and\n           (Match(r'^\\s*MOCK_(?:CONST_)?METHOD\\d+(?:_T)?\\((?:\\S+,)?\\s*$',\n                  clean_lines.elided[linenum - 1]) or\n            Match(r'^\\s*MOCK_(?:CONST_)?METHOD\\d+(?:_T)?\\(\\s*$',\n                  clean_lines.elided[linenum - 2]) or\n            Search(r'\\bstd::m?function\\s*\\<\\s*$',\n                   clean_lines.elided[linenum - 1]))))\n\n\n_HEADERS_CONTAINING_TEMPLATES = (\n    ('<deque>', ('deque',)),\n    ('<functional>', ('unary_function', 'binary_function',\n                      'plus', 'minus', 'multiplies', 'divides', 'modulus',\n                      'negate',\n                      'equal_to', 'not_equal_to', 'greater', 'less',\n                      'greater_equal', 'less_equal',\n                      'logical_and', 'logical_or', 'logical_not',\n                      'unary_negate', 'not1', 'binary_negate', 'not2',\n                      'bind1st', 'bind2nd',\n                      'pointer_to_unary_function',\n                      'pointer_to_binary_function',\n                      'ptr_fun',\n                      'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',\n                      'mem_fun_ref_t',\n                      'const_mem_fun_t', 'const_mem_fun1_t',\n                      'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',\n                      'mem_fun_ref',\n                     )),\n    ('<limits>', ('numeric_limits',)),\n    ('<list>', ('list',)),\n    ('<map>', ('multimap',)),\n    ('<memory>', ('allocator', 'make_shared', 'make_unique', 'shared_ptr',\n                  'unique_ptr', 'weak_ptr')),\n    ('<queue>', ('queue', 'priority_queue',)),\n    ('<set>', ('multiset',)),\n    ('<stack>', ('stack',)),\n    ('<string>', ('char_traits', 'basic_string',)),\n    ('<tuple>', ('tuple',)),\n    ('<unordered_map>', ('unordered_map', 'unordered_multimap')),\n    ('<unordered_set>', ('unordered_set', 'unordered_multiset')),\n    ('<utility>', ('pair',)),\n    ('<vector>', ('vector',)),\n\n    # gcc extensions.\n    # Note: std::hash is their hash, ::hash is our hash\n    ('<hash_map>', ('hash_map', 'hash_multimap',)),\n    ('<hash_set>', ('hash_set', 'hash_multiset',)),\n    ('<slist>', ('slist',)),\n    )\n\n_HEADERS_MAYBE_TEMPLATES = (\n    ('<algorithm>', ('copy', 'max', 'min', 'min_element', 'sort',\n                     'transform',\n                    )),\n    ('<utility>', ('forward', 'make_pair', 'move', 'swap')),\n    )\n\n_RE_PATTERN_STRING = re.compile(r'\\bstring\\b')\n\n_re_pattern_headers_maybe_templates = []\nfor _header, _templates in _HEADERS_MAYBE_TEMPLATES:\n  for _template in _templates:\n    # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or\n    # 'type::max()'.\n    _re_pattern_headers_maybe_templates.append(\n        (re.compile(r'[^>.]\\b' + _template + r'(<.*?>)?\\([^\\)]'),\n            _template,\n            _header))\n# Match set<type>, but not foo->set<type>, foo.set<type>\n_re_pattern_headers_maybe_templates.append(\n    (re.compile(r'[^>.]\\bset\\s*\\<'),\n        'set<>',\n        '<set>'))\n# Match 'map<type> var' and 'std::map<type>(...)', but not 'map<type>(...)''\n_re_pattern_headers_maybe_templates.append(\n    (re.compile(r'(std\\b::\\bmap\\s*\\<)|(^(std\\b::\\b)map\\b\\(\\s*\\<)'),\n        'map<>',\n        '<map>'))\n\n# Other scripts may reach in and modify this pattern.\n_re_pattern_templates = []\nfor _header, _templates in _HEADERS_CONTAINING_TEMPLATES:\n  for _template in _templates:\n    _re_pattern_templates.append(\n        (re.compile(r'(\\<|\\b)' + _template + r'\\s*\\<'),\n         _template + '<>',\n         _header))\n\n\ndef FilesBelongToSameModule(filename_cc, filename_h):\n  \"\"\"Check if these two filenames belong to the same module.\n\n  The concept of a 'module' here is a as follows:\n  foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the\n  same 'module' if they are in the same directory.\n  some/path/public/xyzzy and some/path/internal/xyzzy are also considered\n  to belong to the same module here.\n\n  If the filename_cc contains a longer path than the filename_h, for example,\n  '/absolute/path/to/base/sysinfo.cc', and this file would include\n  'base/sysinfo.h', this function also produces the prefix needed to open the\n  header. This is used by the caller of this function to more robustly open the\n  header file. We don't have access to the real include paths in this context,\n  so we need this guesswork here.\n\n  Known bugs: tools/base/bar.cc and base/bar.h belong to the same module\n  according to this implementation. Because of this, this function gives\n  some false positives. This should be sufficiently rare in practice.\n\n  Args:\n    filename_cc: is the path for the source (e.g. .cc) file\n    filename_h: is the path for the header path\n\n  Returns:\n    Tuple with a bool and a string:\n    bool: True if filename_cc and filename_h belong to the same module.\n    string: the additional prefix needed to open the header file.\n  \"\"\"\n  fileinfo_cc = FileInfo(filename_cc)\n  if not fileinfo_cc.Extension().lstrip('.') in GetNonHeaderExtensions():\n    return (False, '')\n\n  fileinfo_h = FileInfo(filename_h)\n  if not IsHeaderExtension(fileinfo_h.Extension().lstrip('.')):\n    return (False, '')\n\n  filename_cc = filename_cc[:-(len(fileinfo_cc.Extension()))]\n  matched_test_suffix = Search(_TEST_FILE_SUFFIX, fileinfo_cc.BaseName())\n  if matched_test_suffix:\n    filename_cc = filename_cc[:-len(matched_test_suffix.group(1))]\n\n  filename_cc = filename_cc.replace('/public/', '/')\n  filename_cc = filename_cc.replace('/internal/', '/')\n\n  filename_h = filename_h[:-(len(fileinfo_h.Extension()))]\n  if filename_h.endswith('-inl'):\n    filename_h = filename_h[:-len('-inl')]\n  filename_h = filename_h.replace('/public/', '/')\n  filename_h = filename_h.replace('/internal/', '/')\n\n  files_belong_to_same_module = filename_cc.endswith(filename_h)\n  common_path = ''\n  if files_belong_to_same_module:\n    common_path = filename_cc[:-len(filename_h)]\n  return files_belong_to_same_module, common_path\n\n\ndef UpdateIncludeState(filename, include_dict, io=codecs):\n  \"\"\"Fill up the include_dict with new includes found from the file.\n\n  Args:\n    filename: the name of the header to read.\n    include_dict: a dictionary in which the headers are inserted.\n    io: The io factory to use to read the file. Provided for testability.\n\n  Returns:\n    True if a header was successfully added. False otherwise.\n  \"\"\"\n  headerfile = None\n  try:\n    with io.open(filename, 'r', 'utf8', 'replace') as headerfile:\n      linenum = 0\n      for line in headerfile:\n        linenum += 1\n        clean_line = CleanseComments(line)\n        match = _RE_PATTERN_INCLUDE.search(clean_line)\n        if match:\n          include = match.group(2)\n          include_dict.setdefault(include, linenum)\n    return True\n  except IOError:\n    return False\n\n\n\ndef CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,\n                              io=codecs):\n  \"\"\"Reports for missing stl includes.\n\n  This function will output warnings to make sure you are including the headers\n  necessary for the stl containers and functions that you use. We only give one\n  reason to include a header. For example, if you use both equal_to<> and\n  less<> in a .h file, only one (the latter in the file) of these will be\n  reported as a reason to include the <functional>.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    include_state: An _IncludeState instance.\n    error: The function to call with any errors found.\n    io: The IO factory to use to read the header file. Provided for unittest\n        injection.\n  \"\"\"\n  required = {}  # A map of header name to linenumber and the template entity.\n                 # Example of required: { '<functional>': (1219, 'less<>') }\n\n  for linenum in xrange(clean_lines.NumLines()):\n    line = clean_lines.elided[linenum]\n    if not line or line[0] == '#':\n      continue\n\n    # String is special -- it is a non-templatized type in STL.\n    matched = _RE_PATTERN_STRING.search(line)\n    if matched:\n      # Don't warn about strings in non-STL namespaces:\n      # (We check only the first match per line; good enough.)\n      prefix = line[:matched.start()]\n      if prefix.endswith('std::') or not prefix.endswith('::'):\n        required['<string>'] = (linenum, 'string')\n\n    for pattern, template, header in _re_pattern_headers_maybe_templates:\n      if pattern.search(line):\n        required[header] = (linenum, template)\n\n    # The following function is just a speed up, no semantics are changed.\n    if not '<' in line:  # Reduces the cpu time usage by skipping lines.\n      continue\n\n    for pattern, template, header in _re_pattern_templates:\n      matched = pattern.search(line)\n      if matched:\n        # Don't warn about IWYU in non-STL namespaces:\n        # (We check only the first match per line; good enough.)\n        prefix = line[:matched.start()]\n        if prefix.endswith('std::') or not prefix.endswith('::'):\n          required[header] = (linenum, template)\n\n  # The policy is that if you #include something in foo.h you don't need to\n  # include it again in foo.cc. Here, we will look at possible includes.\n  # Let's flatten the include_state include_list and copy it into a dictionary.\n  include_dict = dict([item for sublist in include_state.include_list\n                       for item in sublist])\n\n  # Did we find the header for this file (if any) and successfully load it?\n  header_found = False\n\n  # Use the absolute path so that matching works properly.\n  abs_filename = FileInfo(filename).FullName()\n\n  # For Emacs's flymake.\n  # If cpplint is invoked from Emacs's flymake, a temporary file is generated\n  # by flymake and that file name might end with '_flymake.cc'. In that case,\n  # restore original file name here so that the corresponding header file can be\n  # found.\n  # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'\n  # instead of 'foo_flymake.h'\n  abs_filename = re.sub(r'_flymake\\.cc$', '.cc', abs_filename)\n\n  # include_dict is modified during iteration, so we iterate over a copy of\n  # the keys.\n  header_keys = list(include_dict.keys())\n  for header in header_keys:\n    (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)\n    fullpath = common_path + header\n    if same_module and UpdateIncludeState(fullpath, include_dict, io):\n      header_found = True\n\n  # If we can't find the header file for a .cc, assume it's because we don't\n  # know where to look. In that case we'll give up as we're not sure they\n  # didn't include it in the .h file.\n  # TODO(unknown): Do a better job of finding .h files so we are confident that\n  # not having the .h file means there isn't one.\n  if not header_found:\n    for extension in GetNonHeaderExtensions():\n      if filename.endswith('.' + extension):\n        return\n\n  # All the lines have been processed, report the errors found.\n  for required_header_unstripped in sorted(required, key=required.__getitem__):\n    template = required[required_header_unstripped][1]\n    if required_header_unstripped.strip('<>\"') not in include_dict:\n      error(filename, required[required_header_unstripped][0],\n            'build/include_what_you_use', 4,\n            'Add #include ' + required_header_unstripped + ' for ' + template)\n\n\n_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\\bmake_pair\\s*<')\n\n\ndef CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):\n  \"\"\"Check that make_pair's template arguments are deduced.\n\n  G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are\n  specified explicitly, and such use isn't intended in any case.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line)\n  if match:\n    error(filename, linenum, 'build/explicit_make_pair',\n          4,  # 4 = high confidence\n          'For C++11-compatibility, omit template arguments from make_pair'\n          ' OR use pair directly OR if appropriate, construct a pair directly')\n\n\ndef CheckRedundantVirtual(filename, clean_lines, linenum, error):\n  \"\"\"Check if line contains a redundant \"virtual\" function-specifier.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  # Look for \"virtual\" on current line.\n  line = clean_lines.elided[linenum]\n  virtual = Match(r'^(.*)(\\bvirtual\\b)(.*)$', line)\n  if not virtual: return\n\n  # Ignore \"virtual\" keywords that are near access-specifiers.  These\n  # are only used in class base-specifier and do not apply to member\n  # functions.\n  if (Search(r'\\b(public|protected|private)\\s+$', virtual.group(1)) or\n      Match(r'^\\s+(public|protected|private)\\b', virtual.group(3))):\n    return\n\n  # Ignore the \"virtual\" keyword from virtual base classes.  Usually\n  # there is a column on the same line in these cases (virtual base\n  # classes are rare in google3 because multiple inheritance is rare).\n  if Match(r'^.*[^:]:[^:].*$', line): return\n\n  # Look for the next opening parenthesis.  This is the start of the\n  # parameter list (possibly on the next line shortly after virtual).\n  # TODO(unknown): doesn't work if there are virtual functions with\n  # decltype() or other things that use parentheses, but csearch suggests\n  # that this is rare.\n  end_col = -1\n  end_line = -1\n  start_col = len(virtual.group(2))\n  for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())):\n    line = clean_lines.elided[start_line][start_col:]\n    parameter_list = Match(r'^([^(]*)\\(', line)\n    if parameter_list:\n      # Match parentheses to find the end of the parameter list\n      (_, end_line, end_col) = CloseExpression(\n          clean_lines, start_line, start_col + len(parameter_list.group(1)))\n      break\n    start_col = 0\n\n  if end_col < 0:\n    return  # Couldn't find end of parameter list, give up\n\n  # Look for \"override\" or \"final\" after the parameter list\n  # (possibly on the next few lines).\n  for i in xrange(end_line, min(end_line + 3, clean_lines.NumLines())):\n    line = clean_lines.elided[i][end_col:]\n    match = Search(r'\\b(override|final)\\b', line)\n    if match:\n      error(filename, linenum, 'readability/inheritance', 4,\n            ('\"virtual\" is redundant since function is '\n             'already declared as \"%s\"' % match.group(1)))\n\n    # Set end_col to check whole lines after we are done with the\n    # first line.\n    end_col = 0\n    if Search(r'[^\\w]\\s*$', line):\n      break\n\n\ndef CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error):\n  \"\"\"Check if line contains a redundant \"override\" or \"final\" virt-specifier.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  # Look for closing parenthesis nearby.  We need one to confirm where\n  # the declarator ends and where the virt-specifier starts to avoid\n  # false positives.\n  line = clean_lines.elided[linenum]\n  declarator_end = line.rfind(')')\n  if declarator_end >= 0:\n    fragment = line[declarator_end:]\n  else:\n    if linenum > 1 and clean_lines.elided[linenum - 1].rfind(')') >= 0:\n      fragment = line\n    else:\n      return\n\n  # Check that at most one of \"override\" or \"final\" is present, not both\n  if Search(r'\\boverride\\b', fragment) and Search(r'\\bfinal\\b', fragment):\n    error(filename, linenum, 'readability/inheritance', 4,\n          ('\"override\" is redundant since function is '\n           'already declared as \"final\"'))\n\n\n\n\n# Returns true if we are at a new block, and it is directly\n# inside of a namespace.\ndef IsBlockInNameSpace(nesting_state, is_forward_declaration):\n  \"\"\"Checks that the new block is directly in a namespace.\n\n  Args:\n    nesting_state: The _NestingState object that contains info about our state.\n    is_forward_declaration: If the class is a forward declared class.\n  Returns:\n    Whether or not the new block is directly in a namespace.\n  \"\"\"\n  if is_forward_declaration:\n    return len(nesting_state.stack) >= 1 and (\n      isinstance(nesting_state.stack[-1], _NamespaceInfo))\n\n\n  return (len(nesting_state.stack) > 1 and\n          nesting_state.stack[-1].check_namespace_indentation and\n          isinstance(nesting_state.stack[-2], _NamespaceInfo))\n\n\ndef ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item,\n                                    raw_lines_no_comments, linenum):\n  \"\"\"This method determines if we should apply our namespace indentation check.\n\n  Args:\n    nesting_state: The current nesting state.\n    is_namespace_indent_item: If we just put a new class on the stack, True.\n      If the top of the stack is not a class, or we did not recently\n      add the class, False.\n    raw_lines_no_comments: The lines without the comments.\n    linenum: The current line number we are processing.\n\n  Returns:\n    True if we should apply our namespace indentation check. Currently, it\n    only works for classes and namespaces inside of a namespace.\n  \"\"\"\n\n  is_forward_declaration = IsForwardClassDeclaration(raw_lines_no_comments,\n                                                     linenum)\n\n  if not (is_namespace_indent_item or is_forward_declaration):\n    return False\n\n  # If we are in a macro, we do not want to check the namespace indentation.\n  if IsMacroDefinition(raw_lines_no_comments, linenum):\n    return False\n\n  return IsBlockInNameSpace(nesting_state, is_forward_declaration)\n\n\n# Call this method if the line is directly inside of a namespace.\n# If the line above is blank (excluding comments) or the start of\n# an inner namespace, it cannot be indented.\ndef CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum,\n                                    error):\n  line = raw_lines_no_comments[linenum]\n  if Match(r'^\\s+', line):\n    error(filename, linenum, 'runtime/indentation_namespace', 4,\n          'Do not indent within a namespace')\n\n\ndef ProcessLine(filename, file_extension, clean_lines, line,\n                include_state, function_state, nesting_state, error,\n                extra_check_functions=None):\n  \"\"\"Processes a single line in the file.\n\n  Args:\n    filename: Filename of the file that is being processed.\n    file_extension: The extension (dot not included) of the file.\n    clean_lines: An array of strings, each representing a line of the file,\n                 with comments stripped.\n    line: Number of line being processed.\n    include_state: An _IncludeState instance in which the headers are inserted.\n    function_state: A _FunctionState instance which counts function lines, etc.\n    nesting_state: A NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: A callable to which errors are reported, which takes 4 arguments:\n           filename, line number, error level, and message\n    extra_check_functions: An array of additional check functions that will be\n                           run on each source line. Each function takes 4\n                           arguments: filename, clean_lines, line, error\n  \"\"\"\n  raw_lines = clean_lines.raw_lines\n  ParseNolintSuppressions(filename, raw_lines[line], line, error)\n  nesting_state.Update(filename, clean_lines, line, error)\n  CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line,\n                               error)\n  if nesting_state.InAsmBlock(): return\n  CheckForFunctionLengths(filename, clean_lines, line, function_state, error)\n  CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)\n  CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)\n  CheckLanguage(filename, clean_lines, line, file_extension, include_state,\n                nesting_state, error)\n  CheckForNonConstReference(filename, clean_lines, line, nesting_state, error)\n  CheckForNonStandardConstructs(filename, clean_lines, line,\n                                nesting_state, error)\n  CheckVlogArguments(filename, clean_lines, line, error)\n  CheckPosixThreading(filename, clean_lines, line, error)\n  CheckInvalidIncrement(filename, clean_lines, line, error)\n  CheckMakePairUsesDeduction(filename, clean_lines, line, error)\n  CheckRedundantVirtual(filename, clean_lines, line, error)\n  CheckRedundantOverrideOrFinal(filename, clean_lines, line, error)\n  if extra_check_functions:\n    for check_fn in extra_check_functions:\n      check_fn(filename, clean_lines, line, error)\n\ndef FlagCxx11Features(filename, clean_lines, linenum, error):\n  \"\"\"Flag those c++11 features that we only allow in certain places.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  include = Match(r'\\s*#\\s*include\\s+[<\"]([^<\"]+)[\">]', line)\n\n  # Flag unapproved C++ TR1 headers.\n  if include and include.group(1).startswith('tr1/'):\n    error(filename, linenum, 'build/c++tr1', 5,\n          ('C++ TR1 headers such as <%s> are unapproved.') % include.group(1))\n\n  # Flag unapproved C++11 headers.\n  if include and include.group(1) in ('cfenv',\n                                      'condition_variable',\n                                      'fenv.h',\n                                      'future',\n                                      'mutex',\n                                      'thread',\n                                      'chrono',\n                                      'ratio',\n                                      'regex',\n                                      'system_error',\n                                     ):\n    error(filename, linenum, 'build/c++11', 5,\n          ('<%s> is an unapproved C++11 header.') % include.group(1))\n\n  # The only place where we need to worry about C++11 keywords and library\n  # features in preprocessor directives is in macro definitions.\n  if Match(r'\\s*#', line) and not Match(r'\\s*#\\s*define\\b', line): return\n\n  # These are classes and free functions.  The classes are always\n  # mentioned as std::*, but we only catch the free functions if\n  # they're not found by ADL.  They're alphabetical by header.\n  for top_name in (\n      # type_traits\n      'alignment_of',\n      'aligned_union',\n      ):\n    if Search(r'\\bstd::%s\\b' % top_name, line):\n      error(filename, linenum, 'build/c++11', 5,\n            ('std::%s is an unapproved C++11 class or function.  Send c-style '\n             'an example of where it would make your code more readable, and '\n             'they may let you use it.') % top_name)\n\n\ndef FlagCxx14Features(filename, clean_lines, linenum, error):\n  \"\"\"Flag those C++14 features that we restrict.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  include = Match(r'\\s*#\\s*include\\s+[<\"]([^<\"]+)[\">]', line)\n\n  # Flag unapproved C++14 headers.\n  if include and include.group(1) in ('scoped_allocator', 'shared_mutex'):\n    error(filename, linenum, 'build/c++14', 5,\n          ('<%s> is an unapproved C++14 header.') % include.group(1))\n\n\ndef ProcessFileData(filename, file_extension, lines, error,\n                    extra_check_functions=None):\n  \"\"\"Performs lint checks and reports any errors to the given error function.\n\n  Args:\n    filename: Filename of the file that is being processed.\n    file_extension: The extension (dot not included) of the file.\n    lines: An array of strings, each representing a line of the file, with the\n           last element being empty if the file is terminated with a newline.\n    error: A callable to which errors are reported, which takes 4 arguments:\n           filename, line number, error level, and message\n    extra_check_functions: An array of additional check functions that will be\n                           run on each source line. Each function takes 4\n                           arguments: filename, clean_lines, line, error\n  \"\"\"\n  lines = (['// marker so line numbers and indices both start at 1'] + lines +\n           ['// marker so line numbers end in a known way'])\n\n  include_state = _IncludeState()\n  function_state = _FunctionState()\n  nesting_state = NestingState()\n\n  ResetNolintSuppressions()\n\n  CheckForCopyright(filename, lines, error)\n  ProcessGlobalSuppresions(lines)\n  RemoveMultiLineComments(filename, lines, error)\n  clean_lines = CleansedLines(lines)\n\n  if IsHeaderExtension(file_extension):\n    CheckForHeaderGuard(filename, clean_lines, error)\n\n  for line in xrange(clean_lines.NumLines()):\n    ProcessLine(filename, file_extension, clean_lines, line,\n                include_state, function_state, nesting_state, error,\n                extra_check_functions)\n    FlagCxx11Features(filename, clean_lines, line, error)\n  nesting_state.CheckCompletedBlocks(filename, error)\n\n  CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)\n\n  # Check that the .cc file has included its header if it exists.\n  if _IsSourceExtension(file_extension):\n    CheckHeaderFileIncluded(filename, include_state, error)\n\n  # We check here rather than inside ProcessLine so that we see raw\n  # lines rather than \"cleaned\" lines.\n  CheckForBadCharacters(filename, lines, error)\n\n  CheckForNewlineAtEOF(filename, lines, error)\n\ndef ProcessConfigOverrides(filename):\n  \"\"\" Loads the configuration files and processes the config overrides.\n\n  Args:\n    filename: The name of the file being processed by the linter.\n\n  Returns:\n    False if the current |filename| should not be processed further.\n  \"\"\"\n\n  abs_filename = os.path.abspath(filename)\n  cfg_filters = []\n  keep_looking = True\n  while keep_looking:\n    abs_path, base_name = os.path.split(abs_filename)\n    if not base_name:\n      break  # Reached the root directory.\n\n    cfg_file = os.path.join(abs_path, \"CPPLINT.cfg\")\n    abs_filename = abs_path\n    if not os.path.isfile(cfg_file):\n      continue\n\n    try:\n      with open(cfg_file) as file_handle:\n        for line in file_handle:\n          line, _, _ = line.partition('#')  # Remove comments.\n          if not line.strip():\n            continue\n\n          name, _, val = line.partition('=')\n          name = name.strip()\n          val = val.strip()\n          if name == 'set noparent':\n            keep_looking = False\n          elif name == 'filter':\n            cfg_filters.append(val)\n          elif name == 'exclude_files':\n            # When matching exclude_files pattern, use the base_name of\n            # the current file name or the directory name we are processing.\n            # For example, if we are checking for lint errors in /foo/bar/baz.cc\n            # and we found the .cfg file at /foo/CPPLINT.cfg, then the config\n            # file's \"exclude_files\" filter is meant to be checked against \"bar\"\n            # and not \"baz\" nor \"bar/baz.cc\".\n            if base_name:\n              pattern = re.compile(val)\n              if pattern.match(base_name):\n                if _cpplint_state.quiet:\n                  # Suppress \"Ignoring file\" warning when using --quiet.\n                  return False\n                _cpplint_state.PrintInfo('Ignoring \"%s\": file excluded by \"%s\". '\n                                 'File path component \"%s\" matches '\n                                 'pattern \"%s\"\\n' %\n                                 (filename, cfg_file, base_name, val))\n                return False\n          elif name == 'linelength':\n            global _line_length\n            try:\n              _line_length = int(val)\n            except ValueError:\n              _cpplint_state.PrintError('Line length must be numeric.')\n          elif name == 'extensions':\n            ProcessExtensionsOption(val)\n          elif name == 'root':\n            global _root\n            # root directories are specified relative to CPPLINT.cfg dir.\n            _root = os.path.join(os.path.dirname(cfg_file), val)\n          elif name == 'headers':\n            ProcessHppHeadersOption(val)\n          elif name == 'includeorder':\n            ProcessIncludeOrderOption(val)\n          else:\n            _cpplint_state.PrintError(\n                'Invalid configuration option (%s) in file %s\\n' %\n                (name, cfg_file))\n\n    except IOError:\n      _cpplint_state.PrintError(\n          \"Skipping config file '%s': Can't open for reading\\n\" % cfg_file)\n      keep_looking = False\n\n  # Apply all the accumulated filters in reverse order (top-level directory\n  # config options having the least priority).\n  for cfg_filter in reversed(cfg_filters):\n    _AddFilters(cfg_filter)\n\n  return True\n\n\ndef ProcessFile(filename, vlevel, extra_check_functions=None):\n  \"\"\"Does google-lint on a single file.\n\n  Args:\n    filename: The name of the file to parse.\n\n    vlevel: The level of errors to report.  Every error of confidence\n    >= verbose_level will be reported.  0 is a good default.\n\n    extra_check_functions: An array of additional check functions that will be\n                           run on each source line. Each function takes 4\n                           arguments: filename, clean_lines, line, error\n  \"\"\"\n\n  _SetVerboseLevel(vlevel)\n  _BackupFilters()\n  old_errors = _cpplint_state.error_count\n\n  if not ProcessConfigOverrides(filename):\n    _RestoreFilters()\n    return\n\n  lf_lines = []\n  crlf_lines = []\n  try:\n    # Support the UNIX convention of using \"-\" for stdin.  Note that\n    # we are not opening the file with universal newline support\n    # (which codecs doesn't support anyway), so the resulting lines do\n    # contain trailing '\\r' characters if we are reading a file that\n    # has CRLF endings.\n    # If after the split a trailing '\\r' is present, it is removed\n    # below.\n    if filename == '-':\n      lines = codecs.StreamReaderWriter(sys.stdin,\n                                        codecs.getreader('utf8'),\n                                        codecs.getwriter('utf8'),\n                                        'replace').read().split('\\n')\n    else:\n      with codecs.open(filename, 'r', 'utf8', 'replace') as target_file:\n        lines = target_file.read().split('\\n')\n\n    # Remove trailing '\\r'.\n    # The -1 accounts for the extra trailing blank line we get from split()\n    for linenum in range(len(lines) - 1):\n      if lines[linenum].endswith('\\r'):\n        lines[linenum] = lines[linenum].rstrip('\\r')\n        crlf_lines.append(linenum + 1)\n      else:\n        lf_lines.append(linenum + 1)\n\n  except IOError:\n    _cpplint_state.PrintError(\n        \"Skipping input '%s': Can't open for reading\\n\" % filename)\n    _RestoreFilters()\n    return\n\n  # Note, if no dot is found, this will give the entire filename as the ext.\n  file_extension = filename[filename.rfind('.') + 1:]\n\n  # When reading from stdin, the extension is unknown, so no cpplint tests\n  # should rely on the extension.\n  if filename != '-' and file_extension not in GetAllExtensions():\n    _cpplint_state.PrintError('Ignoring %s; not a valid file name '\n                     '(%s)\\n' % (filename, ', '.join(GetAllExtensions())))\n  else:\n    ProcessFileData(filename, file_extension, lines, Error,\n                    extra_check_functions)\n\n    # If end-of-line sequences are a mix of LF and CR-LF, issue\n    # warnings on the lines with CR.\n    #\n    # Don't issue any warnings if all lines are uniformly LF or CR-LF,\n    # since critique can handle these just fine, and the style guide\n    # doesn't dictate a particular end of line sequence.\n    #\n    # We can't depend on os.linesep to determine what the desired\n    # end-of-line sequence should be, since that will return the\n    # server-side end-of-line sequence.\n    if lf_lines and crlf_lines:\n      # Warn on every line with CR.  An alternative approach might be to\n      # check whether the file is mostly CRLF or just LF, and warn on the\n      # minority, we bias toward LF here since most tools prefer LF.\n      for linenum in crlf_lines:\n        Error(filename, linenum, 'whitespace/newline', 1,\n              'Unexpected \\\\r (^M) found; better to use only \\\\n')\n\n  # Suppress printing anything if --quiet was passed unless the error\n  # count has increased after processing this file.\n  if not _cpplint_state.quiet or old_errors != _cpplint_state.error_count:\n    _cpplint_state.PrintInfo('Done processing %s\\n' % filename)\n  _RestoreFilters()\n\n\ndef PrintUsage(message):\n  \"\"\"Prints a brief usage string and exits, optionally with an error message.\n\n  Args:\n    message: The optional error message.\n  \"\"\"\n  sys.stderr.write(_USAGE  % (sorted(list(GetAllExtensions())),\n       ','.join(sorted(list(GetAllExtensions()))),\n       sorted(GetHeaderExtensions()),\n       ','.join(sorted(GetHeaderExtensions()))))\n\n  if message:\n    sys.exit('\\nFATAL ERROR: ' + message)\n  else:\n    sys.exit(0)\n\ndef PrintVersion():\n  sys.stdout.write('Cpplint fork (https://github.com/cpplint/cpplint)\\n')\n  sys.stdout.write('cpplint ' + __VERSION__ + '\\n')\n  sys.stdout.write('Python ' + sys.version + '\\n')\n  sys.exit(0)\n\ndef PrintCategories():\n  \"\"\"Prints a list of all the error-categories used by error messages.\n\n  These are the categories used to filter messages via --filter.\n  \"\"\"\n  sys.stderr.write(''.join('  %s\\n' % cat for cat in _ERROR_CATEGORIES))\n  sys.exit(0)\n\n\ndef ParseArguments(args):\n  \"\"\"Parses the command line arguments.\n\n  This may set the output format and verbosity level as side-effects.\n\n  Args:\n    args: The command line arguments:\n\n  Returns:\n    The list of filenames to lint.\n  \"\"\"\n  try:\n    (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',\n                                                 'v=',\n                                                 'version',\n                                                 'counting=',\n                                                 'filter=',\n                                                 'root=',\n                                                 'repository=',\n                                                 'linelength=',\n                                                 'extensions=',\n                                                 'exclude=',\n                                                 'recursive',\n                                                 'headers=',\n                                                 'includeorder=',\n                                                 'quiet'])\n  except getopt.GetoptError:\n    PrintUsage('Invalid arguments.')\n\n  verbosity = _VerboseLevel()\n  output_format = _OutputFormat()\n  filters = ''\n  quiet = _Quiet()\n  counting_style = ''\n  recursive = False\n\n  for (opt, val) in opts:\n    if opt == '--help':\n      PrintUsage(None)\n    if opt == '--version':\n      PrintVersion()\n    elif opt == '--output':\n      if val not in ('emacs', 'vs7', 'eclipse', 'junit', 'sed', 'gsed'):\n        PrintUsage('The only allowed output formats are emacs, vs7, eclipse '\n                   'sed, gsed and junit.')\n      output_format = val\n    elif opt == '--quiet':\n      quiet = True\n    elif opt == '--verbose' or opt == '--v':\n      verbosity = int(val)\n    elif opt == '--filter':\n      filters = val\n      if not filters:\n        PrintCategories()\n    elif opt == '--counting':\n      if val not in ('total', 'toplevel', 'detailed'):\n        PrintUsage('Valid counting options are total, toplevel, and detailed')\n      counting_style = val\n    elif opt == '--root':\n      global _root\n      _root = val\n    elif opt == '--repository':\n      global _repository\n      _repository = val\n    elif opt == '--linelength':\n      global _line_length\n      try:\n        _line_length = int(val)\n      except ValueError:\n        PrintUsage('Line length must be digits.')\n    elif opt == '--exclude':\n      global _excludes\n      if not _excludes:\n        _excludes = set()\n      _excludes.update(glob.glob(val))\n    elif opt == '--extensions':\n      ProcessExtensionsOption(val)\n    elif opt == '--headers':\n      ProcessHppHeadersOption(val)\n    elif opt == '--recursive':\n      recursive = True\n    elif opt == '--includeorder':\n      ProcessIncludeOrderOption(val)\n\n  if not filenames:\n    PrintUsage('No files were specified.')\n\n  if recursive:\n    filenames = _ExpandDirectories(filenames)\n\n  if _excludes:\n    filenames = _FilterExcludedFiles(filenames)\n\n  _SetOutputFormat(output_format)\n  _SetQuiet(quiet)\n  _SetVerboseLevel(verbosity)\n  _SetFilters(filters)\n  _SetCountingStyle(counting_style)\n\n  filenames.sort()\n  return filenames\n\ndef _ExpandDirectories(filenames):\n  \"\"\"Searches a list of filenames and replaces directories in the list with\n  all files descending from those directories. Files with extensions not in\n  the valid extensions list are excluded.\n\n  Args:\n    filenames: A list of files or directories\n\n  Returns:\n    A list of all files that are members of filenames or descended from a\n    directory in filenames\n  \"\"\"\n  expanded = set()\n  for filename in filenames:\n    if not os.path.isdir(filename):\n      expanded.add(filename)\n      continue\n\n    for root, _, files in os.walk(filename):\n      for loopfile in files:\n        fullname = os.path.join(root, loopfile)\n        if fullname.startswith('.' + os.path.sep):\n          fullname = fullname[len('.' + os.path.sep):]\n        expanded.add(fullname)\n\n  filtered = []\n  for filename in expanded:\n    if os.path.splitext(filename)[1][1:] in GetAllExtensions():\n      filtered.append(filename)\n  return filtered\n\ndef _FilterExcludedFiles(fnames):\n  \"\"\"Filters out files listed in the --exclude command line switch. File paths\n  in the switch are evaluated relative to the current working directory\n  \"\"\"\n  exclude_paths = [os.path.abspath(f) for f in _excludes]\n  # because globbing does not work recursively, exclude all subpath of all excluded entries\n  return [f for f in fnames\n          if not any(e for e in exclude_paths\n                  if _IsParentOrSame(e, os.path.abspath(f)))]\n\ndef _IsParentOrSame(parent, child):\n  \"\"\"Return true if child is subdirectory of parent.\n  Assumes both paths are absolute and don't contain symlinks.\n  \"\"\"\n  parent = os.path.normpath(parent)\n  child = os.path.normpath(child)\n  if parent == child:\n    return True\n\n  prefix = os.path.commonprefix([parent, child])\n  if prefix != parent:\n    return False\n  # Note: os.path.commonprefix operates on character basis, so\n  # take extra care of situations like '/foo/ba' and '/foo/bar/baz'\n  child_suffix = child[len(prefix):]\n  child_suffix = child_suffix.lstrip(os.sep)\n  return child == os.path.join(prefix, child_suffix)\n\ndef main():\n  filenames = ParseArguments(sys.argv[1:])\n  backup_err = sys.stderr\n  try:\n    # Change stderr to write with replacement characters so we don't die\n    # if we try to print something containing non-ASCII characters.\n    sys.stderr = codecs.StreamReader(sys.stderr, 'replace')\n\n    _cpplint_state.ResetErrorCounts()\n    for filename in filenames:\n      ProcessFile(filename, _cpplint_state.verbose_level)\n    # If --quiet is passed, suppress printing error count unless there are errors.\n    if not _cpplint_state.quiet or _cpplint_state.error_count > 0:\n      _cpplint_state.PrintErrorCounts()\n\n    if _cpplint_state.output_format == 'junit':\n      sys.stderr.write(_cpplint_state.FormatJUnitXML())\n\n  finally:\n    sys.stderr = backup_err\n\n  sys.exit(_cpplint_state.error_count > 0)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/cpplint/update.sh",
    "content": "#!/bin/sh\n\nwget -N https://raw.githubusercontent.com/cpplint/cpplint/master/cpplint.py\nwget -N https://raw.githubusercontent.com/cpplint/cpplint/master/LICENSE\nwget -N https://raw.githubusercontent.com/cpplint/cpplint/master/README.rst\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/gdb_pretty_printer/README.md",
    "content": "# GDB Pretty Printer\n\nFile [nlohmann-json.py](nlohmann-json.py) contains a pretty printer for GDB for JSON values of this library. It was originally published as [Gist](https://gist.github.com/ssbssa/60da5339c6e6036b2afce17de06050ea#file-nlohmann-json-py) by [Hannes Domani](https://github.com/ssbssa).\n\n## How to use\n\n- Add line\n  \n  ```\n  source /path/to/nlohmann-json.py\n  ```\n  \n  to `~/.gdbinit`. Note you must replace `/path/to` with whatever path you stored file `nlohmann-json.py`.\n- In GDB, debug as usual. When you want to pretty-print a JSON value `var`, type\n  \n  ```\n  p -pretty on -array on -- var\n  ```\n  \n  The result should look like\n  \n  ```\n    $1 = std::map with 5 elements = {\n        [\"Baptiste\"] = std::map with 1 element = {\n            [\"first\"] = \"second\"\n        },\n        [\"Emmanuel\"] = std::vector of length 3, capacity 3 = {\n            3,\n            \"25\",\n            0.5\n        },\n        [\"Jean\"] = 0.7,\n        [\"Zorg\"] = std::map with 8 elements = {\n            [\"array\"] = std::vector of length 3, capacity 3 = {\n                1,\n                0,\n                2\n            },\n            [\"awesome_str\"] = \"bleh\",\n            [\"bool\"] = true,\n            [\"flex\"] = 0.2,\n            [\"float\"] = 5.22,\n            [\"int\"] = 5,\n            [\"nested\"] = std::map with 1 element = {\n                [\"bar\"] = \"barz\"\n            },\n            [\"trap \"] = \"you fell\"\n        },\n        [\"empty\"] = nlohmann::detail::value_t::null\n    }\n    ```\n\nTested with GDB 9.2. See [#1952](https://github.com/nlohmann/json/issues/1952) for more information. Please post questions there.\n\n## Copyright\n\nMIT License\n\nCopyright (C) 2020 [Hannes Domani](https://github.com/ssbssa)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/gdb_pretty_printer/nlohmann-json.py",
    "content": "import gdb\n\nclass JsonValuePrinter:\n    \"Print a json-value\"\n\n    def __init__(self, val):\n        self.val = val\n\n    def to_string(self):\n        if self.val.type.strip_typedefs().code == gdb.TYPE_CODE_FLT:\n            return (\"%.6f\" % float(self.val)).rstrip(\"0\")\n        return self.val\n\ndef json_lookup_function(val):\n    name = val.type.strip_typedefs().name\n    if name and name.startswith(\"nlohmann::basic_json<\") and name.endswith(\">\"):\n        t = str(val['m_type'])\n        if t.startswith(\"nlohmann::detail::value_t::\"):\n            try:\n                union_val = val['m_value'][t[27:]]\n                if union_val.type.code == gdb.TYPE_CODE_PTR:\n                    return gdb.default_visualizer(union_val.dereference())\n                else:\n                    return JsonValuePrinter(union_val)\n            except:\n                return JsonValuePrinter(val['m_type'])\n\ngdb.pretty_printers.append(json_lookup_function)\n"
  },
  {
    "path": "subprojects/nlohmann_json/third_party/macro_builder/main.cpp",
    "content": "#include <cstdlib>\n#include <iostream>\n#include <sstream>\n\nusing namespace std;\n\nvoid build_code(int max_args)\n{\n    stringstream ss;\n    ss << \"#define NLOHMANN_JSON_EXPAND( x ) x\" << endl;\n    ss << \"#define NLOHMANN_JSON_GET_MACRO(\";\n    for (int i = 0 ; i < max_args ; i++)\n        ss << \"_\" << i + 1 << \", \";\n    ss << \"NAME,...) NAME\" << endl;\n    \n    ss << \"#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \\\\\" << endl;\n    for (int i = max_args ; i > 1 ; i--)\n        ss << \"NLOHMANN_JSON_PASTE\" << i << \", \\\\\" << endl;\n    ss << \"NLOHMANN_JSON_PASTE1)(__VA_ARGS__))\" << endl;\n    \n    ss << \"#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)\" << endl;\n    for (int i = 3 ; i <= max_args ; i++)\n    {\n        ss << \"#define NLOHMANN_JSON_PASTE\" << i << \"(func, \"; \n        for (int j = 1 ; j < i -1 ; j++)\n            ss << \"v\" << j << \", \"; \n        ss << \"v\" << i-1 << \") NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE\" << i-1 << \"(func, \";\n        for (int j = 2 ; j < i-1 ; j++)\n            ss << \"v\" << j << \", \";\n        ss << \"v\" << i-1 << \")\" << endl;\n    }\n    \n    cout << ss.str() << endl;\n}\n\nint main(int argc, char** argv) \n{\n    int max_args = 64;\n    build_code(max_args);\n       \n    return 0;\n}\n\n"
  },
  {
    "path": "subprojects/nlohmann_json/wsjcpp.yml",
    "content": "wsjcpp_version: \"v0.1.1\"\ncmake_minimum_required: \"3.0\"\ncmake_cxx_standard: \"11\"\nname: \"nlohmann/json\"\nversion: \"v3.10.5\"\ndescription: \"JSON for Modern C++\"\nissues: \"https://github.com/nlohmann/json/issues\"\nkeywords:\n  - \"c++\"\n  - \"json\"\n\nrepositories:\n  - type: main\n    url: \"https://github.com/nlohmann/json\"\n\nauthors:\n  - name: \"Niels Lohmann\"\n    email: \"mail@nlohmann.me\"\n\ndistribution:\n  - source-file: \"single_include/nlohmann/json.hpp\"\n    target-file: \"json.hpp\"\n    type: \"source-code\"\n"
  },
  {
    "path": "subprojects/nlohmann_json.wrap",
    "content": "[wrap-file]\ndirectory = nlohmann_json-3.11.2\nlead_directory_missing = true\nsource_url = https://github.com/nlohmann/json/releases/download/v3.11.2/include.zip\nsource_filename = nlohmann_json-3.11.2.zip\nsource_hash = e5c7a9f49a16814be27e4ed0ee900ecd0092bfb7dbfca65b5a421b774dccaaed\nwrapdb_version = 3.11.2-1\n\n[provide]\nnlohmann_json = nlohmann_json_dep\n"
  },
  {
    "path": "subprojects/packagefiles/bzip2.patch",
    "content": "diff --git a/CMakeLists.txt b/CMakeLists.txt\nindex 9d7eb62..76e4f49 100644\n--- a/CMakeLists.txt\n+++ b/CMakeLists.txt\n@@ -14,7 +14,7 @@ ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)\n SET(BZIP2_SRCS blocksort.c huffman.c crctable.c randtable.c\n                compress.c decompress.c bzlib.c )\n\n-ADD_LIBRARY(bz2 SHARED ${BZIP2_SRCS} libbz2.def)\n+ADD_LIBRARY(bz2 STATIC ${BZIP2_SRCS} libbz2.def)\n\n ADD_EXECUTABLE(bzip2 bzip2.c)\n TARGET_LINK_LIBRARIES(bzip2 bz2)\n"
  },
  {
    "path": "subprojects/win-iconv/CMakeLists.txt",
    "content": "project(win_iconv)\n\ncmake_minimum_required(VERSION 3.0)\nset(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})\n\nset(CPACK_GENERATOR \"TBZ2\")\ninclude(CPack)\n\noption(BUILD_TEST \"build test executable\" OFF)\noption(BUILD_STATIC \"build the static library\" ON)\noption(BUILD_SHARED \"build the shared library\" OFF)\noption(BUILD_EXECUTABLE \"build the win_iconv executable\" OFF)\n\nif(BUILD_TEST)\n    enable_testing()\nendif(BUILD_TEST)\n\nif(MSVC)\n    add_definitions(-D_CRT_SECURE_NO_WARNINGS)\nendif(MSVC)\n\nif(NOT WINCE)\n    add_definitions(-DUSE_LIBICONV_DLL)\n    if(DEFAULT_LIBICONV_DLL)\n        add_definitions(-DDEFAULT_LIBICONV_DLL=${DEFAULT_LIBICONV_DLL})\n    endif(DEFAULT_LIBICONV_DLL)\nelse(NOT WINCE)\n    find_package(Wcecompat REQUIRED)\n    include_directories(${WCECOMPAT_INCLUDE_DIR})\nendif(NOT WINCE)\n\nif(BUILD_SHARED)\n    add_library(iconv SHARED win_iconv.c iconv.def)\n    set_target_properties(iconv PROPERTIES COMPILE_FLAGS \"-DMAKE_DLL\"\n                                           PREFIX \"\")\n    if(WINCE)\n        target_link_libraries(iconv ${WCECOMPAT_LIBRARIES})\n    endif(WINCE)\n    install(TARGETS iconv RUNTIME DESTINATION bin\n                          LIBRARY DESTINATION lib\n                          ARCHIVE DESTINATION lib)\nendif(BUILD_SHARED)\n\nif(BUILD_EXECUTABLE)\n    add_executable(win_iconv win_iconv.c)\n    set_target_properties(win_iconv PROPERTIES COMPILE_FLAGS \"-DMAKE_EXE\")\n    if(WINCE)\n        target_link_libraries(win_iconv ${WCECOMPAT_LIBRARIES})\n    endif(WINCE)\n    install(TARGETS win_iconv RUNTIME DESTINATION bin\n                              LIBRARY DESTINATION lib\n                              ARCHIVE DESTINATION lib)\nendif(BUILD_EXECUTABLE)\n\nif(BUILD_STATIC)\n    add_library(iconv-static STATIC win_iconv.c)\n    set_target_properties(iconv-static PROPERTIES OUTPUT_NAME \"iconv-static\")\n    if(WINCE)\n        target_link_libraries(iconv-static ${WCECOMPAT_LIBRARIES})\n    endif(WINCE)\n    install(TARGETS iconv-static RUNTIME DESTINATION bin\n                                 LIBRARY DESTINATION lib\n                                 ARCHIVE DESTINATION lib)\nendif(BUILD_STATIC)\n\n\ninstall(FILES iconv.h DESTINATION include)\n\nif(BUILD_TEST)\n    # tests:\n    add_executable(win_iconv_test win_iconv_test.c)\n    add_test(win_iconv_test win_iconv_test)\n    if(WINCE)\n        target_link_libraries(win_iconv_test ${WCECOMPAT_LIBRARIES})\n    endif(WINCE)\nendif(BUILD_TEST)\n"
  },
  {
    "path": "subprojects/win-iconv/ChangeLog",
    "content": "2016-01-12  Yukihiro Nakadaira\n\n\t* win_iconv.c, win_iconv_test.c: Make >=0x80 byte illegal in ascii.\n\t* iconv.h: Add WINICONV_CONST macro.\n\n2014-02-05  Yukihiro Nakadaira\n\n\t* win_iconv.c: Added alias.  ISO_8859-* ISO_8859_*\n\t* win_iconv.c, win_iconv_test.c: Fixed for compiler warning.\n\n2013-09-15  Yukihiro Nakadaira\n\n\t* iconv.h: Fixed c++ style comment. (Issue 21) (Thanks to bgilbert)\n\n2012-11-22  Yukihiro Nakadaira\n\n\t* win_iconv.c: Fix warnings.\n\t(Issue 19) (Thanks to yselkowitz)\n\n2012-10-21  Yukihiro Nakadaira\n\n\t* win_iconv.c, win_iconv_test.c: Add //ignore and -c flag.\n\n2012-10-15  Yukihiro Nakadaira\n\n\t* win_iconv.c, win_iconv_test.c: cosmetic change.\n\n2012-09-19  Yukihiro Nakadaira\n\n\t* iconv.h, win_iconv.c, win_iconv_test.c: Change iconv(3) prototype.\n\t\"const char **inbuf\" -> \"char **inbuf\"\n\t(Issue 8)\n\n\t* win_iconv.c: Change to not use TEXT macro for GetProcAddress.\n\t(Issue 17) (Thanks to EPienkowskia)\n\n\t* win_iconv_test.c: Fix for -DUNICODE.  Use GetModuleFileNameA.\n\n2011-10-28  Yukihiro Nakadaira\n\n\t* win_iconv.c: Add UCS-2.\n\t(Issue 14) (Thanks to j.g.rennison)\n\n2011-10-24  Yukihiro Nakadaira\n\n\t* win_iconv.c: Add Big5-HKSCS alias.\n\t(Issue 13) (Thanks to timothy.ty.lee)\n\n2011-09-06  Yukihiro Nakadaira\n\n\t* Makefile: Improvement of the creation of the DLL.\n\t(Issue 10) (Thanks to vincent.torri)\n\n2011-08-19  Yukihiro Nakadaira\n\n\t* win_iconv.c: Fixed a bug that assumption that\n\tsizeof(DWORD)==sizeof(void*) in find_imported_module_by_funcname.\n\t(Issue 7) (Thanks to j.g.rennison)\n\n2011-08-13  Yukihiro Nakadaira\n\n\t* win_iconv.c, win_iconv_test.c: Fixed a bug that //translit\n\tflag does not work when transliterating to the default\n\tcharacter.\n\t(Issue 9) (Thanks to j.g.rennison)\n\n2011-07-26  Yukihiro Nakadaira\n\n\t* CMakeLists.txt: fix dll name with mingw.\n\t(Issue 6) (Thanks to kalevlember)\n\n\n2011-05-19  Yukihiro Nakadaira\n\n\t* win_iconv.c: Add some more UCS aliases.\n\tMerge from Tor Lillqvist version.\n\t(Issue 4) (Thanks to mkbosmans)\n\n2011-05-15  Yukihiro Nakadaira\n\n\t* Makefile: use variable for tools in Makefile\n\t(Issue 3) (Thanks to mkbosmans)\n\n2011-01-13  Yukihiro Nakadaira\n\n\t* win_iconv_test.c: Removed unused variable.\n\n\t* win_iconv_test.c: Added USE_ICONV_H flag to compile with -liconv.\n\t(Issue 2) (Thanks to amorilia.gamebox)\n\n2010-04-14  Patrick von Reth\n\n\t* added c++ support\n\n2010-03-28  Patrick Spendrin\n\n    * CMakeLists.txt, win_iconv.c: add CMake buildsystem, fix bug from issue tracker\n\n2009-07-25  Yukihiro Nakadaira\n\n\t* win_iconv.c, readme.txt: doc fix\n\n2009-07-06  Yukihiro Nakadaira\n\n\t* win_iconv.c, Makefile, readme.txt: doc fix\n\n2009-06-19  Yukihiro Nakadaira\n\n\t* win_iconv.c: cosmetic change\n\t* win_iconv.c: Change Unicode BOM behavior\n\t1. Remove the BOM when \"fromcode\" is utf-16 or utf-32.\n\t2. Add the BOM when \"tocode\" is utf-16 or utf-32.\n\n2009-06-18  Yukihiro Nakadaira\n\n\t* win_iconv.c: Fixed a bug that invalid input may cause an\n\tendless loop\n\n2009-06-18  Yukihiro Nakadaira\n\n\t* win_iconv.c: Fixed a bug that libiconv_iconv_open() doesn't\n\twork (Christophe Benoit)\n\n2008-04-01  Yukihiro Nakadaira\n\n\t* win_iconv.c: Added //TRANSLIT option.\n\thttp://bugzilla.gnome.org/show_bug.cgi?id=524314\n\n2008-03-20  Yukihiro Nakadaira\n\n\t* win_iconv.c: The dwFlags parameter to MultiByteToWideChars()\n\tmust be zero for some code pages (Tor Lillqvist)\n\n2008-03-19  Yukihiro Nakadaira\n\n\t* win_iconv.c: Added support for UCS-2 and GB18030 (Tor Lillqvist)\n\n2007-12-03  Yukihiro Nakadaira\n\n\t* iconv.h: #include <stddef.h> to use size_t\n\n2007-11-28  Yukihiro Nakadaira\n\n\t* win_iconv.c: bug fix for two things (Tor Lillqvist)\n\t1) This is probably not important: Add a function\n\t   must_use_null_useddefaultchar() that checks for those\n\t   codepages for which the docs for WideCharToMultiByte() say\n\t   one has to use a NULL lpDefaultChar pointer. Don't know if\n\t   this is actually needed, but better to be safe than sorry.\n\t2) This is essential: In kernel_wctomb(), the code should first\n\t   check if bufsize is zero, and return the E2BIG error in that\n\t   case.\n\n2007-11-26  Yukihiro Nakadaira\n\n\t* win_iconv.c: ISO-8859-1 should be CP28591, not CP1252 (Tor\n\tLillqvist)\n\n2007-11-26  Yukihiro Nakadaira\n\n\t* win_iconv.c: patch from Tor Lillqvist (with alteration)\n\n2007-09-04  Yukihiro Nakadaira\n\n\t* : Initial import\n \n"
  },
  {
    "path": "subprojects/win-iconv/FindWcecompat.cmake",
    "content": "# Try to find Wcecompat functionality\n# Once done this will define\n#\n#  WCECOMPAT_FOUND - system has Wcecompat\n#  WCECOMPAT_INCLUDE_DIR - Wcecompat include directory\n#  WCECOMPAT_LIBRARIES - Libraries needed to use Wcecompat\n#\n# Copyright (c) 2010, Andreas Holzammer, <andy@kdab.com>\n#\n# Redistribution and use is allowed according to the terms of the BSD license.\n\nif(WCECOMPAT_INCLUDE_DIR AND WCECOMPAT_LIB_FOUND)\n  set(Wcecompat_FIND_QUIETLY TRUE)\nendif(WCECOMPAT_INCLUDE_DIR AND WCECOMPAT_LIB_FOUND)\n\nfind_path(WCECOMPAT_INCLUDE_DIR errno.h PATH_SUFFIXES wcecompat)\n\nset(WCECOMPAT_LIB_FOUND FALSE)\n\nif(WCECOMPAT_INCLUDE_DIR)\n    find_library(WCECOMPAT_LIBRARIES NAMES wcecompat wcecompatex )\n    if(WCECOMPAT_LIBRARIES)\n      set(WCECOMPAT_LIB_FOUND TRUE)\n    endif(WCECOMPAT_LIBRARIES)\nendif(WCECOMPAT_INCLUDE_DIR)\n\n# I have no idea what this is about, but it seems to be used quite often, so I add this here\nset(WCECOMPAT_CONST const)\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(Wcecompat  DEFAULT_MSG  WCECOMPAT_LIBRARIES  WCECOMPAT_LIB_FOUND)\n\nmark_as_advanced(WCECOMPAT_INCLUDE_DIR  WCECOMPAT_LIBRARIES  WCECOMPAT_CONST  WCECOMPAT_LIB_FOUND)\n"
  },
  {
    "path": "subprojects/win-iconv/Makefile",
    "content": "# Makefile for win-iconv\n#\n# Variables that can be overridden:\n#\n# CC, AR, RANLIB, DLLTOOL\n# MKDIR_P, INSTALL, RM\n# prefix, BINARY_PATH, INCLUDE_PATH, LIBRARY_PATH\n\nCC ?= gcc\nAR ?= ar\nRANLIB ?= ranlib\nDLLTOOL ?= dlltool\n\nMKDIR_P = mkdir -p\nINSTALL = install -c\nRM = rm -f\n\n# comma separated list (e.g. \"iconv.dll,libiconv.dll\")\nDEFAULT_LIBICONV_DLL ?= \\\"\\\"\n\nCFLAGS += -pedantic -Wall\nCFLAGS += -DUSE_LIBICONV_DLL\nCFLAGS += -DDEFAULT_LIBICONV_DLL=$(DEFAULT_LIBICONV_DLL)\n\nprefix ?= /usr/local\nBINARY_PATH = $(prefix)/bin\nINCLUDE_PATH = $(prefix)/include\nLIBRARY_PATH = $(prefix)/lib\n\nall: iconv.dll libiconv.a win_iconv.exe\n\ndist: test win_iconv.zip\n\niconv.dll: win_iconv.c\n\t$(CC) $(CFLAGS) -c win_iconv.c -DMAKE_DLL\n\t$(CC) -shared -o iconv.dll -Wl,-s -Wl,--out-implib=libiconv.dll.a -Wl,--export-all-symbols win_iconv.o $(SPECS_FLAGS)\n\nlibiconv.a: win_iconv.c\n\t$(CC) $(CFLAGS) -c win_iconv.c\n\t$(AR) rcs libiconv.a win_iconv.o\n\t$(RANLIB) libiconv.a\n\nwin_iconv.exe: win_iconv.c\n\t$(CC) $(CFLAGS) -s -o win_iconv.exe win_iconv.c -DMAKE_EXE\n\nlibmlang.a: mlang.def\n\t$(DLLTOOL) --kill-at --input-def mlang.def --output-lib libmlang.a\n\ntest:\n\t$(CC) $(CFLAGS) -s -o win_iconv_test.exe win_iconv_test.c\n\t./win_iconv_test.exe\n\nwin_iconv.zip: msvcrt msvcr70 msvcr71\n\trm -rf win_iconv\n\tsvn export . win_iconv\n\tcp msvcrt/iconv.dll msvcrt/win_iconv.exe win_iconv/\n\tmkdir win_iconv/msvcr70\n\tcp msvcr70/iconv.dll win_iconv/msvcr70/\n\tmkdir win_iconv/msvcr71\n\tcp msvcr71/iconv.dll win_iconv/msvcr71/\n\tzip -r win_iconv.zip win_iconv\n\nmsvcrt:\n\tsvn export . msvcrt; \\\n\tcd msvcrt; \\\n\t$(MAKE);\n\nmsvcr70:\n\tsvn export . msvcr70; \\\n\tcd msvcr70; \\\n\tgcc -dumpspecs | sed s/-lmsvcrt/-lmsvcr70/ > specs; \\\n\t$(MAKE) \"SPECS_FLAGS=-specs=$$PWD/specs\";\n\nmsvcr71:\n\tsvn export . msvcr71; \\\n\tcd msvcr71; \\\n\tgcc -dumpspecs | sed s/-lmsvcrt/-lmsvcr71/ > specs; \\\n\t$(MAKE) \"SPECS_FLAGS=-specs=$$PWD/specs\";\n\ninstall: iconv.dll libiconv.a win_iconv.exe\n\t-@$(MKDIR_P) '$(DESTDIR)$(BINARY_PATH)'\n\t-@$(MKDIR_P) '$(DESTDIR)$(INCLUDE_PATH)'\n\t-@$(MKDIR_P) '$(DESTDIR)$(LIBRARY_PATH)'\n\t-$(INSTALL) iconv.dll '$(DESTDIR)$(BINARY_PATH)'\n\t-$(INSTALL) win_iconv.exe '$(DESTDIR)$(BINARY_PATH)'\n\t-$(INSTALL) -m 0644 iconv.h '$(DESTDIR)$(INCLUDE_PATH)'\n\t-$(INSTALL) -m 0644 libiconv.dll.a '$(DESTDIR)$(LIBRARY_PATH)'\n\t-$(INSTALL) -m 0644 libiconv.a '$(DESTDIR)$(LIBRARY_PATH)'\n\nuninstall:\n\t-$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/libiconv.a\n\t-$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/libiconv.dll.a\n\t-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/iconv.h\n\t-$(RM) '$(DESTDIR)$(BINARY_PATH)'/win_iconv.exe\n\t-$(RM) '$(DESTDIR)$(BINARY_PATH)'/iconv.dll\n\nclean:\n\trm -f win_iconv.exe\n\trm -f win_iconv.o\n\trm -f iconv.dll*\n\trm -f libiconv.a\n\trm -f libiconv.dll\n\trm -f win_iconv_test.exe\n\trm -f libmlang.a\n\trm -rf win_iconv\n\trm -rf win_iconv.zip\n\trm -rf msvcrt\n\trm -rf msvcr70\n\trm -rf msvcr71\n\n"
  },
  {
    "path": "subprojects/win-iconv/iconv.def",
    "content": "EXPORTS\n  iconv\n  iconv_open\n  iconv_close\n  iconvctl\n  libiconv=iconv\n  libiconv_open=iconv_open\n  libiconv_close=iconv_close\n  libiconvctl=iconvctl\n;; libiconv-1.11.dll\n;; TODO for binary compatibility\n;  _libiconv_version @1\n;  aliases2_lookup @2\n;  aliases_lookup @3\n;  iconv_canonicalize @4\n;  libiconv @5\n;  libiconv_close @6\n;  libiconv_open @7\n;  libiconv_relocate @8\n;  libiconv_set_relocation_prefix @9\n;  libiconvctl @10\n;  libiconvlist @11\n;  locale_charset @12\n"
  },
  {
    "path": "subprojects/win-iconv/iconv.h",
    "content": "#ifndef _LIBICONV_H\n#define _LIBICONV_H\n#include <stddef.h>\n#ifndef WINICONV_CONST\n# ifdef ICONV_CONST\n#  define WINICONV_CONST ICONV_CONST\n# else\n#  define WINICONV_CONST const\n# endif\n#endif\n#ifdef __cplusplus\nextern \"C\" {\n#endif\ntypedef void* iconv_t;\niconv_t iconv_open(const char *tocode, const char *fromcode);\nint iconv_close(iconv_t cd);\nsize_t iconv(iconv_t cd, WINICONV_CONST char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "subprojects/win-iconv/mlang.def",
    "content": "LIBRARY MLANG.DLL\nEXPORTS\n  ConvertINetMultiByteToUnicode@24\n  ;; ConvertINetReset (not documented)\n  ConvertINetString@28\n  ConvertINetUnicodeToMultiByte@24\n  IsConvertINetStringAvailable@8\n  LcidToRfc1766A@12\n  LcidToRfc1766W@12\n  Rfc1766ToLcidA@8\n  Rfc1766ToLcidW@8\n"
  },
  {
    "path": "subprojects/win-iconv/mlang.h",
    "content": "HRESULT WINAPI ConvertINetString(\n    LPDWORD lpdwMode,\n    DWORD dwSrcEncoding,\n    DWORD dwDstEncoding,\n    LPCSTR lpSrcStr,\n    LPINT lpnSrcSize,\n    LPBYTE lpDstStr,\n    LPINT lpnDstSize\n);\n\nHRESULT WINAPI ConvertINetMultiByteToUnicode(\n    LPDWORD lpdwMode,\n    DWORD dwSrcEncoding,\n    LPCSTR lpSrcStr,\n    LPINT lpnMultiCharCount,\n    LPWSTR lpDstStr,\n    LPINT lpnWideCharCount\n);\n\nHRESULT WINAPI ConvertINetUnicodeToMultiByte(\n    LPDWORD lpdwMode,\n    DWORD dwEncoding,\n    LPCWSTR lpSrcStr,\n    LPINT lpnWideCharCount,\n    LPSTR lpDstStr,\n    LPINT lpnMultiCharCount\n);\n\nHRESULT WINAPI IsConvertINetStringAvailable(\n    DWORD dwSrcEncoding,\n    DWORD dwDstEncoding\n);\n\nHRESULT WINAPI LcidToRfc1766A(\n    LCID Locale,\n    LPSTR pszRfc1766,\n    int nChar\n);\n\nHRESULT WINAPI LcidToRfc1766W(\n    LCID Locale,\n    LPWSTR pszRfc1766,\n    int nChar\n);\n\nHRESULT WINAPI Rfc1766ToLcidA(\n    LCID *pLocale,\n    LPSTR pszRfc1766\n);\n\nHRESULT WINAPI Rfc1766ToLcidW(\n    LCID *pLocale,\n    LPWSTR pszRfc1766\n);\n"
  },
  {
    "path": "subprojects/win-iconv/readme.txt",
    "content": "Inlined from https://github.com/win-iconv/win-iconv/ at commit: 9f98392dfecadffd62572e73e9aba878e03496c4\n\nwin_iconv is a iconv implementation using Win32 API to convert.\n\nwin_iconv is placed in the public domain.\n\nENVIRONMENT VARIABLE:\n    WINICONV_LIBICONV_DLL\n        If $WINICONV_LIBICONV_DLL is set, win_iconv uses the DLL.  If\n        loading the DLL or iconv_open() failed, falls back to internal\n        conversion.  If a few DLL are specified as comma separated list,\n        the first loadable DLL is used.  The DLL should have\n        iconv_open(), iconv_close() and iconv().  Or libiconv_open(),\n        libiconv_close() and libiconv().\n        (only available when USE_LIBICONV_DLL is defined at compile time)\n\nWin32 API does not support strict encoding conversion for some codepage.\nAnd MLang function drops or replaces invalid bytes and does not return\nuseful error status as iconv does.  This implementation cannot be used for\nencoding validation purpose.\n\nYukihiro Nakadaira <yukihiro.nakadaira@gmail.com>\n"
  },
  {
    "path": "subprojects/win-iconv/win_iconv.c",
    "content": "/*\n * iconv implementation using Win32 API to convert.\n *\n * This file is placed in the public domain.\n */\n\n/* for WC_NO_BEST_FIT_CHARS */\n#ifndef WINVER\n# define WINVER 0x0500\n#endif\n\n#define STRICT\n#include <windows.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n\n#ifdef __GNUC__\n#define UNUSED __attribute__((unused))\n#else\n#define UNUSED\n#endif\n\n/* WORKAROUND: */\n#ifndef UNDER_CE\n#define GetProcAddressA GetProcAddress\n#endif\n\n#if 0\n# define MAKE_EXE\n# define MAKE_DLL\n# define USE_LIBICONV_DLL\n#endif\n\n#if !defined(DEFAULT_LIBICONV_DLL)\n# define DEFAULT_LIBICONV_DLL \"\"\n#endif\n\n#define MB_CHAR_MAX 16\n\n#define UNICODE_MODE_BOM_DONE   1\n#define UNICODE_MODE_SWAPPED    2\n\n#define FLAG_USE_BOM            1\n#define FLAG_TRANSLIT           2 /* //TRANSLIT */\n#define FLAG_IGNORE             4 /* //IGNORE */\n\ntypedef unsigned char uchar;\ntypedef unsigned short ushort;\ntypedef unsigned int uint;\n\ntypedef void* iconv_t;\n\niconv_t iconv_open(const char *tocode, const char *fromcode);\nint iconv_close(iconv_t cd);\nsize_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);\n\n/* libiconv interface for vim */\n#if defined(MAKE_DLL)\nint\niconvctl (iconv_t cd, int request, void* argument)\n{\n    /* not supported */\n    return 0;\n}\n#endif\n\ntypedef struct compat_t compat_t;\ntypedef struct csconv_t csconv_t;\ntypedef struct rec_iconv_t rec_iconv_t;\n\ntypedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode);\ntypedef int (*f_iconv_close)(iconv_t cd);\ntypedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);\ntypedef int* (*f_errno)(void);\ntypedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);\ntypedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);\ntypedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize);\ntypedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize);\n\n#define COMPAT_IN   1\n#define COMPAT_OUT  2\n\n/* unicode mapping for compatibility with other conversion table. */\nstruct compat_t {\n    uint in;\n    uint out;\n    uint flag;\n};\n\nstruct csconv_t {\n    int codepage;\n    int flags;\n    f_mbtowc mbtowc;\n    f_wctomb wctomb;\n    f_mblen mblen;\n    f_flush flush;\n    DWORD mode;\n    compat_t *compat;\n};\n\nstruct rec_iconv_t {\n    iconv_t cd;\n    f_iconv_close iconv_close;\n    f_iconv iconv;\n    f_errno _errno;\n    csconv_t from;\n    csconv_t to;\n#if defined(USE_LIBICONV_DLL)\n    HMODULE hlibiconv;\n#endif\n};\n\nstatic int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);\nstatic int win_iconv_close(iconv_t cd);\nstatic size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);\n\nstatic int load_mlang(void);\nstatic int make_csconv(const char *name, csconv_t *cv);\nstatic int name_to_codepage(const char *name);\nstatic uint utf16_to_ucs4(const ushort *wbuf);\nstatic void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize);\nstatic int mbtowc_flags(int codepage);\nstatic int must_use_null_useddefaultchar(int codepage);\nstatic char *strrstr(const char *str, const char *token);\nstatic char *xstrndup(const char *s, size_t n);\nstatic int seterror(int err);\n\n#if defined(USE_LIBICONV_DLL)\nstatic int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);\nstatic PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size);\nstatic FARPROC find_imported_function(HMODULE hModule, const char *funcname);\n\nstatic HMODULE hwiniconv;\n#endif\n\nstatic int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);\nstatic int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);\nstatic int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);\nstatic int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize);\nstatic int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize);\n\nstatic int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);\nstatic int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);\nstatic int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);\nstatic int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);\nstatic int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);\nstatic int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);\nstatic int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);\nstatic int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);\nstatic int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);\nstatic int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);\nstatic int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize);\n\nstatic struct {\n    int codepage;\n    const char *name;\n} codepage_alias[] = {\n    {65001, \"CP65001\"},\n    {65001, \"UTF8\"},\n    {65001, \"UTF-8\"},\n\n    {1200, \"CP1200\"},\n    {1200, \"UTF16LE\"},\n    {1200, \"UTF-16LE\"},\n    {1200, \"UCS2LE\"},\n    {1200, \"UCS-2LE\"},\n    {1200, \"UCS-2-INTERNAL\"},\n\n    {1201, \"CP1201\"},\n    {1201, \"UTF16BE\"},\n    {1201, \"UTF-16BE\"},\n    {1201, \"UCS2BE\"},\n    {1201, \"UCS-2BE\"},\n    {1201, \"unicodeFFFE\"},\n\n    {12000, \"CP12000\"},\n    {12000, \"UTF32LE\"},\n    {12000, \"UTF-32LE\"},\n    {12000, \"UCS4LE\"},\n    {12000, \"UCS-4LE\"},\n\n    {12001, \"CP12001\"},\n    {12001, \"UTF32BE\"},\n    {12001, \"UTF-32BE\"},\n    {12001, \"UCS4BE\"},\n    {12001, \"UCS-4BE\"},\n\n#ifndef GLIB_COMPILATION\n    /*\n     * Default is big endian.\n     * See rfc2781 4.3 Interpreting text labelled as UTF-16.\n     */\n    {1201, \"UTF16\"},\n    {1201, \"UTF-16\"},\n    {1201, \"UCS2\"},\n    {1201, \"UCS-2\"},\n    {12001, \"UTF32\"},\n    {12001, \"UTF-32\"},\n    {12001, \"UCS-4\"},\n    {12001, \"UCS4\"},\n#else\n    /* Default is little endian, because the platform is */\n    {1200, \"UTF16\"},\n    {1200, \"UTF-16\"},\n    {1200, \"UCS2\"},\n    {1200, \"UCS-2\"},\n    {12000, \"UTF32\"},\n    {12000, \"UTF-32\"},\n    {12000, \"UCS4\"},\n    {12000, \"UCS-4\"},\n#endif\n\n    /* copy from libiconv `iconv -l` */\n    /* !IsValidCodePage(367) */\n    {20127, \"ANSI_X3.4-1968\"},\n    {20127, \"ANSI_X3.4-1986\"},\n    {20127, \"ASCII\"},\n    {20127, \"CP367\"},\n    {20127, \"IBM367\"},\n    {20127, \"ISO-IR-6\"},\n    {20127, \"ISO646-US\"},\n    {20127, \"ISO_646.IRV:1991\"},\n    {20127, \"US\"},\n    {20127, \"US-ASCII\"},\n    {20127, \"CSASCII\"},\n\n    /* !IsValidCodePage(819) */\n    {1252, \"CP819\"},\n    {1252, \"IBM819\"},\n    {28591, \"ISO-8859-1\"},\n    {28591, \"ISO-IR-100\"},\n    {28591, \"ISO8859-1\"},\n    {28591, \"ISO_8859-1\"},\n    {28591, \"ISO_8859-1:1987\"},\n    {28591, \"L1\"},\n    {28591, \"LATIN1\"},\n    {28591, \"CSISOLATIN1\"},\n\n    {1250, \"CP1250\"},\n    {1250, \"MS-EE\"},\n    {1250, \"WINDOWS-1250\"},\n\n    {1251, \"CP1251\"},\n    {1251, \"MS-CYRL\"},\n    {1251, \"WINDOWS-1251\"},\n\n    {1252, \"CP1252\"},\n    {1252, \"MS-ANSI\"},\n    {1252, \"WINDOWS-1252\"},\n\n    {1253, \"CP1253\"},\n    {1253, \"MS-GREEK\"},\n    {1253, \"WINDOWS-1253\"},\n\n    {1254, \"CP1254\"},\n    {1254, \"MS-TURK\"},\n    {1254, \"WINDOWS-1254\"},\n\n    {1255, \"CP1255\"},\n    {1255, \"MS-HEBR\"},\n    {1255, \"WINDOWS-1255\"},\n\n    {1256, \"CP1256\"},\n    {1256, \"MS-ARAB\"},\n    {1256, \"WINDOWS-1256\"},\n\n    {1257, \"CP1257\"},\n    {1257, \"WINBALTRIM\"},\n    {1257, \"WINDOWS-1257\"},\n\n    {1258, \"CP1258\"},\n    {1258, \"WINDOWS-1258\"},\n\n    {850, \"850\"},\n    {850, \"CP850\"},\n    {850, \"IBM850\"},\n    {850, \"CSPC850MULTILINGUAL\"},\n\n    /* !IsValidCodePage(862) */\n    {862, \"862\"},\n    {862, \"CP862\"},\n    {862, \"IBM862\"},\n    {862, \"CSPC862LATINHEBREW\"},\n\n    {866, \"866\"},\n    {866, \"CP866\"},\n    {866, \"IBM866\"},\n    {866, \"CSIBM866\"},\n\n    /* !IsValidCodePage(154) */\n    {154, \"CP154\"},\n    {154, \"CYRILLIC-ASIAN\"},\n    {154, \"PT154\"},\n    {154, \"PTCP154\"},\n    {154, \"CSPTCP154\"},\n\n    /* !IsValidCodePage(1133) */\n    {1133, \"CP1133\"},\n    {1133, \"IBM-CP1133\"},\n\n    {874, \"CP874\"},\n    {874, \"WINDOWS-874\"},\n\n    /* !IsValidCodePage(51932) */\n    {51932, \"CP51932\"},\n    {51932, \"MS51932\"},\n    {51932, \"WINDOWS-51932\"},\n    {51932, \"EUC-JP\"},\n\n    {932, \"CP932\"},\n    {932, \"MS932\"},\n    {932, \"SHIFFT_JIS\"},\n    {932, \"SHIFFT_JIS-MS\"},\n    {932, \"SJIS\"},\n    {932, \"SJIS-MS\"},\n    {932, \"SJIS-OPEN\"},\n    {932, \"SJIS-WIN\"},\n    {932, \"WINDOWS-31J\"},\n    {932, \"WINDOWS-932\"},\n    {932, \"CSWINDOWS31J\"},\n\n    {50221, \"CP50221\"},\n    {50221, \"ISO-2022-JP\"},\n    {50221, \"ISO-2022-JP-MS\"},\n    {50221, \"ISO2022-JP\"},\n    {50221, \"ISO2022-JP-MS\"},\n    {50221, \"MS50221\"},\n    {50221, \"WINDOWS-50221\"},\n\n    {936, \"CP936\"},\n    {936, \"GBK\"},\n    {936, \"MS936\"},\n    {936, \"WINDOWS-936\"},\n\n    {950, \"CP950\"},\n    {950, \"BIG5\"},\n    {950, \"BIG5HKSCS\"},\n    {950, \"BIG5-HKSCS\"},\n\n    {949, \"CP949\"},\n    {949, \"UHC\"},\n    {949, \"EUC-KR\"},\n\n    {1361, \"CP1361\"},\n    {1361, \"JOHAB\"},\n\n    {437, \"437\"},\n    {437, \"CP437\"},\n    {437, \"IBM437\"},\n    {437, \"CSPC8CODEPAGE437\"},\n\n    {737, \"CP737\"},\n\n    {775, \"CP775\"},\n    {775, \"IBM775\"},\n    {775, \"CSPC775BALTIC\"},\n\n    {852, \"852\"},\n    {852, \"CP852\"},\n    {852, \"IBM852\"},\n    {852, \"CSPCP852\"},\n\n    /* !IsValidCodePage(853) */\n    {853, \"CP853\"},\n\n    {855, \"855\"},\n    {855, \"CP855\"},\n    {855, \"IBM855\"},\n    {855, \"CSIBM855\"},\n\n    {857, \"857\"},\n    {857, \"CP857\"},\n    {857, \"IBM857\"},\n    {857, \"CSIBM857\"},\n\n    /* !IsValidCodePage(858) */\n    {858, \"CP858\"},\n\n    {860, \"860\"},\n    {860, \"CP860\"},\n    {860, \"IBM860\"},\n    {860, \"CSIBM860\"},\n\n    {861, \"861\"},\n    {861, \"CP-IS\"},\n    {861, \"CP861\"},\n    {861, \"IBM861\"},\n    {861, \"CSIBM861\"},\n\n    {863, \"863\"},\n    {863, \"CP863\"},\n    {863, \"IBM863\"},\n    {863, \"CSIBM863\"},\n\n    {864, \"CP864\"},\n    {864, \"IBM864\"},\n    {864, \"CSIBM864\"},\n\n    {865, \"865\"},\n    {865, \"CP865\"},\n    {865, \"IBM865\"},\n    {865, \"CSIBM865\"},\n\n    {869, \"869\"},\n    {869, \"CP-GR\"},\n    {869, \"CP869\"},\n    {869, \"IBM869\"},\n    {869, \"CSIBM869\"},\n\n    /* !IsValidCodePage(1152) */\n    {1125, \"CP1125\"},\n\n    /*\n     * Code Page Identifiers\n     * http://msdn2.microsoft.com/en-us/library/ms776446.aspx\n     */\n    {37, \"IBM037\"}, /* IBM EBCDIC US-Canada */\n    {437, \"IBM437\"}, /* OEM United States */\n    {500, \"IBM500\"}, /* IBM EBCDIC International */\n    {708, \"ASMO-708\"}, /* Arabic (ASMO 708) */\n    /* 709 \t\tArabic (ASMO-449+, BCON V4) */\n    /* 710 \t\tArabic - Transparent Arabic */\n    {720, \"DOS-720\"}, /* Arabic (Transparent ASMO); Arabic (DOS) */\n    {737, \"ibm737\"}, /* OEM Greek (formerly 437G); Greek (DOS) */\n    {775, \"ibm775\"}, /* OEM Baltic; Baltic (DOS) */\n    {850, \"ibm850\"}, /* OEM Multilingual Latin 1; Western European (DOS) */\n    {852, \"ibm852\"}, /* OEM Latin 2; Central European (DOS) */\n    {855, \"IBM855\"}, /* OEM Cyrillic (primarily Russian) */\n    {857, \"ibm857\"}, /* OEM Turkish; Turkish (DOS) */\n    {858, \"IBM00858\"}, /* OEM Multilingual Latin 1 + Euro symbol */\n    {860, \"IBM860\"}, /* OEM Portuguese; Portuguese (DOS) */\n    {861, \"ibm861\"}, /* OEM Icelandic; Icelandic (DOS) */\n    {862, \"DOS-862\"}, /* OEM Hebrew; Hebrew (DOS) */\n    {863, \"IBM863\"}, /* OEM French Canadian; French Canadian (DOS) */\n    {864, \"IBM864\"}, /* OEM Arabic; Arabic (864) */\n    {865, \"IBM865\"}, /* OEM Nordic; Nordic (DOS) */\n    {866, \"cp866\"}, /* OEM Russian; Cyrillic (DOS) */\n    {869, \"ibm869\"}, /* OEM Modern Greek; Greek, Modern (DOS) */\n    {870, \"IBM870\"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */\n    {874, \"windows-874\"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */\n    {875, \"cp875\"}, /* IBM EBCDIC Greek Modern */\n    {932, \"shift_jis\"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */\n    {932, \"shift-jis\"}, /* alternative name for it */\n    {936, \"gb2312\"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */\n    {949, \"ks_c_5601-1987\"}, /* ANSI/OEM Korean (Unified Hangul Code) */\n    {950, \"big5\"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */\n    {950, \"big5hkscs\"}, /* ANSI/OEM Traditional Chinese (Hong Kong SAR); Chinese Traditional (Big5-HKSCS) */\n    {950, \"big5-hkscs\"}, /* alternative name for it */\n    {1026, \"IBM1026\"}, /* IBM EBCDIC Turkish (Latin 5) */\n    {1047, \"IBM01047\"}, /* IBM EBCDIC Latin 1/Open System */\n    {1140, \"IBM01140\"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */\n    {1141, \"IBM01141\"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */\n    {1142, \"IBM01142\"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */\n    {1143, \"IBM01143\"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */\n    {1144, \"IBM01144\"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */\n    {1145, \"IBM01145\"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */\n    {1146, \"IBM01146\"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */\n    {1147, \"IBM01147\"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */\n    {1148, \"IBM01148\"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */\n    {1149, \"IBM01149\"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */\n    {1250, \"windows-1250\"}, /* ANSI Central European; Central European (Windows) */\n    {1251, \"windows-1251\"}, /* ANSI Cyrillic; Cyrillic (Windows) */\n    {1252, \"windows-1252\"}, /* ANSI Latin 1; Western European (Windows) */\n    {1253, \"windows-1253\"}, /* ANSI Greek; Greek (Windows) */\n    {1254, \"windows-1254\"}, /* ANSI Turkish; Turkish (Windows) */\n    {1255, \"windows-1255\"}, /* ANSI Hebrew; Hebrew (Windows) */\n    {1256, \"windows-1256\"}, /* ANSI Arabic; Arabic (Windows) */\n    {1257, \"windows-1257\"}, /* ANSI Baltic; Baltic (Windows) */\n    {1258, \"windows-1258\"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */\n    {1361, \"Johab\"}, /* Korean (Johab) */\n    {10000, \"macintosh\"}, /* MAC Roman; Western European (Mac) */\n    {10001, \"x-mac-japanese\"}, /* Japanese (Mac) */\n    {10002, \"x-mac-chinesetrad\"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */\n    {10003, \"x-mac-korean\"}, /* Korean (Mac) */\n    {10004, \"x-mac-arabic\"}, /* Arabic (Mac) */\n    {10005, \"x-mac-hebrew\"}, /* Hebrew (Mac) */\n    {10006, \"x-mac-greek\"}, /* Greek (Mac) */\n    {10007, \"x-mac-cyrillic\"}, /* Cyrillic (Mac) */\n    {10008, \"x-mac-chinesesimp\"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */\n    {10010, \"x-mac-romanian\"}, /* Romanian (Mac) */\n    {10017, \"x-mac-ukrainian\"}, /* Ukrainian (Mac) */\n    {10021, \"x-mac-thai\"}, /* Thai (Mac) */\n    {10029, \"x-mac-ce\"}, /* MAC Latin 2; Central European (Mac) */\n    {10079, \"x-mac-icelandic\"}, /* Icelandic (Mac) */\n    {10081, \"x-mac-turkish\"}, /* Turkish (Mac) */\n    {10082, \"x-mac-croatian\"}, /* Croatian (Mac) */\n    {20000, \"x-Chinese_CNS\"}, /* CNS Taiwan; Chinese Traditional (CNS) */\n    {20001, \"x-cp20001\"}, /* TCA Taiwan */\n    {20002, \"x_Chinese-Eten\"}, /* Eten Taiwan; Chinese Traditional (Eten) */\n    {20003, \"x-cp20003\"}, /* IBM5550 Taiwan */\n    {20004, \"x-cp20004\"}, /* TeleText Taiwan */\n    {20005, \"x-cp20005\"}, /* Wang Taiwan */\n    {20105, \"x-IA5\"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */\n    {20106, \"x-IA5-German\"}, /* IA5 German (7-bit) */\n    {20107, \"x-IA5-Swedish\"}, /* IA5 Swedish (7-bit) */\n    {20108, \"x-IA5-Norwegian\"}, /* IA5 Norwegian (7-bit) */\n    {20127, \"us-ascii\"}, /* US-ASCII (7-bit) */\n    {20261, \"x-cp20261\"}, /* T.61 */\n    {20269, \"x-cp20269\"}, /* ISO 6937 Non-Spacing Accent */\n    {20273, \"IBM273\"}, /* IBM EBCDIC Germany */\n    {20277, \"IBM277\"}, /* IBM EBCDIC Denmark-Norway */\n    {20278, \"IBM278\"}, /* IBM EBCDIC Finland-Sweden */\n    {20280, \"IBM280\"}, /* IBM EBCDIC Italy */\n    {20284, \"IBM284\"}, /* IBM EBCDIC Latin America-Spain */\n    {20285, \"IBM285\"}, /* IBM EBCDIC United Kingdom */\n    {20290, \"IBM290\"}, /* IBM EBCDIC Japanese Katakana Extended */\n    {20297, \"IBM297\"}, /* IBM EBCDIC France */\n    {20420, \"IBM420\"}, /* IBM EBCDIC Arabic */\n    {20423, \"IBM423\"}, /* IBM EBCDIC Greek */\n    {20424, \"IBM424\"}, /* IBM EBCDIC Hebrew */\n    {20833, \"x-EBCDIC-KoreanExtended\"}, /* IBM EBCDIC Korean Extended */\n    {20838, \"IBM-Thai\"}, /* IBM EBCDIC Thai */\n    {20866, \"koi8-r\"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */\n    {20871, \"IBM871\"}, /* IBM EBCDIC Icelandic */\n    {20880, \"IBM880\"}, /* IBM EBCDIC Cyrillic Russian */\n    {20905, \"IBM905\"}, /* IBM EBCDIC Turkish */\n    {20924, \"IBM00924\"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */\n    {20932, \"EUC-JP\"}, /* Japanese (JIS 0208-1990 and 0121-1990) */\n    {20936, \"x-cp20936\"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */\n    {20949, \"x-cp20949\"}, /* Korean Wansung */\n    {21025, \"cp1025\"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */\n    /* 21027 \t\t(deprecated) */\n    {21866, \"koi8-u\"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */\n    {28591, \"iso-8859-1\"}, /* ISO 8859-1 Latin 1; Western European (ISO) */\n    {28591, \"iso8859-1\"}, /* ISO 8859-1 Latin 1; Western European (ISO) */\n    {28591, \"iso_8859-1\"},\n    {28591, \"iso_8859_1\"},\n    {28592, \"iso-8859-2\"}, /* ISO 8859-2 Central European; Central European (ISO) */\n    {28592, \"iso8859-2\"}, /* ISO 8859-2 Central European; Central European (ISO) */\n    {28592, \"iso_8859-2\"},\n    {28592, \"iso_8859_2\"},\n    {28593, \"iso-8859-3\"}, /* ISO 8859-3 Latin 3 */\n    {28593, \"iso8859-3\"}, /* ISO 8859-3 Latin 3 */\n    {28593, \"iso_8859-3\"},\n    {28593, \"iso_8859_3\"},\n    {28594, \"iso-8859-4\"}, /* ISO 8859-4 Baltic */\n    {28594, \"iso8859-4\"}, /* ISO 8859-4 Baltic */\n    {28594, \"iso_8859-4\"},\n    {28594, \"iso_8859_4\"},\n    {28595, \"iso-8859-5\"}, /* ISO 8859-5 Cyrillic */\n    {28595, \"iso8859-5\"}, /* ISO 8859-5 Cyrillic */\n    {28595, \"iso_8859-5\"},\n    {28595, \"iso_8859_5\"},\n    {28596, \"iso-8859-6\"}, /* ISO 8859-6 Arabic */\n    {28596, \"iso8859-6\"}, /* ISO 8859-6 Arabic */\n    {28596, \"iso_8859-6\"},\n    {28596, \"iso_8859_6\"},\n    {28597, \"iso-8859-7\"}, /* ISO 8859-7 Greek */\n    {28597, \"iso8859-7\"}, /* ISO 8859-7 Greek */\n    {28597, \"iso_8859-7\"},\n    {28597, \"iso_8859_7\"},\n    {28598, \"iso-8859-8\"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */\n    {28598, \"iso8859-8\"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */\n    {28598, \"iso_8859-8\"},\n    {28598, \"iso_8859_8\"},\n    {28599, \"iso-8859-9\"}, /* ISO 8859-9 Turkish */\n    {28599, \"iso8859-9\"}, /* ISO 8859-9 Turkish */\n    {28599, \"iso_8859-9\"},\n    {28599, \"iso_8859_9\"},\n    {28603, \"iso-8859-13\"}, /* ISO 8859-13 Estonian */\n    {28603, \"iso8859-13\"}, /* ISO 8859-13 Estonian */\n    {28603, \"iso_8859-13\"},\n    {28603, \"iso_8859_13\"},\n    {28605, \"iso-8859-15\"}, /* ISO 8859-15 Latin 9 */\n    {28605, \"iso8859-15\"}, /* ISO 8859-15 Latin 9 */\n    {28605, \"iso_8859-15\"},\n    {28605, \"iso_8859_15\"},\n    {29001, \"x-Europa\"}, /* Europa 3 */\n    {38598, \"iso-8859-8-i\"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */\n    {38598, \"iso8859-8-i\"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */\n    {38598, \"iso_8859-8-i\"},\n    {38598, \"iso_8859_8-i\"},\n    {50220, \"iso-2022-jp\"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */\n    {50221, \"csISO2022JP\"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */\n    {50222, \"iso-2022-jp\"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */\n    {50225, \"iso-2022-kr\"}, /* ISO 2022 Korean */\n    {50225, \"iso2022-kr\"}, /* ISO 2022 Korean */\n    {50227, \"x-cp50227\"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */\n    /* 50229 \t\tISO 2022 Traditional Chinese */\n    /* 50930 \t\tEBCDIC Japanese (Katakana) Extended */\n    /* 50931 \t\tEBCDIC US-Canada and Japanese */\n    /* 50933 \t\tEBCDIC Korean Extended and Korean */\n    /* 50935 \t\tEBCDIC Simplified Chinese Extended and Simplified Chinese */\n    /* 50936 \t\tEBCDIC Simplified Chinese */\n    /* 50937 \t\tEBCDIC US-Canada and Traditional Chinese */\n    /* 50939 \t\tEBCDIC Japanese (Latin) Extended and Japanese */\n    {51932, \"euc-jp\"}, /* EUC Japanese */\n    {51936, \"EUC-CN\"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */\n    {51949, \"euc-kr\"}, /* EUC Korean */\n    /* 51950 \t\tEUC Traditional Chinese */\n    {52936, \"hz-gb-2312\"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */\n    {54936, \"GB18030\"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */\n    {57002, \"x-iscii-de\"}, /* ISCII Devanagari */\n    {57003, \"x-iscii-be\"}, /* ISCII Bengali */\n    {57004, \"x-iscii-ta\"}, /* ISCII Tamil */\n    {57005, \"x-iscii-te\"}, /* ISCII Telugu */\n    {57006, \"x-iscii-as\"}, /* ISCII Assamese */\n    {57007, \"x-iscii-or\"}, /* ISCII Oriya */\n    {57008, \"x-iscii-ka\"}, /* ISCII Kannada */\n    {57009, \"x-iscii-ma\"}, /* ISCII Malayalam */\n    {57010, \"x-iscii-gu\"}, /* ISCII Gujarati */\n    {57011, \"x-iscii-pa\"}, /* ISCII Punjabi */\n\n    {0, NULL}\n};\n\n/*\n * SJIS SHIFTJIS table              CP932 table\n * ---- --------------------------- --------------------------------\n *   5C U+00A5 YEN SIGN             U+005C REVERSE SOLIDUS\n *   7E U+203E OVERLINE             U+007E TILDE\n * 815C U+2014 EM DASH              U+2015 HORIZONTAL BAR\n * 815F U+005C REVERSE SOLIDUS      U+FF3C FULLWIDTH REVERSE SOLIDUS\n * 8160 U+301C WAVE DASH            U+FF5E FULLWIDTH TILDE\n * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO\n * 817C U+2212 MINUS SIGN           U+FF0D FULLWIDTH HYPHEN-MINUS\n * 8191 U+00A2 CENT SIGN            U+FFE0 FULLWIDTH CENT SIGN\n * 8192 U+00A3 POUND SIGN           U+FFE1 FULLWIDTH POUND SIGN\n * 81CA U+00AC NOT SIGN             U+FFE2 FULLWIDTH NOT SIGN\n *\n * EUC-JP and ISO-2022-JP should be compatible with CP932.\n *\n * Kernel and MLang have different Unicode mapping table.  Make sure\n * which API is used.\n */\nstatic compat_t cp932_compat[] = {\n    {0x00A5, 0x005C, COMPAT_OUT},\n    {0x203E, 0x007E, COMPAT_OUT},\n    {0x2014, 0x2015, COMPAT_OUT},\n    {0x301C, 0xFF5E, COMPAT_OUT},\n    {0x2016, 0x2225, COMPAT_OUT},\n    {0x2212, 0xFF0D, COMPAT_OUT},\n    {0x00A2, 0xFFE0, COMPAT_OUT},\n    {0x00A3, 0xFFE1, COMPAT_OUT},\n    {0x00AC, 0xFFE2, COMPAT_OUT},\n    {0, 0, 0}\n};\n\nstatic compat_t cp20932_compat[] = {\n    {0x00A5, 0x005C, COMPAT_OUT},\n    {0x203E, 0x007E, COMPAT_OUT},\n    {0x2014, 0x2015, COMPAT_OUT},\n    {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN},\n    {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN},\n    {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN},\n    {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN},\n    {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN},\n    {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN},\n    {0, 0, 0}\n};\n\nstatic compat_t *cp51932_compat = cp932_compat;\n\n/* cp20932_compat for kernel.  cp932_compat for mlang. */\nstatic compat_t *cp5022x_compat = cp932_compat;\n\ntypedef HRESULT (WINAPI *CONVERTINETSTRING)(\n    LPDWORD lpdwMode,\n    DWORD dwSrcEncoding,\n    DWORD dwDstEncoding,\n    LPCSTR lpSrcStr,\n    LPINT lpnSrcSize,\n    LPBYTE lpDstStr,\n    LPINT lpnDstSize\n);\ntypedef HRESULT (WINAPI *CONVERTINETMULTIBYTETOUNICODE)(\n    LPDWORD lpdwMode,\n    DWORD dwSrcEncoding,\n    LPCSTR lpSrcStr,\n    LPINT lpnMultiCharCount,\n    LPWSTR lpDstStr,\n    LPINT lpnWideCharCount\n);\ntypedef HRESULT (WINAPI *CONVERTINETUNICODETOMULTIBYTE)(\n    LPDWORD lpdwMode,\n    DWORD dwEncoding,\n    LPCWSTR lpSrcStr,\n    LPINT lpnWideCharCount,\n    LPSTR lpDstStr,\n    LPINT lpnMultiCharCount\n);\ntypedef HRESULT (WINAPI *ISCONVERTINETSTRINGAVAILABLE)(\n    DWORD dwSrcEncoding,\n    DWORD dwDstEncoding\n);\ntypedef HRESULT (WINAPI *LCIDTORFC1766A)(\n    LCID Locale,\n    LPSTR pszRfc1766,\n    int nChar\n);\ntypedef HRESULT (WINAPI *LCIDTORFC1766W)(\n    LCID Locale,\n    LPWSTR pszRfc1766,\n    int nChar\n);\ntypedef HRESULT (WINAPI *RFC1766TOLCIDA)(\n    LCID *pLocale,\n    LPSTR pszRfc1766\n);\ntypedef HRESULT (WINAPI *RFC1766TOLCIDW)(\n    LCID *pLocale,\n    LPWSTR pszRfc1766\n);\nstatic CONVERTINETSTRING ConvertINetString;\nstatic CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode;\nstatic CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte;\nstatic ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable;\nstatic LCIDTORFC1766A LcidToRfc1766A;\nstatic RFC1766TOLCIDA Rfc1766ToLcidA;\n\nstatic int\nload_mlang(void)\n{\n    HMODULE h;\n    if (ConvertINetString != NULL)\n        return TRUE;\n    h = LoadLibrary(TEXT(\"mlang.dll\"));\n    if (!h)\n        return FALSE;\n    ConvertINetString = (CONVERTINETSTRING)GetProcAddressA(h, \"ConvertINetString\");\n    ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddressA(h, \"ConvertINetMultiByteToUnicode\");\n    ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddressA(h, \"ConvertINetUnicodeToMultiByte\");\n    IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddressA(h, \"IsConvertINetStringAvailable\");\n    LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddressA(h, \"LcidToRfc1766A\");\n    Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddressA(h, \"Rfc1766ToLcidA\");\n    return TRUE;\n}\n\niconv_t\niconv_open(const char *tocode, const char *fromcode)\n{\n    rec_iconv_t *cd;\n\n    cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t));\n    if (cd == NULL)\n        return (iconv_t)(-1);\n\n#if defined(USE_LIBICONV_DLL)\n    errno = 0;\n    if (libiconv_iconv_open(cd, tocode, fromcode))\n        return (iconv_t)cd;\n#endif\n\n    /* reset the errno to prevent reporting wrong error code.\n     * 0 for unsorted error. */\n    errno = 0;\n    if (win_iconv_open(cd, tocode, fromcode))\n        return (iconv_t)cd;\n\n    free(cd);\n\n    return (iconv_t)(-1);\n}\n\nint\niconv_close(iconv_t _cd)\n{\n    rec_iconv_t *cd = (rec_iconv_t *)_cd;\n    int r = cd->iconv_close(cd->cd);\n    int e = *(cd->_errno());\n#if defined(USE_LIBICONV_DLL)\n    if (cd->hlibiconv != NULL)\n        FreeLibrary(cd->hlibiconv);\n#endif\n    free(cd);\n    errno = e;\n    return r;\n}\n\nsize_t\niconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)\n{\n    rec_iconv_t *cd = (rec_iconv_t *)_cd;\n    size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft);\n    errno = *(cd->_errno());\n    return r;\n}\n\nstatic int\nwin_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)\n{\n    if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to))\n        return FALSE;\n    cd->iconv_close = win_iconv_close;\n    cd->iconv = win_iconv;\n    cd->_errno = _errno;\n    cd->cd = (iconv_t)cd;\n    return TRUE;\n}\n\nstatic int\nwin_iconv_close(iconv_t cd UNUSED)\n{\n    return 0;\n}\n\nstatic size_t\nwin_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)\n{\n    rec_iconv_t *cd = (rec_iconv_t *)_cd;\n    ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */\n    int insize;\n    int outsize;\n    int wsize;\n    DWORD frommode;\n    DWORD tomode;\n    uint wc;\n    compat_t *cp;\n    int i;\n\n    if (inbuf == NULL || *inbuf == NULL)\n    {\n        if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL)\n        {\n            tomode = cd->to.mode;\n            outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft);\n            if (outsize == -1)\n            {\n                if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)\n                {\n                    outsize = 0;\n                }\n                else\n                {\n                    cd->to.mode = tomode;\n                    return (size_t)(-1);\n                }\n            }\n            *outbuf += outsize;\n            *outbytesleft -= outsize;\n        }\n        cd->from.mode = 0;\n        cd->to.mode = 0;\n        return 0;\n    }\n\n    while (*inbytesleft != 0)\n    {\n        frommode = cd->from.mode;\n        tomode = cd->to.mode;\n        wsize = MB_CHAR_MAX;\n\n        insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize);\n        if (insize == -1)\n        {\n            if (cd->to.flags & FLAG_IGNORE)\n            {\n                cd->from.mode = frommode;\n                insize = 1;\n                wsize = 0;\n            }\n            else\n            {\n                cd->from.mode = frommode;\n                return (size_t)(-1);\n            }\n        }\n\n        if (wsize == 0)\n        {\n            *inbuf += insize;\n            *inbytesleft -= insize;\n            continue;\n        }\n\n        if (cd->from.compat != NULL)\n        {\n            wc = utf16_to_ucs4(wbuf);\n            cp = cd->from.compat;\n            for (i = 0; cp[i].in != 0; ++i)\n            {\n                if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc)\n                {\n                    ucs4_to_utf16(cp[i].in, wbuf, &wsize);\n                    break;\n                }\n            }\n        }\n\n        if (cd->to.compat != NULL)\n        {\n            wc = utf16_to_ucs4(wbuf);\n            cp = cd->to.compat;\n            for (i = 0; cp[i].in != 0; ++i)\n            {\n                if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc)\n                {\n                    ucs4_to_utf16(cp[i].out, wbuf, &wsize);\n                    break;\n                }\n            }\n        }\n\n        outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft);\n        if (outsize == -1)\n        {\n            if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)\n            {\n                cd->to.mode = tomode;\n                outsize = 0;\n            }\n            else\n            {\n                cd->from.mode = frommode;\n                cd->to.mode = tomode;\n                return (size_t)(-1);\n            }\n        }\n\n        *inbuf += insize;\n        *outbuf += outsize;\n        *inbytesleft -= insize;\n        *outbytesleft -= outsize;\n    }\n\n    return 0;\n}\n\nstatic int\nmake_csconv(const char *_name, csconv_t *cv)\n{\n    CPINFO cpinfo;\n    int use_compat = TRUE;\n    int flag = 0;\n    char *name;\n    char *p;\n\n    name = xstrndup(_name, strlen(_name));\n    if (name == NULL)\n        return FALSE;\n\n    /* check for option \"enc_name//opt1//opt2\" */\n    while ((p = strrstr(name, \"//\")) != NULL)\n    {\n        if (_stricmp(p + 2, \"nocompat\") == 0)\n            use_compat = FALSE;\n        else if (_stricmp(p + 2, \"translit\") == 0)\n            flag |= FLAG_TRANSLIT;\n        else if (_stricmp(p + 2, \"ignore\") == 0)\n            flag |= FLAG_IGNORE;\n        *p = 0;\n    }\n\n    cv->mode = 0;\n    cv->flags = flag;\n    cv->mblen = NULL;\n    cv->flush = NULL;\n    cv->compat = NULL;\n    cv->codepage = name_to_codepage(name);\n    if (cv->codepage == 1200 || cv->codepage == 1201)\n    {\n        cv->mbtowc = utf16_mbtowc;\n        cv->wctomb = utf16_wctomb;\n        if (_stricmp(name, \"UTF-16\") == 0 || _stricmp(name, \"UTF16\") == 0 ||\n          _stricmp(name, \"UCS-2\") == 0 || _stricmp(name, \"UCS2\") == 0 ||\n\t  _stricmp(name,\"UCS-2-INTERNAL\") == 0)\n            cv->flags |= FLAG_USE_BOM;\n    }\n    else if (cv->codepage == 12000 || cv->codepage == 12001)\n    {\n        cv->mbtowc = utf32_mbtowc;\n        cv->wctomb = utf32_wctomb;\n        if (_stricmp(name, \"UTF-32\") == 0 || _stricmp(name, \"UTF32\") == 0 ||\n          _stricmp(name, \"UCS-4\") == 0 || _stricmp(name, \"UCS4\") == 0)\n            cv->flags |= FLAG_USE_BOM;\n    }\n    else if (cv->codepage == 65001)\n    {\n        cv->mbtowc = kernel_mbtowc;\n        cv->wctomb = kernel_wctomb;\n        cv->mblen = utf8_mblen;\n    }\n    else if ((cv->codepage == 50220 || cv->codepage == 50221 || cv->codepage == 50222) && load_mlang())\n    {\n        cv->mbtowc = iso2022jp_mbtowc;\n        cv->wctomb = iso2022jp_wctomb;\n        cv->flush = iso2022jp_flush;\n    }\n    else if (cv->codepage == 51932 && load_mlang())\n    {\n        cv->mbtowc = mlang_mbtowc;\n        cv->wctomb = mlang_wctomb;\n        cv->mblen = eucjp_mblen;\n    }\n    else if (IsValidCodePage(cv->codepage)\n\t     && GetCPInfo(cv->codepage, &cpinfo) != 0)\n    {\n        cv->mbtowc = kernel_mbtowc;\n        cv->wctomb = kernel_wctomb;\n        if (cpinfo.MaxCharSize == 1)\n            cv->mblen = sbcs_mblen;\n        else if (cpinfo.MaxCharSize == 2)\n            cv->mblen = dbcs_mblen;\n        else\n\t    cv->mblen = mbcs_mblen;\n    }\n    else\n    {\n        /* not supported */\n        free(name);\n        errno = EINVAL;\n        return FALSE;\n    }\n\n    if (use_compat)\n    {\n        switch (cv->codepage)\n        {\n        case 932: cv->compat = cp932_compat; break;\n        case 20932: cv->compat = cp20932_compat; break;\n        case 51932: cv->compat = cp51932_compat; break;\n        case 50220: case 50221: case 50222: cv->compat = cp5022x_compat; break;\n        }\n    }\n\n    free(name);\n\n    return TRUE;\n}\n\nstatic int\nname_to_codepage(const char *name)\n{\n    int i;\n\n    if (*name == '\\0' ||\n\tstrcmp(name, \"char\") == 0)\n        return GetACP();\n    else if (strcmp(name, \"wchar_t\") == 0)\n        return 1200;\n    else if (_strnicmp(name, \"cp\", 2) == 0)\n        return atoi(name + 2); /* CP123 */\n    else if ('0' <= name[0] && name[0] <= '9')\n        return atoi(name);     /* 123 */\n    else if (_strnicmp(name, \"xx\", 2) == 0)\n        return atoi(name + 2); /* XX123 for debug */\n\n    for (i = 0; codepage_alias[i].name != NULL; ++i)\n        if (_stricmp(name, codepage_alias[i].name) == 0)\n            return codepage_alias[i].codepage;\n    return -1;\n}\n\n/*\n * http://www.faqs.org/rfcs/rfc2781.html\n */\nstatic uint\nutf16_to_ucs4(const ushort *wbuf)\n{\n    uint wc = wbuf[0];\n    if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)\n        wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000;\n    return wc;\n}\n\nstatic void\nucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize)\n{\n    if (wc < 0x10000)\n    {\n        wbuf[0] = wc;\n        *wbufsize = 1;\n    }\n    else\n    {\n        wc -= 0x10000;\n        wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF);\n        wbuf[1] = 0xDC00 | (wc & 0x3FF);\n        *wbufsize = 2;\n    }\n}\n\n/*\n * Check if codepage is one of those for which the dwFlags parameter\n * to MultiByteToWideChar() must be zero. Return zero or\n * MB_ERR_INVALID_CHARS.  The docs in Platform SDK for Windows\n * Server 2003 R2 claims that also codepage 65001 is one of these, but\n * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave\n * out 65001 (UTF-8), and that indeed seems to be the case on XP, it\n * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting\n * from UTF-8.\n */\nstatic int\nmbtowc_flags(int codepage)\n{\n    return (codepage == 50220 || codepage == 50221 ||\n\t    codepage == 50222 || codepage == 50225 ||\n\t    codepage == 50227 || codepage == 50229 ||\n\t    codepage == 52936 || codepage == 54936 ||\n\t    (codepage >= 57002 && codepage <= 57011) ||\n\t    codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS;\n}\n\n/*\n * Check if codepage is one those for which the lpUsedDefaultChar\n * parameter to WideCharToMultiByte() must be NULL.  The docs in\n * Platform SDK for Windows Server 2003 R2 claims that this is the\n * list below, while the MSDN docs for MSVS2008 claim that it is only\n * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform\n * SDK seems to be correct, at least for XP.\n */\nstatic int\nmust_use_null_useddefaultchar(int codepage)\n{\n    return (codepage == 65000 || codepage == 65001 ||\n            codepage == 50220 || codepage == 50221 ||\n            codepage == 50222 || codepage == 50225 ||\n            codepage == 50227 || codepage == 50229 ||\n            codepage == 52936 || codepage == 54936 ||\n            (codepage >= 57002 && codepage <= 57011) ||\n            codepage == 42);\n}\n\nstatic char *\nstrrstr(const char *str, const char *token)\n{\n    int len = strlen(token);\n    const char *p = str + strlen(str);\n\n    while (str <= --p)\n        if (p[0] == token[0] && strncmp(p, token, len) == 0)\n            return (char *)p;\n    return NULL;\n}\n\nstatic char *\nxstrndup(const char *s, size_t n)\n{\n    char *p;\n\n    p = (char *)malloc(n + 1);\n    if (p == NULL)\n        return NULL;\n    memcpy(p, s, n);\n    p[n] = '\\0';\n    return p;\n}\n\nstatic int\nseterror(int err)\n{\n    errno = err;\n    return -1;\n}\n\n#if defined(USE_LIBICONV_DLL)\nstatic int\nlibiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)\n{\n    HMODULE hlibiconv = NULL;\n    char *dllname;\n    const char *p;\n    const char *e;\n    f_iconv_open _iconv_open;\n\n    /*\n     * always try to load dll, so that we can switch dll in runtime.\n     */\n\n    /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */\n    p = getenv(\"WINICONV_LIBICONV_DLL\");\n    if (p == NULL)\n        p = DEFAULT_LIBICONV_DLL;\n    /* parse comma separated value */\n    for ( ; *p != 0; p = (*e == ',') ? e + 1 : e)\n    {\n        e = strchr(p, ',');\n        if (p == e)\n            continue;\n        else if (e == NULL)\n            e = p + strlen(p);\n        dllname = xstrndup(p, e - p);\n        if (dllname == NULL)\n            return FALSE;\n        hlibiconv = LoadLibraryA(dllname);\n        free(dllname);\n        if (hlibiconv != NULL)\n        {\n            if (hlibiconv == hwiniconv)\n            {\n                FreeLibrary(hlibiconv);\n                hlibiconv = NULL;\n                continue;\n            }\n            break;\n        }\n    }\n\n    if (hlibiconv == NULL)\n        goto failed;\n\n    _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, \"libiconv_open\");\n    if (_iconv_open == NULL)\n        _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, \"iconv_open\");\n    cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, \"libiconv_close\");\n    if (cd->iconv_close == NULL)\n        cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, \"iconv_close\");\n    cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, \"libiconv\");\n    if (cd->iconv == NULL)\n        cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, \"iconv\");\n    cd->_errno = (f_errno)find_imported_function(hlibiconv, \"_errno\");\n    if (_iconv_open == NULL || cd->iconv_close == NULL\n            || cd->iconv == NULL || cd->_errno == NULL)\n        goto failed;\n\n    cd->cd = _iconv_open(tocode, fromcode);\n    if (cd->cd == (iconv_t)(-1))\n        goto failed;\n\n    cd->hlibiconv = hlibiconv;\n    return TRUE;\n\nfailed:\n    if (hlibiconv != NULL)\n        FreeLibrary(hlibiconv);\n    return FALSE;\n}\n\n/*\n * Reference:\n * http://forums.belution.com/ja/vc/000/234/78s.shtml\n * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html\n *\n * The formal way is\n *   imagehlp.h or dbghelp.h\n *   imagehlp.lib or dbghelp.lib\n *   ImageDirectoryEntryToData()\n */\n#define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base))\n#define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew))\nstatic PVOID\nMyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size)\n{\n    /* TODO: MappedAsImage? */\n    PIMAGE_DATA_DIRECTORY p;\n    p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry;\n    if (p->VirtualAddress == 0) {\n      *Size = 0;\n      return NULL;\n    }\n    *Size = p->Size;\n    return (PVOID)((LPBYTE)Base + p->VirtualAddress);\n}\n\nstatic FARPROC\nfind_imported_function(HMODULE hModule, const char *funcname)\n{\n    DWORD_PTR Base;\n    ULONG Size;\n    PIMAGE_IMPORT_DESCRIPTOR Imp;\n    PIMAGE_THUNK_DATA Address;      /* Import Address Table */\n    PIMAGE_THUNK_DATA Name;         /* Import Name Table */\n    PIMAGE_IMPORT_BY_NAME ImpName;\n\n    Base = (DWORD_PTR)hModule;\n    Imp = (PIMAGE_IMPORT_DESCRIPTOR)MyImageDirectoryEntryToData(\n            (LPVOID)Base,\n            TRUE,\n            IMAGE_DIRECTORY_ENTRY_IMPORT,\n            &Size);\n    if (Imp == NULL)\n        return NULL;\n    for ( ; Imp->OriginalFirstThunk != 0; ++Imp)\n    {\n        Address = (PIMAGE_THUNK_DATA)(Base + Imp->FirstThunk);\n        Name = (PIMAGE_THUNK_DATA)(Base + Imp->OriginalFirstThunk);\n        for ( ; Name->u1.Ordinal != 0; ++Name, ++Address)\n        {\n            if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal))\n            {\n                ImpName = (PIMAGE_IMPORT_BY_NAME)\n                    (Base + (DWORD_PTR)Name->u1.AddressOfData);\n                if (strcmp((char *)ImpName->Name, funcname) == 0)\n                    return (FARPROC)Address->u1.Function;\n            }\n        }\n    }\n    return NULL;\n}\n#endif\n\nstatic int\nsbcs_mblen(csconv_t *cv UNUSED, const uchar *buf UNUSED, int bufsize UNUSED)\n{\n    return 1;\n}\n\nstatic int\ndbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)\n{\n    int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1;\n    if (bufsize < len)\n        return seterror(EINVAL);\n    return len;\n}\n\nstatic int\nmbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)\n{\n    int len = 0;\n\n    if (cv->codepage == 54936) {\n\tif (buf[0] <= 0x7F) len = 1;\n\telse if (buf[0] >= 0x81 && buf[0] <= 0xFE &&\n\t\t bufsize >= 2 &&\n\t\t ((buf[1] >= 0x40 && buf[1] <= 0x7E) ||\n\t\t  (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2;\n\telse if (buf[0] >= 0x81 && buf[0] <= 0xFE &&\n\t\t bufsize >= 4 &&\n\t\t buf[1] >= 0x30 && buf[1] <= 0x39) len = 4;\n\telse\n\t    return seterror(EINVAL);\n\treturn len;\n    }\n    else\n\treturn seterror(EINVAL);\n}\n\nstatic int\nutf8_mblen(csconv_t *cv UNUSED, const uchar *buf, int bufsize)\n{\n    int len = 0;\n\n    if (buf[0] < 0x80) len = 1;\n    else if ((buf[0] & 0xE0) == 0xC0) len = 2;\n    else if ((buf[0] & 0xF0) == 0xE0) len = 3;\n    else if ((buf[0] & 0xF8) == 0xF0) len = 4;\n    else if ((buf[0] & 0xFC) == 0xF8) len = 5;\n    else if ((buf[0] & 0xFE) == 0xFC) len = 6;\n\n    if (len == 0)\n        return seterror(EILSEQ);\n    else if (bufsize < len)\n        return seterror(EINVAL);\n    return len;\n}\n\nstatic int\neucjp_mblen(csconv_t *cv UNUSED, const uchar *buf, int bufsize)\n{\n    if (buf[0] < 0x80) /* ASCII */\n        return 1;\n    else if (buf[0] == 0x8E) /* JIS X 0201 */\n    {\n        if (bufsize < 2)\n            return seterror(EINVAL);\n        else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF))\n            return seterror(EILSEQ);\n        return 2;\n    }\n    else if (buf[0] == 0x8F) /* JIS X 0212 */\n    {\n        if (bufsize < 3)\n            return seterror(EINVAL);\n        else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE)\n                || !(0xA1 <= buf[2] && buf[2] <= 0xFE))\n            return seterror(EILSEQ);\n        return 3;\n    }\n    else /* JIS X 0208 */\n    {\n        if (bufsize < 2)\n            return seterror(EINVAL);\n        else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE)\n                || !(0xA1 <= buf[1] && buf[1] <= 0xFE))\n            return seterror(EILSEQ);\n        return 2;\n    }\n}\n\nstatic int\nkernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)\n{\n    int len;\n\n    len = cv->mblen(cv, buf, bufsize);\n    if (len == -1)\n        return -1;\n    /* If converting from ASCII, reject 8bit\n     * chars. MultiByteToWideChar() doesn't. Note that for ASCII we\n     * know that the mblen function is sbcs_mblen() so len is 1.\n     */\n    if (cv->codepage == 20127 && buf[0] >= 0x80)\n        return seterror(EILSEQ);\n    *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage),\n            (const char *)buf, len, (wchar_t *)wbuf, *wbufsize);\n    if (*wbufsize == 0)\n        return seterror(EILSEQ);\n    return len;\n}\n\nstatic int\nkernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)\n{\n    BOOL usedDefaultChar = 0;\n    BOOL *p = NULL;\n    int flags = 0;\n    int len;\n\n    if (bufsize == 0)\n        return seterror(E2BIG);\n    if (!must_use_null_useddefaultchar(cv->codepage))\n    {\n        p = &usedDefaultChar;\n#ifdef WC_NO_BEST_FIT_CHARS\n        if (!(cv->flags & FLAG_TRANSLIT))\n            flags |= WC_NO_BEST_FIT_CHARS;\n#endif\n    }\n    len = WideCharToMultiByte(cv->codepage, flags,\n            (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p);\n    if (len == 0)\n    {\n        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\n            return seterror(E2BIG);\n        return seterror(EILSEQ);\n    }\n    else if (usedDefaultChar && !(cv->flags & FLAG_TRANSLIT))\n        return seterror(EILSEQ);\n    else if (cv->mblen(cv, buf, len) != len) /* validate result */\n        return seterror(EILSEQ);\n    return len;\n}\n\n/*\n * It seems that the mode (cv->mode) is fixnum.\n * For example, when converting iso-2022-jp(cp50221) to unicode:\n *      in ascii sequence: mode=0xC42C0000\n *   in jisx0208 sequence: mode=0xC42C0001\n * \"C42C\" is same for each convert session.\n * It should be: ((codepage-1)<<16)|state\n */\nstatic int\nmlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)\n{\n    int len;\n    int insize;\n    HRESULT hr;\n\n    len = cv->mblen(cv, buf, bufsize);\n    if (len == -1)\n        return -1;\n    insize = len;\n    hr = ConvertINetMultiByteToUnicode(&cv->mode, cv->codepage,\n            (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize);\n    if (hr != S_OK || insize != len)\n        return seterror(EILSEQ);\n    return len;\n}\n\nstatic int\nmlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)\n{\n    char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */\n    int tmpsize = MB_CHAR_MAX;\n    int insize = wbufsize;\n    HRESULT hr;\n\n    hr = ConvertINetUnicodeToMultiByte(&cv->mode, cv->codepage,\n            (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize);\n    if (hr != S_OK || insize != wbufsize)\n        return seterror(EILSEQ);\n    else if (bufsize < tmpsize)\n        return seterror(E2BIG);\n    else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize)\n        return seterror(EILSEQ);\n    memcpy(buf, tmpbuf, tmpsize);\n    return tmpsize;\n}\n\nstatic int\nutf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)\n{\n    int codepage = cv->codepage;\n\n    /* swap endian: 1200 <-> 1201 */\n    if (cv->mode & UNICODE_MODE_SWAPPED)\n        codepage ^= 1;\n\n    if (bufsize < 2)\n        return seterror(EINVAL);\n    if (codepage == 1200) /* little endian */\n        wbuf[0] = (buf[1] << 8) | buf[0];\n    else if (codepage == 1201) /* big endian */\n        wbuf[0] = (buf[0] << 8) | buf[1];\n\n    if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))\n    {\n        cv->mode |= UNICODE_MODE_BOM_DONE;\n        if (wbuf[0] == 0xFFFE)\n        {\n            cv->mode |= UNICODE_MODE_SWAPPED;\n            *wbufsize = 0;\n            return 2;\n        }\n        else if (wbuf[0] == 0xFEFF)\n        {\n            *wbufsize = 0;\n            return 2;\n        }\n    }\n\n    if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF)\n        return seterror(EILSEQ);\n    if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)\n    {\n        if (bufsize < 4)\n            return seterror(EINVAL);\n        if (codepage == 1200) /* little endian */\n            wbuf[1] = (buf[3] << 8) | buf[2];\n        else if (codepage == 1201) /* big endian */\n            wbuf[1] = (buf[2] << 8) | buf[3];\n        if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF))\n            return seterror(EILSEQ);\n        *wbufsize = 2;\n        return 4;\n    }\n    *wbufsize = 1;\n    return 2;\n}\n\nstatic int\nutf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)\n{\n    if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))\n    {\n        int r;\n\n        cv->mode |= UNICODE_MODE_BOM_DONE;\n        if (bufsize < 2)\n            return seterror(E2BIG);\n        if (cv->codepage == 1200) /* little endian */\n            memcpy(buf, \"\\xFF\\xFE\", 2);\n        else if (cv->codepage == 1201) /* big endian */\n            memcpy(buf, \"\\xFE\\xFF\", 2);\n\n        r = utf16_wctomb(cv, wbuf, wbufsize, buf + 2, bufsize - 2);\n        if (r == -1)\n            return -1;\n        return r + 2;\n    }\n\n    if (bufsize < 2)\n        return seterror(E2BIG);\n    if (cv->codepage == 1200) /* little endian */\n    {\n        buf[0] = (wbuf[0] & 0x00FF);\n        buf[1] = (wbuf[0] & 0xFF00) >> 8;\n    }\n    else if (cv->codepage == 1201) /* big endian */\n    {\n        buf[0] = (wbuf[0] & 0xFF00) >> 8;\n        buf[1] = (wbuf[0] & 0x00FF);\n    }\n    if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)\n    {\n        if (bufsize < 4)\n            return seterror(E2BIG);\n        if (cv->codepage == 1200) /* little endian */\n        {\n            buf[2] = (wbuf[1] & 0x00FF);\n            buf[3] = (wbuf[1] & 0xFF00) >> 8;\n        }\n        else if (cv->codepage == 1201) /* big endian */\n        {\n            buf[2] = (wbuf[1] & 0xFF00) >> 8;\n            buf[3] = (wbuf[1] & 0x00FF);\n        }\n        return 4;\n    }\n    return 2;\n}\n\nstatic int\nutf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)\n{\n    int codepage = cv->codepage;\n    uint wc = 0xD800;\n\n    /* swap endian: 12000 <-> 12001 */\n    if (cv->mode & UNICODE_MODE_SWAPPED)\n        codepage ^= 1;\n\n    if (bufsize < 4)\n        return seterror(EINVAL);\n    if (codepage == 12000) /* little endian */\n        wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];\n    else if (codepage == 12001) /* big endian */\n        wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];\n\n    if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))\n    {\n        cv->mode |= UNICODE_MODE_BOM_DONE;\n        if (wc == 0xFFFE0000)\n        {\n            cv->mode |= UNICODE_MODE_SWAPPED;\n            *wbufsize = 0;\n            return 4;\n        }\n        else if (wc == 0x0000FEFF)\n        {\n            *wbufsize = 0;\n            return 4;\n        }\n    }\n\n    if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc)\n        return seterror(EILSEQ);\n    ucs4_to_utf16(wc, wbuf, wbufsize);\n    return 4;\n}\n\nstatic int\nutf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)\n{\n    uint wc;\n\n    if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))\n    {\n        int r;\n\n        cv->mode |= UNICODE_MODE_BOM_DONE;\n        if (bufsize < 4)\n            return seterror(E2BIG);\n        if (cv->codepage == 12000) /* little endian */\n            memcpy(buf, \"\\xFF\\xFE\\x00\\x00\", 4);\n        else if (cv->codepage == 12001) /* big endian */\n            memcpy(buf, \"\\x00\\x00\\xFE\\xFF\", 4);\n\n        r = utf32_wctomb(cv, wbuf, wbufsize, buf + 4, bufsize - 4);\n        if (r == -1)\n            return -1;\n        return r + 4;\n    }\n\n    if (bufsize < 4)\n        return seterror(E2BIG);\n    wc = utf16_to_ucs4(wbuf);\n    if (cv->codepage == 12000) /* little endian */\n    {\n        buf[0] = wc & 0x000000FF;\n        buf[1] = (wc & 0x0000FF00) >> 8;\n        buf[2] = (wc & 0x00FF0000) >> 16;\n        buf[3] = (wc & 0xFF000000) >> 24;\n    }\n    else if (cv->codepage == 12001) /* big endian */\n    {\n        buf[0] = (wc & 0xFF000000) >> 24;\n        buf[1] = (wc & 0x00FF0000) >> 16;\n        buf[2] = (wc & 0x0000FF00) >> 8;\n        buf[3] = wc & 0x000000FF;\n    }\n    return 4;\n}\n\n/*\n * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)\n * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow\n *        1 byte Kana)\n * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte\n *        Kana - SO/SI)\n *\n * MultiByteToWideChar() and WideCharToMultiByte() behave differently\n * depending on Windows version.  On XP, WideCharToMultiByte() doesn't\n * terminate result sequence with ascii escape.  But Vista does.\n * Use MLang instead.\n */\n\n#define ISO2022_MODE(cs, shift) (((cs) << 8) | (shift))\n#define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF)\n#define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF)\n\n#define ISO2022_SI  0\n#define ISO2022_SO  1\n\n/* shift in */\nstatic const char iso2022_SI_seq[] = \"\\x0F\";\n/* shift out */\nstatic const char iso2022_SO_seq[] = \"\\x0E\";\n\ntypedef struct iso2022_esc_t iso2022_esc_t;\nstruct iso2022_esc_t {\n    const char *esc;\n    int esc_len;\n    int len;\n    int cs;\n};\n\n#define ISO2022JP_CS_ASCII            0\n#define ISO2022JP_CS_JISX0201_ROMAN   1\n#define ISO2022JP_CS_JISX0201_KANA    2\n#define ISO2022JP_CS_JISX0208_1978    3\n#define ISO2022JP_CS_JISX0208_1983    4\n#define ISO2022JP_CS_JISX0212         5\n\nstatic iso2022_esc_t iso2022jp_esc[] = {\n    {\"\\x1B\\x28\\x42\", 3, 1, ISO2022JP_CS_ASCII},\n    {\"\\x1B\\x28\\x4A\", 3, 1, ISO2022JP_CS_JISX0201_ROMAN},\n    {\"\\x1B\\x28\\x49\", 3, 1, ISO2022JP_CS_JISX0201_KANA},\n    {\"\\x1B\\x24\\x40\", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */\n    {\"\\x1B\\x24\\x42\", 3, 2, ISO2022JP_CS_JISX0208_1983},\n    {\"\\x1B\\x24\\x28\\x44\", 4, 2, ISO2022JP_CS_JISX0212},\n    {NULL, 0, 0, 0}\n};\n\nstatic int\niso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)\n{\n    iso2022_esc_t *iesc = iso2022jp_esc;\n    char tmp[MB_CHAR_MAX];\n    int insize;\n    HRESULT hr;\n    DWORD dummy = 0;\n    int len;\n    int esc_len;\n    int cs;\n    int shift;\n    int i;\n\n    if (buf[0] == 0x1B)\n    {\n        for (i = 0; iesc[i].esc != NULL; ++i)\n        {\n            esc_len = iesc[i].esc_len;\n            if (bufsize < esc_len)\n            {\n                if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0)\n                    return seterror(EINVAL);\n            }\n            else\n            {\n                if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0)\n                {\n                    cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI);\n                    *wbufsize = 0;\n                    return esc_len;\n                }\n            }\n        }\n        /* not supported escape sequence */\n        return seterror(EILSEQ);\n    }\n    else if (buf[0] == iso2022_SO_seq[0])\n    {\n        cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SO);\n        *wbufsize = 0;\n        return 1;\n    }\n    else if (buf[0] == iso2022_SI_seq[0])\n    {\n        cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SI);\n        *wbufsize = 0;\n        return 1;\n    }\n\n    cs = ISO2022_MODE_CS(cv->mode);\n    shift = ISO2022_MODE_SHIFT(cv->mode);\n\n    /* reset the mode for informal sequence */\n    if (buf[0] < 0x20)\n    {\n        cs = ISO2022JP_CS_ASCII;\n        shift = ISO2022_SI;\n    }\n\n    len = iesc[cs].len;\n    if (bufsize < len)\n        return seterror(EINVAL);\n    for (i = 0; i < len; ++i)\n        if (!(buf[i] < 0x80))\n            return seterror(EILSEQ);\n    esc_len = iesc[cs].esc_len;\n    memcpy(tmp, iesc[cs].esc, esc_len);\n    if (shift == ISO2022_SO)\n    {\n        memcpy(tmp + esc_len, iso2022_SO_seq, 1);\n        esc_len += 1;\n    }\n    memcpy(tmp + esc_len, buf, len);\n\n    if ((cv->codepage == 50220 || cv->codepage == 50221\n                || cv->codepage == 50222) && shift == ISO2022_SO)\n    {\n        /* XXX: shift-out cannot be used for mbtowc (both kernel and\n         * mlang) */\n        esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len;\n        memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len);\n        memcpy(tmp + esc_len, buf, len);\n    }\n\n    insize = len + esc_len;\n    hr = ConvertINetMultiByteToUnicode(&dummy, cv->codepage,\n            (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize);\n    if (hr != S_OK || insize != len + esc_len)\n        return seterror(EILSEQ);\n\n    /* Check for conversion error.  Assuming defaultChar is 0x3F. */\n    /* ascii should be converted from ascii */\n    if (wbuf[0] == buf[0]\n            && cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI))\n        return seterror(EILSEQ);\n\n    /* reset the mode for informal sequence */\n    if (cv->mode != ISO2022_MODE(cs, shift))\n        cv->mode = ISO2022_MODE(cs, shift);\n\n    return len;\n}\n\nstatic int\niso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)\n{\n    iso2022_esc_t *iesc = iso2022jp_esc;\n    char tmp[MB_CHAR_MAX];\n    int tmpsize = MB_CHAR_MAX;\n    int insize = wbufsize;\n    HRESULT hr;\n    DWORD dummy = 0;\n    int len;\n    int esc_len;\n    int cs;\n    int shift;\n    int i;\n\n    /*\n     * MultiByte = [escape sequence] + character + [escape sequence]\n     *\n     * Whether trailing escape sequence is added depends on which API is\n     * used (kernel or MLang, and its version).\n     */\n    hr = ConvertINetUnicodeToMultiByte(&dummy, cv->codepage,\n            (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize);\n    if (hr != S_OK || insize != wbufsize)\n        return seterror(EILSEQ);\n    else if (bufsize < tmpsize)\n        return seterror(E2BIG);\n\n    if (tmpsize == 1)\n    {\n        cs = ISO2022JP_CS_ASCII;\n        esc_len = 0;\n    }\n    else\n    {\n        for (i = 1; iesc[i].esc != NULL; ++i)\n        {\n            esc_len = iesc[i].esc_len;\n            if (strncmp(tmp, iesc[i].esc, esc_len) == 0)\n            {\n                cs = iesc[i].cs;\n                break;\n            }\n        }\n        if (iesc[i].esc == NULL)\n            /* not supported escape sequence */\n            return seterror(EILSEQ);\n    }\n\n    shift = ISO2022_SI;\n    if (tmp[esc_len] == iso2022_SO_seq[0])\n    {\n        shift = ISO2022_SO;\n        esc_len += 1;\n    }\n\n    len = iesc[cs].len;\n\n    /* Check for converting error.  Assuming defaultChar is 0x3F. */\n    /* ascii should be converted from ascii */\n    if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80))\n        return seterror(EILSEQ);\n    else if (tmpsize < esc_len + len)\n        return seterror(EILSEQ);\n\n    if (cv->mode == ISO2022_MODE(cs, shift))\n    {\n        /* remove escape sequence */\n        if (esc_len != 0)\n            memmove(tmp, tmp + esc_len, len);\n        esc_len = 0;\n    }\n    else\n    {\n        if (cs == ISO2022JP_CS_ASCII)\n        {\n            esc_len = iesc[ISO2022JP_CS_ASCII].esc_len;\n            memmove(tmp + esc_len, tmp, len);\n            memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len);\n        }\n        if (ISO2022_MODE_SHIFT(cv->mode) == ISO2022_SO)\n        {\n            /* shift-in before changing to other mode */\n            memmove(tmp + 1, tmp, len + esc_len);\n            memcpy(tmp, iso2022_SI_seq, 1);\n            esc_len += 1;\n        }\n    }\n\n    if (bufsize < len + esc_len)\n        return seterror(E2BIG);\n    memcpy(buf, tmp, len + esc_len);\n    cv->mode = ISO2022_MODE(cs, shift);\n    return len + esc_len;\n}\n\nstatic int\niso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize)\n{\n    iso2022_esc_t *iesc = iso2022jp_esc;\n    int esc_len;\n\n    if (cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI))\n    {\n        esc_len = 0;\n        if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI)\n            esc_len += 1;\n        if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII)\n            esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;\n        if (bufsize < esc_len)\n            return seterror(E2BIG);\n\n        esc_len = 0;\n        if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI)\n        {\n            memcpy(buf, iso2022_SI_seq, 1);\n            esc_len += 1;\n        }\n        if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII)\n        {\n            memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc,\n                    iesc[ISO2022JP_CS_ASCII].esc_len);\n            esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;\n        }\n        return esc_len;\n    }\n    return 0;\n}\n\n#if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL)\nBOOL WINAPI\nDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)\n{\n    switch( fdwReason )\n    {\n    case DLL_PROCESS_ATTACH:\n        hwiniconv = (HMODULE)hinstDLL;\n        break;\n    case DLL_THREAD_ATTACH:\n    case DLL_THREAD_DETACH:\n    case DLL_PROCESS_DETACH:\n        break;\n    }\n    return TRUE;\n}\n#endif\n\n#if defined(MAKE_EXE)\n#include <stdio.h>\n#include <fcntl.h>\n#include <io.h>\nint\nmain(int argc, char **argv)\n{\n    char *fromcode = NULL;\n    char *tocode = NULL;\n    int i;\n    char inbuf[BUFSIZ];\n    char outbuf[BUFSIZ];\n    const char *pin;\n    char *pout;\n    size_t inbytesleft;\n    size_t outbytesleft;\n    size_t rest = 0;\n    iconv_t cd;\n    size_t r;\n    FILE *in = stdin;\n    FILE *out = stdout;\n    int ignore = 0;\n    char *p;\n\n    _setmode(_fileno(stdin), _O_BINARY);\n    _setmode(_fileno(stdout), _O_BINARY);\n\n    for (i = 1; i < argc; ++i)\n    {\n        if (strcmp(argv[i], \"-l\") == 0)\n        {\n            for (i = 0; codepage_alias[i].name != NULL; ++i)\n                printf(\"%s\\n\", codepage_alias[i].name);\n            return 0;\n        }\n\n        if (strcmp(argv[i], \"-f\") == 0)\n            fromcode = argv[++i];\n        else if (strcmp(argv[i], \"-t\") == 0)\n            tocode = argv[++i];\n        else if (strcmp(argv[i], \"-c\") == 0)\n            ignore = 1;\n        else if (strcmp(argv[i], \"--output\") == 0)\n        {\n            out = fopen(argv[++i], \"wb\");\n            if(out == NULL)\n            {\n                fprintf(stderr, \"cannot open %s\\n\", argv[i]);\n                return 1;\n            }\n        }\n        else\n        {\n            in = fopen(argv[i], \"rb\");\n            if (in == NULL)\n            {\n                fprintf(stderr, \"cannot open %s\\n\", argv[i]);\n                return 1;\n            }\n            break;\n        }\n    }\n\n    if (fromcode == NULL || tocode == NULL)\n    {\n        printf(\"usage: %s [-c] -f from-enc -t to-enc [file]\\n\", argv[0]);\n        return 0;\n    }\n\n    if (ignore)\n    {\n        p = tocode;\n        tocode = (char *)malloc(strlen(p) + strlen(\"//IGNORE\") + 1);\n        if (tocode == NULL)\n        {\n            perror(\"fatal error\");\n            return 1;\n        }\n        strcpy(tocode, p);\n        strcat(tocode, \"//IGNORE\");\n    }\n\n    cd = iconv_open(tocode, fromcode);\n    if (cd == (iconv_t)(-1))\n    {\n        perror(\"iconv_open error\");\n        return 1;\n    }\n\n    while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0\n            || rest != 0)\n    {\n        inbytesleft += rest;\n        pin = inbuf;\n        pout = outbuf;\n        outbytesleft = sizeof(outbuf);\n        r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft);\n        fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);\n        if (r == (size_t)(-1) && errno != E2BIG && (errno != EINVAL || feof(in)))\n        {\n            perror(\"conversion error\");\n            return 1;\n        }\n        memmove(inbuf, pin, inbytesleft);\n        rest = inbytesleft;\n    }\n    pout = outbuf;\n    outbytesleft = sizeof(outbuf);\n    r = iconv(cd, NULL, NULL, &pout, &outbytesleft);\n    fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);\n    if (r == (size_t)(-1))\n    {\n        perror(\"conversion error\");\n        return 1;\n    }\n\n    iconv_close(cd);\n\n    return 0;\n}\n#endif\n\n"
  },
  {
    "path": "subprojects/win-iconv/win_iconv_test.c",
    "content": "\n#ifdef USE_ICONV_H\n#include <iconv.h>\n#include <windows.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n#else\n#include \"win_iconv.c\"\n#endif\n\n#include <stdio.h>\n\nconst char *\ntohex(const char *str, int size)\n{\n    static char buf[BUFSIZ];\n    char *pbuf = buf;\n    int i;\n    buf[0] = 0;\n    for (i = 0; i < size; ++i)\n        pbuf += sprintf(pbuf, \"%02X\", str[i] & 0xFF);\n    return buf;\n}\n\nconst char *\nerrstr(int errcode)\n{\n    static char buf[BUFSIZ];\n    switch (errcode)\n    {\n    case 0: return \"NOERROR\";\n    case EINVAL: return \"EINVAL\";\n    case EILSEQ: return \"EILSEQ\";\n    case E2BIG: return \"E2BIG\";\n    }\n    sprintf(buf, \"%d\\n\", errcode);\n    return buf;\n}\n\n#ifdef USE_LIBICONV_DLL\nint use_dll;\n\nint\nsetdll(const char *dllpath)\n{\n    char buf[BUFSIZ];\n    rec_iconv_t cd;\n\n    sprintf(buf, \"WINICONV_LIBICONV_DLL=%s\", dllpath);\n    putenv(buf);\n    if (libiconv_iconv_open(&cd, \"ascii\", \"ascii\"))\n    {\n        FreeLibrary(cd.hlibiconv);\n        use_dll = TRUE;\n        return TRUE;\n    }\n    use_dll = FALSE;\n    return FALSE;\n}\n#endif\n\n/*\n * We can test the codepage that is installed in the system.\n */\nint\ncheck_enc(const char *encname, int codepage)\n{\n    iconv_t cd;\n    int cp;\n    cd = iconv_open(\"utf-8\", encname);\n    if (cd == (iconv_t)(-1))\n    {\n        printf(\"%s(%d) IS NOT SUPPORTED: SKIP THE TEST\\n\", encname, codepage);\n        return FALSE;\n    }\n#ifndef USE_ICONV_H\n    cp = ((rec_iconv_t *)cd)->from.codepage;\n    if (cp != codepage)\n    {\n        printf(\"%s(%d) ALIAS IS MAPPED TO DIFFERENT CODEPAGE (%d)\\n\", encname, codepage, cp);\n        exit(1);\n    }\n#endif\n    iconv_close(cd);\n    return TRUE;\n}\n\nvoid\ntest(const char *from, const char *fromstr, int fromsize, const char *to, const char *tostr, int tosize, int errcode, int bufsize, int line)\n{\n    char outbuf[BUFSIZ];\n    const char *pin;\n    char *pout;\n    size_t inbytesleft;\n    size_t outbytesleft;\n    iconv_t cd;\n    size_t r;\n#ifdef USE_LIBICONV_DLL\n    char dllpath[_MAX_PATH];\n#endif\n\n    cd = iconv_open(to, from);\n    if (cd == (iconv_t)(-1))\n    {\n        printf(\"%s -> %s: NG: INVALID ENCODING NAME: line=%d\\n\", from, to, line);\n        exit(1);\n    }\n\n#ifdef USE_LIBICONV_DLL\n    if (((rec_iconv_t *)cd)->hlibiconv != NULL)\n        GetModuleFileNameA(((rec_iconv_t *)cd)->hlibiconv, dllpath, sizeof(dllpath));\n\n    if (use_dll && ((rec_iconv_t *)cd)->hlibiconv == NULL)\n    {\n        printf(\"%s: %s -> %s: NG: FAILED TO USE DLL: line=%d\\n\", dllpath, from, to, line);\n        exit(1);\n    }\n    else if (!use_dll && ((rec_iconv_t *)cd)->hlibiconv != NULL)\n    {\n        printf(\"%s: %s -> %s: NG: DLL IS LOADED UNEXPECTEDLY: line=%d\\n\", dllpath, from, to, line);\n        exit(1);\n    }\n#endif\n\n    errno = 0;\n\n    pin = (char *)fromstr;\n    pout = outbuf;\n    inbytesleft = fromsize;\n    outbytesleft = bufsize;\n    r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft);\n    if (r != (size_t)(-1))\n        r = iconv(cd, NULL, NULL, &pout, &outbytesleft);\n    *pout = 0;\n\n#ifdef USE_LIBICONV_DLL\n    if (use_dll)\n        printf(\"%s: \", dllpath);\n#endif\n    printf(\"%s(%s) -> \", from, tohex(fromstr, fromsize));\n    printf(\"%s(%s%s%s): \", to, tohex(tostr, tosize),\n            errcode == 0 ? \"\" : \":\",\n            errcode == 0 ? \"\" : errstr(errcode));\n    if (strcmp(outbuf, tostr) == 0 && errno == errcode)\n        printf(\"OK\\n\");\n    else\n    {\n        printf(\"RESULT(%s:%s): \", tohex(outbuf, sizeof(outbuf) - outbytesleft),\n                errstr(errno));\n        printf(\"NG: line=%d\\n\", line);\n        exit(1);\n    }\n}\n\n#define STATIC_STRLEN(arr) (sizeof(arr) - 1)\n\n#define success(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), 0, BUFSIZ, __LINE__)\n#define einval(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), EINVAL, BUFSIZ, __LINE__)\n#define eilseq(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), EILSEQ, BUFSIZ, __LINE__)\n#define e2big(from, fromstr, to, tostr, bufsize) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), E2BIG, bufsize, __LINE__)\n\nint\nmain(int argc, char **argv)\n{\n#ifdef USE_LIBICONV_DLL\n    /* test use of dll if $DEFAULT_LIBICONV_DLL was defined. */\n    if (setdll(\"\"))\n    {\n        success(\"ascii\", \"ABC\", \"ascii\", \"ABC\");\n        success(\"ascii\", \"ABC\", \"utf-16be\", \"\\x00\\x41\\x00\\x42\\x00\\x43\");\n    }\n    else\n    {\n        printf(\"\\nDLL TEST IS SKIPPED\\n\\n\");\n    }\n\n    setdll(\"none\");\n#endif\n\n    if (check_enc(\"ascii\", 20127))\n    {\n        success(\"ascii\", \"ABC\", \"ascii\", \"ABC\");\n        eilseq(\"ascii\", \"\\x80\", \"ascii\", \"\");\n        eilseq(\"ascii\", \"\\xFF\", \"ascii\", \"\");\n    }\n\n    /* unicode (CP1200 CP1201 CP12000 CP12001 CP65001) */\n    if (check_enc(\"utf-8\", 65001)\n            && check_enc(\"utf-16be\", 1201) && check_enc(\"utf-16le\", 1200)\n            && check_enc(\"utf-32be\", 12001) && check_enc(\"utf-32le\", 12000)\n            )\n    {\n        /* Test the BOM behavior\n         * 1. Remove the BOM when \"fromcode\" is utf-16 or utf-32.\n         * 2. Add the BOM when \"tocode\" is utf-16 or utf-32.  */\n        success(\"utf-16\", \"\\xFE\\xFF\\x01\\x02\", \"utf-16be\", \"\\x01\\x02\");\n        success(\"utf-16\", \"\\xFF\\xFE\\x02\\x01\", \"utf-16be\", \"\\x01\\x02\");\n        success(\"utf-32\", \"\\x00\\x00\\xFE\\xFF\\x00\\x00\\x01\\x02\", \"utf-32be\", \"\\x00\\x00\\x01\\x02\");\n        success(\"utf-32\", \"\\xFF\\xFE\\x00\\x00\\x02\\x01\\x00\\x00\", \"utf-32be\", \"\\x00\\x00\\x01\\x02\");\n        success(\"utf-16\", \"\\xFE\\xFF\\x00\\x01\", \"utf-8\", \"\\x01\");\n#ifndef GLIB_COMPILATION\n        success(\"utf-8\", \"\\x01\", \"utf-16\", \"\\xFE\\xFF\\x00\\x01\");\n        success(\"utf-8\", \"\\x01\", \"utf-32\", \"\\x00\\x00\\xFE\\xFF\\x00\\x00\\x00\\x01\");\n#else\n        success(\"utf-8\", \"\\x01\", \"utf-16\", \"\\xFF\\xFE\\x01\\x00\");\n        success(\"utf-8\", \"\\x01\", \"utf-32\", \"\\xFF\\xFE\\x00\\x00\\x01\\x00\\x00\\x00\");\n#endif\n\n        success(\"utf-16be\", \"\\xFE\\xFF\\x01\\x02\", \"utf-16be\", \"\\xFE\\xFF\\x01\\x02\");\n        success(\"utf-16le\", \"\\xFF\\xFE\\x02\\x01\", \"utf-16be\", \"\\xFE\\xFF\\x01\\x02\");\n        success(\"utf-32be\", \"\\x00\\x00\\xFE\\xFF\\x00\\x00\\x01\\x02\", \"utf-32be\", \"\\x00\\x00\\xFE\\xFF\\x00\\x00\\x01\\x02\");\n        success(\"utf-32le\", \"\\xFF\\xFE\\x00\\x00\\x02\\x01\\x00\\x00\", \"utf-32be\", \"\\x00\\x00\\xFE\\xFF\\x00\\x00\\x01\\x02\");\n        success(\"utf-16be\", \"\\xFE\\xFF\\x00\\x01\", \"utf-8\", \"\\xEF\\xBB\\xBF\\x01\");\n        success(\"utf-8\", \"\\xEF\\xBB\\xBF\\x01\", \"utf-8\", \"\\xEF\\xBB\\xBF\\x01\");\n\n        success(\"utf-16be\", \"\\x01\\x02\", \"utf-16le\", \"\\x02\\x01\");\n        success(\"utf-16le\", \"\\x02\\x01\", \"utf-16be\", \"\\x01\\x02\");\n        success(\"utf-16be\", \"\\xFE\\xFF\", \"utf-16le\", \"\\xFF\\xFE\");\n        success(\"utf-16le\", \"\\xFF\\xFE\", \"utf-16be\", \"\\xFE\\xFF\");\n        success(\"utf-32be\", \"\\x00\\x00\\x03\\x04\", \"utf-32le\", \"\\x04\\x03\\x00\\x00\");\n        success(\"utf-32le\", \"\\x04\\x03\\x00\\x00\", \"utf-32be\", \"\\x00\\x00\\x03\\x04\");\n        success(\"utf-32be\", \"\\x00\\x00\\xFF\\xFF\", \"utf-16be\", \"\\xFF\\xFF\");\n        success(\"utf-16be\", \"\\xFF\\xFF\", \"utf-32be\", \"\\x00\\x00\\xFF\\xFF\");\n        success(\"utf-32be\", \"\\x00\\x01\\x00\\x00\", \"utf-16be\", \"\\xD8\\x00\\xDC\\x00\");\n        success(\"utf-16be\", \"\\xD8\\x00\\xDC\\x00\", \"utf-32be\", \"\\x00\\x01\\x00\\x00\");\n        success(\"utf-32be\", \"\\x00\\x10\\xFF\\xFF\", \"utf-16be\", \"\\xDB\\xFF\\xDF\\xFF\");\n        success(\"utf-16be\", \"\\xDB\\xFF\\xDF\\xFF\", \"utf-32be\", \"\\x00\\x10\\xFF\\xFF\");\n        eilseq(\"utf-32be\", \"\\x00\\x11\\x00\\x00\", \"utf-16be\", \"\");\n        eilseq(\"utf-16be\", \"\\xDB\\xFF\\xE0\\x00\", \"utf-32be\", \"\");\n        success(\"utf-8\", \"\\xE3\\x81\\x82\", \"utf-16be\", \"\\x30\\x42\");\n        einval(\"utf-8\", \"\\xE3\", \"utf-16be\", \"\");\n    }\n\n    /* Japanese (CP932 CP20932 CP50220 CP50221 CP50222 CP51932) */\n    if (check_enc(\"cp932\", 932)\n            && check_enc(\"cp20932\", 20932) && check_enc(\"euc-jp\", 51932)\n            && check_enc(\"cp50220\", 50220) && check_enc(\"cp50221\", 50221)\n            && check_enc(\"cp50222\", 50222) && check_enc(\"iso-2022-jp\", 50221))\n    {\n        /* Test the compatibility for each other Japanese codepage.\n         * And validate the escape sequence handling for iso-2022-jp. */\n        success(\"utf-16be\", \"\\xFF\\x5E\", \"cp932\", \"\\x81\\x60\");\n        success(\"utf-16be\", \"\\x30\\x1C\", \"cp932\", \"\\x81\\x60\");\n        success(\"utf-16be\", \"\\xFF\\x5E\", \"cp932//nocompat\", \"\\x81\\x60\");\n        eilseq(\"utf-16be\", \"\\x30\\x1C\", \"cp932//nocompat\", \"\");\n        success(\"euc-jp\", \"\\xA4\\xA2\", \"utf-16be\", \"\\x30\\x42\");\n        einval(\"euc-jp\", \"\\xA4\\xA2\\xA4\", \"utf-16be\", \"\\x30\\x42\");\n        eilseq(\"euc-jp\", \"\\xA4\\xA2\\xFF\\xFF\", \"utf-16be\", \"\\x30\\x42\");\n        success(\"cp932\", \"\\x81\\x60\", \"iso-2022-jp\", \"\\x1B\\x24\\x42\\x21\\x41\\x1B\\x28\\x42\");\n        success(\"UTF-16BE\", \"\\xFF\\x5E\", \"iso-2022-jp\", \"\\x1B\\x24\\x42\\x21\\x41\\x1B\\x28\\x42\");\n        eilseq(\"UTF-16BE\", \"\\x30\\x1C\", \"iso-2022-jp//nocompat\", \"\");\n        success(\"UTF-16BE\", \"\\x30\\x42\\x30\\x44\", \"iso-2022-jp\", \"\\x1B\\x24\\x42\\x24\\x22\\x24\\x24\\x1B\\x28\\x42\");\n        success(\"iso-2022-jp\", \"\\x1B\\x24\\x42\\x21\\x41\\x1B\\x28\\x42\", \"UTF-16BE\", \"\\xFF\\x5E\");\n    }\n\n    /*\n     * test for //translit\n     * U+FF41 (FULLWIDTH LATIN SMALL LETTER A) <-> U+0062 (LATIN SMALL LETTER A)\n     */\n    eilseq(\"UTF-16BE\", \"\\xFF\\x41\", \"iso-8859-1\", \"\");\n    success(\"UTF-16BE\", \"\\xFF\\x41\", \"iso-8859-1//translit\", \"a\");\n\n    /*\n     * test for //translit\n     * Some character, not in \"to\" encoding -> DEFAULT CHARACTER (maybe \"?\")\n     */\n    eilseq(\"UTF-16BE\", \"\\x30\\x42\", \"ascii\", \"\");\n    success(\"UTF-16BE\", \"\\x30\\x42\", \"ascii//translit\", \"?\");\n\n    /*\n     * test for //ignore\n     */\n    eilseq(\"UTF-8\", \"\\xFF A \\xFF B\", \"ascii//ignore\", \" A  B\");\n    eilseq(\"UTF-8\", \"\\xEF\\xBC\\xA1 A \\xEF\\xBC\\xA2 B\", \"ascii//ignore\", \" A  B\");\n    eilseq(\"UTF-8\", \"\\xEF\\x01 A \\xEF\\x02 B\", \"ascii//ignore\", \"\\x01 A \\x02 B\");\n\n    /*\n     * TODO:\n     * Test for state after iconv() failed.\n     * Ensure iconv() error is safe and continuable.\n     */\n\n    return 0;\n}\n\n"
  },
  {
    "path": "subprojects/zlib.wrap",
    "content": "[wrap-file]\ndirectory = zlib-1.2.13\nsource_url = http://zlib.net/fossils/zlib-1.2.13.tar.gz\nsource_filename = zlib-1.2.13.tar.gz\nsource_hash = b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30\npatch_filename = zlib_1.2.13-1_patch.zip\npatch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.13-1/get_patch\npatch_hash = 73a0103df54133b10f8774f92e23da048bd22554523e2b833cdb72b2702c0628\nwrapdb_version = 1.2.13-1\n\n[provide]\nzlib = zlib_dep\n"
  },
  {
    "path": "test/gamedata/dat/CSVExporter.cpp",
    "content": "/*\n * CSVExporter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"CSVExporter.h\"\n#include \"dat/Unit.h\"\n\n// system\n#include <vector>\n#include <iostream>\n#include <string>\n\nusing namespace std;\nusing namespace dat;\n\nstatic const int units_units_ready_sound_end = 106;\n\nCSVExporter::CSVExporter(DataHub &datahub) :\n  mDatahub(datahub)\n{\n\n}\n\nCSVExporter::~CSVExporter()\n{\n\n}\n\nvoid CSVExporter::print()\n{\n  string csv_dat;\n  char buf[1024];\n  const string CSV_ENDLINE = \"\\n\";\n  const string CSV_SEPARATOR = \";\";\n\n  std::vector<uint32_t> *sfxdata_sound_file_vec;\n  std::vector<uint32_t> *mapdata_mission_dir_vec;\n\n  // units.dat\n  std::vector<uint8_t> *units_graphics_vec = mDatahub.units->flingy();\n  std::vector<uint8_t> *units_ground_weapon_vec = mDatahub.units->ground_weapon();\n  std::vector<units_dat_t::staredit_group_flags_type_t *> *se_group_flags_vec =\n      mDatahub.units->staredit_group_flags();\n  std::vector<uint16_t> *units_ready_sound_vec = mDatahub.units->ready_sound();\n  std::vector<uint16_t> *units_portrait_vec = mDatahub.units->portrait();\n  std::vector<uint8_t> *units_armor_upgrade_vec = mDatahub.units->armor_upgrade();\n\n  // orders.dat\n  std::vector<uint16_t> *orders_label_vec = mDatahub.orders->label();\n\n  // weapons.dat\n  std::vector<uint16_t> *weapon_label_vec = mDatahub.weapons->label();\n  std::vector<uint32_t> *weapon_graphics_vec = mDatahub.weapons->graphics();\n  std::vector<uint16_t> *weapon_error_message_vec = mDatahub.weapons->error_message();\n  std::vector<uint16_t> *flingy_sprites_vec = mDatahub.flingy->sprite();\n\n  // sprites.dat\n  std::vector<uint16_t> *sprites_images_vec = mDatahub.sprites->image();\n\n  std::vector<uint32_t> *images_grp_vec = mDatahub.images->grp();\n\n  sfxdata_sound_file_vec = mDatahub.sfxdata->sound_file();\n\n  std::vector<uint32_t> *portdata_portrait_idle_vec = mDatahub.portdata->video_idle();\n  std::vector<uint32_t> *portdata_portrait_talking_vec = mDatahub.portdata->video_talking();\n\n  // upgrades.dat\n  std::vector<uint16_t> *upgrades_label_vec = mDatahub.upgrades->label();\n\n  // techdata.dat\n  std::vector<uint16_t> *techdata_label_vec = mDatahub.techdata->label();\n\n  // mapdata.dat\n  mapdata_mission_dir_vec = mDatahub.mapdata->mission_dir();\n\n  // images.dat\n  std::vector<images_dat_t::draw_function_enum_t> *images_draw_function = mDatahub.images->draw_function();\n  std::vector<images_dat_t::remapping_enum_t> *images_remapping_function = mDatahub.images->remapping();\n\n  // units.dat\n  for (unsigned int i = 0; i < units_graphics_vec->size(); i++)\n  {\n    csv_dat += \"units.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint8_t graphic_id = units_graphics_vec->at(i);\n    sprintf(buf, \"graphics=%d\", graphic_id);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    units_dat_t::staredit_group_flags_type_t *se_group_flags =\n      se_group_flags_vec->at(i);\n    bool zerg = se_group_flags->zerg();\n    bool terran = se_group_flags->terran();\n    bool protoss = se_group_flags->protoss();\n\n    if (zerg)\n    {\n      csv_dat += \"race=zerg\";\n    }\n    else if (terran)\n    {\n      csv_dat += \"race=terran\";\n    }\n    else if (protoss)\n    {\n      csv_dat += \"race=protoss\";\n    }\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry = mDatahub.stat_txt_units_tbl_vec.at(i);\n    csv_dat += \"ref:name=\" + tblEntry.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t sprite_id = flingy_sprites_vec->at(graphic_id);\n    sprintf(buf, \"ref:sprite=%d\", sprite_id);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t weapon_id = units_ground_weapon_vec->at(i);\n    sprintf(buf, \"weapon=%d\", weapon_id);\n    csv_dat += buf;\n\n    if (i < units_units_ready_sound_end)\n    {\n      csv_dat += CSV_SEPARATOR;\n      uint16_t ready_sound_id = units_ready_sound_vec->at(i);\n      sprintf(buf, \"ready_sound=%d\", ready_sound_id);\n      csv_dat += buf;\n    }\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint32_t units_portrait_file = units_portrait_vec->at(i);\n    sprintf(buf, \"portrait=%d\", units_portrait_file);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    if (units_portrait_file != Unit::portrait_none)\n    {\n      uint32_t portrait_file = portdata_portrait_idle_vec->at(units_portrait_file);\n      sprintf(buf, \"ref:portrait_idle_file=%d\", portrait_file - 1);\n      csv_dat += buf;\n\n      csv_dat += CSV_SEPARATOR;\n\n      TblEntry tblEntry_portrait = mDatahub.portdata_tbl_vec.at(portrait_file - 1);\n      csv_dat += \"ref:portrait_idle=\" + tblEntry_portrait.name1;\n\n      csv_dat += CSV_SEPARATOR;\n    }\n\n    if (units_portrait_file != Unit::portrait_none)\n    {\n      uint32_t portrait_file = portdata_portrait_talking_vec->at(units_portrait_file);\n      sprintf(buf, \"ref:portrait_talking_file=%d\", portrait_file);\n      csv_dat += buf;\n\n      csv_dat += CSV_SEPARATOR;\n\n      TblEntry tblEntry_portrait = mDatahub.portdata_tbl_vec.at(portrait_file - 1);\n      csv_dat += \"ref:portrait_talking=\" + tblEntry_portrait.name1;\n\n      csv_dat += CSV_SEPARATOR;\n    }\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint8_t units_armor_upgrade = units_armor_upgrade_vec->at(i);\n    sprintf(buf, \"units_armor_upgrade=%d\", units_armor_upgrade);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // weapons.dat\n  for (unsigned int i = 0; i < weapon_label_vec->size(); i++)\n  {\n    csv_dat += \"weapons.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t label_id = weapon_label_vec->at(i);\n    sprintf(buf, \"label=%d\", label_id);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry_label = mDatahub.stat_txt_tbl_vec.at(label_id);\n    csv_dat += \"ref:name=\" + tblEntry_label.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint32_t graphic = weapon_graphics_vec->at(i);\n    sprintf(buf, \"graphics=%d\", graphic);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t error_id = weapon_error_message_vec->at(i);\n    sprintf(buf, \"error_id=%d\", error_id);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry_error = mDatahub.stat_txt_tbl_vec.at(error_id);\n    csv_dat += \" ref:error_text=\" + tblEntry_error.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // flingy.dat\n  for (unsigned int i = 0; i < flingy_sprites_vec->size(); i++)\n  {\n    csv_dat += \"flingy.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t flingy_id = flingy_sprites_vec->at(i);\n    sprintf(buf, \"sprite=%d\", flingy_id);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // sprites.dat\n  for (unsigned int i = 0; i < sprites_images_vec->size(); i++)\n  {\n    csv_dat += \"sprites.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t image_id = sprites_images_vec->at(i);\n    sprintf(buf, \"images_file=%d\", image_id);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // images.dat\n  for (unsigned int i = 0; i < images_grp_vec->size(); i++)\n  {\n    csv_dat += \"images.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t grp_id = images_grp_vec->at(i);\n    sprintf(buf, \"grp_file=%d\", grp_id);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry = mDatahub.images_tbl_vec.at(grp_id - 1); // spec says first index is -1\n    csv_dat += \"ref:name=\" + tblEntry.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"ref:draw_function=\" + to_string(images_draw_function->at(i));\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"ref:remapping_function=\" + to_string(images_remapping_function->at(i));\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // sfxdata.dat\n  for (unsigned int i = 0; i < sfxdata_sound_file_vec->size()-1; i++)\n  {\n    csv_dat += \"sfxdata.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint32_t sound_file = sfxdata_sound_file_vec->at(i);\n    sprintf(buf, \"sound_file=%d\", sound_file);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry = mDatahub.sfxdata_tbl_vec.at(sound_file);\n    csv_dat += \"ref:name=\" + tblEntry.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // portrait.dat\n  for (unsigned int i = 0; i < portdata_portrait_idle_vec->size(); i++)\n  {\n    csv_dat += \"portrait.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint32_t portrait_idle = portdata_portrait_idle_vec->at(i);\n    sprintf(buf, \"portrait_idle=%d\", portrait_idle);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry_idle = mDatahub.portdata_tbl_vec.at(portrait_idle - 1);\n    csv_dat += \"ref:idle=\" + tblEntry_idle.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint32_t portrait_talking = portdata_portrait_talking_vec->at(i);\n    sprintf(buf, \"portrait_talking=%d\", portrait_talking);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry_talking = mDatahub.portdata_tbl_vec.at(portrait_talking - 1);\n    csv_dat += \"ref:talking=\" + tblEntry_talking.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // upgrades.dat\n  for (unsigned int i = 0; i < upgrades_label_vec->size(); i++)\n  {\n    csv_dat += \"upgrades.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t upgrades_label = upgrades_label_vec->at(i);\n    sprintf(buf, \"upgrades_label=%d\", upgrades_label);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry = mDatahub.stat_txt_tbl_vec.at(upgrades_label);\n    csv_dat += \"ref:label=\" + tblEntry.name1;\n    sprintf(buf, \"ref:shortcut=%s\", tblEntry.shortcut.c_str());\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // orders.dat\n  for (unsigned int i = 0; i < orders_label_vec->size(); i++)\n  {\n    csv_dat += \"orders.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t orders_label = orders_label_vec->at(i);\n    sprintf(buf, \"orders_label=%d\", orders_label);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry = mDatahub.stat_txt_tbl_vec.at(orders_label);\n    csv_dat += \"ref:label=\" + tblEntry.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // techdata.dat\n  for (unsigned int i = 0; i < techdata_label_vec->size(); i++)\n  {\n    csv_dat += \"techdata.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint16_t techdata_label = techdata_label_vec->at(i);\n    sprintf(buf, \"techdata_label=%d\", techdata_label);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry = mDatahub.stat_txt_tbl_vec.at(techdata_label);\n    csv_dat += \"ref:label=\" + tblEntry.name1;\n    csv_dat += CSV_SEPARATOR;\n    sprintf(buf, \"ref:shortcut=%s\", tblEntry.shortcut.c_str());\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n    sprintf(buf, \"ref:shortcut_pos=%d\", tblEntry.shortcut_pos);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // mapdata.dat\n  for (unsigned int i = 0; i < mapdata_mission_dir_vec->size(); i++)\n  {\n    csv_dat += \"mapdata.dat\";\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += \"id=\" + to_string(i);\n\n    csv_dat += CSV_SEPARATOR;\n\n    uint32_t mapdata_label = mapdata_mission_dir_vec->at(i);\n    sprintf(buf, \"mapdata_label=%d\", mapdata_label);\n    csv_dat += buf;\n\n    csv_dat += CSV_SEPARATOR;\n\n    TblEntry tblEntry = mDatahub.mapdata_tbl_vec.at(mapdata_label - 1);\n    csv_dat += \"ref:dir=\" + tblEntry.name1;\n\n    csv_dat += CSV_SEPARATOR;\n\n    csv_dat += CSV_ENDLINE;\n  }\n\n  // stdout\n  cout << csv_dat;\n}\n"
  },
  {
    "path": "test/gamedata/dat/CSVExporter.h",
    "content": "/*\n * CSVExporter.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef CSVEXPORTER_H\n#define CSVEXPORTER_H\n\n#include \"dat/DataHub.h\"\n\n/**\n * Just some experiments for development to print the dat files into a csv compatible format\n */\nclass CSVExporter\n{\npublic:\n  CSVExporter(dat::DataHub &datahub);\n  virtual ~CSVExporter();\n\n  void print();\n\nprivate:\n  dat::DataHub &mDatahub;\n};\n\n#endif /* CSVEXPORTER_H */\n"
  },
  {
    "path": "test/gamedata/dat/DatTest.cpp",
    "content": "/*\n * DatTest.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"dat/DataHub.h\"\n#include \"CSVExporter.h\"\n#include \"Breeze.h\"\n#include \"FileUtil.h\"\n#include \"Logger.h\"\n#include \"optparser.h\"\n\n// system\n#include <iostream>\n\nusing namespace std;\n\n// some global variables\nstatic Logger logger(\"startool.DatTest\");\nstring dat_files_directory;\n\n\n/** option parser **/\nstruct Arg: public option::Arg\n{\n  static void printError(const char *msg1, const option::Option &opt, const char *msg2)\n  {\n    fprintf(stderr, \"%s\", msg1);\n    fwrite(opt.name, opt.namelen, 1, stderr);\n    fprintf(stderr, \"%s\", msg2);\n  }\n\n  static option::ArgStatus Unknown(const option::Option &option, bool msg)\n  {\n    if (msg)\n      printError(\"Unknown option '\", option, \"'\\n\");\n\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Required(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires an argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus NonEmpty(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0 && option.arg[0] != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a non-empty argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Numeric(const option::Option &option, bool msg)\n  {\n    char *endptr = 0;\n    if (option.arg != 0 && strtol(option.arg, &endptr, 10))\n    {\n    };\n    if (endptr != option.arg && *endptr == 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a numeric argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n};\n\nenum optionIndex\n{\n  UNKNOWN, HELP\n};\nconst option::Descriptor usage[] =\n{\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None, \"USAGE: DatTest <dat_files_directory>\\n\\n\"\n    \"Options:\"\n  },\n  { HELP, 0, \"h\", \"help\", option::Arg::None, \"  --help, -h  \\t\\tPrint usage and exit\" },  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None,\n    \"\\ndat_files_directory \\t\\tDirectory which contain the extracted stardat.mpq files with arr/*.dat inside...\\n\"\n\n  },\n  { 0, 0, 0, 0, 0, 0 }\n};\n\nint parseOptions(int argc, const char **argv)\n{\n  argc -= (argc > 0);\n  argv += (argc > 0); // skip program name argv[0] if present\n  option::Stats stats(usage, argc, argv);\n  std::unique_ptr<option::Option[]> options(new option::Option[stats.options_max]), buffer(new option::Option[stats.buffer_max]);\n  option::Parser parse(usage, argc, argv, options.get(), buffer.get());\n\n  if (parse.error())\n    exit(0);\n\n  if (options[HELP])\n  {\n    option::printUsage(std::cout, usage);\n    exit(0);\n  }\n\n  // parse options\n\n  for (option::Option *opt = options[UNKNOWN]; opt; opt = opt->next())\n    std::cout << \"Unknown option: \" << opt->name << \"\\n\";\n\n  for (int i = 0; i < parse.nonOptionsCount(); ++i)\n  {\n    switch (i)\n    {\n    case 0:\n      cerr << \"archive-directory #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      dat_files_directory = parse.nonOption(i);\n      break;\n    default:\n      break;\n    }\n  }\n\n  if (dat_files_directory.empty())\n  {\n    cerr << \"Error: 'dat_files_directory' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  return 0;\n}\n\nint main(int argc, const char **argv)\n{\n#ifdef HAVE_LOG4CXX\n  if (FileExists(\"logging.prop\"))\n  {\n    log4cxx::PropertyConfigurator::configure(\"logging.prop\");\n  }\n  else\n  {\n    logger.off();\n  }\n#endif // HAVE_LOG4CXX\n\n  parseOptions(argc, argv);\n\n\n  shared_ptr<Breeze> storm = make_shared<Breeze>(dat_files_directory);\n  dat::DataHub datahub(storm);\n\n  CSVExporter csvexporter(datahub);\n\n  csvexporter.print();\n\n  return 0;\n}\n\n"
  },
  {
    "path": "test/gamedata/dat/meson.build",
    "content": "TestDatafilesDat_sources = files(\n  'DatTest.cpp',\n  'CSVExporter.cpp'\n  )\n\nexecutable('DatTest',\n\t\t\tTestDatafilesDat_sources,\n\t\t\tinclude_directories : [config_incdir],\n\t\t\tdependencies : [cppunit_dep, log4cxx_dep, libstarformat_dep],\n\t\t\tinstall : false)\n"
  },
  {
    "path": "test/lua/CreateUnitLuaTest.cpp",
    "content": "/*\n * CreateUnitLuaTest.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"CreateUnitLuaTest.h\"\n#include \"luagen.h\"\n#include \"Storage.h\"\n#include \"FileUtil.h\"\n\n// system\n#include <iostream>\n#include <fstream>\n#include <memory>\n\nusing namespace std;\n\nCreateUnitLuaTest::CreateUnitLuaTest(json &unitsJson)\n{\n  Storage luagen;\n  luagen.setDataPath(\"data\"); // FIXME for now need to copy this manually into your data directory\n  luagen.setDataType(\"luagen/tests\");\n  CheckPath(luagen.getFullPath());\n\n  Storage lua_file_store(luagen(\"CreateUnitLuaTest.lua\"));\n\n  ofstream lua_file;\n  lua_file.open (lua_file_store.getFullPath());\n\n\n  lua_file << lg::line(\"function CreateUnitLuaTest_intern(unit, part)\");\n  lua_file << lg::line(\"  if not part then part = \\\"\\\" end\");\n  lua_file << lg::line(\"  if string.find(unit, part) then\");\n  lua_file << lg::line(\"    print('CreateUnit(\\\"' .. unit .. '\\\", 0, {0, 0})')\");\n  lua_file << lg::line(\"    CreateUnit(unit, 0, {0, 0})\");\n  lua_file << lg::line(\"  end\");\n  lua_file << lg::line(\"end\");\n\n  lua_file << lg::line(\"function CreateUnitLuaTest(part)\");\n\n  unsigned int end = 0;\n  for(auto &array : unitsJson)\n  {\n    string unit_name = array.at(\"name\");\n\n    // intermediate solution to jump over (currently/not yet) known not working units\n    vector<string> brokenUnits({\n\n    });\n\n    if(std::find(brokenUnits.begin(), brokenUnits.end(), unit_name) == brokenUnits.end())\n    {\n      //string create_unit = lg::CreateUnit(unit_name, 0, Pos(0,0));\n      string create_unit = lg::function(\"CreateUnitLuaTest_intern\", {lg::singleQuote(unit_name), \"part\"});\n\n      lua_file << create_unit << endl;\n    }\n\n    end++;\n  }\n\n  lua_file << lg::line(\"end\");\n\n  lua_file.close();\n\n}\n\nCreateUnitLuaTest::~CreateUnitLuaTest()\n{\n\n}\n\n"
  },
  {
    "path": "test/lua/CreateUnitLuaTest.h",
    "content": "/*\n * CreateUnitLuaTest.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef CREATEUNITLUATEST_H\n#define CREATEUNITLUATEST_H\n\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nclass CreateUnitLuaTest\n{\npublic:\n  CreateUnitLuaTest(json &unitsJson);\n  virtual ~CreateUnitLuaTest();\n\nprivate:\n\n};\n\n#endif /* CREATEUNITLUATEST_H */\n"
  },
  {
    "path": "test/lua/LuaTest.cpp",
    "content": "/*\n * LuaTest.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"CreateUnitLuaTest.h\"\n\n// system\n#include <fstream>\n#include <iostream>\n\nusing namespace std;\n\nint main(int argc, char **argv)\n{\n  // read in the json file\n  std::ifstream json_file(\"dataset/units.json\");\n  json units_json;\n  json_file >> units_json;\n\n  cout << \"Run CreateUnitLuaTest...\" << endl;\n  CreateUnitLuaTest createUnitLuaTest(units_json);\n\n\n  return 0;\n}\n\n"
  },
  {
    "path": "test/lua/meson.build",
    "content": "\nLuaTest_sources = files(\n  'CreateUnitLuaTest.cpp',\n  'LuaTest.cpp'\n  )\n\nexecutable('LuaTest',\n\t\t\tLuaTest_sources,\n\t\t\tinclude_directories : [config_incdir],\n\t\t\tdependencies : [log4cxx_dep, libstarformat_dep, nlohmann_json_dep],\n\t\t\tinstall : false)\n\n\n"
  },
  {
    "path": "test/module/BreezeTest.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n// System\n#include <zlib.h>\n\n// Project\n#include \"BreezeTest.h\"\n#include \"platform.h\"\n\nusing namespace std;\n\nCPPUNIT_TEST_SUITE_REGISTRATION(BreezeTest);\n\nvoid BreezeTest::setUp()\n{\n\n}\n\nvoid BreezeTest::tearDown()\n{\n\n}\n\nvoid BreezeTest::test1_txt_extractMemory()\n{\n  unsigned char *text_str = NULL;\n  size_t bufLen = 0;\n  string test_data_dir = \"test/module/data/\";\n  string content_result = \"breezetest\";\n  string arc_file = \"breezetest.txt\";\n\n  shared_ptr<Breeze> breeze = make_shared<Breeze>(test_data_dir);\n\n  bool result = breeze->extractMemory(arc_file, &text_str, &bufLen);\n\n  CPPUNIT_ASSERT(result == true);\n  CPPUNIT_ASSERT((int)bufLen == ((int)content_result.length() + 1)); // calculate +1 because the '\\0' counts extra in the raw char* data\n  CPPUNIT_ASSERT(string((char *) text_str) != string(content_result));\n\n  CPPUNIT_ASSERT(true);\n}\n\nvoid BreezeTest::test2_txt_extractFile()\n{\n  string test_data_dir = \"test/module/data/\";\n  string content_result = \"breezetest\";\n  string arc_file = \"breezetest.txt\";\n  string savename = \"breezetest_test.txt\";\n\n  shared_ptr<Breeze> breeze = make_shared<Breeze>(test_data_dir);\n\n  bool result = breeze->extractFile(arc_file, savename, false);\n\n  string line;\n  string filecontent;\n  ifstream readfile(savename);\n  if (readfile.is_open())\n  {\n    while (getline(readfile, line))\n    {\n      filecontent += line;\n    }\n    readfile.close();\n  }\n\n  CPPUNIT_ASSERT(result == true);\n  CPPUNIT_ASSERT(content_result == filecontent);\n\n  fs::remove(savename);\n}\n\nvoid BreezeTest::test3_txt_extractFileCompressed()\n{\n  string test_data_dir = \"test/module/data/\";\n  string content_result = \"breezetest\";\n  string arc_file = \"breezetest.txt\";\n  string savename = \"test.txt.gz\";\n  gzFile gzfile = nullptr;\n\n  shared_ptr<Breeze> breeze = make_shared<Breeze>(test_data_dir);\n\n  bool result = breeze->extractFile(arc_file, savename, true);\n\n  // read back & compare ->\n\n  gzfile = gzopen(savename.c_str(), \"r\");\n\n  int err;\n  int bytes_read;\n  int max_length = 1024;\n  unsigned char buffer[max_length];\n  bytes_read = gzread(gzfile, buffer, max_length - 1);\n  buffer[bytes_read] = '\\0';\n\n  if (bytes_read < max_length - 1)\n  {\n    if (!gzeof(gzfile))\n    {\n      gzerror(gzfile, & err);\n      CPPUNIT_ASSERT(err);\n    }\n  }\n\n  std::string dest(buffer, buffer + bytes_read-1);\n\n  CPPUNIT_ASSERT(result == true);\n  CPPUNIT_ASSERT(content_result == dest);\n\n  fs::remove(savename);\n}\n"
  },
  {
    "path": "test/module/BreezeTest.h",
    "content": "#ifndef BREEZE_TEST_H\n#define BREEZE_TEST_H\n\n#include <cppunit/TestFixture.h>\n#include <cppunit/extensions/HelperMacros.h>\n\n// system\n#include <string.h>\n#include <cstdio>\n\n// project\n#include \"Breeze.h\"\n\nclass BreezeTest : public CPPUNIT_NS::TestFixture\n{\n  CPPUNIT_TEST_SUITE(BreezeTest);\n\n  CPPUNIT_TEST(test1_txt_extractMemory);\n  CPPUNIT_TEST(test2_txt_extractFile);\n  CPPUNIT_TEST(test3_txt_extractFileCompressed);\n\n  CPPUNIT_TEST_SUITE_END();\n\npublic:\n  void setUp();\n  void tearDown();\n\nprotected:\n  /**\n   * Extract file from a file from that \"archive\" into memory and compare the content\n   */\n  void test1_txt_extractMemory();\n\n  /**\n   * Extract file from a file from that \"archive\" into a file, read it back and compare the content\n   */\n  void test2_txt_extractFile();\n\n  /**\n   * Extract file from a file from that \"archive\" into a file (gzip compressed), read it back and compare the content\n   */\n  void test3_txt_extractFileCompressed();\n\n\nprivate:\n\n};\n\n#endif // BREEZE_TEST_H\n"
  },
  {
    "path": "test/module/DataChunkTest.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n// System\n\n\n// Project\n#include \"DataChunkTest.h\"\n#include \"platform.h\"\n\nusing namespace std;\n\nCPPUNIT_TEST_SUITE_REGISTRATION(DataChunkTest);\n\nvoid DataChunkTest::setUp()\n{\n\n}\n\nvoid DataChunkTest::tearDown()\n{\n\n}\n\nvoid DataChunkTest::test1_addData()\n{\n  DataChunk dc;\n  int LENGTH = 5;\n\n  unsigned char rawdata[LENGTH];\n  rawdata[0] = 0x1;\n  rawdata[1] = 0x2;\n  rawdata[2] = 0x3;\n  rawdata[3] = 0x4;\n  rawdata[4] = 0x5;\n\n  dc.addData(rawdata, LENGTH);\n\n  CPPUNIT_ASSERT(dc.at(0) == 0x1);\n  CPPUNIT_ASSERT(dc.at(1) == 0x2);\n  CPPUNIT_ASSERT(dc.at(2) == 0x3);\n  CPPUNIT_ASSERT(dc.at(3) == 0x4);\n  CPPUNIT_ASSERT(dc.at(4) == 0x5);\n}\n\nvoid DataChunkTest::test2_createFromExistingHeap()\n{\n  int LENGTH = 5;\n\n  unsigned char *rawdata = new unsigned char(LENGTH);\n  rawdata[0] = 0x1;\n  rawdata[1] = 0x2;\n  rawdata[2] = 0x3;\n  rawdata[3] = 0x4;\n  rawdata[4] = 0x5;\n\n  DataChunk dc(&rawdata, LENGTH);\n\n  unsigned char *retdata = dc.getDataPointer();\n\n  CPPUNIT_ASSERT(retdata[0] == 0x1);\n  CPPUNIT_ASSERT(retdata[1] == 0x2);\n  CPPUNIT_ASSERT(retdata[2] == 0x3);\n  CPPUNIT_ASSERT(retdata[3] == 0x4);\n  CPPUNIT_ASSERT(retdata[4] == 0x5);\n}\n\nvoid DataChunkTest::test3_vectorReturn()\n{\n  DataChunk dc;\n  int LENGTH = 5;\n\n  unsigned char rawdata[LENGTH];\n  rawdata[0] = 0x1;\n  rawdata[1] = 0x2;\n  rawdata[2] = 0x3;\n  rawdata[3] = 0x4;\n  rawdata[4] = 0x5;\n\n  dc.addData(rawdata, LENGTH);\n\n  std::vector<unsigned char> datavec = dc.getUCharVector();\n\n  CPPUNIT_ASSERT(datavec.at(0) == 0x1);\n  CPPUNIT_ASSERT(datavec.at(1) == 0x2);\n  CPPUNIT_ASSERT(datavec.at(2) == 0x3);\n  CPPUNIT_ASSERT(datavec.at(3) == 0x4);\n  CPPUNIT_ASSERT(datavec.at(4) == 0x5);\n}\n\nvoid DataChunkTest::test4_write_compare()\n{\n  DataChunk dc;\n  int LENGTH = 5;\n  string savename = \"datachunk.txt\";\n\n  unsigned char rawdata[LENGTH];\n  rawdata[0] = 0x1;\n  rawdata[1] = 0x2;\n  rawdata[2] = 0x3;\n  rawdata[3] = 0x4;\n  rawdata[4] = 0x5;\n\n  dc.addData(rawdata, LENGTH);\n\n  dc.write(savename);\n\n  string line;\n  string filecontent;\n  ifstream readfile(savename);\n  if (readfile.is_open())\n  {\n    while (getline(readfile, line))\n    {\n      filecontent += line;\n    }\n    readfile.close();\n  }\n\n  CPPUNIT_ASSERT(filecontent.at(0) == 0x1);\n  CPPUNIT_ASSERT(filecontent.at(1) == 0x2);\n  CPPUNIT_ASSERT(filecontent.at(2) == 0x3);\n  CPPUNIT_ASSERT(filecontent.at(3) == 0x4);\n  CPPUNIT_ASSERT(filecontent.at(4) == 0x5);\n\n  fs::remove(savename);\n}\n\nvoid DataChunkTest::test5_read_write_compare()\n{\n  DataChunk dc;\n  int LENGTH = 5;\n  string savename = \"datachunk.txt\";\n\n  unsigned char rawdata[LENGTH];\n  rawdata[0] = 0x1;\n  rawdata[1] = 0x2;\n  rawdata[2] = 0x3;\n  rawdata[3] = 0x4;\n  rawdata[4] = 0x5;\n\n  dc.addData(rawdata, LENGTH);\n\n  dc.write(savename);\n\n  string line;\n  string filecontent;\n\n  DataChunk dc_read;\n  dc_read.read(savename);\n\n  CPPUNIT_ASSERT(dc_read.at(0) == rawdata[0]);\n  CPPUNIT_ASSERT(dc_read.at(1) == rawdata[1]);\n  CPPUNIT_ASSERT(dc_read.at(2) == rawdata[2]);\n  CPPUNIT_ASSERT(dc_read.at(3) == rawdata[3]);\n  CPPUNIT_ASSERT(dc_read.at(4) == rawdata[4]);\n\n  fs::remove(savename);\n}\n"
  },
  {
    "path": "test/module/DataChunkTest.h",
    "content": "#ifndef DATACHUNK_TEST_H\n#define DATACHUNK_TEST_H\n\n#include <cppunit/TestFixture.h>\n#include <cppunit/extensions/HelperMacros.h>\n\n// system\n#include <string.h>\n#include <cstdio>\n\n// project\n#include \"DataChunk.h\"\n\nclass DataChunkTest : public CPPUNIT_NS::TestFixture\n{\n  CPPUNIT_TEST_SUITE(DataChunkTest);\n\n  CPPUNIT_TEST(test1_addData);\n  CPPUNIT_TEST(test2_createFromExistingHeap);\n  CPPUNIT_TEST(test3_vectorReturn);\n  CPPUNIT_TEST(test4_write_compare);\n  CPPUNIT_TEST(test5_read_write_compare);\n\n\n  CPPUNIT_TEST_SUITE_END();\n\npublic:\n  void setUp();\n  void tearDown();\n\nprotected:\n  /**\n   * Create an empty DataCkunk add some data, read it back with the at() function and compare with input data\n   */\n  void test1_addData();\n\n  /**\n   * Create an DataCkunk from heap memory, add some data, read it back with the getDataPointer() function and compare content\n   */\n  void test2_createFromExistingHeap();\n\n  /**\n   * Create an empty DataCkunk add some data, read it back with the getUCharVector() function and compare input data with vector content\n   */\n  void test3_vectorReturn();\n\n  /**\n   * Create an empty DataCkunk add some data, write it into a file, read it back from file and compare with input data\n   */\n  void test4_write_compare();\n\n  /**\n   * Similar to test4_write_compare() but with the DataChunk::read() function\n   */\n  void test5_read_write_compare();\n\nprivate:\n\n};\n\n#endif // DATACHUNK_TEST_H\n"
  },
  {
    "path": "test/module/PcxTest.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n// System\n\n\n// Project\n#include \"PcxTest.h\"\n#include \"platform.h\"\n\nusing namespace std;\n\nCPPUNIT_TEST_SUITE_REGISTRATION(PcxTest);\n\nvoid PcxTest::setUp()\n{\n\n}\n\nvoid PcxTest::tearDown()\n{\n\n}\n\nvoid PcxTest::test1_SaveIndexedPalettePNG()\n{\n  string test_data_dir = \"test/module/data/\";\n  string load_pcx_name = \"PcxTest_red_zergb.pcx\";\n  string save_pal_name = \"red_zergb.pal\";\n  string save_png_name = \"red_zergb.png\";\n\n  shared_ptr<Breeze> breeze = make_shared<Breeze>(test_data_dir);\n\n  Pcx pcx1(breeze, load_pcx_name);\n  pcx1.savePNG(save_png_name);\n  std::shared_ptr<Palette> pal = pcx1.getPalette();\n  pal->createDataChunk()->write(save_pal_name);\n\n  CPPUNIT_ASSERT(compareFiles(save_pal_name, test_data_dir + \"/PcxTest_\" + save_pal_name));\n  CPPUNIT_ASSERT(compareFiles(save_png_name, test_data_dir + \"/PcxTest_\" + save_png_name));\n\n  fs::remove(save_pal_name.c_str());\n  fs::remove(save_png_name.c_str());\n}\n\nvoid PcxTest::test2_mapIndexPalette()\n{\n  string test_data_dir = \"test/module/data/\";\n  string load_pcx_name = \"PcxTest_ticon.pcx\";\n\n  shared_ptr<Breeze> breeze = make_shared<Breeze>(test_data_dir);\n\n  Pcx pcx1(breeze);\n\n  for(unsigned int index = 0; index < 6; index++)\n  {\n    string save_pal_name = string(\"ticon_\") + to_string(index) + \".pal\";\n    string save_png_name = string(\"ticon_\") + to_string(index) + \".png\";\n\n    pcx1.load(load_pcx_name);\n    pcx1.savePNG(save_png_name);\n    std::shared_ptr<Palette> pal = pcx1.mapIndexPalette(8, 1, index);\n    pal->createDataChunk()->write(save_pal_name);\n\n    CPPUNIT_ASSERT(compareFiles(save_pal_name, test_data_dir + \"/PcxTest_\" + save_pal_name));\n    CPPUNIT_ASSERT(compareFiles(save_png_name, test_data_dir + \"/PcxTest_\" + save_png_name));\n\n    fs::remove(save_pal_name.c_str());\n    fs::remove(save_png_name.c_str());\n  }\n}\n\n"
  },
  {
    "path": "test/module/PcxTest.h",
    "content": "#ifndef PCX_TEST_H\n#define PCX_TEST_H\n\n#include <cppunit/TestFixture.h>\n#include <cppunit/extensions/HelperMacros.h>\n\n// system\n#include <string.h>\n#include <cstdio>\n#include <cstring>\n\n// project\n#include \"Pcx.h\"\n#include \"Breeze.h\"\n#include \"TestHelpers.h\"\n\nclass PcxTest : public CPPUNIT_NS::TestFixture\n{\n  CPPUNIT_TEST_SUITE(PcxTest);\n\n  CPPUNIT_TEST(test1_SaveIndexedPalettePNG);\n  CPPUNIT_TEST(test2_mapIndexPalette);\n\n  CPPUNIT_TEST_SUITE_END();\n\npublic:\n  void setUp();\n  void tearDown();\n\nprotected:\n\n  /**\n   * Idea for test cases: (always compare with result test data for sure)\n   * -\n   *\n   *   - use case: Player coloring\n   *   - use case: Icon coloring\n   *   - use case: terrain coloring\n   *   - use case: fire coloring\n   *   - use case: ???\n   */\n\n\n  /**\n   * Load a PCX, save as PNG with Palette indexing, file compare PNG image and also the palette data\n   */\n  void test1_SaveIndexedPalettePNG();\n\n\n  /**\n   * - Load a PCX, use only the Palette information,  exchange palette position with image position -> mapIndexPalette()\n   */\n  void test2_mapIndexPalette();\n\n\n\nprivate:\n\n};\n\n#endif // PCX_TEST_H\n"
  },
  {
    "path": "test/module/StormTest.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n// System\n#include <zlib.h>\n\n// Project\n#include \"StormTest.h\"\n#include \"platform.h\"\n\nusing namespace std;\n\nCPPUNIT_TEST_SUITE_REGISTRATION(StormTest);\n\nvoid StormTest::setUp()\n{\n\n}\n\nvoid StormTest::tearDown()\n{\n\n}\n\nvoid StormTest::test1_mpq_txt_extractMemory()\n{\n  unsigned char *text_str = NULL;\n  size_t bufLen = 0;\n  string test_data_dir = \"test/module/data/\";\n  string content_result = \"stormtest\";\n  string mpq_arc_file = \"test.txt\";\n\n  shared_ptr<Storm> storm = make_shared<Storm>(test_data_dir + \"StormTest_test1_mpq_txt.mpq\");\n\n  bool result = storm->extractMemory(mpq_arc_file, &text_str, &bufLen);\n\n  CPPUNIT_ASSERT(result == true);\n  CPPUNIT_ASSERT((int)bufLen == ((int)content_result.length() + 1)); // calculate +1 because the '\\0' counts extra in the raw char* data\n  CPPUNIT_ASSERT(string((char *) text_str) != string(content_result));\n\n  free(text_str);\n}\n\nvoid StormTest::test2_mpq_txt_extractFile()\n{\n  string test_data_dir = \"test/module/data/\";\n  string content_result = \"stormtest\";\n  string mpq_arc_file = \"test.txt\";\n  string savename = \"test.txt\";\n\n  shared_ptr<Storm> storm = make_shared<Storm>(test_data_dir + \"StormTest_test1_mpq_txt.mpq\");\n\n  bool result = storm->extractFile(mpq_arc_file, savename, false);\n\n  string line;\n  string filecontent;\n  ifstream readfile(savename);\n  if (readfile.is_open())\n  {\n    while (getline(readfile, line))\n    {\n      filecontent += line;\n    }\n    readfile.close();\n  }\n\n  CPPUNIT_ASSERT(result == true);\n  CPPUNIT_ASSERT(content_result == filecontent);\n\n  fs::remove(savename);\n}\n\nvoid StormTest::test3_mpq_txt_extractFileCompressed()\n{\n  string test_data_dir = \"test/module/data/\";\n  string content_result = \"stormtest\";\n  string mpq_arc_file = \"test.txt\";\n  string savename = \"test.txt.gz\";\n  gzFile gzfile = nullptr;\n\n  shared_ptr<Storm> storm = make_shared<Storm>(test_data_dir + \"StormTest_test1_mpq_txt.mpq\");\n\n  bool result = storm->extractFile(mpq_arc_file, savename, true);\n\n  // read back & compare ->\n\n  gzfile = gzopen(savename.c_str(), \"r\");\n\n  int err;\n  int bytes_read;\n  int max_length = 1024;\n  unsigned char buffer[max_length];\n  bytes_read = gzread(gzfile, buffer, max_length - 1);\n  buffer[bytes_read] = '\\0';\n\n  if (bytes_read < max_length - 1)\n  {\n    if (!gzeof(gzfile))\n    {\n      gzerror(gzfile, & err);\n      CPPUNIT_ASSERT(err);\n    }\n  }\n\n  std::string dest(buffer, buffer + bytes_read-1);\n\n  CPPUNIT_ASSERT(result == true);\n  CPPUNIT_ASSERT(content_result == dest);\n\n  fs::remove(savename);\n}\n"
  },
  {
    "path": "test/module/StormTest.h",
    "content": "#ifndef STORM_TEST_H\n#define STORM_TEST_H\n\n#include <cppunit/TestFixture.h>\n#include <cppunit/extensions/HelperMacros.h>\n\n// system\n#include <string.h>\n#include <cstdio>\n\n\n// project\n#include \"Storm.h\"\n#include \"StringUtil.h\"\n\nclass StormTest : public CPPUNIT_NS::TestFixture\n{\n  CPPUNIT_TEST_SUITE(StormTest);\n\n  CPPUNIT_TEST(test1_mpq_txt_extractMemory);\n  CPPUNIT_TEST(test2_mpq_txt_extractFile);\n  CPPUNIT_TEST(test3_mpq_txt_extractFileCompressed);\n\n  CPPUNIT_TEST_SUITE_END();\n\npublic:\n  void setUp();\n  void tearDown();\n\nprotected:\n  /**\n   * Test the extractMemory() function by reading a string from a example .mpq file and compare the content\n   */\n  void test1_mpq_txt_extractMemory();\n\n  /**\n   * Test extractFile() function by expanding the file on drive and then read in again and compare the content\n   */\n  void test2_mpq_txt_extractFile();\n\n  /**\n   * Test extractFile() function by expanding the file (gzip compressed) on drive and then read in again and compare the content\n   */\n  void test3_mpq_txt_extractFileCompressed();\n\nprivate:\n\n};\n\n#endif // STORM_TEST_H\n"
  },
  {
    "path": "test/module/TestHelpers.cpp",
    "content": "/*\n * TestHelpers.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"TestHelpers.h\"\n#include \"FileUtil.h\"\n\n// system\n#include <cstdio>\n#include <fstream>\n\nusing namespace std;\n\nconst std::string getStringFromFile(const std::string &file)\n{\n  string line;\n  string filecontent;\n  ifstream readfile(file);\n\n  if (readfile.is_open())\n  {\n    while (getline(readfile, line))\n    {\n      filecontent += line;\n    }\n    readfile.close();\n  }\n\n  return filecontent;\n}\n\nbool compareFiles(const std::string &file1, const std::string &file2)\n{\n  if(!FileExists(file1) || !FileExists(file2))\n  {\n    return false;\n  }\n\n  string file1_content = getStringFromFile(file1);\n  string file2_content = getStringFromFile(file2);\n\n  if(file1_content.length() != file2_content.length())\n  {\n    return false;\n  }\n  else\n  {\n      const int ret = std::memcmp(file1_content.c_str(), file2_content.c_str(), file1_content.length());\n      if(ret != 0)\n      {\n        return false;\n      }\n  }\n\n  return true;\n}\n"
  },
  {
    "path": "test/module/TestHelpers.h",
    "content": "/*\n * TestHelpers.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef TESTHELPERS_H\n#define TESTHELPERS_H\n\n#include <string>\n#include <cstring>\n\nconst std::string getStringFromFile(const std::string &file);\n\nbool compareFiles(const std::string &file1, const std::string &file2);\n\n#endif /* TESTHELPERS_H */\n"
  },
  {
    "path": "test/module/TestMain.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <cppunit/CompilerOutputter.h>\n#include <cppunit/extensions/TestFactoryRegistry.h>\n#include <cppunit/TestResult.h>\n#include <cppunit/TestResultCollector.h>\n#include <cppunit/TestRunner.h>\n#include <cppunit/BriefTestProgressListener.h>\n#include <cppunit/TextTestRunner.h>\n\n/* log4cxx */\n#ifdef HAVE_LOG4CXX\n#include \"log4cxx/logger.h\"\n#include \"log4cxx/basicconfigurator.h\"\n#include \"log4cxx/propertyconfigurator.h\"\n#include \"log4cxx/helpers/exception.h\"\n#endif // HAVE_LOG4CXX\n\n#ifdef HAVE_LOG4CXX\nusing namespace log4cxx;\nusing namespace log4cxx::helpers;\n#endif // HAVE_LOG4CXX\n\nusing namespace std;\n\nint main (int argc, char **argv)\n{\n  #ifdef HAVE_LOG4CXX\n    PropertyConfigurator::configure (\"logging.prop\");\n  #endif // HAVE_LOG4CXX\n\n  // informs test-listener about testresults\n  CPPUNIT_NS::TestResult testresult;\n  \n  // register listener for collecting the test-results\n  CPPUNIT_NS::TestResultCollector collectedresults;\n  testresult.addListener (&collectedresults);\n\n  CPPUNIT_NS::BriefTestProgressListener progress;\n  testresult.addListener (&progress);\n\n  // insert test-suite at test-runner by registry\n  CPPUNIT_NS::TextTestRunner testrunner;\n  testrunner.setOutputter (CppUnit::CompilerOutputter::defaultOutputter(\n                           &testrunner.result(), std::cerr));\n\n  testrunner.addTest (CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest ());\n  testrunner.run (testresult);\n\n  // output results in compiler-format\n  CPPUNIT_NS::CompilerOutputter compileroutputter (&collectedresults, std::cerr);\n\n  compileroutputter.write ();\n    \n  // return 0 if tests were successful\n  return collectedresults.wasSuccessful () ? 0 : 1;\n}\n"
  },
  {
    "path": "test/module/TiledPaletteImageTest.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n// Project\n#include \"TiledPaletteImageTest.h\"\n#include \"tileset/TiledPaletteImage.h\"\n#include \"PngExporter.h\"\n#include \"TestHelpers.h\"\n#include \"platform.h\"\n\n\n// System\n\nusing namespace std;\n\nCPPUNIT_TEST_SUITE_REGISTRATION(TiledPaletteImageTest);\n\nvoid TiledPaletteImageTest::setUp()\n{\n\n}\n\nvoid TiledPaletteImageTest::tearDown()\n{\n\n}\n\nvoid TiledPaletteImageTest::test1_tileStrategyCompare()\n{\n  string test_data_dir = \"test/module/data/\";\n  string reference_small_name_png = \"TiledPaletteImage_small.png\";\n\n  string save_num_name_png = \"test1_tileStrategyCompare_num.png\";\n  string save_pos_name_png = \"test1_tileStrategyCompare_pos.png\";\n\n  Palette pal(generateTestPalette());\n\n  PaletteImage red_image(Size(8, 8));\n  red_image.fill(ColorRed);\n\n  PaletteImage green_image(Size(8, 8));\n  green_image.fill(ColorGreen);\n\n  PaletteImage blue_image(Size(8, 8));\n  blue_image.fill(ColorBlue);\n\n  PaletteImage yellow_image(Size(8, 8));\n  yellow_image.fill(ColorYellow);\n\n  tileset::TiledPaletteImage tiled_image_num(Size(2, 2), Size(8, 8));\n  tileset::TiledPaletteImage tiled_image_pos(Size(2, 2), Size(8, 8));\n\n  // fill the tiled image with the little tiles by incrementing number\n  tiled_image_num.copyTile(red_image, 0);\n  tiled_image_num.copyTile(green_image, 1);\n  tiled_image_num.copyTile(blue_image, 2);\n  tiled_image_num.copyTile(yellow_image, 3);\n\n  // fill the tiled image with the little tiles by specifying the tile position\n  tiled_image_pos.copyTile(red_image, Pos(0, 0));\n  tiled_image_pos.copyTile(green_image, Pos(1, 0));\n  tiled_image_pos.copyTile(blue_image, Pos(0, 1));\n  tiled_image_pos.copyTile(yellow_image, Pos(1, 1));\n\n  // export the PNGs for visual test feedback\n  PngExporter::saveRGB(save_num_name_png, tiled_image_num, pal, 255);\n  PngExporter::saveRGB(save_pos_name_png, tiled_image_pos, pal, 255);\n\n  // this test just checks if adding the tiles by #num or Pos gives us the same result\n  CPPUNIT_ASSERT(tiled_image_num == tiled_image_pos);\n  CPPUNIT_ASSERT(compareFiles(save_num_name_png, test_data_dir + \"/\" + reference_small_name_png));\n  CPPUNIT_ASSERT(compareFiles(save_pos_name_png, test_data_dir + \"/\" + reference_small_name_png));\n\n  // TODO: save both vectors into file and compare them with a working result!\n  // maybe as other additional test??\n\n  fs::remove(save_num_name_png);\n  fs::remove(save_pos_name_png);\n}\n\nvoid TiledPaletteImageTest::test2_tileHorizontalFlipping()\n{\n  string test_data_dir = \"test/module/data/\";\n  string reference_big_flipped_name_png = \"TiledPaletteImageTest2_big_flipped.png\";\n\n  string save_name_flipped_png = \"test2_tileHorizontalFlipping.png\";\n\n  Palette pal(generateTestPalette());\n\n  PaletteImage red_image(Size(8, 8));\n  red_image.fill(ColorRed);\n\n  PaletteImage green_image(Size(8, 8));\n  green_image.fill(ColorGreen);\n\n  PaletteImage blue_image(Size(8, 8));\n  blue_image.fill(ColorBlue);\n\n  PaletteImage yellow_image(Size(8, 8));\n  yellow_image.fill(ColorYellow);\n\n  tileset::TiledPaletteImage tiled_image_num(Size(2, 2), Size(8, 8));\n\n  // fill the tiled image with the little tiles by incrementing number\n  tiled_image_num.copyTile(red_image, 0);\n  tiled_image_num.copyTile(green_image, 1);\n  tiled_image_num.copyTile(blue_image, 2);\n  tiled_image_num.copyTile(yellow_image, 3);\n\n  tileset::TiledPaletteImage tiled_image_big(Size(2, 2), Size(16, 16));\n\n  tiled_image_big.copyTile(tiled_image_num, 0, true); // flip horizontal\n  tiled_image_big.copyTile(tiled_image_num, 1);\n  tiled_image_big.copyTile(tiled_image_num, 2, true); // flip horizontal\n  tiled_image_big.copyTile(tiled_image_num, 3);\n\n  PngExporter::saveRGB(save_name_flipped_png, tiled_image_big, pal, 255);\n\n  CPPUNIT_ASSERT(compareFiles(save_name_flipped_png, test_data_dir + \"/\" + reference_big_flipped_name_png));\n\n  fs::remove(save_name_flipped_png);\n}\n\nPalette TiledPaletteImageTest::generateTestPalette()\n{\n  Palette pal;\n\n  // define the colors\n  Color black(0, 0, 0);\n  Color red(255, 0, 0);\n  Color green(0, 255, 0);\n  Color blue(0, 0, 255);\n  Color yellow(255, 255, 0);\n\n  // add the colors in the palette\n  pal.at(0) = black;\n  pal.at(1) = red;\n  pal.at(2) = green;\n  pal.at(3) = blue;\n  pal.at(4) = yellow;\n\n  return pal;\n}\n"
  },
  {
    "path": "test/module/TiledPaletteImageTest.h",
    "content": "#ifndef TILEDPALETTEIMAGE_TEST_H\n#define TILEDPALETTEIMAGE_TEST_H\n\n#include <cppunit/TestFixture.h>\n#include <cppunit/extensions/HelperMacros.h>\n\n// system\n#include <string.h>\n#include <cstdio>\n\n// project\n#include \"Palette.h\"\n\nclass TiledPaletteImageTest : public CPPUNIT_NS::TestFixture\n{\n  CPPUNIT_TEST_SUITE(TiledPaletteImageTest);\n\n  CPPUNIT_TEST(test1_tileStrategyCompare);\n  CPPUNIT_TEST(test2_tileHorizontalFlipping);\n\n  CPPUNIT_TEST_SUITE_END();\n\npublic:\n  void setUp();\n  void tearDown();\n\nprotected:\n  /**\n   * Generate 8x8 image in red, green, blue, yellow and order them in a 2x2 tile.\n   * Compare both results by comparing both images vector data. This test doesn't\n   * check if the image itself was created as specified or if both are wrong.\n   */\n  void test1_tileStrategyCompare();\n\n  void test2_tileHorizontalFlipping();\n\n\nprivate:\n  Palette generateTestPalette();\n\n  const unsigned char ColorBlack  = 0;\n  const unsigned char ColorRed    = 1;\n  const unsigned char ColorGreen  = 2;\n  const unsigned char ColorBlue   = 3;\n  const unsigned char ColorYellow = 4;\n\n};\n\n#endif // TILEDPALETTEIMAGE_TEST_H\n"
  },
  {
    "path": "test/module/data/breezetest.txt",
    "content": "breezetest\n"
  },
  {
    "path": "test/module/luagenTest.cpp",
    "content": "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n// system\n#include <string>\n\n// project\n#include \"luagenTest.h\"\n#include \"luagen.h\"\n\nusing namespace std;\n\nCPPUNIT_TEST_SUITE_REGISTRATION(luagenTest);\n\nvoid luagenTest::setUp()\n{\n\n}\n\nvoid luagenTest::tearDown()\n{\n\n}\n\n\nvoid luagenTest::test_function()\n{\n  string string_function = lg::function(\"name\", \"one, two, three\");\n  string initializer_list_function = lg::function(\"name\", {\"one\", \"two\", \"three\"});\n\n  string lua_result_spec(\"name(one, two, three)\");\n\n  CPPUNIT_ASSERT(initializer_list_function == lua_result_spec);\n  CPPUNIT_ASSERT(initializer_list_function == string_function);\n}\n\nvoid luagenTest::test_table()\n{\n  string string_table = lg::table(\"one, two, three\");\n  string initializer_list_table = lg::table({\"one\", \"two\", \"three\"});\n\n  string lua_result_spec(\"{one, two, three}\");\n\n  CPPUNIT_ASSERT(string_table == lua_result_spec);\n  CPPUNIT_ASSERT(initializer_list_table == lua_result_spec);\n}\n\nvoid luagenTest::test_assign()\n{\n  string result = lg::assign(\"a\", \"b\");\n\n  CPPUNIT_ASSERT(result == \"a = b\");\n}\n\nvoid luagenTest::test_quote()\n{\n  string result = lg::quote(\"example\");\n\n  CPPUNIT_ASSERT(result == \"\\\"example\\\"\");\n}\n\nvoid luagenTest::test_singleQuote()\n{\n  string result = lg::singleQuote(\"example\");\n\n  CPPUNIT_ASSERT(result == \"'example'\");\n}\n\n\nvoid luagenTest::test_params()\n{\n  vector<string> vector_params_input;\n  vector_params_input.push_back(\"one\");\n  vector_params_input.push_back(\"two\");\n  vector_params_input.push_back(\"three\");\n\n  string intitializer_list_params = lg::params({\"one\", \"two\", \"three\"});\n  string vector_params = lg::params(vector_params_input);\n\n  string lua_result_spec(\"one, two, three\");\n\n  CPPUNIT_ASSERT(intitializer_list_params == lua_result_spec);\n  CPPUNIT_ASSERT(vector_params == lua_result_spec);\n}\n\nvoid luagenTest::test_paramsQuote()\n{\n  vector<string> vector_params_input;\n  vector_params_input.push_back(\"one\");\n  vector_params_input.push_back(\"two\");\n  vector_params_input.push_back(\"three\");\n\n  string intitializer_list_params = lg::paramsQuote({\"one\", \"two\", \"three\"});\n  string vector_params = lg::paramsQuote(vector_params_input);\n\n  string lua_result_spec(\"\\\"one\\\", \\\"two\\\", \\\"three\\\"\");\n\n  CPPUNIT_ASSERT(intitializer_list_params == lua_result_spec);\n  CPPUNIT_ASSERT(vector_params == lua_result_spec);\n}\n\nvoid luagenTest::test_line()\n{\n  string result = lg::line(\"example\");\n\n  CPPUNIT_ASSERT(result == \"example\\n\");\n}\n"
  },
  {
    "path": "test/module/luagenTest.h",
    "content": "#ifndef LUAGEN_TEST_H\n#define LUAGEN_TEST_H\n\n#include <cppunit/TestFixture.h>\n#include <cppunit/extensions/HelperMacros.h>\n\n// system\n#include <string.h>\n#include <cstdio>\n\n// project\n\nclass luagenTest : public CPPUNIT_NS::TestFixture\n{\n  CPPUNIT_TEST_SUITE(luagenTest);\n\n  CPPUNIT_TEST(test_function);\n  CPPUNIT_TEST(test_table);\n  CPPUNIT_TEST(test_assign);\n  CPPUNIT_TEST(test_quote);\n  CPPUNIT_TEST(test_singleQuote);\n  CPPUNIT_TEST(test_params);\n  CPPUNIT_TEST(test_paramsQuote);\n  CPPUNIT_TEST(test_line);\n\n  CPPUNIT_TEST_SUITE_END();\n\npublic:\n  void setUp();\n  void tearDown();\n\nprotected:\n  /**\n   * Test the LUA function generators: name()\n   */\n  void test_function();\n\n  /**\n   * Test the LUA table generators: {name}\n   */\n  void test_table();\n\n  /**\n   * Test the LUA assign generators: a = b\n   */\n  void test_assign();\n\n  /**\n   * Test the LUA quoting generators to surround a string with \"\"\n   */\n  void test_quote();\n\n  /**\n   * Test the LUA quoting generators to surround a string with ''\n   */\n  void test_singleQuote();\n\n  /**\n   * Test the LUA parameters (in functions, tables,... generators: a, b, c\n   */\n  void test_params();\n\n  /**\n   * Test the LUA parameters (in functions, tables,... generators: \"a\", \"b\", \"c\"\n   */\n  void test_paramsQuote();\n\n  /**\n   * The a simple newline generator: line\\n\n   */\n  void test_line();\n\nprivate:\n\n};\n\n#endif // LUAGEN_TEST_H\n"
  },
  {
    "path": "test/module/meson.build",
    "content": "\nStartoolUnitTest_sources = files(\n  'TestHelpers.cpp',\n  'TestMain.cpp',\n  'StormTest.cpp',\n  'DataChunkTest.cpp',\n  'BreezeTest.cpp',\n  'PcxTest.cpp',\n  'TiledPaletteImageTest.cpp',\n  'luagenTest.cpp',\n  )\n\nexecutable('StartoolUnitTest',\n\t\t\tStartoolUnitTest_sources,\n\t\t\tinclude_directories : [config_incdir],\n\t\t\tdependencies : [cppunit_dep, zlib_dep, log4cxx_dep, libstarformat_dep],\n\t\t\tinstall : false)\n"
  },
  {
    "path": "tools/binreader.c",
    "content": "#include <stdio.h>\n#include <string.h>\n\ntypedef struct {\n\tunsigned short NextOffset;\n\tunsigned short Unknown2;\n\tunsigned short X1;\n\tunsigned short Y1;\n\tunsigned short X2;\n\tunsigned short Y2;\n\tunsigned short Width;\n\tunsigned short Height;\n\tunsigned short Unknown9;\n\tunsigned short Unknown10;\n\tunsigned short TextOffset;\n\tunsigned short Unknown12;\n\tunsigned int Flags; // 28\n\tunsigned short Unknown15;\n\tunsigned short Unknown16;\n\tshort UnknownIndex;\n\tunsigned short Type;\n\tunsigned short Unknown19;\n\tunsigned short Unknown20;\n\tunsigned short Unknown21;\n\tunsigned short Unknown22;\n\tunsigned short Unknown23;\n\tunsigned short Unknown24;\n\tunsigned short Unknown25;\n\tunsigned short Unknown26;\n\tunsigned short Unknown27;\n\tunsigned short DialogWidth_MouseX1;\n\tunsigned short DialogWidth_MouseY1;\n\tunsigned short MouseX2;\n\tunsigned short MouseY2;\n\tunsigned short Unknown32;\n\tunsigned short Unknown33; // 66\n\tunsigned short ChildOffset;\n\tunsigned short Unknown35;\n\tunsigned short TextX1;\n\tunsigned short TextY1;\n\tunsigned short TextX2;\n\tunsigned short TextY2;\n\tunsigned short Unknown40;\n\tunsigned short Unknown41;\n\tunsigned short Unknown42;\n\tunsigned short Unknown43; // 86\n} Level12;\n\ntypedef struct {\n\tunsigned short NextOffset;\n\tunsigned short Unknown2;\n\tunsigned short Flags;\n\tunsigned short Unknown4;\n\tunsigned short Unknown5;\n\tunsigned short TextOffset;\n\tunsigned short Unknown7;\n\tunsigned short Unknown8;\n\tunsigned short Unknown9;\n\tunsigned short X;\n\tunsigned short Y;\n\tunsigned short Unknown12;\n\tunsigned short Unknown13;\n\tunsigned short Unknown14;\n\tunsigned short Unknown15;\n} Level3;\n\n\nchar buf[64 * 1024];\n\n\nvoid DoLevel3(Level3 *l3)\n{\n\tprintf(\"-------------- Level 3 ------------------\\n\");\n}\n\nvoid print(char *s)\n{\n\twhile (*s) {\n\t\tif (*s >= 0x20) {\n\t\t\tfputc(*s, stdout);\n\t\t} else {\n\t\t\tprintf(\"<%d>\", *s);\n\t\t}\n\t\t++s;\n\t}\n\tfputc('\\n', stdout);\n}\n\nvoid DoLevel12(Level12 *l, int level)\n{\n\tchar tmp[4096];\n\n\tprintf(\"---------------Level %d ------------------\\n\", level);\n\tprintf(\"X1,Y1 = %d,%d\\n\", l->X1, l->Y1);\n\tprintf(\"X2,Y2 = %d,%d\\n\", l->X2, l->Y2);\n\tprintf(\"Width,Height = %d,%d\\n\", l->Width, l->Height);\n//\tprintf(\"l->ChildOffset: %X\\n\", l->ChildOffset);\n//\tprintf(\"l->NextOffset: %X\\n\", l->NextOffset);\n\tif (l->Flags) {\n\t\tprintf(\"Flags = %X\\n\", l->Flags);\n\t}\n\tif (l->TextOffset) {\n\t\tsprintf(tmp, \"Text: %s\", buf + l->TextOffset);\n\t\tprint(tmp);\n\t}\n\n\tif (l->ChildOffset) {\n\t\tif (level == 1) {\n\t\t\tDoLevel12((Level12*)(buf + l->ChildOffset), level + 1);\n\t\t} else {\n\t\t\tDoLevel3((Level3*)(buf + l->ChildOffset));\n\t\t}\n\t}\n\tif (l->NextOffset) {\n\t\tDoLevel12((Level12*)(buf + l->NextOffset), level);\n\t}\n}\n\n\nint main(int argc, char *argv[])\n{\n\tFILE *fd = fopen(argv[1], \"rb\");\n\n\tchar *ptr = buf;\n\n\n\tfread(buf, 1, sizeof(buf), fd);\n\tfclose(fd);\n\n\tDoLevel12((Level12 *)buf, 1);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "tools/grptool/grptool.cpp",
    "content": "/*\n * grptool.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"optparser.h\"\n#include \"libgrp/libgrp.hpp\"\n#include \"Logger.h\"\n#include \"FileUtil.h\"\n#include \"Breeze.h\"\n#include \"NoValidPaletteException.h\"\n#include \"Palette2D.h\"\n\n// system\n#include <iostream>\n#include <memory>\n\nusing namespace std;\n\n/**\n * Description\n */\n\nstatic Logger logger(\"grptool\");\n\n// some global variables\nstring palette_file;\nstring grp_file;\nbool duplicates = true;\nbool single_stiched = true;\nint image_per_row = 10;\nbool rgba = false;\n\n\n/** option parser **/\nstruct Arg: public option::Arg\n{\n  static void printError(const char *msg1, const option::Option &opt, const char *msg2)\n  {\n    fprintf(stderr, \"%s\", msg1);\n    fwrite(opt.name, opt.namelen, 1, stderr);\n    fprintf(stderr, \"%s\", msg2);\n  }\n\n  static option::ArgStatus Unknown(const option::Option &option, bool msg)\n  {\n    if (msg)\n      printError(\"Unknown option '\", option, \"'\\n\");\n\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Required(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires an argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus NonEmpty(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0 && option.arg[0] != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a non-empty argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Numeric(const option::Option &option, bool msg)\n  {\n    char *endptr = 0;\n    if (option.arg != 0 && strtol(option.arg, &endptr, 10))\n    {\n    };\n    if (endptr != option.arg && *endptr == 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a numeric argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n};\n\nenum optionIndex\n{\n  UNKNOWN, HELP, PALETTE, DUPLICATES, IMAGE_ROW, SINGLE_FRAMES, RGBA\n};\nconst option::Descriptor usage[] =\n{\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None, \"USAGE: grptool [options] grp-file\\n\\n\"\n    \"Options:\"\n  },\n  { HELP, 0, \"h\", \"help\", option::Arg::None, \"  --help, -h  \\t\\tPrint usage and exit\" },\n  { RGBA, 0, \"r\", \"rgba\", option::Arg::None, \"  --rgba, -r  \\t\\tForce RGBA PNG export for 8-bit palettes\" },\n  { DUPLICATES, 0, \"d\", \"duplicates\", Arg::Required, \"  --duplicates yes|no, -d yes|no  \\t\\tgenerate duplicate frames (default: yes)\" },\n  { PALETTE, 0, \"p\", \"palette\", Arg::Required, \"  --palette, -p  \\t\\tSpecify the path to a palette file\" },\n  { IMAGE_ROW, 0, \"i\", \"image-row\", Arg::Numeric, \"  --image-row, -i  \\t\\tIf stitching is enabled, how many images should be saved per row (default: 10)\" },\n  { SINGLE_FRAMES, 0, \"s\", \"single-frames\", Arg::None, \"  --single-frames, -s  \\t\\tExport each frame into one image (default: all stitched together)\" },\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None,\n    \"\\ngrp-file \\t\\tThe GRP file which should be converted.\\n\"\n\n  },\n  { 0, 0, 0, 0, 0, 0 }\n};\n\nint parseOptions(int argc, const char **argv)\n{\n  argc -= (argc > 0);\n  argv += (argc > 0); // skip program name argv[0] if present\n  option::Stats stats(usage, argc, argv);\n  std::unique_ptr<option::Option[]> options(new option::Option[stats.options_max]), buffer(new option::Option[stats.buffer_max]);\n  option::Parser parse(usage, argc, argv, options.get(), buffer.get());\n\n  if (parse.error())\n    exit(0);\n\n  if (options[HELP])\n  {\n    option::printUsage(std::cout, usage);\n    exit(0);\n  }\n\n  if ( options[DUPLICATES].count() > 0 )\n  {\n    if(string(options[DUPLICATES].arg) == \"no\")\n    {\n      duplicates = false;\n    }\n    else\n    {\n      duplicates = true;\n    }\n  }\n\n  if(options[IMAGE_ROW].count() > 0)\n  {\n    image_per_row = stoi(options[IMAGE_ROW].arg);\n  }\n\n  if(options[SINGLE_FRAMES].count() > 0)\n  {\n    single_stiched = false;\n  }\n\n  if(options[PALETTE].count() > 0)\n  {\n    palette_file = options[PALETTE].arg;\n  }\n  else\n  {\n    cerr << \"Error: 'palette' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  if(options[RGBA].count() > 0 )\n  {\n    rgba = true;\n  }\n\n  // parse options\n\n  for (option::Option *opt = options[UNKNOWN]; opt; opt = opt->next())\n    std::cout << \"Unknown option: \" << opt->name << \"\\n\";\n\n  for (int i = 0; i < parse.nonOptionsCount(); ++i)\n  {\n    switch (i)\n    {\n    case 0:\n      grp_file = parse.nonOption(i);\n      break;\n    default:\n      break;\n    }\n  }\n\n  if (grp_file.empty())\n  {\n    cerr << \"Error: 'archive' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  return 0;\n}\n\nint main(int argc, const char **argv)\n{\n#ifdef HAVE_LOG4CXX\n  if (FileExists(\"logging.prop\"))\n  {\n    log4cxx::PropertyConfigurator::configure(\"logging.prop\");\n  }\n  else\n  {\n    logger.off();\n  }\n#endif // HAVE_LOG4CXX\n\n  parseOptions(argc, argv);\n\n  std::shared_ptr<AbstractPalette> myGRPPallete;\n  try\n  {\n    shared_ptr<DataChunk> dc = make_shared<DataChunk>();\n    dc->read(palette_file);\n    myGRPPallete = AbstractPalette::create(dc);\n  }\n  catch(NoValidPaletteException &palEx)\n  {\n    cerr << palEx.what() << endl;\n  }\n\n  bool grp_file_exist = FileExists(grp_file);\n  if(!grp_file_exist)\n  {\n    cerr << \"GRP file not existing - Exit!\" << endl;\n    exit(1);\n  }\n\n  if(myGRPPallete)\n  {\n    //myGRPPallete->write(\"test.pal\");\n\n    GRPImage myGRPImage(grp_file, !duplicates);\n    myGRPImage.SetColorPalette(myGRPPallete);\n\n    //image_per_row=17 => starcraft\n    if(single_stiched)\n    {\n      myGRPImage.SaveStitchedPNG(\"output_frame.png\", 0, myGRPImage.getNumberOfFrames(), image_per_row, rgba);\n    }\n    else\n    {\n      myGRPImage.SaveSinglePNG(\"output_frame%d.png\", 0, myGRPImage.getNumberOfFrames(), rgba);\n    }\n\n    //myGRPImage.SaveConvertedImage(\"output_frame_magic.png\", 0, myGRPImage.getNumberOfFrames(), single_stiched, image_per_row);\n\n    //myGRPImage.LoadImage(grp_file, remove_duplicates);\n    //myGRPImage.SaveConvertedImage(\"output_big_file.png\", 0, myGRPImage.getNumberOfFrames(), false, 17);\n  }\n  else\n  {\n    cerr << \"Palette not successful loaded - Exit!\" << endl;\n    exit(1);\n  }\n\n  cout << \"Application finished!\" << endl;\n\n  return 0;\n}\n"
  },
  {
    "path": "tools/grptool/meson.build",
    "content": "\ngrptool_sources = files(\n\t'grptool.cpp'\n\t)\n\nexecutable('grptool', \n\tgrptool_sources,\n\tdependencies : [log4cxx_dep,libstarformat_dep],\n\tinstall : true)\n\t\n"
  },
  {
    "path": "tools/iscript.c",
    "content": "//\n// iscript.bin parser\n//\n// Copyright 2008 Jimmy Salmon && Jon Goodliffe\n//\n\n#include <stdio.h>\n#include <stdlib.h>\n\n\nunsigned char *ReadFile(const char *fileName)\n{\n\tFILE *fd;\n\tlong fileSize;\n\tunsigned char *data = NULL;\n\n\t// Open\n\tfd = fopen(fileName, \"rb\");\n\tif (!fd) {\n\t\tperror(\"Could not open file\");\n\t\tgoto Cleanup;\n\t}\n\n\t// Get file size\n\tif (fseek(fd, 0, SEEK_END)) {\n\t\tfprintf(stderr, \"fseek failed\\n\");\n\t\tgoto Cleanup;\n\t}\n\tfileSize = ftell(fd);\n\tif (fseek(fd, 0, SEEK_SET)) {\n\t\tfprintf(stderr, \"fseek failed\\n\");\n\t\tgoto Cleanup;\n\t}\n\n\t// Read file\n\tdata = (unsigned char *)malloc(fileSize);\n\tif (!data) {\n\t\tfprintf(stderr, \"Out of memory\\n\");\n\t\tgoto Cleanup;\n\t}\n\tfread(data, fileSize, 1, fd);\n\nCleanup:\n\tif (fd) {\n\t\tfclose(fd);\n\t}\n\n\treturn data;\n}\n\nunsigned char ReadByte(const unsigned char **p)\n{\n\tunsigned char c = *(*p);\n\t(*p) += 1;\n\treturn c;\n}\n\n#if  defined(__i386__) || defined(__ia64__) || defined(WIN32) || \\\n   (defined(__alpha__) || defined(__alpha)) || \\\n    defined(__arm__) || \\\n   (defined(__mips__) && defined(__MIPSEL__)) || \\\n    defined(__SYMBIAN32__) || \\\n    defined(__x86_64__) || \\\n    defined(__LITTLE_ENDIAN__)\nunsigned short ReadShort(const unsigned char **p)\n{\n\tunsigned short s = *(const unsigned short *)(*p);\n\t(*p) += 2;\n\treturn s;\n}\n#else\nunsigned short ReadShort(const unsigned char **p)\n{\n\tunsigned short s = *(const unsigned short *)(*p);\n\ts = (s << 8) | (s >> 8);\n\t(*p) += 2;\n\treturn s;\n}\n#endif\n\nvoid DoDecode(const unsigned char *data, unsigned short offset)\n{\n\tconst unsigned char *p;\n\tunsigned char c1, c2;\n\tunsigned short s1, s2;\n\tunsigned char opcode;\n\tFILE * log = fopen(\"out.lua\", \"w+\");\n\tint stop = 0;\n\tint i;\n\n\tp = data + offset;\n\tfprintf(log, \"\\nAnimation = {\\n\");\n\twhile (!stop) {\n\t\tprintf(\"\\n%04hX \", (unsigned short)(p - data));\n\t\tfprintf(log,\" \\\"lable %04hX\\\", \", (unsigned long)p);\n\t\topcode = ReadByte(&p);\n\t\tswitch (opcode)\n\t\t{\n\t\t\tcase 0x00:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\tprintf(\"play frame from set: %hu\", s1);\n\t\t\t\tfprintf(log,\" \\\"frame %hu\\\", \", s1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x03:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"shift position down: %u\", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x05:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"wait: %u\", (unsigned)c1);\n\t\t\t\tfprintf(log,\" \\\"wait %u\\\", \", c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x06:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tc2 = ReadByte(&p);\n\t\t\t\tprintf(\"wait random time: %u, %u\", (unsigned)c1, (unsigned)c2);\n\t\t\t\tfprintf(log,\" \\\"random-wait %u %u\\\", \", (unsigned)c1, (unsigned)c2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x07:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\tprintf(\"goto: %04hX\", s1);\n\t\t\t\tprintf(\" \\\"goto %04hX\\\", \", (unsigned)s1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x08:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\ts2 = ReadShort(&p);\n\t\t\t\tprintf(\"place active overlay: %hu, %hu\", s1, s2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x09:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tc2 = ReadByte(&p);\n\t\t\t\tprintf(\"place active underlay: %hu, %u, %u\", s1, (unsigned)c1, (unsigned)c2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0D:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\ts2 = ReadShort(&p);\n\t\t\t\tprintf(\"0x0D unknown: %hu, %hu\", s1, s2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0F:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"0x0F unknown: %u\", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x10:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\ts2 = ReadShort(&p);\n\t\t\t\tprintf(\"place underlay under this anim level: %hu, %hu\", s1, s2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x11:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\ts2 = ReadShort(&p);\n\t\t\t\tprintf(\"place underlay under everything: %hu, %hu\", s1, s2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x15:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\ts2 = ReadShort(&p);\n\t\t\t\tprintf(\"0x15 unknown: %hu, %hu\", s1, s2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x16:\n\t\t\t\tprintf(\"end animation and remove graphic\");\n\t\t\t\tbreak;\n\n\t\t\tcase 0x18:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\tprintf(\"play sound: %hu\", s1);\n\t\t\t\tfprintf(log,\" \\\"sound %hu\\\", \", s1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x19:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"random play sound: %u\", (unsigned)c1);\n\t\t\t\tfor (i = 0; i < c1; ++i) {\n\t\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\t\tprintf(\", %hu\", s1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 0x1A:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\ts2 = ReadShort(&p);\n\t\t\t\tprintf(\"random play sound: %hu, %hu\", s1, s2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x1C:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"melee attack sound: %u\", (unsigned)c1);\n\t\t\t\tfor (i = 0; i < c1; ++i) {\n\t\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\t\tprintf(\", %hu\", s1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 0x1D:\n\t\t\t\tprintf(\"shadow opcode\");\n\t\t\t\tbreak;\n\n\t\t\tcase 0x1E:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\tprintf(\"random goto offset: %u, %04hX\", (unsigned)c1, s1);\n\t\t\t\tfprintf(log,\" \\\"random-goto %u, %04hX\\\", \", (unsigned)c1, s1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x1F:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"turn counterclockwise: %u\", (unsigned)c1);\n\t\t\t\tfprintf(log,\" \\\"rotate %u\\\", \", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x20:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"turn clockwise: %u\", (unsigned)c1);\n\t\t\t\tfprintf(log,\" \\\"rotate %u\\\", \", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x21:\n\t\t\t\tprintf(\"turn 1 frame clockwise\");\n\t\t\t\tbreak;\n\n\t\t\tcase 0x22:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"turn graphic in random direction: %u\", (unsigned)c1);\n\t\t\t\tfprintf(log,\" \\\"random-rotate %u\\\", \", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x24:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"0x24 unknown: %u\", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x25:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"attack: %u\", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x27:\n\t\t\t\tprintf(\"cast spell\");\n\t\t\t\tbreak;\n\n\t\t\tcase 0x29:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"move %u\", (unsigned)c1);\n\t\t\t\tfprintf(log,\" \\\"move %u\\\", \", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x2A:\n\t\t\t\tprintf(\"looping attack\");\n\t\t\t\tbreak;\n\n\t\t\tcase 0x2E:\n\t\t\t\tprintf(\"unbreakable section begin\");\n\t\t\t\tfprintf(log,\"\\\"unbreakable begin\\\",\");\n\t\t\t\tbreak;\n\n\t\t\tcase 0x2F:\n\t\t\t\tprintf(\"unbreakable section end\");\n\t\t\t\tfprintf(log,\"\\\"unbreakable end\\\",\");\n\t\t\t\tbreak;\n\n\t\t\tcase 0x30:\n\t\t\t\tprintf(\"ignore the rest?\");\n\t\t\t\tstop = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase 0x31:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"projectile attack from angle: %u\", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x34:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"play specific frame: %u\", (unsigned)c1);\n\t\t\t\tfprintf(log,\" \\\"exact-frame %u\\\", \", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x38:\n\t\t\t\tc1 = ReadByte(&p);\n\t\t\t\tprintf(\"unknown 0x38 extractor?: %u\", (unsigned)c1);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x3F:\n\t\t\t\ts1 = ReadShort(&p);\n\t\t\t\tprintf(\"0x3F goto?: %04hX\", s1);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tprintf(\"unsupported opcode: %u\", (unsigned)opcode);\n\t\t\t\tstop = 1;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tprintf(\"\\n\");\n    fprintf(log, \"\\n},\\n\");\n}\n\n\nint CheckForHeader(const unsigned char *p)\n{\n\t// Check for 'SCPE'\n\tif (p[0] == 'S' && p[1] == 'C' && p[2] == 'P' && p[3] == 'E') {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nvoid DecodeAnimation(const unsigned char *data, unsigned short offset)\n{\n\tconst unsigned char *p;\n\n\tp = data + offset;\n\n\tif (CheckForHeader(p)) {\n\t\tint i;\n\t\tunsigned short number;\n\n\t\tp += 4;\n\t\tnumber = ReadShort(&p);\n\t\tprintf(\"number: %hu\\n\", number);\n\n\t\tif (number < 16) {\n\t\t\tnumber = 16;\n\t\t}\n\t\tfor (i = 0; i < number; ++i) {\n\t\t\tprintf(\"%04hX\\n\", ReadShort(&p));\n\t\t}\n\t} else {\n\t\tDoDecode(data, offset);\n\t}\n}\n\n\nint main(int argc, char *argv[])\n{\n\tunsigned char *data;\n\tunsigned short offset;\n\n\tif (argc != 2) {\n\t\tfprintf(stderr, \"Usage: iscript hexoffset\\n\");\n\t\treturn -1;\n\t}\n\n\toffset = (unsigned short)strtoul(argv[1], NULL, 16);\n\tprintf(\"offset: %X\\n\", offset);\n\n\tdata = ReadFile(\"iscript.bin\");\n\tif (!data) {\n\t\treturn -1;\n\t}\n\n\tDecodeAnimation(data, offset);\n\n\tfree(data);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "tools/json_transition.cpp",
    "content": "/*\n * json_transition.cpp\n *\n *  This is just a temporary tool for transition of the old array style data to json\n *\n *      Author: Andreas Volz\n */\n\n\n#include <nlohmann/json.hpp>\n#include <string>\n#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <string>\n#include <fstream>\n\n#include \"../src/startool_mpq.h\"\n\nusing namespace std;\n\nusing json = nlohmann::json;\n\nextern const char *UnitNames[];\n\nstruct Unit\n{\n  string name;\n  int id;\n};\n\nstring getTypeName(int type)\n{\n  string str;\n\n  switch (type)\n  {\n  case S:    // Setup\n    str = \"S\";\n    break;\n  case F:    // File                          (name)\n    str = \"F\";\n    break;\n  case M:    // Map                           (name)\n    str = \"M\";\n    break;\n  case T:    // Tileset                       (name,pal,mega,mini,map)\n    str = \"T\";\n    break;\n  case R:    // RGB -> gimp                   (name,rgb)\n    str = \"R\";\n    break;\n  case G:    // Graphics                      (name,pal,gfx)\n    str = \"G\";\n    break;\n  case U:    // Uncompressed Graphics         (name,pal,gfu)\n    str = \"U\";\n    break;\n  case I:    // Widgets                       (name,pal,gfu)\n    str = \"I\";\n    break;\n  case N:    // Font                          (name,idx)\n    str = \"N\";\n    break;\n  case W:    // Wav                           (name,wav)\n    str = \"W\";\n    break;\n  case H:    // Pcx                           (name)\n    str = \"W\";\n    break;\n  case E:    // Raw extract                   (name)\n    str = \"E\";\n    break;\n  case V:    // SMK Video                     (name,video)\n    str = \"V\";\n    break;\n  case L:    // Campaign Levels\n    str = \"L\";\n    break;\n  case Q:    // MPQ archive\n    str = \"Q\";\n    break;\n  case D:    // Graphics in DDS format\n    str = \"D\";\n    break;\n  case P:    // SMK Portraits\n    str = \"P\";\n    break;\n  case PAL:  // Palette from pcx file\n    str = \"PAL\";\n    break;\n  case WPE:   // Palette from wpe file\n    str = \"WPE\";\n    break;\n  default:\n    break;\n  }\n\n  return str;\n}\n\nvoid to_json(json &j, const Control &c)\n{\n  j = json{ {\"type\", getTypeName(c.Type)}, {\"file\", c.File}, {\"arcfile\", c.ArcFile} };\n}\n\nvoid to_json(json &j, const Unit &u)\n{\n  j = json{ {\"name\", u.name}, {\"id\", u.id} };\n}\n\nvoid Unit_Array_Creator()\n{\n  for(unsigned int un = 0; un < 228; un++)\n  {\n    printf(\"unit %d: %s\\n\", un, UnitNames[un]);\n  }\n}\n\nvoid Todo_creator()\n{\n  Control *c = nullptr;\n  unsigned int len = 0;\n\n  c = Todo_bootstrap;\n  len = sizeof(Todo_bootstrap) / sizeof(*Todo_bootstrap);\n  for (unsigned int u = 0; u < len; ++u)\n  {\n    switch (c[u].Type)\n    {\n    case F:\n    {\n\n    }\n    break;\n    default:\n      break;\n    }\n  }\n\n  c = Todo_bootstrap;\n  len = sizeof(Todo_bootstrap) / sizeof(*Todo_bootstrap);\n  for (unsigned int u = 0; u < len; ++u)\n  {\n    switch (c[u].Type)\n    {\n    case F:\n    {\n\n    }\n    break;\n    default:\n      break;\n    }\n  }\n\n  json j;\n\n  for (unsigned int i = 0; i <= 1; ++i)\n  {\n    switch (i)\n    {\n    case 0:\n      // StarDat.mpq or stardat.mpq from inside files\\\\stardat.mpq\n      c = Todo;\n      len = sizeof(Todo) / sizeof(*Todo);\n\n      break;\n    case 1:\n      // CD install.exe renamed to StarCraft.mpq or other main mpq file\n      c = CDTodo;\n      len = sizeof(CDTodo) / sizeof(*CDTodo);\n\n      break;\n    }\n\n    for (unsigned int u = 0; u < len; ++u)\n    {\n\n      j[\"object\" + to_string(u)] = c[u];\n\n      /*   j[\"type\"] = c[u].Type;\n         j[\"file\"] = c[u].File;\n         j[\"arcfile\"] = c[u].ArcFile;\n         j[\"Arg1\"] = c[u].Arg1;\n         j[\"Arg2\"] = c[u].Arg2;\n         j[\"Arg3\"] = c[u].Arg3;\n         j[\"Arg4\"] = c[u].Arg4;\n      */\n\n      switch (c[u].Type)\n      {\n      case PAL:\n      {\n        break;\n      }\n      }\n    }\n  }\n\n  cout << std::setw(4) << j << endl;\n}\n\nvoid Unit_File_Creator(string filename)\n{\n  json j;\n\n  ifstream input_file(filename);\n\n  std::string line;\n  int i = 0;\n  while (std::getline(input_file, line))\n  {\n    //cout << line << endl;\n\n    std::for_each(line.begin(), line.end(), [](char & c)\n    {\n        c = ::tolower(c);\n    });\n\n    Unit u;\n    u.name = \"unit-\" + line;\n    u.id = i;\n\n    j[i] = u;\n\n    i++;\n  }\n\n  cout << std::setw(4) << j << endl;\n}\n\nint main(int argc, char **argv)\n{\n  //Unit_File_Creator(\"..b/data/units.txt\");\n  //Unit_Array_Creator();\n  Todo_creator();\n\n  return 0;\n}\n\nconst char *UnitNames[] =\n{\n  \"unit-terran-marine\", \"unit-terran-ghost\", \"unit-terran-vulture\",\n  \"unit-terran-goliath\", \"Goliath-Turret\",\n  \"unit-terran-siege-tank-(Tank-Mode)\", \"Tank-Turret(Tank-Mode)\",\n  \"unit-terran-scv\", \"unit-terran-wraith\", \"unit-terran-science-vessel\",\n  \"Gui-Montang-(Firebat)\", \"unit-terran-dropship\",\n  \"unit-terran-battlecruiser\", \"Vulture-Spider-Mine\", \"Nuclear-Missile\",\n  \"unit-terran-civilian\", \"Sarah-Kerrigan-(Ghost)\", \"Alan-Schezar-(Goliath)\",\n  \"Alan-Schezar-Turret\", \"Jim-Raynor-(Vulture)\", \"Jim-Raynor-(Marine)\",\n  \"Tom-Kazansky-(Wraith)\", \"Magellan-(Science-Vessel)\",\n  \"Edmund-Duke-(Siege-Tank)\", \"Edmund-Duke-Turret\",\n  \"Edmund-Duke-(Siege-Mode)\", \"Edmund-Duke-Turret\",\n  \"Arcturus-Mengsk-(Battlecruiser)\", \"Hyperion-(Battlecruiser)\",\n  \"Norad-II-(Battlecruiser)\", \"unit-terran-siege-tank-(Siege-Mode)\",\n  \"Tank-Turret-(Siege-Mode)\", \"Firebat\", \"Scanner-Sweep\", \"unit-terran-medic\",\n  \"unit-zerg-larva\", \"unit-zerg-egg\", \"unit-zerg-zergling\",\n  \"unit-zerg-hydralisk\", \"unit-zerg-ultralisk\", \"unit-zerg-broodling\",\n  \"unit-zerg-drone\", \"unit-zerg-overlord\", \"unit-zerg-mutalisk\",\n  \"unit-zerg-guardian\", \"unit-zerg-queen\", \"unit-zerg-defiler\",\n  \"unit-zerg-scourge\", \"Torrarsque-(Ultralisk)\", \"Matriarch-(Queen)\",\n  \"Infested-Terran\", \"Infested-Kerrigan\", \"Unclean-One-(Defiler)\",\n  \"Hunter-Killer-(Hydralisk)\", \"Devouring-One-(Zergling)\",\n  \"Kukulza-(Mutalisk)\", \"Kukulza-(Guardian)\", \"Yggdrasill-(Overlord)\",\n  \"unit-terran-valkyrie-frigate\", \"Mutalisk/Guardian-Cocoon\",\n  \"unit-protoss-corsair\", \"unit-protoss-dark-templar(Unit)\",\n  \"unit-zerg-devourer\", \"unit-protoss-dark-archon\", \"unit-protoss-probe\",\n  \"unit-protoss-zealot\", \"unit-protoss-dragoon\", \"unit-protoss-high-templar\",\n  \"unit-protoss-archon\", \"unit-protoss-shuttle\", \"unit-protoss-scout\",\n  \"unit-protoss-arbiter\", \"unit-protoss-carrier\", \"unit-protoss-interceptor\",\n  \"Dark-Templar(Hero)\", \"Zeratul-(Dark-Templar)\", \"Tassadar/Zeratul-(Archon)\",\n  \"Fenix-(Zealot)\", \"Fenix-(Dragoon)\", \"Tassadar-(Templar)\", \"Mojo-(Scout)\",\n  \"Warbringer-(Reaver)\", \"Gantrithor-(Carrier)\", \"unit-protoss-reaver\",\n  \"unit-protoss-observer\", \"unit-protoss-scarab\", \"Danimoth-(Arbiter)\",\n  \"Aldaris-(Templar)\", \"Artanis-(Scout)\", \"Rhynadon-(Badlands-Critter)\",\n  \"Bengalaas-(Jungle-Critter)\", \"Unused---Was-Cargo-Ship\",\n  \"Unused---Was-Mercenary-Gunship\", \"Scantid-(Desert-Critter)\",\n  \"Kakaru-(Twilight-Critter)\", \"Ragnasaur-(Ashworld-Critter)\",\n  \"Ursadon-(Ice-World-Critter)\", \"Lurker-Egg\", \"Raszagal\",\n  \"Samir-Duran-(Ghost)\", \"Alexei-Stukov-(Ghost)\", \"Map-Revealer\",\n  \"Gerard-DuGalle\", \"unit-zerg-Lurker\", \"Infested-Duran\", \"Disruption-Web\",\n  \"unit-terran-command-center\", \"unit-terran-comsat-station\",\n  \"unit-terran-nuclear-silo\", \"unit-terran-supply-depot\",\n  \"unit-terran-refinery\", \"unit-terran-barracks\", \"unit-terran-academy\",\n  \"unit-terran-factory\", \"unit-terran-starport\", \"unit-terran-control-tower\",\n  \"unit-terran-science-facility\", \"unit-terran-covert-ops\",\n  \"unit-terran-physics-lab\", \"Unused---Was-Starbase?\",\n  \"unit-terran-machine-shop\", \"Unused---Was-Repair-Bay?\",\n  \"unit-terran-engineering-bay\", \"unit-terran-armory\",\n  \"unit-terran-missile-turret\", \"unit-terran-bunker\", \"Norad-II\",\n  \"Ion-Cannon\", \"Uraj-Crystal\", \"Khalis-Crystal\", \"Infested-Command-Center\",\n  \"unit-zerg-hatchery\", \"unit-zerg-lair\", \"unit-zerg-hive\",\n  \"unit-zerg-nydus-canal\", \"unit-zerg-hydralisk-den\",\n  \"unit-zerg-defiler-mound\", \"unit-zerg-greater-spire\",\n  \"unit-zerg-queens-nest\", \"unit-zerg-evolution-chamber\",\n  \"unit-zerg-ultralisk-cavern\", \"unit-zerg-spire\", \"unit-zerg-spawning-pool\",\n  \"unit-zerg-creep-colony\", \"unit-zerg-spore-colony\", \"Unused-Zerg-Building\",\n  \"unit-zerg-sunken-colony\", \"unit-zerg-overmind-(With-Shell)\",\n  \"unit-zerg-overmind\", \"unit-zerg-extractor\", \"Mature-Chrysalis\",\n  \"unit-zerg-cerebrate\", \"unit-zerg-cerebrate-daggoth\",\n  \"Unused-Zerg-Building-5\", \"unit-protoss-nexus\",\n  \"unit-protoss-robotics-facility\", \"unit-protoss-pylon\",\n  \"unit-protoss-assimilator\", \"Unused-Protoss-Building\",\n  \"unit-protoss-observatory\", \"unit-protoss-gateway\",\n  \"Unused-Protoss-Building\", \"unit-protoss-photon-cannon\",\n  \"unit-protoss-citadel-of-adun\", \"unit-protoss-cybernetics-core\",\n  \"unit-protoss-templar-archives\", \"unit-protoss-forge\",\n  \"unit-protoss-stargate\", \"Stasis-Cell/Prison\", \"unit-protoss-fleet-beacon\",\n  \"unit-protoss-arbiter-tribunal\", \"unit-protoss-robotics-support-bay\",\n  \"unit-protoss-shield-battery\", \"Khaydarin-Crystal-Formation\",\n  \"unit-protoss-temple\", \"Xel'Naga-Temple\", \"unit-minerals1\",\n  \"unit-minerals2\", \"unit-minerals3\", \"Cave\", \"Cave-in\", \"Cantina\",\n  \"Mining-Platform\", \"Independant-Command-Center\", \"Independant-Starport\",\n  \"Independant-Jump-Gate\", \"Ruins\", \"Kyadarin-Crystal-Formation\",\n  \"unit-vespene-geyser\", \"Warp-Gate\", \"PSI-Disruptor\", \"unit-zerg-marker\",\n  \"unit-terran-marker\", \"unit-protoss-marker\", \"unit-zerg-beacon\",\n  \"unit-terran-beacon\", \"unit-protoss-beacon\", \"unit-zerg-flag-beacon\",\n  \"unit-terran-flag-beacon\", \"unit-protoss-flag-beacon\", \"Power-Generator\",\n  \"Overmind-Cocoon\", \"Dark-Swarm\", \"Floor-Missile-Trap\", \"Floor-Hatch\",\n  \"Left-Upper-Level-Door\", \"Right-Upper-Level-Door\", \"Left-Pit-Door\",\n  \"Right-Pit-Door\", \"Floor-Gun-Trap\", \"Left-Wall-Missile-Trap\",\n  \"Left-Wall-Flame-Trap\", \"Right-Wall-Missile-Trap\", \"Right-Wall-Flame-Trap\",\n  \"Start-Location\", \"Flag\", \"Young-Chrysalis\", \"Psi-Emitter\", \"Data-Disc\",\n  \"Khaydarin-Crystal\", \"Mineral-Cluster-Type-1\", \"Mineral-Cluster-Type-2\",\n  \"unit-protoss-vespene-gas-orb-type-1\",\n  \"unit-protoss-vespene-gas-orb-type-2\", \"unit-zerg-vespene-gas-sac-type-1\",\n  \"unit-zerg-vespene-gas-sac-type-2\", \"unit-terran-vespene-gas-tank-type-1\",\n  \"unit-terran-vespene-gas-tank-type-2\",\n};\n"
  },
  {
    "path": "tools/meson.build",
    "content": "\niscript_sources = files('iscript.c')\n\njson_transition_sources = files('json_transition.cpp')\n\nexecutable('iscript', \n\tiscript_sources,\n\tinstall : false)\n\t\nexecutable('json_transition', \n\tjson_transition_sources,\n\tdependencies : [nlohmann_json_dep, png_dep],\n\tinstall : false)\n"
  },
  {
    "path": "tools/sauwetter/meson.build",
    "content": "\nsauwetter_sources = files('sauwetter.cpp')\n\nexecutable('sauwetter', \n\tsauwetter_sources,\n\tdependencies : [libstarformat_dep],\n\tinstall : true)\n\t\n"
  },
  {
    "path": "tools/sauwetter/sauwetter.cpp",
    "content": "/*\n * sauwetter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Breeze.h\"\n#include \"Storm.h\"\n#include \"Casc.h\"\n#include \"FileUtil.h\"\n#include \"StringUtil.h\"\n#include \"optparser.h\"\n\n// system\n#include <iostream>\n\nusing namespace std;\n\n// some global variables\nstring backend;\nstring archive;\nstring archive_file;\nstring destination_directory;\n\nbool CheckCASCDataFolder(const std::string &dir)\n{\n  return FileExists(dir + \"/.build.info\");\n}\n\n/** option parser **/\nstruct Arg: public option::Arg\n{\n  static void printError(const char *msg1, const option::Option &opt, const char *msg2)\n  {\n    fprintf(stderr, \"%s\", msg1);\n    fwrite(opt.name, opt.namelen, 1, stderr);\n    fprintf(stderr, \"%s\", msg2);\n  }\n\n  static option::ArgStatus Unknown(const option::Option &option, bool msg)\n  {\n    if (msg)\n      printError(\"Unknown option '\", option, \"'\\n\");\n\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Required(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires an argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus NonEmpty(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0 && option.arg[0] != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a non-empty argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Numeric(const option::Option &option, bool msg)\n  {\n    char *endptr = 0;\n    if (option.arg != 0 && strtol(option.arg, &endptr, 10))\n    {\n    };\n    if (endptr != option.arg && *endptr == 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a numeric argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n};\n\nenum optionIndex\n{\n  UNKNOWN, HELP, BACKEND\n};\nconst option::Descriptor usage[] =\n{\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None, \"USAGE: sauwetter archive [options] archive-file destination-directory\\n\\n\"\n    \"Options:\"\n  },\n  { HELP, 0, \"h\", \"help\", option::Arg::None, \"  --help, -h  \\t\\tPrint usage and exit\" },\n  { BACKEND, 0, \"b\", \"backend\", Arg::Required, \"  --backend BACKEND, -b BACKEND  \\t\\tChoose a backend (Storm=St*arcr*ft1/Br**dwar;Casc=Remastered;Breeze=Folder)\" },\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None,\n    \"\\narchive \\t\\tDestination to the archive (mpq, casc or dummy folder) based on backend.\\n\"\n    \"\\narchive-file \\t\\tThe file inside the archive (with relative path) that is to be extracted.\\n\"\n    \"\\ndestination-directory \\t\\tWhere to save the extracted file with same relative path.\\n\"\n\n  },\n  { 0, 0, 0, 0, 0, 0 }\n};\n\nint parseOptions(int argc, const char **argv)\n{\n  argc -= (argc > 0);\n  argv += (argc > 0); // skip program name argv[0] if present\n  option::Stats stats(usage, argc, argv);\n  std::unique_ptr<option::Option[]> options(new option::Option[stats.options_max]), buffer(new option::Option[stats.buffer_max]);\n  option::Parser parse(usage, argc, argv, options.get(), buffer.get());\n\n  if (parse.error())\n    exit(0);\n\n  if (options[HELP])\n  {\n    option::printUsage(std::cout, usage);\n    exit(0);\n  }\n\n  if(options[BACKEND].count() > 0)\n  {\n    backend = options[BACKEND].arg;\n  }\n  else\n  {\n    cerr << \"Error: 'backend' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  // parse options\n\n  for (option::Option *opt = options[UNKNOWN]; opt; opt = opt->next())\n    std::cout << \"Unknown option: \" << opt->name << \"\\n\";\n\n  for (int i = 0; i < parse.nonOptionsCount(); ++i)\n  {\n    switch (i)\n    {\n    case 0:\n      //cerr << \"archive #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      archive = parse.nonOption(i);\n      break;\n    case 1:\n      //cerr << \"archive-file #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      archive_file = parse.nonOption(i);\n      break;\n    case 2:\n      //cerr << \"destination-directory #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      destination_directory = parse.nonOption(i);\n      break;\n    default:\n      break;\n    }\n  }\n\n  if (archive.empty())\n  {\n    cerr << \"Error: 'archive' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  if (archive_file.empty())\n  {\n    cerr << \"Error: 'archive_file' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  if (destination_directory.empty())\n  {\n    cerr << \"Error: 'destination_directory' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  return 0;\n}\n\nint main(int argc, const char **argv)\n{\n  parseOptions(argc, argv);\n\n  bool archive_exists = FileExists(archive);\n  if(!archive_exists)\n  {\n    cerr << \"archive not existing - exit!\" << endl;\n    exit(1);\n  }\n\n  shared_ptr<Hurricane> hurricane;\n\n  cerr << \"Backend: \" << backend << endl;\n  if(to_lower(backend) == \"breeze\")\n  {\n    hurricane = make_shared<Breeze>(archive);\n  }\n  else if(to_lower(backend) == \"storm\")\n  {\n    hurricane = make_shared<Storm>(archive);\n  }\n  else if(to_lower(backend) == \"casc\")\n  {\n#ifdef HAVE_CASC\n    if(CheckCASCDataFolder(archive))\n    {\n      hurricane = make_shared<Casc>(archive);\n    }\n    else\n    {\n      cerr << \"Error: 'archive' is not a CASC archive!\" << endl;\n    }\n#else\n    cerr << \"Error: No CASC support compiled into sauwetter!\" << endl;\n    exit(1);\n#endif\n  }\n\n\n  string archive_file_slash(archive_file);\n  replaceString(\"\\\\\", \"/\", archive_file_slash);\n  string destination_full_path = destination_directory + \"/\" + archive_file_slash;\n\n  bool result = hurricane->extractFile(archive_file, destination_full_path, false);\n\n  printf(\"extracted %s ... %s\\n\", destination_full_path.c_str(), result ? \"ok\" : \"nok\");\n\n  return !result;\n}\n\n"
  },
  {
    "path": "tools/scdat2json/SCJsonExporter.cpp",
    "content": "/*\n * SCJsonExporter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"SCJsonExporter.h\"\n#include \"to_json.h\"\n\n// system\n#include <iostream>\n#include <string>\n#include <fstream>\n\nusing namespace std;\nusing namespace dat;\n\n\n\nSCJsonExporter::SCJsonExporter(dat::DataHub &datahub) :\n  mDatahub(datahub)\n{\n\n}\n\nSCJsonExporter::~SCJsonExporter()\n{\n\n}\n\njson SCJsonExporter::export_unit_dat()\n{\n  // TODO: check if to_json() method for units_dat_t is good\n  std::shared_ptr<units_dat_t> units = mDatahub.units;\n\n  json j;\n\n  j[\"flingy\"] = json(*units->flingy());\n\n  j[\"subunit1\"] = json(*units->subunit1());\n\n  j[\"subunit2\"] = json(*units->subunit2());\n\n  j[\"infestation\"] = json(*units->infestation());\n\n  j[\"construction_animation\"] = json(*units->construction_animation());\n\n  j[\"unit_direction\"] = json(*units->unit_direction());\n\n  j[\"shield_enable\"] = json(*units->shield_enable());\n\n  j[\"shield_amount\"] = json(*units->shield_amount());\n\n  j[\"hit_points\"] = json(*units->hit_points());\n\n  j[\"elevation_level\"] = json(*units->elevation_level());\n\n  j[\"unknown\"] = json(*units->unknown());\n\n  j[\"rank\"] = json(*units->rank());\n\n  j[\"ai_computer_idle\"] = json(*units->ai_computer_idle());\n\n  j[\"ai_human_idle\"] = json(*units->ai_human_idle());\n\n  j[\"ai_return_to_idle\"] = json(*units->ai_return_to_idle());\n\n  j[\"ai_attack_unit\"] = json(*units->ai_attack_unit());\n\n  j[\"ai_attack_move\"] = json(*units->ai_attack_move());\n\n  j[\"ground_weapon\"] = json(*units->ground_weapon());\n\n  if(units->is_format_bw())\n  {\n    j[\"max_ground_hits\"] = json(*units->max_ground_hits());\n  }\n\n  j[\"air_weapon\"] = json(*units->air_weapon());\n\n  if(units->is_format_bw())\n  {\n    j[\"max_air_hits\"] = json(*units->max_air_hits());\n  }\n\n  j[\"ai_internal\"] = json(*units->ai_internal());\n\n  j[\"special_ability_flags\"] = json(*units->special_ability_flags());\n\n  j[\"target_acquisition_range\"] = json(*units->target_acquisition_range());\n\n  j[\"sight_range\"] = json(*units->sight_range());\n\n  j[\"armor_upgrade\"] = json(*units->armor_upgrade());\n\n  j[\"unit_size\"] = json(*units->unit_size());\n\n  j[\"armor\"] = json(*units->armor());\n\n  j[\"right_click_action\"] = json(*units->right_click_action());\n\n  j[\"ready_sound\"] = json(*units->ready_sound());\n\n  j[\"what_sound_start\"] = json(*units->what_sound_start());\n\n  j[\"what_sound_end\"] = json(*units->what_sound_end());\n\n  j[\"piss_sound_start\"] = json(*units->piss_sound_start());\n\n  j[\"piss_sound_end\"] = json(*units->piss_sound_end());\n\n  j[\"yes_sound_start\"] = json(*units->yes_sound_start());\n\n  j[\"yes_sound_end\"] = json(*units->yes_sound_end());\n\n  j[\"staredit_placement_box\"] = json(*units->staredit_placement_box());\n\n  j[\"addon_position\"] = json(*units->addon_position());\n\n  j[\"unit_dimension\"] = json(*units->unit_dimension());\n\n  j[\"portrait\"] = json(*units->portrait());\n\n  j[\"mineral_cost\"] = json(*units->mineral_cost());\n\n  j[\"vespene_cost\"] = json(*units->vespene_cost());\n\n  j[\"build_time\"] = json(*units->build_time());\n\n  j[\"requirements\"] = json(*units->requirements());\n\n  j[\"staredit_group_flags\"] = json(*units->staredit_group_flags());\n\n  j[\"supply_provided\"] = json(*units->supply_provided());\n\n  j[\"supply_required\"] = json(*units->supply_required());\n\n  j[\"space_required\"] = json(*units->space_required());\n\n  j[\"space_provided\"] = json(*units->space_provided());\n\n  j[\"build_score\"] = json(*units->build_score());\n\n  j[\"destroy_score\"] = json(*units->destroy_score());\n\n  j[\"unit_map_string\"] = json(*units->unit_map_string());\n\n  if(units->is_format_bw())\n  {\n    j[\"broodwar_flag\"] = json(*units->broodwar_flag());\n  }\n\n  j[\"staredit_availability_flags\"] = json(*units->staredit_availability_flags());\n\n  return j;\n}\n\njson SCJsonExporter::export_orders_dat()\n{\n  std::shared_ptr<orders_dat_t> orders = mDatahub.orders;\n\n  json j;\n\n  j[\"label\"] = json(*orders->label());\n\n  j[\"use_weapon_targeting\"] = json(*orders->use_weapon_targeting());\n\n  j[\"unknown2\"] = json(*orders->unknown2());\n\n  j[\"unknown3\"] = json(*orders->unknown3());\n\n  j[\"unknown4\"] = json(*orders->unknown4());\n\n  j[\"unknown5\"] = json(*orders->unknown5());\n\n  j[\"interruptible\"] = json(*orders->interruptible());\n\n  j[\"unknown7\"] = json(*orders->unknown7());\n\n  j[\"queueable\"] = json(*orders->queueable());\n\n  j[\"unknown9\"] = json(*orders->unknown9());\n\n  j[\"unknown10\"] = json(*orders->unknown10());\n\n  j[\"unknown11\"] = json(*orders->unknown11());\n\n  j[\"unknown12\"] = json(*orders->unknown12());\n\n  j[\"targeting\"] = json(*orders->targeting());\n\n  j[\"energy\"] = json(*orders->energy());\n\n  j[\"animation\"] = json(*orders->animation());\n\n  j[\"highlight\"] = json(*orders->highlight());\n\n  j[\"unknown17\"] = json(*orders->unknown17());\n\n  j[\"obscured_order\"] = json(*orders->obscured_order());\n\n  return j;\n}\n\njson SCJsonExporter::export_weapons_dat()\n{\n  std::shared_ptr<weapons_dat_t> weapons = mDatahub.weapons;\n\n  json j;\n\n  j[\"label\"] = json(*weapons->label());\n\n  j[\"graphics\"] = json(*weapons->graphics());\n\n  j[\"explosion\"] = json(*weapons->explosion());\n\n  j[\"target_flags\"] = json(*weapons->target_flags());\n\n  j[\"minimum_range\"] = json(*weapons->minimum_range());\n\n  j[\"maximum_range\"] = json(*weapons->maximum_range());\n\n  j[\"damage_upgrade\"] = json(*weapons->damage_upgrade());\n\n  j[\"weapon_type\"] = json(*weapons->weapon_type());\n\n  j[\"weapon_behaviour\"] = json(*weapons->weapon_behaviour());\n\n  j[\"remove_after\"] = json(*weapons->remove_after());\n\n  j[\"explosive_type\"] = json(*weapons->explosive_type());\n\n  j[\"inner_splash_range\"] = json(*weapons->inner_splash_range());\n\n  j[\"medium_splash_range\"] = json(*weapons->medium_splash_range());\n\n  j[\"outer_splash_range\"] = json(*weapons->outer_splash_range());\n\n  j[\"damage_amount\"] = json(*weapons->damage_amount());\n\n  j[\"damage_bonus\"] = json(*weapons->damage_bonus());\n\n  j[\"weapon_cooldown\"] = json(*weapons->weapon_cooldown());\n\n  j[\"damage_factor\"] = json(*weapons->damage_factor());\n\n  j[\"attack_angle\"] = json(*weapons->attack_angle());\n\n  j[\"launch_spin\"] = json(*weapons->launch_spin());\n\n  j[\"x_offset\"] = json(*weapons->x_offset());\n\n  j[\"y_offset\"] = json(*weapons->y_offset());\n\n  j[\"error_message\"] = json(*weapons->error_message());\n\n  j[\"icon\"] = json(*weapons->icon());\n\n  return j;\n}\n\njson SCJsonExporter::export_flingy_dat()\n{\n  std::shared_ptr<flingy_dat_t> flingy = mDatahub.flingy;\n\n  json j;\n\n  j[\"sprite\"] = json(*flingy->sprite());\n\n  j[\"speed\"] = json(*flingy->speed());\n\n  j[\"acceleration\"] = json(*flingy->acceleration());\n\n  j[\"halt_distance\"] = json(*flingy->halt_distance());\n\n  j[\"turn_radius\"] = json(*flingy->turn_radius());\n\n  j[\"unused\"] = json(*flingy->unused());\n\n  j[\"movement_control\"] = json(*flingy->movement_control());\n\n  return j;\n}\n\njson SCJsonExporter::export_sprites_dat()\n{\n  std::shared_ptr<sprites_dat_t> sprites = mDatahub.sprites;\n\n  json j;\n\n  j[\"image\"] = json(*sprites->image());\n\n  j[\"health_bar\"] = json(*sprites->health_bar());\n\n  j[\"unknown2\"] = json(*sprites->unknown2());\n\n  j[\"is_visible\"] = json(*sprites->is_visible());\n\n  j[\"select_circle_image_size\"] = json(*sprites->select_circle_image_size());\n\n  j[\"select_circle_vertical_pos\"] = json(*sprites->select_circle_vertical_pos());\n\n  return j;\n}\n\njson SCJsonExporter::export_images_dat()\n{\n  std::shared_ptr<images_dat_t> images = mDatahub.images;\n\n  json j;\n\n  j[\"grp\"] = json(*images->grp());\n\n  j[\"gfx_turns\"] = json(*images->gfx_turns());\n\n  j[\"clickable\"] = json(*images->clickable());\n\n  j[\"use_full_iscript\"] = json(*images->use_full_iscript());\n\n  j[\"draw_if_cloaked\"] = json(*images->draw_if_cloaked());\n\n  j[\"draw_function\"] = json(*images->draw_function());\n\n  j[\"remapping\"] = json(*images->remapping());\n\n  j[\"iscript\"] = json(*images->iscript());\n\n  j[\"shield_overlay\"] = json(*images->shield_overlay());\n\n  j[\"attack_overlay\"] =  json(*images->attack_overlay());\n\n  j[\"damage_overlay\"] = json(*images->damage_overlay());\n\n  j[\"special_overlay\"] = json(*images->special_overlay());\n\n  j[\"landing_dust_overlay\"] = json(*images->landing_dust_overlay());\n\n  j[\"lift_off_dust_overlay\"] = json(*images->lift_off_dust_overlay());\n\n  return j;\n}\n\njson SCJsonExporter::export_sfxdata_dat()\n{\n  std::shared_ptr<sfxdata_dat_t> sfxdata = mDatahub.sfxdata;\n\n  json j;\n\n  j[\"sound_file\"] = json(*sfxdata->sound_file());\n\n  j[\"unknown1\"] = json(*sfxdata->unknown1());\n\n  j[\"unknown2\"] = json(*sfxdata->unknown2());\n\n  j[\"unknown3\"] = json(*sfxdata->unknown3());\n\n  j[\"unknown4\"] = json(*sfxdata->unknown4());\n\n  return j;\n}\n\njson SCJsonExporter::export_portdata_dat()\n{\n  std::shared_ptr<portdata_dat_t> portdata = mDatahub.portdata;\n\n  json j;\n\n  j[\"video_idle\"] = json(*portdata->video_idle());\n\n  j[\"video_talking\"] = json(*portdata->video_talking());\n\n  j[\"change_idle\"] = json(*portdata->change_idle());\n\n  j[\"unknown1_idle\"] = json(*portdata->unknown1_idle());\n\n  j[\"unknown1_talking\"] = json(*portdata->unknown1_talking());\n\n  return j;\n}\n\njson SCJsonExporter::export_upgrades_dat()\n{\n  std::shared_ptr<upgrades_dat_t> upgrades = mDatahub.upgrades;\n\n  json j;\n\n  j[\"mineral_cost_base\"] = json(*upgrades->mineral_cost_base());\n\n  j[\"mineral_cost_factor\"] = json(*upgrades->mineral_cost_factor());\n\n  j[\"vespene_cost_base\"] = json(*upgrades->vespene_cost_base());\n\n  j[\"vespene_cost_factor\"] = json(*upgrades->vespene_cost_factor());\n\n  j[\"research_time_base\"] = json(*upgrades->research_time_base());\n\n  j[\"research_time_factor\"] = json(*upgrades->research_time_factor());\n\n  j[\"unknown6\"] = json(*upgrades->unknown6());\n\n  j[\"icon\"] = json(*upgrades->icon());\n\n  j[\"label\"] = json(*upgrades->label());\n\n  j[\"race\"] = json(*upgrades->race());\n\n  j[\"max_repeats\"] = json(*upgrades->max_repeats());\n\n  if(upgrades->has_broodwar_flag())\n  {\n    j[\"broodwar_flags\"] = json(*upgrades->broodwar_flags());\n  }\n\n  return j;\n}\n\njson SCJsonExporter::export_techdata_dat()\n{\n  std::shared_ptr<techdata_dat_t> techdata = mDatahub.techdata;\n\n  json j;\n\n  j[\"mineral_cost\"] = json(*techdata->mineral_cost());\n\n  j[\"vespene_cost\"] = json(*techdata->vespene_cost());\n\n  j[\"research_time\"] = json(*techdata->research_time());\n\n  j[\"energy_required\"] = json(*techdata->energy_required());\n\n  j[\"unknown4\"] = json(*techdata->unknown4());\n\n  j[\"icon\"] = json(*techdata->icon());\n\n  j[\"label\"] = json(*techdata->label());\n\n  j[\"race\"] = json(*techdata->race());\n\n  j[\"unused\"] = json(*techdata->unused());\n\n  if(techdata->has_broodwar_flag())\n  {\n    j[\"broodwar_flag\"] = json(*techdata->broodwar_flag());\n  }\n\n  return j;\n}\n\njson SCJsonExporter::export_mapdata_dat()\n{\n  std::shared_ptr<mapdata_dat_t> mapdata = mDatahub.mapdata;\n\n  json j;\n\n  j[\"mission_dir\"] = json(*mapdata->mission_dir());\n\n  return j;\n}\n\njson SCJsonExporter::export_file_tbl(std::vector<TblEntry> &tblentry_vec)\n{\n  json j(tblentry_vec);\n\n  return j;\n}\n\n"
  },
  {
    "path": "tools/scdat2json/SCJsonExporter.h",
    "content": "/*\n * SCJsonExporter.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef SCJSONEXPORTER_H\n#define SCJSONEXPORTER_H\n\n#include \"dat/DataHub.h\"\n\nclass SCJsonExporter\n{\npublic:\n  SCJsonExporter(dat::DataHub &datahub);\n  virtual ~SCJsonExporter();\n\n  json export_unit_dat();\n  json export_orders_dat();\n  json export_weapons_dat();\n  json export_flingy_dat();\n  json export_sprites_dat();\n  json export_images_dat();\n  json export_sfxdata_dat();\n  json export_portdata_dat();\n  json export_upgrades_dat();\n  json export_techdata_dat();\n  json export_mapdata_dat();\n\n  json export_file_tbl(std::vector<dat::TblEntry> &tblentry_vec);\n\nprivate:\n  dat::DataHub &mDatahub;\n};\n\n#endif /* SCJSONEXPORTER_H */\n"
  },
  {
    "path": "tools/scdat2json/UnitsJsonExporter.cpp",
    "content": "/*\n * UnitsJsonExporter.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"UnitsJsonExporter.h\"\n#include \"to_json.h\"\n\n// system\n#include <iostream>\n#include <string>\n#include <fstream>\n\nusing namespace std;\nusing namespace dat;\n\nUnitsJsonExporter::UnitsJsonExporter(dat::DataHub &datahub)  :\n  mDatahub(datahub)\n{\n\n}\n\nUnitsJsonExporter::~UnitsJsonExporter()\n{\n\n}\n\n\n\n\nvoid UnitsJsonExporter::exportUnit(unsigned int id, const std::string &idString)\n{\n  /*Unit unit(mDatahub, id, idString);\n\n  json j;\n\n  json j_unit(unit);\n  j[\"unit\"] = j_unit;*/\n\n\n}\n\n"
  },
  {
    "path": "tools/scdat2json/UnitsJsonExporter.h",
    "content": "/*\n * UnitsJsonExporter.h\n *\n  *      Author: Andreas Volz\n */\n\n#ifndef UNITSJSONEXPORTER_H\n#define UNITSJSONEXPORTER_H\n\n#include \"dat/DataHub.h\"\n\nclass UnitsJsonExporter\n{\npublic:\n  UnitsJsonExporter(dat::DataHub &datahub);\n  virtual ~UnitsJsonExporter();\n\n  void exportUnit(unsigned int id, const std::string &idString);\n\nprivate:\n  dat::DataHub &mDatahub;\n};\n\n#endif /* UNITSJSONEXPORTER_H */\n"
  },
  {
    "path": "tools/scdat2json/meson.build",
    "content": "\nscdat2json_sources = files(\n\t'scdat2json.cpp',\n\t'SCJsonExporter.cpp',\n\t'UnitsJsonExporter.cpp',\n\t'to_json.cpp'\n\t)\n\nexecutable('scdat2json', \n\tscdat2json_sources,\n\tdependencies : [log4cxx_dep,libstarformat_dep,nlohmann_json_dep],\n\tinstall : true)\n\t\n"
  },
  {
    "path": "tools/scdat2json/scdat2json.cpp",
    "content": "/*\n * scdat2json.cpp\n *\n *      Author: Andreas Volz\n */\n\n// project\n#include \"Breeze.h\"\n#include \"Storm.h\"\n#include \"Casc.h\"\n#include \"FileUtil.h\"\n#include \"StringUtil.h\"\n#include \"optparser.h\"\n#include \"dat/DataHub.h\"\n#include \"Storage.h\"\n#include \"SCJsonExporter.h\"\n#include \"UnitsJsonExporter.h\"\n#include \"Logger.h\"\n#include \"pacman.h\"\n#include \"dat/Unit.h\"\n#include \"to_json.h\"\n\n// system\n#include <iostream>\n#include <nlohmann/json.hpp>\n#include <fstream>\n\nusing namespace std;\nusing namespace dat;\n\n/**\n * The scdat2json tool idea is to export the data in all relevant *.dat and corresponding *.tbl in a raw format to JSON.\n * At this point of transformation isn't much format conversation done. Just put the data as in original data structures, but readable.\n * Only exception for now is that .tbl files get some basic control sequence parsing.\n */\n\nstatic Logger logger(\"startool.scdat2json\");\n\n// some global variables\nstring backend;\nstring archive;\nstring destination_directory;\nbool pretty = true;\n\nbool CheckCASCDataFolder(const std::string &dir)\n{\n  return FileExists(dir + \"/.build.info\");\n}\n\n/** option parser **/\nstruct Arg: public option::Arg\n{\n  static void printError(const char *msg1, const option::Option &opt, const char *msg2)\n  {\n    fprintf(stderr, \"%s\", msg1);\n    fwrite(opt.name, opt.namelen, 1, stderr);\n    fprintf(stderr, \"%s\", msg2);\n  }\n\n  static option::ArgStatus Unknown(const option::Option &option, bool msg)\n  {\n    if (msg)\n      printError(\"Unknown option '\", option, \"'\\n\");\n\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Required(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires an argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus NonEmpty(const option::Option &option, bool msg)\n  {\n    if (option.arg != 0 && option.arg[0] != 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a non-empty argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n\n  static option::ArgStatus Numeric(const option::Option &option, bool msg)\n  {\n    char *endptr = 0;\n    if (option.arg != 0 && strtol(option.arg, &endptr, 10))\n    {\n    };\n    if (endptr != option.arg && *endptr == 0)\n      return option::ARG_OK;\n\n    if (msg)\n      printError(\"Option '\", option, \"' requires a numeric argument\\n\");\n    return option::ARG_ILLEGAL;\n  }\n};\n\nenum optionIndex\n{\n  UNKNOWN, HELP, BACKEND, PRETTY\n};\nconst option::Descriptor usage[] =\n{\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None, \"USAGE: scdat2json [options] archive archive-file destination-directory\\n\\n\"\n    \"Options:\"\n  },\n  { HELP, 0, \"h\", \"help\", option::Arg::None, \"  --help, -h  \\t\\tPrint usage and exit\" },\n  { PRETTY, 0, \"p\", \"pretty\", Arg::Required, \"  --pretty=[yes/no], -p  \\t\\tPretty print the formated JSON file (default: yes)\" },\n  { BACKEND, 0, \"b\", \"backend\", Arg::Required, \"  --backend, -b  \\t\\tChoose a backend (Storm=St*arcr*ft1/Br**dwar;Casc=Remastered;Breeze=Folder)\" },\n  {\n    UNKNOWN, 0, \"\", \"\", option::Arg::None,\n    \"\\narchive \\t\\tDestination to the archive (mpq, casc or dummy folder) based on backend.\\n\"\n    \"\\ndestination-directory \\t\\tWhere to save the extracted file with same relative path.\\n\"\n\n  },\n  { 0, 0, 0, 0, 0, 0 }\n};\n\nint parseOptions(int argc, const char **argv)\n{\n  argc -= (argc > 0);\n  argv += (argc > 0); // skip program name argv[0] if present\n  option::Stats stats(usage, argc, argv);\n  std::unique_ptr<option::Option[]> options(new option::Option[stats.options_max]), buffer(new option::Option[stats.buffer_max]);\n  option::Parser parse(usage, argc, argv, options.get(), buffer.get());\n\n  if (parse.error())\n    exit(0);\n\n  if (options[HELP])\n  {\n    option::printUsage(std::cout, usage);\n    exit(0);\n  }\n\n  if ( options[PRETTY].count() > 0 )\n  {\n    if (string(options[PRETTY].arg) == \"yes\")\n    {\n      pretty = true;\n    }\n    else if (string(options[PRETTY].arg) == \"no\")\n    {\n      pretty = false;\n    }\n  }\n\n  if(options[BACKEND].count() > 0)\n  {\n    backend = options[BACKEND].arg;\n  }\n  else\n  {\n    cerr << \"Error: 'backend' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  // parse options\n\n  for (option::Option *opt = options[UNKNOWN]; opt; opt = opt->next())\n    std::cout << \"Unknown option: \" << opt->name << \"\\n\";\n\n  for (int i = 0; i < parse.nonOptionsCount(); ++i)\n  {\n    switch (i)\n    {\n    case 0:\n      //cerr << \"archive #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      archive = parse.nonOption(i);\n      break;\n    case 1:\n      //cerr << \"destination-directory #\" << i << \": \" << parse.nonOption(i) << \"\\n\";\n      destination_directory = parse.nonOption(i);\n      break;\n    default:\n      break;\n    }\n  }\n\n  if (archive.empty())\n  {\n    cerr << \"Error: 'archive' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  if (destination_directory.empty())\n  {\n    cerr << \"Error: 'destination_directory' not given!\" << endl << endl;\n    option::printUsage(std::cout, usage);\n    exit(1);\n  }\n\n  return 0;\n}\n\nvoid saveJson(json &j, const std::string &file, bool pretty)\n{\n  std::ofstream filestream(file);\n\n  if(pretty)\n  {\n    filestream << std::setw(4) << j;\n  }\n  else\n  {\n    filestream << j;\n  }\n}\n\nint main(int argc, const char **argv)\n{\n#ifdef HAVE_LOG4CXX\n  if (FileExists(\"logging.prop\"))\n  {\n    log4cxx::PropertyConfigurator::configure(\"logging.prop\");\n  }\n  else\n  {\n    logger.off();\n  }\n#endif // HAVE_LOG4CXX\n\n  parseOptions(argc, argv);\n  CheckPath(destination_directory);\n\n  bool archive_exists = FileExists(archive);\n  if(!archive_exists)\n  {\n    cerr << \"archive not existing - exit!\" << endl;\n    exit(1);\n  }\n\n  // read in the json file\n  std::ifstream json_file(pacman::searchFile(\"dataset/units.json\"));\n  json units_json; //create unitiialized json object\n  json_file >> units_json; // initialize json object with what was read from file\n\n  shared_ptr<Hurricane> hurricane;\n\n  if(to_lower(backend) == \"breeze\")\n  {\n    hurricane = make_shared<Breeze>(archive);\n  }\n  else if(to_lower(backend) == \"storm\")\n  {\n    hurricane = make_shared<Storm>(archive);\n  }\n  else if(to_lower(backend) == \"casc\")\n  {\n#ifdef HAVE_CASC\n    if(CheckCASCDataFolder(archive))\n    {\n      hurricane = make_shared<Casc>(archive);\n    }\n    else\n    {\n      cerr << \"Error: 'archive' is not a CASC archive!\" << endl;\n    }\n#else\n    cerr << \"Error: No CASC support compiled into sauwetter!\" << endl;\n    exit(1);\n#endif\n  }\n\n  dat::DataHub datahub(hurricane);\n\n  Storage jsonStorage;\n  jsonStorage.setDataPath(destination_directory);\n\n  //UnitsJsonExporter unitsjsonexporter(datahub);\n  for(auto &array : units_json)\n  {\n    string id_string = array.at(\"name\");\n    int id = array.at(\"id\");\n    //unitsjsonexporter.exportUnit(id, id_string);\n\n    Unit unit(datahub, id, id_string);\n\n    json j_unit(unit);\n\n    saveJson(j_unit, jsonStorage(id_string + \".json\"), pretty);\n  }\n\n  /*for(unsigned int i = 0; i < datahub.images->grp()->size(); i++)\n  {\n    Image image(datahub, i);\n\n    json j_image(image);\n\n    saveJson(j_image, jsonStorage(image.getIDString() + \".json\"), pretty);\n  }*/\n\n  SCJsonExporter scjsonexporter(datahub);\n\n  json j_unit_dat = scjsonexporter.export_unit_dat();\n  saveJson(j_unit_dat, jsonStorage(\"units_dat.json\"), pretty);\n\n  json j_orders_dat = scjsonexporter.export_orders_dat();\n  saveJson(j_orders_dat, jsonStorage(\"orders_dat.json\"), pretty);\n\n  json j_weapons_dat = scjsonexporter.export_weapons_dat();\n  saveJson(j_weapons_dat, jsonStorage(\"weapons_dat.json\"), pretty);\n\n  json j_flingy_dat = scjsonexporter.export_flingy_dat();\n  saveJson(j_flingy_dat, jsonStorage(\"flingy_dat.json\"), pretty);\n\n  json j_sprites_dat = scjsonexporter.export_sprites_dat();\n  saveJson(j_sprites_dat, jsonStorage(\"sprites_dat.json\"), pretty);\n\n  json j_images_dat = scjsonexporter.export_images_dat();\n  saveJson(j_images_dat, jsonStorage(\"images_dat.json\"), pretty);\n\n  json j_sfxdata_dat = scjsonexporter.export_sfxdata_dat();\n  saveJson(j_sfxdata_dat, jsonStorage(\"sfxdata_dat.json\"), pretty);\n\n  json j_portdata_dat = scjsonexporter.export_portdata_dat();\n  saveJson(j_portdata_dat, jsonStorage(\"portdata_dat.json\"), pretty);\n\n  json j_upgrades_dat = scjsonexporter.export_upgrades_dat();\n  saveJson(j_upgrades_dat, jsonStorage(\"upgrades_dat.json\"), pretty);\n\n  json j_techdata_dat = scjsonexporter.export_techdata_dat();\n  saveJson(j_techdata_dat, jsonStorage(\"techdata_dat.json\"), pretty);\n\n  json j_mapdata_dat = scjsonexporter.export_mapdata_dat();\n  saveJson(j_mapdata_dat, jsonStorage(\"mapdata_dat.json\"), pretty);\n\n  // export all the .tbl ->\n\n  json j_images_tbl = scjsonexporter.export_file_tbl(datahub.images_tbl_vec);\n  saveJson(j_images_tbl, jsonStorage(\"images_tbl.json\"), pretty);\n\n  json j_sfxdata_tbl = scjsonexporter.export_file_tbl(datahub.sfxdata_tbl_vec);\n  saveJson(j_sfxdata_tbl, jsonStorage(\"sfxdata_tbl.json\"), pretty);\n\n  json j_portdata_tbl = scjsonexporter.export_file_tbl(datahub.portdata_tbl_vec);\n  saveJson(j_portdata_tbl, jsonStorage(\"portdata_tbl.json\"), pretty);\n\n  json j_mapdata_tbl = scjsonexporter.export_file_tbl(datahub.mapdata_tbl_vec);\n  saveJson(j_mapdata_tbl, jsonStorage(\"mapdata_tbl.json\"), pretty);\n\n  /// save all the the stat_txt.tbl parts...\n\n\n  json stat_txt_tbl = scjsonexporter.export_file_tbl(datahub.stat_txt_tbl_vec);\n  saveJson(stat_txt_tbl, jsonStorage(\"stat_txt_tbl.json\"), pretty);\n\n  /*json stat_txt_units_tbl = scjsonexporter.export_file_tbl(datahub.stat_txt_units_tbl_vec);\n  saveJson(stat_txt_units_tbl, jsonStorage(\"stat_txt_units_tbl.json\"), pretty);\n\n  json stat_txt_weapons_tbljson = scjsonexporter.export_file_tbl(datahub.stat_txt_weapons_tbl_vec);\n  saveJson(stat_txt_weapons_tbljson, jsonStorage(\"stat_txt_weapons_tbl.json\"), pretty);\n\n  json stat_txt_error_messages_tbl = scjsonexporter.export_file_tbl(datahub.stat_txt_error_messages_tbl_vec);\n  saveJson(stat_txt_error_messages_tbl, jsonStorage(\"stat_txt_error_messages_tbl.json\"), pretty);\n\n  json stat_txt_upgrades_tbl = scjsonexporter.export_file_tbl(datahub.stat_txt_upgrades_tbl_vec);\n  saveJson(stat_txt_upgrades_tbl, jsonStorage(\"stat_txt_upgrades_tbl.json\"), pretty);\n\n  json stat_txt_orders_tbl = scjsonexporter.export_file_tbl(datahub.stat_txt_orders_tbl_vec);\n  saveJson(stat_txt_orders_tbl, jsonStorage(\"stat_txt_orders_tbl.json\"), pretty);\n\n  json stat_txt_techdata_tbl = scjsonexporter.export_file_tbl(datahub.stat_txt_techdata_tbl_vec);\n  saveJson(stat_txt_techdata_tbl, jsonStorage(\"stat_txt_techdata_tbl.json\"), pretty);*/\n\n  cerr << \"Application finished!\" << endl;\n\n  return 0;\n}\n"
  },
  {
    "path": "tools/scdat2json/to_json.cpp",
    "content": "#include \"to_json.h\"\n#include \"StringUtil.h\"\n\n#include <iostream>\n\nusing namespace std;\nusing namespace dat;\n\n\n\nvoid to_json(json &j, units_dat_t::hit_points_type_t *t)\n{\n  j = json{ {\"hitpoints\", t->hitpoints()} };\n}\n\nvoid to_json(json &j, units_dat_t::special_ability_flags_type_t *t)\n{\n  j = json\n  {\n    {\"building\", t->building()},\n    {\"addon\", t->addon()},\n    {\"flyer\", t->flyer()},\n    {\"resourceminer\", t->resourceminer()},\n    {\"subunit\", t->subunit()},\n    {\"flyingbuilding\", t->flyingbuilding()},\n    {\"hero\", t->hero()},\n    {\"regenerate\", t->regenerate()},\n    {\"animatedidle\", t->animatedidle()},\n    {\"cloakable\", t->cloakable()},\n    {\"twounitsinoneegg\", t->twounitsinoneegg()},\n    {\"singleentity\", t->singleentity()},\n    {\"resourcedepot\", t->resourcedepot()},\n    {\"resourcecontainter\", t->resourcecontainter()},\n    {\"robotic\", t->robotic()},\n    {\"detector\", t->detector()},\n    {\"organic\", t->organic()},\n    {\"requirescreep\", t->requirescreep()},\n    {\"unused\", t->unused()},\n    {\"requirespsi\", t->requirespsi()},\n    {\"burrowable\", t->burrowable()},\n    {\"spellcaster\", t->spellcaster()},\n    {\"permanentcloak\", t->permanentcloak()},\n    {\"pickupitem\", t->pickupitem()},\n    {\"ignoresupplycheck\", t->ignoresupplycheck()},\n    {\"usemediumoverlays\", t->usemediumoverlays()},\n    {\"uselargeoverlays\", t->uselargeoverlays()},\n    {\"battlereactions\", t->battlereactions()},\n    {\"fullautoattack\", t->fullautoattack()},\n    {\"invincible\", t->invincible()},\n    {\"mechanical\", t->mechanical()},\n    {\"producesunits\", t->producesunits()}\n  };\n}\n\nvoid to_json(json &j, units_dat_t::staredit_placement_box_type_t *t)\n{\n  j = json{ {\"width\", t->width()}, {\"height\", t->height()} };\n}\n\nvoid to_json(json &j, units_dat_t::addon_position_type_t *t)\n{\n  j = json{ {\"horizontal\", t->horizontal()}, {\"vertical\", t->vertical()} };\n}\n\nvoid to_json(json &j, units_dat_t::unit_dimension_type_t *t)\n{\n  j = json{ {\"left\", t->left()}, {\"up\", t->up()}, {\"right\", t->right()}, {\"down\", t->down()} };\n}\n\nvoid to_json(json &j, units_dat_t::staredit_group_flags_type_t *t)\n{\n  j = json\n  {\n    {\"zerg\", t->zerg()},\n    {\"terran\", t->terran()},\n    {\"protoss\", t->protoss()},\n    {\"men\", t->men()},\n    {\"building\", t->building()},\n    {\"factory\", t->factory()},\n    {\"independent\", t->independent()},\n    {\"neutral\", t->neutral()}\n  };\n}\n\nvoid to_json(json &j, units_dat_t::staredit_availability_flags_type_t *t)\n{\n  j = json\n  {\n    {\"non_neutral\", t->non_neutral()},\n    {\"unit_listing\", t->unit_listing()},\n    {\"mission_briefing\", t->mission_briefing()},\n    {\"player_settings\", t->player_settings()},\n    {\"all_races\", t->all_races()},\n    {\"set_doodad_state\", t->set_doodad_state()},\n    {\"non_location_triggers\", t->non_location_triggers()},\n    {\"unit_hero_settings\", t->unit_hero_settings()},\n    {\"location_triggers\", t->location_triggers()},\n    {\"brood_war_only\", t->brood_war_only()}\n  };\n}\n\nNLOHMANN_JSON_SERIALIZE_ENUM(iscript_bin_t::opcode_t,\n{\n  {iscript_bin_t::opcode_t::OPCODE_PLAYFRAM, \"playfram\"},\n  {iscript_bin_t::opcode_t::OPCODE_PLAYFRAMTILE, \"playframtile\"},\n  {iscript_bin_t::opcode_t::OPCODE_SETHORPOS, \"sethorpos\"},\n  {iscript_bin_t::opcode_t::OPCODE_SETVERTPOS, \"setvertpos\"},\n  {iscript_bin_t::opcode_t::OPCODE_SETPOS, \"setpos\"},\n  {iscript_bin_t::opcode_t::OPCODE_WAIT, \"wait\"},\n  {iscript_bin_t::opcode_t::OPCODE_WAITRAND, \"waitrand\"},\n  {iscript_bin_t::opcode_t::OPCODE_GOTO, \"goto\"},\n  {iscript_bin_t::opcode_t::OPCODE_IMGOL, \"imgol\"},\n  {iscript_bin_t::opcode_t::OPCODE_IMGUL, \"imgul\"},\n  {iscript_bin_t::opcode_t::OPCODE_IMGOLORIG, \"imgolorig\"},\n  {iscript_bin_t::opcode_t::OPCODE_SWITCHUL, \"switchul\"},\n  {iscript_bin_t::opcode_t::OPCODE_UNKNOWN_0C, \"unknown_0c\"},\n  {iscript_bin_t::opcode_t::OPCODE_IMGOLUSELO, \"imgoluselo\"},\n  {iscript_bin_t::opcode_t::OPCODE_IMGULUSELO, \"imguluselo\"},\n  {iscript_bin_t::opcode_t::OPCODE_SPROL, \"sprol\"},\n  {iscript_bin_t::opcode_t::OPCODE_HIGHSPROL, \"highsprol\"},\n  {iscript_bin_t::opcode_t::OPCODE_LOWSPRUL, \"lowsprul\"},\n  {iscript_bin_t::opcode_t::OPCODE_UFLUNSTABLE, \"uflunstable\"},\n  {iscript_bin_t::opcode_t::OPCODE_SPRULUSELO, \"spruluselo\"},\n  {iscript_bin_t::opcode_t::OPCODE_SPRUL, \"sprul\"},\n  {iscript_bin_t::opcode_t::OPCODE_SPROLUSELO, \"sproluselo\"},\n  {iscript_bin_t::opcode_t::OPCODE_END, \"end\"},\n  {iscript_bin_t::opcode_t::OPCODE_SETFLIPSTATE, \"setflipstate\"},\n  {iscript_bin_t::opcode_t::OPCODE_PLAYSND, \"playsnd\"},\n  {iscript_bin_t::opcode_t::OPCODE_PLAYSNDRAND, \"playsndrand\"},\n  {iscript_bin_t::opcode_t::OPCODE_PLAYSNDBTWN, \"playsndbtwn\"},\n  {iscript_bin_t::opcode_t::OPCODE_DOMISSILEDMG, \"domissiledmg\"},\n  {iscript_bin_t::opcode_t::OPCODE_ATTACKMELEE, \"attackmelee\"},\n  {iscript_bin_t::opcode_t::OPCODE_FOLLOWMAINGRAPHIC, \"followmaingraphic\"},\n  {iscript_bin_t::opcode_t::OPCODE_RANDCONDJMP, \"randcondjmp\"},\n  {iscript_bin_t::opcode_t::OPCODE_TURNCCWISE, \"turnccwise\"},\n  {iscript_bin_t::opcode_t::OPCODE_TURNCWISE, \"turncwise\"},\n  {iscript_bin_t::opcode_t::OPCODE_TURN1CWISE, \"turn1cwise\"},\n  {iscript_bin_t::opcode_t::OPCODE_TURNRAND, \"turnrand\"},\n  {iscript_bin_t::opcode_t::OPCODE_SETSPAWNFRAME, \"setspawnframe\"},\n  {iscript_bin_t::opcode_t::OPCODE_SIGORDER, \"sigorder\"},\n  {iscript_bin_t::opcode_t::OPCODE_ATTACKWITH, \"attackwith\"},\n  {iscript_bin_t::opcode_t::OPCODE_ATTACK, \"attack\"},\n  {iscript_bin_t::opcode_t::OPCODE_CASTSPELL, \"castspell\"},\n  {iscript_bin_t::opcode_t::OPCODE_USEWEAPON, \"useweapon\"},\n  {iscript_bin_t::opcode_t::OPCODE_MOVE, \"move\"},\n  {iscript_bin_t::opcode_t::OPCODE_GOTOREPEATATTK, \"gotorepeatattk\"},\n  {iscript_bin_t::opcode_t::OPCODE_ENGFRAME, \"engframe\"},\n  {iscript_bin_t::opcode_t::OPCODE_ENGSET, \"engset\"},\n  {iscript_bin_t::opcode_t::OPCODE_UNKNOWN_2D, \"unknown_2d\"},\n  {iscript_bin_t::opcode_t::OPCODE_NOBRKCODESTART, \"nobrkcodestart\"},\n  {iscript_bin_t::opcode_t::OPCODE_NOBRKCODEEND, \"nobrkcodeend\"},\n  {iscript_bin_t::opcode_t::OPCODE_IGNOREREST, \"ignorerest\"},\n  {iscript_bin_t::opcode_t::OPCODE_ATTKSHIFTPROJ, \"attkshiftproj\"},\n  {iscript_bin_t::opcode_t::OPCODE_TMPRMGRAPHICSTART, \"tmprmgraphicstart\"},\n  {iscript_bin_t::opcode_t::OPCODE_TMPRMGRAPHICEND, \"tmprmgraphicend\"},\n  {iscript_bin_t::opcode_t::OPCODE_SETFLDIRECT, \"setfldirect\"},\n  {iscript_bin_t::opcode_t::OPCODE_CALL, \"call\"},\n  {iscript_bin_t::opcode_t::OPCODE_RETURN, \"return\"},\n  {iscript_bin_t::opcode_t::OPCODE_SETFLSPEED, \"setflspeed\"},\n  {iscript_bin_t::opcode_t::OPCODE_CREATEGASOVERLAYS, \"creategasoverlays\"},\n  {iscript_bin_t::opcode_t::OPCODE_PWRUPCONDJMP, \"pwrupcondjmp\"},\n  {iscript_bin_t::opcode_t::OPCODE_TRGTRANGECONDJMP, \"trgtrangecondjmp\"},\n  {iscript_bin_t::opcode_t::OPCODE_TRGTARCCONDJMP, \"trgtarccondjmp\"},\n  {iscript_bin_t::opcode_t::OPCODE_CURDIRECTCONDJMP, \"curdirectcondjmp\"},\n  {iscript_bin_t::opcode_t::OPCODE_IMGULNEXTID, \"imgulnextid\"},\n  {iscript_bin_t::opcode_t::OPCODE_UNKNOWN_3E, \"unknown_3e\"},\n  {iscript_bin_t::opcode_t::OPCODE_LIFTOFFCONDJMP, \"liftoffcondjmp\"},\n  {iscript_bin_t::opcode_t::OPCODE_WARPOVERLAY, \"warpoverlay\"},\n  {iscript_bin_t::opcode_t::OPCODE_ORDERDONE, \"orderdone\"},\n  {iscript_bin_t::opcode_t::OPCODE_GRDSPROL, \"grdsprol\"},\n  {iscript_bin_t::opcode_t::OPCODE_UNKNOWN_43, \"unknown_43\"},\n  {iscript_bin_t::opcode_t::OPCODE_DOGRDDAMAGE, \"dogrddamage\"},\n})\n\nvoid to_json(json &j, iscript_bin_t::u2_type_t *u2)\n{\n  j = json(to_string(u2->value()));\n}\n\nvoid to_json(json &j, iscript_bin_t::u1_type_t *u1)\n{\n  j = json(to_string(u1->value()));\n}\n\nvoid to_json(json &j, iscript_bin_t::pos_type_t *pos)\n{\n  j[\"x\"] = json(to_string(pos->x()));\n  j[\"y\"] = json(to_string(pos->y()));\n}\n\nvoid to_json(json &j, iscript_bin_t::playsndbtwn_type_t *snd)\n{\n  j[\"firstsound\"] = json(to_string(snd->firstsound()));\n  j[\"lastsound\"] = json(to_string(snd->lastsound()));\n}\n\nvoid to_json(json &j, iscript_bin_t::trgcondjmp_type_t *trgcondjmp)\n{\n  j[\"angle1\"] = json(to_string(trgcondjmp->angle1()));\n  j[\"angle2\"] = json(to_string(trgcondjmp->angle2()));\n  j[\"labelname\"] = json(to_string(trgcondjmp->labelname()));\n}\n\nvoid to_json(json &j, iscript_bin_t::imgl_type_t *imgl)\n{\n  j[\"image\"] = json(to_string(imgl->image()));\n  j[\"pos\"] = json(imgl->pos());\n}\n\nvoid to_json(json &j, iscript_bin_t::sprl_type_t *sprl)\n{\n  j[\"sprite\"] = json(to_string(sprl->sprite()));\n  j[\"pos\"] = json(sprl->pos());\n}\n\nvoid to_json(json &j, iscript_bin_t::trgtrangecondjmp_type_t *ttcj)\n{\n  j[\"distance\"] = json(to_string(ttcj->distance()));\n  j[\"labelname\"] = json(ttcj->labelname());\n}\n\nvoid to_json(json &j, iscript_bin_t::randcondjmp_type_t *rcj)\n{\n  j[\"randchance\"] = json(to_string(rcj->randchance()));\n  j[\"labelname\"] = json(rcj->labelname());\n}\n\nvoid to_json(json &j, iscript_bin_t::playsounds_type_t *ps)\n{\n  j = json::array();\n\n  for(auto sound : *(ps->sound()))\n  {\n    j.push_back(to_string(sound));\n  }\n}\n\nvoid to_json(json &j, iscript_bin_t::sprov_type_t *sprov)\n{\n  j[\"sprite\"] = json(to_string(sprov->sprite()));\n  j[\"overlay\"] = json(to_string(sprov->overlay()));\n}\n\nvoid to_json(json &j, iscript_bin_t::waitrand_type_t *wr)\n{\n  j[\"ticks1\"] = json(to_string(wr->ticks1()));\n  j[\"ticks2\"] = json(to_string(wr->ticks2()));\n}\n\n\nvoid to_json(json &j, iscript_bin_t::opcode_type_t *opcode)\n{\n  iscript_bin_t::opcode_t opcode_code_enum = opcode->code();\n  string opcode_code_name = json(opcode_code_enum);\n\n  switch (opcode_code_enum)\n  {\n  case iscript_bin_t::OPCODE_TURN1CWISE:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_IMGOLORIG:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_UNKNOWN_3E:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_SIGORDER:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_ENGFRAME:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_TURNCCWISE:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_UNKNOWN_2D:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_END:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_PLAYFRAM:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_TMPRMGRAPHICSTART:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_IMGULNEXTID:\n  {\n    iscript_bin_t::pos_type_t *casted_args = static_cast<iscript_bin_t::pos_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_PLAYSNDBTWN:\n  {\n    iscript_bin_t::playsndbtwn_type_t *casted_args = static_cast<iscript_bin_t::playsndbtwn_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_UNKNOWN_0C:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_ENGSET:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SWITCHUL:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_TRGTARCCONDJMP:\n  {\n    iscript_bin_t::trgcondjmp_type_t *casted_args = static_cast<iscript_bin_t::trgcondjmp_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SETFLIPSTATE:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SETPOS:\n  {\n    iscript_bin_t::pos_type_t *casted_args = static_cast<iscript_bin_t::pos_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_IMGOLUSELO:\n  {\n    iscript_bin_t::imgl_type_t *casted_args = static_cast<iscript_bin_t::imgl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_LOWSPRUL:\n  {\n    iscript_bin_t::sprl_type_t *casted_args = static_cast<iscript_bin_t::sprl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_TURNRAND:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_DOMISSILEDMG:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_HIGHSPROL:\n  {\n    iscript_bin_t::sprl_type_t *casted_args = static_cast<iscript_bin_t::sprl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SETFLSPEED:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_USEWEAPON:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_WARPOVERLAY:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_GOTOREPEATATTK:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_UFLUNSTABLE:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_ORDERDONE:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_TRGTRANGECONDJMP:\n  {\n    iscript_bin_t::trgtrangecondjmp_type_t *casted_args = static_cast<iscript_bin_t::trgtrangecondjmp_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_RETURN:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_CASTSPELL:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_FOLLOWMAINGRAPHIC:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_RANDCONDJMP:\n  {\n    iscript_bin_t::randcondjmp_type_t *casted_args = static_cast<iscript_bin_t::randcondjmp_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_NOBRKCODEEND:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_CALL:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_NOBRKCODESTART:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_WAIT:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SPROL:\n  {\n    iscript_bin_t::sprl_type_t *casted_args = static_cast<iscript_bin_t::sprl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_TMPRMGRAPHICEND:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_CREATEGASOVERLAYS:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SETFLDIRECT:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_PWRUPCONDJMP:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SETHORPOS:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SPRULUSELO:\n  {\n    iscript_bin_t::sprl_type_t *casted_args = static_cast<iscript_bin_t::sprl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SPRUL:\n  {\n    iscript_bin_t::sprl_type_t *casted_args = static_cast<iscript_bin_t::sprl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_GRDSPROL:\n  {\n    iscript_bin_t::sprl_type_t *casted_args = static_cast<iscript_bin_t::sprl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_MOVE:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_GOTO:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_IMGUL:\n  {\n    iscript_bin_t::imgl_type_t *casted_args = static_cast<iscript_bin_t::imgl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_PLAYFRAMTILE:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_ATTKSHIFTPROJ:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_LIFTOFFCONDJMP:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_IMGOL:\n  {\n    iscript_bin_t::imgl_type_t *casted_args = static_cast<iscript_bin_t::imgl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_IMGULUSELO:\n  {\n    iscript_bin_t::imgl_type_t *casted_args = static_cast<iscript_bin_t::imgl_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_ATTACK:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_ATTACKMELEE:\n  {\n    iscript_bin_t::playsounds_type_t *casted_args = static_cast<iscript_bin_t::playsounds_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SPROLUSELO:\n  {\n    iscript_bin_t::sprov_type_t *casted_args = static_cast<iscript_bin_t::sprov_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_PLAYSNDRAND:\n  {\n    iscript_bin_t::playsounds_type_t *casted_args = static_cast<iscript_bin_t::playsounds_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_IGNOREREST:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_PLAYSND:\n  {\n    iscript_bin_t::u2_type_t *casted_args = static_cast<iscript_bin_t::u2_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_UNKNOWN_43:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_SETVERTPOS:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_DOGRDDAMAGE:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  case iscript_bin_t::OPCODE_WAITRAND:\n  {\n    iscript_bin_t::waitrand_type_t *casted_args = static_cast<iscript_bin_t::waitrand_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_TURNCWISE:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_CURDIRECTCONDJMP:\n  {\n    iscript_bin_t::trgcondjmp_type_t *casted_args = static_cast<iscript_bin_t::trgcondjmp_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_SETSPAWNFRAME:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  case iscript_bin_t::OPCODE_ATTACKWITH:\n  {\n    iscript_bin_t::u1_type_t *casted_args = static_cast<iscript_bin_t::u1_type_t *>(opcode->args());\n    j[opcode_code_name] = json(casted_args);\n    break;\n  }\n  default:\n  {\n    j[opcode_code_name] = nullptr;\n    break;\n  }\n  }\n\n}\n\nvoid to_json(json &j, std::vector<iscript_bin_t::opcode_type_t *> opcode_vec)\n{\n  j = json::array();\n\n  for (auto opcode : opcode_vec)\n  {\n    j.push_back(opcode);\n  }\n}\n\nnamespace dat\n{\n\nvoid to_json(json &j, TblEntry t)\n{\n  j = json\n  {\n    {\"name1\", t.name1()},\n    {\"name2\", t.name2()},\n    {\"name3\", t.name3()},\n    {\"shortcut_pos\", t.shortcut_pos()},\n    {\"shortcut\", t.shortcut()}\n  };\n}\n\nvoid to_json(json &j, Upgrade u)\n{\n  j[\"id\"] = json(u.id());\n  j[\"mineral_cost_base\"] = json(u.mineral_cost_base());\n  j[\"mineral_cost_factor\"] = json(u.mineral_cost_factor());\n  j[\"vespene_cost_base\"] = json(u.vespene_cost_base());\n  j[\"vespene_cost_factor\"] = json(u.vespene_cost_factor());\n  j[\"research_time_base\"] = json(u.research_time_base());\n  j[\"research_time_factor\"] = json(u.research_time_factor());\n  j[\"unknown6\"] = json(u.unknown6());\n  j[\"icon\"] = json(u.icon());\n  j[\"label\"] = json(u.label());\n  j[\"label_tbl\"] = json(u.label_tbl());\n  j[\"race\"] = json(u.race());\n  j[\"max_repeats\"] = json(u.max_repeats());\n\n  if (u.has_broodwar_flag())\n  {\n    j[\"broodwar_flags\"] = json(u.broodwar_flags());\n  }\n}\n\nvoid to_json(json &j, Order o)\n{\n  j[\"id\"] = json(o.id());\n  j[\"label\"] = json(o.label());\n  j[\"label_tbl\"] = json(o.label_tbl());\n  j[\"use_weapon_targeting\"] = json(o.use_weapon_targeting());\n  j[\"unknown2\"] = json(o.unknown2());\n  j[\"unknown3\"] = json(o.unknown3());\n  j[\"unknown4\"] = json(o.unknown4());\n  j[\"unknown5\"] = json(o.unknown5());\n  j[\"interruptible\"] = json(o.interruptible());\n  j[\"unknown7\"] = json(o.unknown7());\n  j[\"queueable\"] = json(o.queueable());\n  j[\"unknown9\"] = json(o.unknown9());\n  j[\"unknown10\"] = json(o.unknown10());\n  j[\"unknown11\"] = json(o.unknown11());\n  j[\"unknown12\"] = json(o.unknown12());\n\n  j[\"targeting\"] = json(o.targeting());\n  try\n  {\n    j[\"targeting_obj\"] = json(o.targeting_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"energy\"] = json(o.energy());\n  try\n  {\n    j[\"energy_obj\"] = json(o.energy_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"animation\"] = json(o.animation());\n  j[\"highlight\"] = json(o.highlight());\n  j[\"unknown17\"] = json(o.unknown17());\n  j[\"obscured_order\"] = json(o.obscured_order());\n  //j[\"obscured_order_obj\"] = json(o.obscured_order_obj());\n}\n\nvoid to_json(json &j, Techdata t)\n{\n  j[\"id\"] = json(t.id());\n  j[\"mineral_cost\"] = json(t.mineral_cost());\n  j[\"vespene_cost\"] = json(t.vespene_cost());\n  j[\"research_time\"] = json(t.research_time());\n  j[\"energy_required\"] = json(t.energy_required());\n  j[\"unknown4\"] = json(t.unknown4());\n  j[\"icon\"] = json(t.icon());\n  j[\"label\"] = json(t.label());\n  j[\"race\"] = json(t.race());\n  j[\"unused\"] = json(t.unused());\n\n  if (t.has_broodwar_flag())\n  {\n    j[\"broodwar_flag\"] = json(t.broodwar_flag());\n  }\n}\n\nvoid to_json(json &j, Weapon w)\n{\n  j[\"id\"] = json(w.id());\n  j[\"label\"] = json(w.label());\n  j[\"label_tbl\"] = json(w.label_tbl());\n  j[\"graphics\"] = json(w.graphics());\n  j[\"graphics_obj\"] = json(w.graphics_obj());\n  j[\"explosion\"] = json(w.explosion());\n  j[\"target_flags\"] = json(w.target_flags());\n  j[\"minimum_range\"] = json(w.minimum_range());\n  j[\"maximum_range\"] = json(w.maximum_range());\n  j[\"damage_upgrade\"] = json(w.damage_upgrade());\n  j[\"damage_upgrade_obj\"] = json(w.damage_upgrade_obj());\n  j[\"weapon_type\"] = json(w.weapon_type());\n  j[\"weapon_behaviour\"] = json(w.weapon_behaviour());\n  j[\"remove_after\"] = json(w.remove_after());\n  j[\"explosive_type\"] = json(w.explosive_type());\n  j[\"inner_splash_range\"] = json(w.inner_splash_range());\n  j[\"medium_splash_range\"] = json(w.medium_splash_range());\n  j[\"outer_splash_range\"] = json(w.outer_splash_range());\n  j[\"damage_amount\"] = json(w.damage_amount());\n  j[\"damage_bonus\"] = json(w.damage_bonus());\n  j[\"weapon_cooldown\"] = json(w.weapon_cooldown());\n  j[\"damage_factor\"] = json(w.damage_factor());\n  j[\"attack_angle\"] = json(w.attack_angle());\n  j[\"launch_spin\"] = json(w.launch_spin());\n  j[\"x_offset\"] = json(w.x_offset());\n  j[\"y_offset\"] = json(w.y_offset());\n  j[\"error_message\"] = json(w.error_message());\n  j[\"error_message_tbl\"] = json(w.error_message_tbl());\n  j[\"icon\"] = json(w.icon());\n\n}\n\nvoid to_json(json &j, Sfx s)\n{\n  j = json\n  {\n    {\"id\", s.id()},\n    {\"sound_file\", s.sound_file()},\n    {\"sound_file_tbl\", s.sound_file_tbl()},\n    {\"unknown1\", s.unknown1()},\n    {\"unknown2\", s.unknown2()},\n    {\"unknown3\", s.unknown3()},\n    {\"unknown4\", s.unknown4()}\n  };\n}\n\nvoid to_json(json &j, Portrait p)\n{\n  j = json\n  {\n    {\"id\", p.id()},\n    {\"video_idle\", p.video_idle()},\n    {\"video_idle_tbl\", p.video_idle_tbl()},\n    {\"video_talking\", p.video_talking()},\n    {\"video_talking_tbl\", p.video_talking_tbl()},\n    {\"change_idle\", p.change_idle()},\n    {\"change_talking\", p.change_talking()},\n    {\"unknown1_idle\", p.unknown1_idle()},\n    {\"unknown1_talking\", p.unknown1_talking()}\n  };\n}\n\nNLOHMANN_JSON_SERIALIZE_ENUM(IScript::AnimationType,\n{\n  {IScript::AnimationType::Init, \"Init\"},\n  {IScript::AnimationType::Death, \"Death\"},\n  {IScript::AnimationType::GndAttkInit, \"GndAttkInit\"},\n  {IScript::AnimationType::AirAttkInit, \"AirAttkInit\"},\n  {IScript::AnimationType::Unused1, \"Unused1\"},\n  {IScript::AnimationType::GndAttkRpt, \"GndAttkRpt\"},\n  {IScript::AnimationType::AirAttkRpt, \"AirAttkRpt\"},\n  {IScript::AnimationType::CastSpell, \"CastSpell\"},\n  {IScript::AnimationType::GndAttkToIdle, \"GndAttkToIdle\"},\n  {IScript::AnimationType::AirAttkToIdle, \"AirAttkToIdle\"},\n  {IScript::AnimationType::Unused2, \"Unused2\"},\n  {IScript::AnimationType::Walking, \"Walking\"},\n  {IScript::AnimationType::WalkingToIdle, \"WalkingToIdle\"},\n  {IScript::AnimationType::SpecialState1, \"SpecialState1\"},\n  {IScript::AnimationType::SpecialState2, \"SpecialState2\"},\n  {IScript::AnimationType::AlmostBuilt, \"AlmostBuilt\"},\n  {IScript::AnimationType::Built, \"Built\"},\n  {IScript::AnimationType::Landing, \"Landing\"},\n  {IScript::AnimationType::LiftOff, \"LiftOff\"},\n  {IScript::AnimationType::IsWorking, \"IsWorking\"},\n  {IScript::AnimationType::WorkingToIdle, \"WorkingToIdle\"},\n  {IScript::AnimationType::WarpIn, \"WarpIn\"},\n  {IScript::AnimationType::Unused3, \"Unused3\"},\n  {IScript::AnimationType::StarEditInit, \"StarEditInit\"},\n  {IScript::AnimationType::Disable, \"Disable\"},\n  {IScript::AnimationType::Burrow, \"Burrow\"},\n  {IScript::AnimationType::UnBurrow, \"UnBurrow\"},\n  {IScript::AnimationType::Enable, \"Enable\"},\n})\n\nvoid to_json(json &j, IScript is)\n{\n  int animation_count = is.getAnimationCount();\n\n  for (int i = 0; i < animation_count; i++)\n  {\n    IScript::AnimationType anim_t = static_cast<IScript::AnimationType>(i);\n    string anim_name = json(anim_t);\n\n    std::vector<iscript_bin_t::opcode_type_t *> opcode_vec = is.getAnimationScript(i);\n\n    j[anim_name] = json(opcode_vec);\n  }\n}\n\nvoid to_json(json &j, Image i)\n{\n  j[\"id\"] = json(i.id());\n  j[\"grp\"] = json(i.grp());\n  j[\"grp_tbl\"] = json(i.grp_tbl());\n  j[\"gfx_turns\"] = json(i.gfx_turns());\n  j[\"clickable\"] = json(i.clickable());\n  j[\"use_full_iscript\"] = json(i.use_full_iscript());\n  j[\"draw_if_cloaked\"] = json(i.draw_if_cloaked());\n  j[\"draw_function\"] = json(i.draw_function());\n  j[\"remapping\"] = json(i.remapping());\n  j[\"iscript\"] = json(i.iscript());\n  j[\"iscript_obj\"] = json(i.iscript_obj());\n\n  j[\"shield_overlay\"] = json(i.shield_overlay());\n  try\n  {\n    j[\"shield_overlay_tbl\"] = json(i.shield_overlay_tbl());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"attack_overlay\"] = json(i.attack_overlay());\n  try\n  {\n    j[\"attack_overlay_tbl\"] = json(i.attack_overlay_tbl());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"damage_overlay\"] = json(i.damage_overlay());\n  try\n  {\n    j[\"damage_overlay_tbl\"] = json(i.damage_overlay_tbl());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"special_overlay\"] = json(i.special_overlay());\n  try\n  {\n    j[\"special_overlay_tbl\"] = json(i.special_overlay_tbl());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"landing_dust_overlay\"] = json(i.landing_dust_overlay());\n  try\n  {\n    j[\"landing_dust_overlay_tbl\"] = json(i.landing_dust_overlay_tbl());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n}\n\nvoid to_json(json &j, Sprite s)\n{\n  j[\"id\"] = json(s.id());\n  j[\"image\"] = json(s.image());\n  j[\"image_obj\"] = json(s.image_obj());\n\n  try\n  {\n    j[\"health_bar\"] = json(s.health_bar());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"unknown2\"] = json(s.unknown2());\n  j[\"is_visible\"] = json(s.is_visible());\n\n  try\n  {\n    j[\"select_circle_image_size\"] = json(s.select_circle_image_size());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  try\n  {\n    j[\"select_circle_vertical_pos\"] = json(s.select_circle_vertical_pos());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n}\n\nvoid to_json(json &j, Flingy f)\n{\n  j = json\n  {\n    {\"id\", f.id()},\n    {\"sprite\", f.sprite()},\n    {\"sprite_obj\", f.sprite_obj()},\n    {\"speed\", f.speed()},\n    {\"acceleration\", f.acceleration()},\n    {\"halt_distance\", f.halt_distance()},\n    {\"turn_radius\", f.turn_radius()},\n    {\"unused\", f.unused()},\n    {\"movement_control\", f.movement_control()}\n  };\n}\n\nvoid to_json(json &j, Unit u)\n{\n  j[\"id\"] = json(u.id());\n  j[\"id_string\"] = json(u.getIDString());\n  j[\"name_tbl\"] = json(u.name_tbl());\n  j[\"flingy\"] = json(u.flingy());\n  j[\"flingy_obj\"] = json(u.flingy_obj());\n  j[\"subunit1\"] = json(u.subunit1());\n\n  try\n  {\n    j[\"subunit1_obj\"] = json(u.subunit1_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"subunit2\"] = json(u.subunit2());\n\n  try\n  {\n    j[\"subunit2_obj\"] = json(u.subunit2_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  try\n  {\n    j[\"infestation\"] = json(u.infestation());\n    j[\"infestation_obj\"] = json(u.infestation_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  try\n  {\n    j[\"construction_animation\"] = json(u.construction_animation());\n    j[\"construction_animation_obj\"] = json(u.construction_animation_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"unit_direction\"] = json(u.unit_direction());\n  j[\"shield_enable\"] = json(u.shield_enable());\n  j[\"shield_amount\"] = json(u.shield_amount());\n  j[\"hitpoints\"] = json(u.hitpoints());\n  j[\"elevation_level\"] = json(u.elevation_level());\n  j[\"unknown\"] = json(u.unknown());\n  j[\"rank\"] = json(u.rank());\n  j[\"ai_computer_idle\"] = json(u.ai_computer_idle());\n  j[\"ai_computer_idle_obj\"] = json(u.ai_computer_idle_obj());\n  j[\"ai_human_idle\"] = json(u.ai_human_idle());\n  j[\"ai_human_idle_obj\"] = json(u.ai_human_idle_obj());\n  j[\"ai_return_to_idle\"] = json(u.ai_return_to_idle());\n  j[\"ai_return_to_idle_obj\"] = json(u.ai_return_to_idle_obj());\n  j[\"ai_attack_unit\"] = json(u.ai_attack_unit());\n  j[\"ai_attack_unit_obj\"] = json(u.ai_attack_unit_obj());\n  j[\"ai_attack_move\"] = json(u.ai_attack_move());\n  j[\"ai_attack_move_obj\"] = json(u.ai_attack_move_obj());\n\n  try\n  {\n    j[\"ground_weapon\"] = json(u.ground_weapon());\n    j[\"ground_weapon_obj\"] = json(u.ground_weapon_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  if (u.is_format_bw())\n  {\n    j[\"max_ground_hits\"] = json(u.max_ground_hits());\n  }\n\n  try\n  {\n    j[\"air_weapon\"] = json(u.air_weapon());\n    j[\"air_weapon_obj\"] = json(u.air_weapon_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  if (u.is_format_bw())\n  {\n    j[\"max_air_hits\"] = json(u.max_air_hits());\n  }\n\n  j[\"ai_internal\"] = json(u.ai_internal());\n  j[\"special_ability_flags\"] = json(u.special_ability_flags());\n  j[\"target_acquisition_range\"] = json(u.target_acquisition_range());\n  j[\"sight_range\"] = json(u.sight_range());\n  j[\"armor_upgrade\"] = json(u.armor_upgrade());\n  j[\"unit_size\"] = json(u.unit_size());\n  j[\"armor\"] = json(u.armor());\n  j[\"right_click_action\"] = json(u.right_click_action());\n\n  try\n  {\n    j[\"ready_sound\"] = json(u.ready_sound());\n    j[\"ready_sound_obj\"] = json(u.ready_sound_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  try\n  {\n    j[\"what_sound_start\"] = json(u.what_sound_start());\n    j[\"what_sound_end\"] = json(u.what_sound_end());\n    j[\"what_sound_obj\"] = json(u.what_sound_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  try\n  {\n    j[\"piss_sound_start\"] = json(u.piss_sound_start());\n    j[\"piss_sound_end\"] = json(u.piss_sound_end());\n    j[\"piss_sound_obj\"] = json(u.piss_sound_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  try\n  {\n    j[\"what_sound_start\"] = json(u.what_sound_start());\n    j[\"what_sound_end\"] = json(u.what_sound_end());\n    j[\"what_sound_obj\"] = json(u.what_sound_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  try\n  {\n    j[\"yes_sound_start\"] = json(u.yes_sound_start());\n    j[\"yes_sound_end\"] = json(u.yes_sound_end());\n    j[\"yes_sound_obj\"] = json(u.yes_sound_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"staredit_placement_box\"] = json(u.staredit_placement_box());\n\n  try\n  {\n    j[\"addon_position\"] = json(u.addon_position());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"unit_dimension\"] = json(u.unit_dimension());\n  j[\"portrait\"] = json(u.portrait());\n\n  try\n  {\n    j[\"portrait_obj\"] = json(u.portrait_obj());\n  }\n  catch (PropertyNotAvailableException &ex)\n  { /*it's fine, do nothing */ }\n\n  j[\"mineral_cost\"] = json(u.mineral_cost());\n  j[\"vespene_cost\"] = json(u.vespene_cost());\n  j[\"build_time\"] = json(u.build_time());\n  j[\"requirements\"] = json(u.requirements());\n  j[\"staredit_group_flags\"] = json(u.staredit_group_flags());\n  j[\"supply_required\"] = json(u.supply_required());\n  j[\"space_provided\"] = json(u.space_provided());\n  j[\"build_score\"] = json(u.build_score());\n  j[\"destroy_score\"] = json(u.destroy_score());\n  j[\"unit_map_string\"] = json(u.unit_map_string());\n\n  if (u.is_format_bw())\n  {\n    j[\"broodwar_flag\"] = json(u.broodwar_flag());\n  }\n\n  j[\"is_format_bw\"] = json(u.is_format_bw());\n}\n\n} /* namespace dat */\n"
  },
  {
    "path": "tools/scdat2json/to_json.h",
    "content": "/*\n * to_json.h\n *\n *      Author: Andreas Volz\n */\n\n#ifndef TO_JSON_H\n#define TO_JSON_H\n\n#include \"dat/DataHub.h\"\n#include \"dat/Unit.h\"\n\n// -> units_dat.ksy\n\nvoid to_json(json &j, units_dat_t::hit_points_type_t* t);\nvoid to_json(json &j, units_dat_t::special_ability_flags_type_t* t);\nvoid to_json(json &j, units_dat_t::staredit_placement_box_type_t* t);\nvoid to_json(json &j, units_dat_t::addon_position_type_t* t);\nvoid to_json(json &j, units_dat_t::unit_dimension_type_t* t);\nvoid to_json(json &j, units_dat_t::staredit_group_flags_type_t* t);\nvoid to_json(json &j, units_dat_t::staredit_availability_flags_type_t* t);\n\nvoid to_json(json &j, iscript_bin_t::opcode_type_t* opcode);\nvoid to_json(json &j, std::vector<iscript_bin_t::opcode_type_t*> opcode_vec);\nvoid to_json(json &j, iscript_bin_t::u2_type_t *u2);\nvoid to_json(json &j, iscript_bin_t::u1_type_t *u1);\nvoid to_json(json &j, iscript_bin_t::pos_type_t *pos);\nvoid to_json(json &j, iscript_bin_t::playsndbtwn_type_t *snd);\nvoid to_json(json &j, iscript_bin_t::trgcondjmp_type_t *trgcondjmp);\nvoid to_json(json &j, iscript_bin_t::imgl_type_t *imgl);\nvoid to_json(json &j, iscript_bin_t::sprl_type_t *sprl);\nvoid to_json(json &j, iscript_bin_t::trgtrangecondjmp_type_t *ttcj);\nvoid to_json(json &j, iscript_bin_t::randcondjmp_type_t *rcj);\nvoid to_json(json &j, iscript_bin_t::playsounds_type_t *ps);\nvoid to_json(json &j, iscript_bin_t::sprov_type_t *sprov);\n\n// -> file_tbl.ksy\n\n// -> specific wrapper objects in dat namespace\n\nnamespace dat {\n\nvoid to_json(json &j, TblEntry t);\nvoid to_json(json &j, Upgrade u);\nvoid to_json(json &j, Techdata t);\nvoid to_json(json &j, Order o);\nvoid to_json(json &j, Weapon w);\nvoid to_json(json &j, Sfx s);\nvoid to_json(json &j, Portrait p);\nvoid to_json(json &j, Image i);\nvoid to_json(json &j, Sprite s);\nvoid to_json(json &j, Flingy f);\nvoid to_json(json &j, Unit u);\nvoid to_json(json &j, IScript i);\n\n} /* namespace dat */\n\n#endif /* TO_JSON_H_ */\n"
  },
  {
    "path": "tools/tblreader.c",
    "content": "#include <stdio.h>\n#include <string.h>\n\nvoid print(char *str)\n{\n\tchar buf[4096];\n\tchar *b = buf;\n\tstatic int count = 1;\n\n\tmemset(buf, 0, sizeof(buf));\n\n\twhile (*str) {\n\t\tif (*str < 20) {\n\t\t\tstrcpy(b, \"~color\");\n\t\t\tb += 6;\n\t\t\t*b++ = *str++ + '0';\n\t\t\t*b++ = '~';\n\t\t} else if (*str == '\"') {\n\t\t\t*b++ = '\\\\';\n\t\t\t*b++ = *str++;\n\t\t} else {\n\t\t\t*b++ = *str++;\n\t\t}\n\t}\n\tprintf(\"%d %s\\n\", count++, buf);\n}\n\nint main(int argc, char *argv[])\n{\n\tFILE *fd = fopen(argv[1], \"rb\");\n\tchar *buf = (char *)malloc(1024*1024);\n\tchar *ptr = buf;\n\tint *offset;\n\tint i;\n\tint num;\n\n\tfread(buf, 1, 1024*1024, fd);\n\tfclose(fd);\n\n\tnum = *(short *)buf;\n\toffset = (int *)malloc(num * sizeof(int));\n\n\tfor (i = 0; i < num; ++i) {\n\t\toffset[i] = ((short *)buf)[i + 1];\n\t}\n\n\tfor (i = 0; i < num; ++i) {\n\t\tprint(buf + offset[i]);\n\t}\n\n\tfree(buf);\n\tfree(offset);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "tools/unit_dat.cpp",
    "content": "\r\nconst char ** WeaponTypes = {\"unknown\", \"explosive\", \"concussive\", \"normal\", \"spell\"};\r\n\r\n#pragma pack(1)\r\n\r\nstruct WeaponType\r\n{\r\n\tunsigned short label;\r\n\tunsigned short sprite;\r\n\tunsigned short spell;\r\n\tunsigned short flag;\n\tunsigned short range;\r\n\tunsigned short upgrade_type;\r\n\tunsigned short type;\r\n\tunsigned short mbehavior;\r\n\tunsigned short mtype;\n\tunsigned short explosion;\n\tunsigned short splash;\r\n\tunsigned short damage;\n\tunsigned short bonus;\r\n\tunsigned short cool;\r\n\tunsigned short factor;\r\n\tunsigned short pos1;\r\n\tunsigned short pos2;\r\n\tunsigned short msg;\r\n\tunsigned short icon;\r\n};\r\n\r\n#pragma pop()\r\n"
  }
]